widget/android/AndroidBridge.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef AndroidBridge_h__
michael@0 7 #define AndroidBridge_h__
michael@0 8
michael@0 9 #include <jni.h>
michael@0 10 #include <android/log.h>
michael@0 11 #include <cstdlib>
michael@0 12 #include <pthread.h>
michael@0 13
michael@0 14 #include "nsCOMPtr.h"
michael@0 15 #include "nsCOMArray.h"
michael@0 16
michael@0 17 #include "GeneratedJNIWrappers.h"
michael@0 18
michael@0 19 #include "nsIMutableArray.h"
michael@0 20 #include "nsIMIMEInfo.h"
michael@0 21 #include "nsColor.h"
michael@0 22 #include "gfxRect.h"
michael@0 23
michael@0 24 #include "nsIAndroidBridge.h"
michael@0 25 #include "nsIMobileMessageCallback.h"
michael@0 26
michael@0 27 #include "mozilla/Likely.h"
michael@0 28 #include "mozilla/StaticPtr.h"
michael@0 29 #include "mozilla/layers/GeckoContentController.h"
michael@0 30 #include "mozilla/TimeStamp.h"
michael@0 31
michael@0 32 // Some debug #defines
michael@0 33 // #define DEBUG_ANDROID_EVENTS
michael@0 34 // #define DEBUG_ANDROID_WIDGET
michael@0 35
michael@0 36 class nsWindow;
michael@0 37 class nsIDOMMozSmsMessage;
michael@0 38 class nsIObserver;
michael@0 39
michael@0 40 /* See the comment in AndroidBridge about this function before using it */
michael@0 41 extern "C" JNIEnv * GetJNIForThread();
michael@0 42
michael@0 43 extern bool mozilla_AndroidBridge_SetMainThread(pthread_t);
michael@0 44
michael@0 45 namespace base {
michael@0 46 class Thread;
michael@0 47 } // end namespace base
michael@0 48
michael@0 49 typedef void* EGLSurface;
michael@0 50
michael@0 51 namespace mozilla {
michael@0 52
michael@0 53 namespace hal {
michael@0 54 class BatteryInformation;
michael@0 55 class NetworkInformation;
michael@0 56 } // namespace hal
michael@0 57
michael@0 58 namespace dom {
michael@0 59 namespace mobilemessage {
michael@0 60 struct SmsFilterData;
michael@0 61 struct SmsSegmentInfoData;
michael@0 62 } // namespace mobilemessage
michael@0 63 } // namespace dom
michael@0 64
michael@0 65 namespace layers {
michael@0 66 class CompositorParent;
michael@0 67 } // namespace layers
michael@0 68
michael@0 69 // The order and number of the members in this structure must correspond
michael@0 70 // to the attrsAppearance array in GeckoAppShell.getSystemColors()
michael@0 71 typedef struct AndroidSystemColors {
michael@0 72 nscolor textColorPrimary;
michael@0 73 nscolor textColorPrimaryInverse;
michael@0 74 nscolor textColorSecondary;
michael@0 75 nscolor textColorSecondaryInverse;
michael@0 76 nscolor textColorTertiary;
michael@0 77 nscolor textColorTertiaryInverse;
michael@0 78 nscolor textColorHighlight;
michael@0 79 nscolor colorForeground;
michael@0 80 nscolor colorBackground;
michael@0 81 nscolor panelColorForeground;
michael@0 82 nscolor panelColorBackground;
michael@0 83 } AndroidSystemColors;
michael@0 84
michael@0 85 class nsFilePickerCallback : nsISupports {
michael@0 86 public:
michael@0 87 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 88 virtual void handleResult(nsAString& filePath) = 0;
michael@0 89 nsFilePickerCallback() {}
michael@0 90 protected:
michael@0 91 virtual ~nsFilePickerCallback() {}
michael@0 92 };
michael@0 93
michael@0 94 class DelayedTask {
michael@0 95 public:
michael@0 96 DelayedTask(Task* aTask, int aDelayMs) {
michael@0 97 mTask = aTask;
michael@0 98 mRunTime = TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs);
michael@0 99 }
michael@0 100
michael@0 101 bool IsEarlierThan(DelayedTask *aOther) {
michael@0 102 return mRunTime < aOther->mRunTime;
michael@0 103 }
michael@0 104
michael@0 105 int64_t MillisecondsToRunTime() {
michael@0 106 TimeDuration timeLeft = mRunTime - TimeStamp::Now();
michael@0 107 return (int64_t)timeLeft.ToMilliseconds();
michael@0 108 }
michael@0 109
michael@0 110 Task* GetTask() {
michael@0 111 return mTask;
michael@0 112 }
michael@0 113
michael@0 114 private:
michael@0 115 Task* mTask;
michael@0 116 TimeStamp mRunTime;
michael@0 117 };
michael@0 118
michael@0 119
michael@0 120 class AndroidBridge MOZ_FINAL : public mozilla::layers::GeckoContentController
michael@0 121 {
michael@0 122 public:
michael@0 123 enum {
michael@0 124 // Values for NotifyIME, in addition to values from the Gecko
michael@0 125 // IMEMessage enum; use negative values here to prevent conflict
michael@0 126 NOTIFY_IME_OPEN_VKB = -2,
michael@0 127 NOTIFY_IME_REPLY_EVENT = -1,
michael@0 128 };
michael@0 129
michael@0 130 enum {
michael@0 131 LAYER_CLIENT_TYPE_NONE = 0,
michael@0 132 LAYER_CLIENT_TYPE_GL = 2 // AndroidGeckoGLLayerClient
michael@0 133 };
michael@0 134
michael@0 135 static void ConstructBridge(JNIEnv *jEnv);
michael@0 136
michael@0 137 static AndroidBridge *Bridge() {
michael@0 138 return sBridge.get();
michael@0 139 }
michael@0 140
michael@0 141 static JavaVM *GetVM() {
michael@0 142 MOZ_ASSERT(sBridge);
michael@0 143 return sBridge->mJavaVM;
michael@0 144 }
michael@0 145
michael@0 146
michael@0 147 static JNIEnv *GetJNIEnv() {
michael@0 148 MOZ_ASSERT(sBridge);
michael@0 149 if (MOZ_UNLIKELY(!pthread_equal(pthread_self(), sBridge->mThread))) {
michael@0 150 MOZ_CRASH();
michael@0 151 }
michael@0 152 MOZ_ASSERT(sBridge->mJNIEnv);
michael@0 153 return sBridge->mJNIEnv;
michael@0 154 }
michael@0 155
michael@0 156 static bool HasEnv() {
michael@0 157 return sBridge && sBridge->mJNIEnv;
michael@0 158 }
michael@0 159
michael@0 160 static bool ThrowException(JNIEnv *aEnv, const char *aClass,
michael@0 161 const char *aMessage) {
michael@0 162 MOZ_ASSERT(aEnv, "Invalid thread JNI env");
michael@0 163 jclass cls = aEnv->FindClass(aClass);
michael@0 164 MOZ_ASSERT(cls, "Cannot find exception class");
michael@0 165 bool ret = !aEnv->ThrowNew(cls, aMessage);
michael@0 166 aEnv->DeleteLocalRef(cls);
michael@0 167 return ret;
michael@0 168 }
michael@0 169
michael@0 170 static bool ThrowException(JNIEnv *aEnv, const char *aMessage) {
michael@0 171 return ThrowException(aEnv, "java/lang/Exception", aMessage);
michael@0 172 }
michael@0 173
michael@0 174 static void HandleUncaughtException(JNIEnv *aEnv) {
michael@0 175 MOZ_ASSERT(aEnv);
michael@0 176 if (!aEnv->ExceptionCheck()) {
michael@0 177 return;
michael@0 178 }
michael@0 179 jthrowable e = aEnv->ExceptionOccurred();
michael@0 180 MOZ_ASSERT(e);
michael@0 181 aEnv->ExceptionClear();
michael@0 182 mozilla::widget::android::GeckoAppShell::HandleUncaughtException(nullptr, e);
michael@0 183 // Should be dead by now...
michael@0 184 MOZ_CRASH("Failed to handle uncaught exception");
michael@0 185 }
michael@0 186
michael@0 187 // The bridge needs to be constructed via ConstructBridge first,
michael@0 188 // and then once the Gecko main thread is spun up (Gecko side),
michael@0 189 // SetMainThread should be called which will create the JNIEnv for
michael@0 190 // us to use. toolkit/xre/nsAndroidStartup.cpp calls
michael@0 191 // SetMainThread.
michael@0 192 bool SetMainThread(pthread_t thr);
michael@0 193
michael@0 194 /* These are all implemented in Java */
michael@0 195 bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
michael@0 196 bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
michael@0 197
michael@0 198 nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
michael@0 199 void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
michael@0 200 void ContentDocumentChanged();
michael@0 201 bool IsContentDocumentDisplayed();
michael@0 202
michael@0 203 bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, mozilla::ParentLayerRect& aCompositionBounds, mozilla::CSSToParentLayerScale& aZoom);
michael@0 204
michael@0 205 void SetLayerClient(JNIEnv* env, jobject jobj);
michael@0 206 mozilla::widget::android::GeckoLayerClient* GetLayerClient() { return mLayerClient; }
michael@0 207
michael@0 208 bool GetHandlersForURL(const nsAString& aURL,
michael@0 209 nsIMutableArray* handlersArray = nullptr,
michael@0 210 nsIHandlerApp **aDefaultApp = nullptr,
michael@0 211 const nsAString& aAction = EmptyString());
michael@0 212
michael@0 213 bool GetHandlersForMimeType(const nsAString& aMimeType,
michael@0 214 nsIMutableArray* handlersArray = nullptr,
michael@0 215 nsIHandlerApp **aDefaultApp = nullptr,
michael@0 216 const nsAString& aAction = EmptyString());
michael@0 217
michael@0 218 void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType);
michael@0 219 void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt);
michael@0 220
michael@0 221 bool GetClipboardText(nsAString& aText);
michael@0 222
michael@0 223 void ShowAlertNotification(const nsAString& aImageUrl,
michael@0 224 const nsAString& aAlertTitle,
michael@0 225 const nsAString& aAlertText,
michael@0 226 const nsAString& aAlertData,
michael@0 227 nsIObserver *aAlertListener,
michael@0 228 const nsAString& aAlertName);
michael@0 229
michael@0 230 int GetDPI();
michael@0 231 int GetScreenDepth();
michael@0 232
michael@0 233 void ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions);
michael@0 234 void ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType);
michael@0 235 void ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback);
michael@0 236
michael@0 237 void Vibrate(const nsTArray<uint32_t>& aPattern);
michael@0 238
michael@0 239 void GetSystemColors(AndroidSystemColors *aColors);
michael@0 240
michael@0 241 void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf);
michael@0 242
michael@0 243 // Switch Java to composite with the Gecko Compositor thread
michael@0 244 void RegisterCompositor(JNIEnv* env = nullptr);
michael@0 245 EGLSurface CreateEGLSurfaceForCompositor();
michael@0 246
michael@0 247 bool GetStaticStringField(const char *classID, const char *field, nsAString &result, JNIEnv* env = nullptr);
michael@0 248
michael@0 249 bool GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* env = nullptr);
michael@0 250
michael@0 251 // These next four functions are for native Bitmap access in Android 2.2+
michael@0 252 bool HasNativeBitmapAccess();
michael@0 253
michael@0 254 bool ValidateBitmap(jobject bitmap, int width, int height);
michael@0 255
michael@0 256 void *LockBitmap(jobject bitmap);
michael@0 257
michael@0 258 // Returns a global reference to the Context for Fennec's Activity. The
michael@0 259 // caller is responsible for ensuring this doesn't leak by calling
michael@0 260 // DeleteGlobalRef() when the context is no longer needed.
michael@0 261 jobject GetGlobalContextRef(void);
michael@0 262
michael@0 263 void UnlockBitmap(jobject bitmap);
michael@0 264
michael@0 265 /* Copied from Android's native_window.h in newer (platform 9) NDK */
michael@0 266 enum {
michael@0 267 WINDOW_FORMAT_RGBA_8888 = 1,
michael@0 268 WINDOW_FORMAT_RGBX_8888 = 2,
michael@0 269 WINDOW_FORMAT_RGB_565 = 4
michael@0 270 };
michael@0 271
michael@0 272 bool HasNativeWindowAccess();
michael@0 273
michael@0 274 void *AcquireNativeWindow(JNIEnv* aEnv, jobject aSurface);
michael@0 275 void ReleaseNativeWindow(void *window);
michael@0 276
michael@0 277 void *AcquireNativeWindowFromSurfaceTexture(JNIEnv* aEnv, jobject aSurface);
michael@0 278 void ReleaseNativeWindowForSurfaceTexture(void *window);
michael@0 279
michael@0 280 bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
michael@0 281 bool UnlockWindow(void *window);
michael@0 282
michael@0 283 void HandleGeckoMessage(JSContext* cx, JS::HandleObject message);
michael@0 284
michael@0 285 bool InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps);
michael@0 286
michael@0 287 void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
michael@0 288
michael@0 289 nsresult GetSegmentInfoForText(const nsAString& aText,
michael@0 290 nsIMobileMessageCallback* aRequest);
michael@0 291 void SendMessage(const nsAString& aNumber, const nsAString& aText,
michael@0 292 nsIMobileMessageCallback* aRequest);
michael@0 293 void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
michael@0 294 void DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
michael@0 295 void CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter,
michael@0 296 bool aReverse, nsIMobileMessageCallback* aRequest);
michael@0 297 void GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest);
michael@0 298 already_AddRefed<nsIMobileMessageCallback> DequeueSmsRequest(uint32_t aRequestId);
michael@0 299
michael@0 300 void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
michael@0 301
michael@0 302 void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
michael@0 303 void SetPageRect(const CSSRect& aCssPageRect);
michael@0 304 void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
michael@0 305 bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
michael@0 306 LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
michael@0 307 void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
michael@0 308 bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
michael@0 309 bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
michael@0 310
michael@0 311 void AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen);
michael@0 312
michael@0 313 // These methods don't use a ScreenOrientation because it's an
michael@0 314 // enum and that would require including the header which requires
michael@0 315 // include IPC headers which requires including basictypes.h which
michael@0 316 // requires a lot of changes...
michael@0 317 uint32_t GetScreenOrientation();
michael@0 318
michael@0 319 int GetAPIVersion() { return mAPIVersion; }
michael@0 320 bool IsHoneycomb() { return mAPIVersion >= 11 && mAPIVersion <= 13; }
michael@0 321
michael@0 322 void ScheduleComposite();
michael@0 323
michael@0 324 nsresult GetProxyForURI(const nsACString & aSpec,
michael@0 325 const nsACString & aScheme,
michael@0 326 const nsACString & aHost,
michael@0 327 const int32_t aPort,
michael@0 328 nsACString & aResult);
michael@0 329
michael@0 330 // Utility methods.
michael@0 331 static jstring NewJavaString(JNIEnv* env, const char16_t* string, uint32_t len);
michael@0 332 static jstring NewJavaString(JNIEnv* env, const nsAString& string);
michael@0 333 static jstring NewJavaString(JNIEnv* env, const char* string);
michael@0 334 static jstring NewJavaString(JNIEnv* env, const nsACString& string);
michael@0 335
michael@0 336 static jstring NewJavaString(AutoLocalJNIFrame* frame, const char16_t* string, uint32_t len);
michael@0 337 static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string);
michael@0 338 static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string);
michael@0 339 static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string);
michael@0 340
michael@0 341 static jclass GetClassGlobalRef(JNIEnv* env, const char* className);
michael@0 342 static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
michael@0 343 static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
michael@0 344 static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
michael@0 345 static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
michael@0 346 protected:
michael@0 347 static StaticRefPtr<AndroidBridge> sBridge;
michael@0 348 nsTArray<nsCOMPtr<nsIMobileMessageCallback> > mSmsRequests;
michael@0 349
michael@0 350 // the global JavaVM
michael@0 351 JavaVM *mJavaVM;
michael@0 352
michael@0 353 // the JNIEnv for the main thread
michael@0 354 JNIEnv *mJNIEnv;
michael@0 355 pthread_t mThread;
michael@0 356
michael@0 357 mozilla::widget::android::GeckoLayerClient *mLayerClient;
michael@0 358
michael@0 359 // the android.telephony.SmsMessage class
michael@0 360 jclass mAndroidSmsMessageClass;
michael@0 361
michael@0 362 AndroidBridge();
michael@0 363 ~AndroidBridge();
michael@0 364
michael@0 365 void InitStubs(JNIEnv *jEnv);
michael@0 366 bool Init(JNIEnv *jEnv);
michael@0 367
michael@0 368 bool mOpenedGraphicsLibraries;
michael@0 369 void OpenGraphicsLibraries();
michael@0 370 void* GetNativeSurface(JNIEnv* env, jobject surface);
michael@0 371
michael@0 372 bool mHasNativeBitmapAccess;
michael@0 373 bool mHasNativeWindowAccess;
michael@0 374 bool mHasNativeWindowFallback;
michael@0 375
michael@0 376 int mAPIVersion;
michael@0 377
michael@0 378 bool QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut);
michael@0 379
michael@0 380 // other things
michael@0 381 jmethodID jNotifyAppShellReady;
michael@0 382 jmethodID jGetOutstandingDrawEvents;
michael@0 383 jmethodID jPostToJavaThread;
michael@0 384 jmethodID jCreateSurface;
michael@0 385 jmethodID jShowSurface;
michael@0 386 jmethodID jHideSurface;
michael@0 387 jmethodID jDestroySurface;
michael@0 388
michael@0 389 jmethodID jCalculateLength;
michael@0 390
michael@0 391 // For native surface stuff
michael@0 392 jclass jSurfaceClass;
michael@0 393 jfieldID jSurfacePointerField;
michael@0 394
michael@0 395 jclass jLayerView;
michael@0 396
michael@0 397 jfieldID jEGLSurfacePointerField;
michael@0 398 mozilla::widget::android::GLController *mGLControllerObj;
michael@0 399
michael@0 400 // some convinient types to have around
michael@0 401 jclass jStringClass;
michael@0 402
michael@0 403 // calls we've dlopened from libjnigraphics.so
michael@0 404 int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
michael@0 405 int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
michael@0 406 int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
michael@0 407
michael@0 408 void* (*ANativeWindow_fromSurface)(JNIEnv *env, jobject surface);
michael@0 409 void* (*ANativeWindow_fromSurfaceTexture)(JNIEnv *env, jobject surfaceTexture);
michael@0 410 void (*ANativeWindow_release)(void *window);
michael@0 411 int (*ANativeWindow_setBuffersGeometry)(void *window, int width, int height, int format);
michael@0 412
michael@0 413 int (* ANativeWindow_lock)(void *window, void *outBuffer, void *inOutDirtyBounds);
michael@0 414 int (* ANativeWindow_unlockAndPost)(void *window);
michael@0 415
michael@0 416 int (* Surface_lock)(void* surface, void* surfaceInfo, void* region, bool block);
michael@0 417 int (* Surface_unlockAndPost)(void* surface);
michael@0 418 void (* Region_constructor)(void* region);
michael@0 419 void (* Region_set)(void* region, void* rect);
michael@0 420
michael@0 421 private:
michael@0 422 mozilla::widget::android::NativePanZoomController* mNativePanZoomController;
michael@0 423 // This will always be accessed from one thread (the APZC "controller"
michael@0 424 // thread, which is the Java UI thread), so we don't need to do locking
michael@0 425 // to touch it
michael@0 426 nsTArray<DelayedTask*> mDelayedTaskQueue;
michael@0 427
michael@0 428 public:
michael@0 429 mozilla::widget::android::NativePanZoomController* SetNativePanZoomController(jobject obj);
michael@0 430 // GeckoContentController methods
michael@0 431 void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE;
michael@0 432 void AcknowledgeScrollUpdate(const mozilla::layers::FrameMetrics::ViewID& aScrollId,
michael@0 433 const uint32_t& aScrollGeneration) MOZ_OVERRIDE;
michael@0 434 void HandleDoubleTap(const CSSPoint& aPoint,
michael@0 435 int32_t aModifiers,
michael@0 436 const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
michael@0 437 void HandleSingleTap(const CSSPoint& aPoint,
michael@0 438 int32_t aModifiers,
michael@0 439 const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
michael@0 440 void HandleLongTap(const CSSPoint& aPoint,
michael@0 441 int32_t aModifiers,
michael@0 442 const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
michael@0 443 void HandleLongTapUp(const CSSPoint& aPoint,
michael@0 444 int32_t aModifiers,
michael@0 445 const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
michael@0 446 void SendAsyncScrollDOMEvent(bool aIsRoot,
michael@0 447 const CSSRect& aContentRect,
michael@0 448 const CSSSize& aScrollableSize) MOZ_OVERRIDE;
michael@0 449 void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE;
michael@0 450 int64_t RunDelayedTasks();
michael@0 451 };
michael@0 452
michael@0 453 class AutoJObject {
michael@0 454 public:
michael@0 455 AutoJObject(JNIEnv* aJNIEnv = nullptr) : mObject(nullptr)
michael@0 456 {
michael@0 457 mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
michael@0 458 }
michael@0 459
michael@0 460 AutoJObject(JNIEnv* aJNIEnv, jobject aObject)
michael@0 461 {
michael@0 462 mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
michael@0 463 mObject = aObject;
michael@0 464 }
michael@0 465
michael@0 466 ~AutoJObject() {
michael@0 467 if (mObject)
michael@0 468 mJNIEnv->DeleteLocalRef(mObject);
michael@0 469 }
michael@0 470
michael@0 471 jobject operator=(jobject aObject)
michael@0 472 {
michael@0 473 if (mObject) {
michael@0 474 mJNIEnv->DeleteLocalRef(mObject);
michael@0 475 }
michael@0 476 return mObject = aObject;
michael@0 477 }
michael@0 478
michael@0 479 operator jobject() {
michael@0 480 return mObject;
michael@0 481 }
michael@0 482 private:
michael@0 483 JNIEnv* mJNIEnv;
michael@0 484 jobject mObject;
michael@0 485 };
michael@0 486
michael@0 487 class AutoLocalJNIFrame {
michael@0 488 public:
michael@0 489 AutoLocalJNIFrame(int nEntries = 15)
michael@0 490 : mEntries(nEntries)
michael@0 491 , mJNIEnv(AndroidBridge::GetJNIEnv())
michael@0 492 , mHasFrameBeenPushed(false)
michael@0 493 {
michael@0 494 MOZ_ASSERT(mJNIEnv);
michael@0 495 Push();
michael@0 496 }
michael@0 497
michael@0 498 AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 15)
michael@0 499 : mEntries(nEntries)
michael@0 500 , mJNIEnv(aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv())
michael@0 501 , mHasFrameBeenPushed(false)
michael@0 502 {
michael@0 503 MOZ_ASSERT(mJNIEnv);
michael@0 504 Push();
michael@0 505 }
michael@0 506
michael@0 507 ~AutoLocalJNIFrame() {
michael@0 508 if (mHasFrameBeenPushed) {
michael@0 509 Pop();
michael@0 510 }
michael@0 511 }
michael@0 512
michael@0 513 JNIEnv* GetEnv() {
michael@0 514 return mJNIEnv;
michael@0 515 }
michael@0 516
michael@0 517 bool CheckForException() {
michael@0 518 if (mJNIEnv->ExceptionCheck()) {
michael@0 519 AndroidBridge::HandleUncaughtException(mJNIEnv);
michael@0 520 return true;
michael@0 521 }
michael@0 522 return false;
michael@0 523 }
michael@0 524
michael@0 525 // Note! Calling Purge makes all previous local refs created in
michael@0 526 // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down
michael@0 527 // any local refs that you need to keep around in global refs!
michael@0 528 void Purge() {
michael@0 529 Pop();
michael@0 530 Push();
michael@0 531 }
michael@0 532
michael@0 533 template <typename ReturnType = jobject>
michael@0 534 ReturnType Pop(ReturnType aResult = nullptr) {
michael@0 535 MOZ_ASSERT(mHasFrameBeenPushed);
michael@0 536 mHasFrameBeenPushed = false;
michael@0 537 return static_cast<ReturnType>(
michael@0 538 mJNIEnv->PopLocalFrame(static_cast<jobject>(aResult)));
michael@0 539 }
michael@0 540
michael@0 541 private:
michael@0 542 void Push() {
michael@0 543 MOZ_ASSERT(!mHasFrameBeenPushed);
michael@0 544 // Make sure there is enough space to store a local ref to the
michael@0 545 // exception. I am not completely sure this is needed, but does
michael@0 546 // not hurt.
michael@0 547 if (mJNIEnv->PushLocalFrame(mEntries + 1) != 0) {
michael@0 548 CheckForException();
michael@0 549 return;
michael@0 550 }
michael@0 551 mHasFrameBeenPushed = true;
michael@0 552 }
michael@0 553
michael@0 554 const int mEntries;
michael@0 555 JNIEnv* const mJNIEnv;
michael@0 556 bool mHasFrameBeenPushed;
michael@0 557 };
michael@0 558
michael@0 559 }
michael@0 560
michael@0 561 #define NS_ANDROIDBRIDGE_CID \
michael@0 562 { 0x0FE2321D, 0xEBD9, 0x467D, \
michael@0 563 { 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E } }
michael@0 564
michael@0 565 class nsAndroidBridge MOZ_FINAL : public nsIAndroidBridge
michael@0 566 {
michael@0 567 public:
michael@0 568 NS_DECL_ISUPPORTS
michael@0 569 NS_DECL_NSIANDROIDBRIDGE
michael@0 570
michael@0 571 nsAndroidBridge();
michael@0 572
michael@0 573 private:
michael@0 574 ~nsAndroidBridge();
michael@0 575
michael@0 576 protected:
michael@0 577 };
michael@0 578
michael@0 579 #endif /* AndroidBridge_h__ */

mercurial