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

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

mercurial