widget/android/AndroidBridge.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/widget/android/AndroidBridge.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,579 @@
     1.4 +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef AndroidBridge_h__
    1.10 +#define AndroidBridge_h__
    1.11 +
    1.12 +#include <jni.h>
    1.13 +#include <android/log.h>
    1.14 +#include <cstdlib>
    1.15 +#include <pthread.h>
    1.16 +
    1.17 +#include "nsCOMPtr.h"
    1.18 +#include "nsCOMArray.h"
    1.19 +
    1.20 +#include "GeneratedJNIWrappers.h"
    1.21 +
    1.22 +#include "nsIMutableArray.h"
    1.23 +#include "nsIMIMEInfo.h"
    1.24 +#include "nsColor.h"
    1.25 +#include "gfxRect.h"
    1.26 +
    1.27 +#include "nsIAndroidBridge.h"
    1.28 +#include "nsIMobileMessageCallback.h"
    1.29 +
    1.30 +#include "mozilla/Likely.h"
    1.31 +#include "mozilla/StaticPtr.h"
    1.32 +#include "mozilla/layers/GeckoContentController.h"
    1.33 +#include "mozilla/TimeStamp.h"
    1.34 +
    1.35 +// Some debug #defines
    1.36 +// #define DEBUG_ANDROID_EVENTS
    1.37 +// #define DEBUG_ANDROID_WIDGET
    1.38 +
    1.39 +class nsWindow;
    1.40 +class nsIDOMMozSmsMessage;
    1.41 +class nsIObserver;
    1.42 +
    1.43 +/* See the comment in AndroidBridge about this function before using it */
    1.44 +extern "C" JNIEnv * GetJNIForThread();
    1.45 +
    1.46 +extern bool mozilla_AndroidBridge_SetMainThread(pthread_t);
    1.47 +
    1.48 +namespace base {
    1.49 +class Thread;
    1.50 +} // end namespace base
    1.51 +
    1.52 +typedef void* EGLSurface;
    1.53 +
    1.54 +namespace mozilla {
    1.55 +
    1.56 +namespace hal {
    1.57 +class BatteryInformation;
    1.58 +class NetworkInformation;
    1.59 +} // namespace hal
    1.60 +
    1.61 +namespace dom {
    1.62 +namespace mobilemessage {
    1.63 +struct SmsFilterData;
    1.64 +struct SmsSegmentInfoData;
    1.65 +} // namespace mobilemessage
    1.66 +} // namespace dom
    1.67 +
    1.68 +namespace layers {
    1.69 +class CompositorParent;
    1.70 +} // namespace layers
    1.71 +
    1.72 +// The order and number of the members in this structure must correspond
    1.73 +// to the attrsAppearance array in GeckoAppShell.getSystemColors()
    1.74 +typedef struct AndroidSystemColors {
    1.75 +    nscolor textColorPrimary;
    1.76 +    nscolor textColorPrimaryInverse;
    1.77 +    nscolor textColorSecondary;
    1.78 +    nscolor textColorSecondaryInverse;
    1.79 +    nscolor textColorTertiary;
    1.80 +    nscolor textColorTertiaryInverse;
    1.81 +    nscolor textColorHighlight;
    1.82 +    nscolor colorForeground;
    1.83 +    nscolor colorBackground;
    1.84 +    nscolor panelColorForeground;
    1.85 +    nscolor panelColorBackground;
    1.86 +} AndroidSystemColors;
    1.87 +
    1.88 +class nsFilePickerCallback : nsISupports {
    1.89 +public:
    1.90 +    NS_DECL_THREADSAFE_ISUPPORTS
    1.91 +    virtual void handleResult(nsAString& filePath) = 0;
    1.92 +    nsFilePickerCallback() {}
    1.93 +protected:
    1.94 +    virtual ~nsFilePickerCallback() {}
    1.95 +};
    1.96 +
    1.97 +class DelayedTask {
    1.98 +public:
    1.99 +    DelayedTask(Task* aTask, int aDelayMs) {
   1.100 +        mTask = aTask;
   1.101 +        mRunTime = TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs);
   1.102 +    }
   1.103 +
   1.104 +    bool IsEarlierThan(DelayedTask *aOther) {
   1.105 +        return mRunTime < aOther->mRunTime;
   1.106 +    }
   1.107 +
   1.108 +    int64_t MillisecondsToRunTime() {
   1.109 +        TimeDuration timeLeft = mRunTime - TimeStamp::Now();
   1.110 +        return (int64_t)timeLeft.ToMilliseconds();
   1.111 +    }
   1.112 +
   1.113 +    Task* GetTask() {
   1.114 +        return mTask;
   1.115 +    }
   1.116 +
   1.117 +private:
   1.118 +    Task* mTask;
   1.119 +    TimeStamp mRunTime;
   1.120 +};
   1.121 +
   1.122 +
   1.123 +class AndroidBridge MOZ_FINAL : public mozilla::layers::GeckoContentController
   1.124 +{
   1.125 +public:
   1.126 +    enum {
   1.127 +        // Values for NotifyIME, in addition to values from the Gecko
   1.128 +        // IMEMessage enum; use negative values here to prevent conflict
   1.129 +        NOTIFY_IME_OPEN_VKB = -2,
   1.130 +        NOTIFY_IME_REPLY_EVENT = -1,
   1.131 +    };
   1.132 +
   1.133 +    enum {
   1.134 +        LAYER_CLIENT_TYPE_NONE = 0,
   1.135 +        LAYER_CLIENT_TYPE_GL = 2            // AndroidGeckoGLLayerClient
   1.136 +    };
   1.137 +
   1.138 +    static void ConstructBridge(JNIEnv *jEnv);
   1.139 +
   1.140 +    static AndroidBridge *Bridge() {
   1.141 +        return sBridge.get();
   1.142 +    }
   1.143 +
   1.144 +    static JavaVM *GetVM() {
   1.145 +        MOZ_ASSERT(sBridge);
   1.146 +        return sBridge->mJavaVM;
   1.147 +    }
   1.148 +
   1.149 +
   1.150 +    static JNIEnv *GetJNIEnv() {
   1.151 +        MOZ_ASSERT(sBridge);
   1.152 +        if (MOZ_UNLIKELY(!pthread_equal(pthread_self(), sBridge->mThread))) {
   1.153 +            MOZ_CRASH();
   1.154 +        }
   1.155 +        MOZ_ASSERT(sBridge->mJNIEnv);
   1.156 +        return sBridge->mJNIEnv;
   1.157 +    }
   1.158 +
   1.159 +    static bool HasEnv() {
   1.160 +        return sBridge && sBridge->mJNIEnv;
   1.161 +    }
   1.162 +
   1.163 +    static bool ThrowException(JNIEnv *aEnv, const char *aClass,
   1.164 +                               const char *aMessage) {
   1.165 +        MOZ_ASSERT(aEnv, "Invalid thread JNI env");
   1.166 +        jclass cls = aEnv->FindClass(aClass);
   1.167 +        MOZ_ASSERT(cls, "Cannot find exception class");
   1.168 +        bool ret = !aEnv->ThrowNew(cls, aMessage);
   1.169 +        aEnv->DeleteLocalRef(cls);
   1.170 +        return ret;
   1.171 +    }
   1.172 +
   1.173 +    static bool ThrowException(JNIEnv *aEnv, const char *aMessage) {
   1.174 +        return ThrowException(aEnv, "java/lang/Exception", aMessage);
   1.175 +    }
   1.176 +
   1.177 +    static void HandleUncaughtException(JNIEnv *aEnv) {
   1.178 +        MOZ_ASSERT(aEnv);
   1.179 +        if (!aEnv->ExceptionCheck()) {
   1.180 +            return;
   1.181 +        }
   1.182 +        jthrowable e = aEnv->ExceptionOccurred();
   1.183 +        MOZ_ASSERT(e);
   1.184 +        aEnv->ExceptionClear();
   1.185 +        mozilla::widget::android::GeckoAppShell::HandleUncaughtException(nullptr, e);
   1.186 +        // Should be dead by now...
   1.187 +        MOZ_CRASH("Failed to handle uncaught exception");
   1.188 +    }
   1.189 +
   1.190 +    // The bridge needs to be constructed via ConstructBridge first,
   1.191 +    // and then once the Gecko main thread is spun up (Gecko side),
   1.192 +    // SetMainThread should be called which will create the JNIEnv for
   1.193 +    // us to use.  toolkit/xre/nsAndroidStartup.cpp calls
   1.194 +    // SetMainThread.
   1.195 +    bool SetMainThread(pthread_t thr);
   1.196 +
   1.197 +    /* These are all implemented in Java */
   1.198 +    bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
   1.199 +    bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
   1.200 +
   1.201 +    nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
   1.202 +    void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
   1.203 +    void ContentDocumentChanged();
   1.204 +    bool IsContentDocumentDisplayed();
   1.205 +
   1.206 +    bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, mozilla::ParentLayerRect& aCompositionBounds, mozilla::CSSToParentLayerScale& aZoom);
   1.207 +
   1.208 +    void SetLayerClient(JNIEnv* env, jobject jobj);
   1.209 +    mozilla::widget::android::GeckoLayerClient* GetLayerClient() { return mLayerClient; }
   1.210 +
   1.211 +    bool GetHandlersForURL(const nsAString& aURL,
   1.212 +                           nsIMutableArray* handlersArray = nullptr,
   1.213 +                           nsIHandlerApp **aDefaultApp = nullptr,
   1.214 +                           const nsAString& aAction = EmptyString());
   1.215 +
   1.216 +    bool GetHandlersForMimeType(const nsAString& aMimeType,
   1.217 +                                nsIMutableArray* handlersArray = nullptr,
   1.218 +                                nsIHandlerApp **aDefaultApp = nullptr,
   1.219 +                                const nsAString& aAction = EmptyString());
   1.220 +
   1.221 +    void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType);
   1.222 +    void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt);
   1.223 +
   1.224 +    bool GetClipboardText(nsAString& aText);
   1.225 +
   1.226 +    void ShowAlertNotification(const nsAString& aImageUrl,
   1.227 +                               const nsAString& aAlertTitle,
   1.228 +                               const nsAString& aAlertText,
   1.229 +                               const nsAString& aAlertData,
   1.230 +                               nsIObserver *aAlertListener,
   1.231 +                               const nsAString& aAlertName);
   1.232 +
   1.233 +    int GetDPI();
   1.234 +    int GetScreenDepth();
   1.235 +
   1.236 +    void ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions);
   1.237 +    void ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType);
   1.238 +    void ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback);
   1.239 +
   1.240 +    void Vibrate(const nsTArray<uint32_t>& aPattern);
   1.241 +
   1.242 +    void GetSystemColors(AndroidSystemColors *aColors);
   1.243 +
   1.244 +    void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf);
   1.245 +
   1.246 +    // Switch Java to composite with the Gecko Compositor thread
   1.247 +    void RegisterCompositor(JNIEnv* env = nullptr);
   1.248 +    EGLSurface CreateEGLSurfaceForCompositor();
   1.249 +
   1.250 +    bool GetStaticStringField(const char *classID, const char *field, nsAString &result, JNIEnv* env = nullptr);
   1.251 +
   1.252 +    bool GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* env = nullptr);
   1.253 +
   1.254 +    // These next four functions are for native Bitmap access in Android 2.2+
   1.255 +    bool HasNativeBitmapAccess();
   1.256 +
   1.257 +    bool ValidateBitmap(jobject bitmap, int width, int height);
   1.258 +
   1.259 +    void *LockBitmap(jobject bitmap);
   1.260 +
   1.261 +    // Returns a global reference to the Context for Fennec's Activity. The
   1.262 +    // caller is responsible for ensuring this doesn't leak by calling
   1.263 +    // DeleteGlobalRef() when the context is no longer needed.
   1.264 +    jobject GetGlobalContextRef(void);
   1.265 +
   1.266 +    void UnlockBitmap(jobject bitmap);
   1.267 +
   1.268 +    /* Copied from Android's native_window.h in newer (platform 9) NDK */
   1.269 +    enum {
   1.270 +        WINDOW_FORMAT_RGBA_8888          = 1,
   1.271 +        WINDOW_FORMAT_RGBX_8888          = 2,
   1.272 +        WINDOW_FORMAT_RGB_565            = 4
   1.273 +    };
   1.274 +
   1.275 +    bool HasNativeWindowAccess();
   1.276 +
   1.277 +    void *AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface);
   1.278 +    void ReleaseNativeWindow(void *window);
   1.279 +
   1.280 +    void *AcquireNativeWindowFromSurfaceTexture(JNIEnv* aEnv, jobject aSurface);
   1.281 +    void ReleaseNativeWindowForSurfaceTexture(void *window);
   1.282 +
   1.283 +    bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
   1.284 +    bool UnlockWindow(void *window);
   1.285 +
   1.286 +    void HandleGeckoMessage(JSContext* cx, JS::HandleObject message);
   1.287 +
   1.288 +    bool InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps);
   1.289 +
   1.290 +    void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
   1.291 +
   1.292 +    nsresult GetSegmentInfoForText(const nsAString& aText,
   1.293 +                                   nsIMobileMessageCallback* aRequest);
   1.294 +    void SendMessage(const nsAString& aNumber, const nsAString& aText,
   1.295 +                     nsIMobileMessageCallback* aRequest);
   1.296 +    void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
   1.297 +    void DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
   1.298 +    void CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter,
   1.299 +                           bool aReverse, nsIMobileMessageCallback* aRequest);
   1.300 +    void GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest);
   1.301 +    already_AddRefed<nsIMobileMessageCallback> DequeueSmsRequest(uint32_t aRequestId);
   1.302 +
   1.303 +    void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
   1.304 +
   1.305 +    void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
   1.306 +    void SetPageRect(const CSSRect& aCssPageRect);
   1.307 +    void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
   1.308 +                          bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
   1.309 +                          LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
   1.310 +    void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
   1.311 +                          bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
   1.312 +                          bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
   1.313 +
   1.314 +    void AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen);
   1.315 +
   1.316 +    // These methods don't use a ScreenOrientation because it's an
   1.317 +    // enum and that would require including the header which requires
   1.318 +    // include IPC headers which requires including basictypes.h which
   1.319 +    // requires a lot of changes...
   1.320 +    uint32_t GetScreenOrientation();
   1.321 +
   1.322 +    int GetAPIVersion() { return mAPIVersion; }
   1.323 +    bool IsHoneycomb() { return mAPIVersion >= 11 && mAPIVersion <= 13; }
   1.324 +
   1.325 +    void ScheduleComposite();
   1.326 +
   1.327 +    nsresult GetProxyForURI(const nsACString & aSpec,
   1.328 +                            const nsACString & aScheme,
   1.329 +                            const nsACString & aHost,
   1.330 +                            const int32_t      aPort,
   1.331 +                            nsACString & aResult);
   1.332 +
   1.333 +    // Utility methods.
   1.334 +    static jstring NewJavaString(JNIEnv* env, const char16_t* string, uint32_t len);
   1.335 +    static jstring NewJavaString(JNIEnv* env, const nsAString& string);
   1.336 +    static jstring NewJavaString(JNIEnv* env, const char* string);
   1.337 +    static jstring NewJavaString(JNIEnv* env, const nsACString& string);
   1.338 +
   1.339 +    static jstring NewJavaString(AutoLocalJNIFrame* frame, const char16_t* string, uint32_t len);
   1.340 +    static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string);
   1.341 +    static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string);
   1.342 +    static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string);
   1.343 +
   1.344 +    static jclass GetClassGlobalRef(JNIEnv* env, const char* className);
   1.345 +    static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
   1.346 +    static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
   1.347 +    static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
   1.348 +    static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
   1.349 +protected:
   1.350 +    static StaticRefPtr<AndroidBridge> sBridge;
   1.351 +    nsTArray<nsCOMPtr<nsIMobileMessageCallback> > mSmsRequests;
   1.352 +
   1.353 +    // the global JavaVM
   1.354 +    JavaVM *mJavaVM;
   1.355 +
   1.356 +    // the JNIEnv for the main thread
   1.357 +    JNIEnv *mJNIEnv;
   1.358 +    pthread_t mThread;
   1.359 +
   1.360 +    mozilla::widget::android::GeckoLayerClient *mLayerClient;
   1.361 +
   1.362 +    // the android.telephony.SmsMessage class
   1.363 +    jclass mAndroidSmsMessageClass;
   1.364 +
   1.365 +    AndroidBridge();
   1.366 +    ~AndroidBridge();
   1.367 +
   1.368 +    void InitStubs(JNIEnv *jEnv);
   1.369 +    bool Init(JNIEnv *jEnv);
   1.370 +
   1.371 +    bool mOpenedGraphicsLibraries;
   1.372 +    void OpenGraphicsLibraries();
   1.373 +    void* GetNativeSurface(JNIEnv* env, jobject surface);
   1.374 +
   1.375 +    bool mHasNativeBitmapAccess;
   1.376 +    bool mHasNativeWindowAccess;
   1.377 +    bool mHasNativeWindowFallback;
   1.378 +
   1.379 +    int mAPIVersion;
   1.380 +
   1.381 +    bool QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut);
   1.382 +
   1.383 +    // other things
   1.384 +    jmethodID jNotifyAppShellReady;
   1.385 +    jmethodID jGetOutstandingDrawEvents;
   1.386 +    jmethodID jPostToJavaThread;
   1.387 +    jmethodID jCreateSurface;
   1.388 +    jmethodID jShowSurface;
   1.389 +    jmethodID jHideSurface;
   1.390 +    jmethodID jDestroySurface;
   1.391 +
   1.392 +    jmethodID jCalculateLength;
   1.393 +
   1.394 +    // For native surface stuff
   1.395 +    jclass jSurfaceClass;
   1.396 +    jfieldID jSurfacePointerField;
   1.397 +
   1.398 +    jclass jLayerView;
   1.399 +
   1.400 +    jfieldID jEGLSurfacePointerField;
   1.401 +    mozilla::widget::android::GLController *mGLControllerObj;
   1.402 +
   1.403 +    // some convinient types to have around
   1.404 +    jclass jStringClass;
   1.405 +
   1.406 +    // calls we've dlopened from libjnigraphics.so
   1.407 +    int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
   1.408 +    int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
   1.409 +    int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
   1.410 +
   1.411 +    void* (*ANativeWindow_fromSurface)(JNIEnv *env, jobject surface);
   1.412 +    void* (*ANativeWindow_fromSurfaceTexture)(JNIEnv *env, jobject surfaceTexture);
   1.413 +    void (*ANativeWindow_release)(void *window);
   1.414 +    int (*ANativeWindow_setBuffersGeometry)(void *window, int width, int height, int format);
   1.415 +
   1.416 +    int (* ANativeWindow_lock)(void *window, void *outBuffer, void *inOutDirtyBounds);
   1.417 +    int (* ANativeWindow_unlockAndPost)(void *window);
   1.418 +
   1.419 +    int (* Surface_lock)(void* surface, void* surfaceInfo, void* region, bool block);
   1.420 +    int (* Surface_unlockAndPost)(void* surface);
   1.421 +    void (* Region_constructor)(void* region);
   1.422 +    void (* Region_set)(void* region, void* rect);
   1.423 +
   1.424 +private:
   1.425 +    mozilla::widget::android::NativePanZoomController* mNativePanZoomController;
   1.426 +    // This will always be accessed from one thread (the APZC "controller"
   1.427 +    // thread, which is the Java UI thread), so we don't need to do locking
   1.428 +    // to touch it
   1.429 +    nsTArray<DelayedTask*> mDelayedTaskQueue;
   1.430 +
   1.431 +public:
   1.432 +    mozilla::widget::android::NativePanZoomController* SetNativePanZoomController(jobject obj);
   1.433 +    // GeckoContentController methods
   1.434 +    void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE;
   1.435 +    void AcknowledgeScrollUpdate(const mozilla::layers::FrameMetrics::ViewID& aScrollId,
   1.436 +                                 const uint32_t& aScrollGeneration) MOZ_OVERRIDE;
   1.437 +    void HandleDoubleTap(const CSSPoint& aPoint,
   1.438 +                         int32_t aModifiers,
   1.439 +                         const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
   1.440 +    void HandleSingleTap(const CSSPoint& aPoint,
   1.441 +                         int32_t aModifiers,
   1.442 +                         const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
   1.443 +    void HandleLongTap(const CSSPoint& aPoint,
   1.444 +                       int32_t aModifiers,
   1.445 +                       const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
   1.446 +    void HandleLongTapUp(const CSSPoint& aPoint,
   1.447 +                         int32_t aModifiers,
   1.448 +                         const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
   1.449 +    void SendAsyncScrollDOMEvent(bool aIsRoot,
   1.450 +                                 const CSSRect& aContentRect,
   1.451 +                                 const CSSSize& aScrollableSize) MOZ_OVERRIDE;
   1.452 +    void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE;
   1.453 +    int64_t RunDelayedTasks();
   1.454 +};
   1.455 +
   1.456 +class AutoJObject {
   1.457 +public:
   1.458 +    AutoJObject(JNIEnv* aJNIEnv = nullptr) : mObject(nullptr)
   1.459 +    {
   1.460 +        mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
   1.461 +    }
   1.462 +
   1.463 +    AutoJObject(JNIEnv* aJNIEnv, jobject aObject)
   1.464 +    {
   1.465 +        mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
   1.466 +        mObject = aObject;
   1.467 +    }
   1.468 +
   1.469 +    ~AutoJObject() {
   1.470 +        if (mObject)
   1.471 +            mJNIEnv->DeleteLocalRef(mObject);
   1.472 +    }
   1.473 +
   1.474 +    jobject operator=(jobject aObject)
   1.475 +    {
   1.476 +        if (mObject) {
   1.477 +            mJNIEnv->DeleteLocalRef(mObject);
   1.478 +        }
   1.479 +        return mObject = aObject;
   1.480 +    }
   1.481 +
   1.482 +    operator jobject() {
   1.483 +        return mObject;
   1.484 +    }
   1.485 +private:
   1.486 +    JNIEnv* mJNIEnv;
   1.487 +    jobject mObject;
   1.488 +};
   1.489 +
   1.490 +class AutoLocalJNIFrame {
   1.491 +public:
   1.492 +    AutoLocalJNIFrame(int nEntries = 15)
   1.493 +        : mEntries(nEntries)
   1.494 +        , mJNIEnv(AndroidBridge::GetJNIEnv())
   1.495 +        , mHasFrameBeenPushed(false)
   1.496 +    {
   1.497 +        MOZ_ASSERT(mJNIEnv);
   1.498 +        Push();
   1.499 +    }
   1.500 +
   1.501 +    AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 15)
   1.502 +        : mEntries(nEntries)
   1.503 +        , mJNIEnv(aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv())
   1.504 +        , mHasFrameBeenPushed(false)
   1.505 +    {
   1.506 +        MOZ_ASSERT(mJNIEnv);
   1.507 +        Push();
   1.508 +    }
   1.509 +
   1.510 +    ~AutoLocalJNIFrame() {
   1.511 +        if (mHasFrameBeenPushed) {
   1.512 +            Pop();
   1.513 +        }
   1.514 +    }
   1.515 +
   1.516 +    JNIEnv* GetEnv() {
   1.517 +        return mJNIEnv;
   1.518 +    }
   1.519 +
   1.520 +    bool CheckForException() {
   1.521 +        if (mJNIEnv->ExceptionCheck()) {
   1.522 +            AndroidBridge::HandleUncaughtException(mJNIEnv);
   1.523 +            return true;
   1.524 +        }
   1.525 +        return false;
   1.526 +    }
   1.527 +
   1.528 +    // Note! Calling Purge makes all previous local refs created in
   1.529 +    // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down
   1.530 +    // any local refs that you need to keep around in global refs!
   1.531 +    void Purge() {
   1.532 +        Pop();
   1.533 +        Push();
   1.534 +    }
   1.535 +
   1.536 +    template <typename ReturnType = jobject>
   1.537 +    ReturnType Pop(ReturnType aResult = nullptr) {
   1.538 +        MOZ_ASSERT(mHasFrameBeenPushed);
   1.539 +        mHasFrameBeenPushed = false;
   1.540 +        return static_cast<ReturnType>(
   1.541 +            mJNIEnv->PopLocalFrame(static_cast<jobject>(aResult)));
   1.542 +    }
   1.543 +
   1.544 +private:
   1.545 +    void Push() {
   1.546 +        MOZ_ASSERT(!mHasFrameBeenPushed);
   1.547 +        // Make sure there is enough space to store a local ref to the
   1.548 +        // exception.  I am not completely sure this is needed, but does
   1.549 +        // not hurt.
   1.550 +        if (mJNIEnv->PushLocalFrame(mEntries + 1) != 0) {
   1.551 +            CheckForException();
   1.552 +            return;
   1.553 +        }
   1.554 +        mHasFrameBeenPushed = true;
   1.555 +    }
   1.556 +
   1.557 +    const int mEntries;
   1.558 +    JNIEnv* const mJNIEnv;
   1.559 +    bool mHasFrameBeenPushed;
   1.560 +};
   1.561 +
   1.562 +}
   1.563 +
   1.564 +#define NS_ANDROIDBRIDGE_CID \
   1.565 +{ 0x0FE2321D, 0xEBD9, 0x467D, \
   1.566 +    { 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E } }
   1.567 +
   1.568 +class nsAndroidBridge MOZ_FINAL : public nsIAndroidBridge
   1.569 +{
   1.570 +public:
   1.571 +  NS_DECL_ISUPPORTS
   1.572 +  NS_DECL_NSIANDROIDBRIDGE
   1.573 +
   1.574 +  nsAndroidBridge();
   1.575 +
   1.576 +private:
   1.577 +  ~nsAndroidBridge();
   1.578 +
   1.579 +protected:
   1.580 +};
   1.581 +
   1.582 +#endif /* AndroidBridge_h__ */

mercurial