Backed out changeset 0904d8d19947 (bug 913985)
authorEd Morley <emorley@mozilla.com>
Mon, 30 Sep 2013 11:05:35 +0100
changeset 163061 6d82bdf0976509332fb82bab859bf7d94972239e
parent 163060 f60769ee4b04bf570dbbc3979f5a65372f2b574c
child 163062 e03da5926c66f6176171b3f9265c57fce3fbecae
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs913985
milestone27.0a1
backs out0904d8d199472032685b714ad09a93b59e3678f0
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 0904d8d19947 (bug 913985)
dom/ipc/ContentParent.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/system/android/AndroidLocationProvider.cpp
dom/system/android/nsHapticFeedback.cpp
gfx/gl/GLContext.h
gfx/thebes/nsSurfaceTexture.cpp
hal/android/AndroidHal.cpp
hal/android/AndroidSensor.cpp
ipc/glue/MessagePump.cpp
mobile/android/components/build/nsAndroidHistory.cpp
mobile/android/components/build/nsShellService.cpp
netwerk/base/src/Tickler.cpp
netwerk/protocol/device/CameraStreamImpl.cpp
netwerk/system/android/nsAndroidNetworkLinkService.cpp
toolkit/components/alerts/nsAlertsService.cpp
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/components/jsdownloads/src/DownloadPlatform.cpp
toolkit/xre/nsAndroidStartup.cpp
toolkit/xre/nsAppRunner.cpp
tools/profiler/TableTicker.cpp
tools/profiler/platform.cpp
uriloader/exthandler/android/nsAndroidHandlerApp.cpp
uriloader/exthandler/android/nsExternalSharingAppService.cpp
uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidBridgeUtilities.h
widget/android/AndroidJNI.cpp
widget/android/AndroidJNIWrapper.cpp
widget/android/AndroidJavaWrappers.cpp
widget/android/AndroidJavaWrappers.h
widget/android/nsAppShell.cpp
widget/android/nsClipboard.cpp
widget/android/nsIMEPicker.cpp
widget/android/nsLookAndFeel.cpp
widget/android/nsScreenManagerAndroid.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
xpcom/base/nsSystemInfo.cpp
xpcom/components/ManifestParser.cpp
xpcom/io/nsLocalFileUnix.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1555,17 +1555,17 @@ ContentParent::RecvGetIconForExtension(c
 bool
 ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
 {
     // default behavior is to show the last password character
     *showPassword = true;
 #ifdef MOZ_WIDGET_ANDROID
     NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
     if (AndroidBridge::Bridge() != nullptr)
-        *showPassword = GeckoAppShell::GetShowPasswordSetting();
+        *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
 #endif
     return true;
 }
 
 bool
 ContentParent::RecvFirstIdle()
 {
     // When the ContentChild goes idle, it sends us a FirstIdle message which we
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -2255,17 +2255,21 @@ NPError NP_CALLBACK
     case kSupportedDrawingModel_ANPGetValue: {
       LOG("get supported drawing model");
       uint32_t* bits = reinterpret_cast<uint32_t*>(result);
       *bits = kBitmap_ANPDrawingModel && kSurface_ANPDrawingModel;
       return NPERR_NO_ERROR;
     }  
 
     case kJavaContext_ANPGetValue: {
-      jobject ret = GeckoAppShell::GetContext();
+      AndroidBridge *bridge = AndroidBridge::Bridge();
+      if (!bridge)
+        return NPERR_GENERIC_ERROR;
+
+      jobject ret = bridge->GetContext();
       if (!ret)
         return NPERR_GENERIC_ERROR;
 
       int32_t* i  = reinterpret_cast<int32_t*>(result);
       *i = reinterpret_cast<int32_t>(ret);
       return NPERR_NO_ERROR;
     }
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -860,17 +860,17 @@ void nsNPAPIPluginInstance::NotifyFullSc
 
   if (RUNNING != mRunning || mFullScreen == aFullScreen)
     return;
 
   mFullScreen = aFullScreen;
   SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
 
   if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) {
-    GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
+    AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation);
   }
 }
 
 void nsNPAPIPluginInstance::NotifySize(nsIntSize size)
 {
   if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() ||
       size == mCurrentSize)
     return;
@@ -917,21 +917,21 @@ void nsNPAPIPluginInstance::SetFullScree
 
   uint32_t oldOrientation = mFullScreenOrientation;
   mFullScreenOrientation = orientation;
 
   if (mFullScreen) {
     // We're already fullscreen so immediately apply the orientation change
 
     if (mFullScreenOrientation != dom::eScreenOrientation_None) {
-      GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
+      AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation);
     } else if (oldOrientation != dom::eScreenOrientation_None) {
       // We applied an orientation when we entered fullscreen, but
       // we don't want it anymore
-      GeckoAppShell::UnlockScreenOrientation();
+      AndroidBridge::Bridge()->UnlockScreenOrientation();
     }
   }
 }
 
 void nsNPAPIPluginInstance::PopPostedEvent(PluginEventRunnable* r)
 {
   mPostedEvents.RemoveElement(r);
 }
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1653,17 +1653,19 @@ bool nsPluginInstanceOwner::AddPluginVie
   return true;
 }
 
 void nsPluginInstanceOwner::RemovePluginView()
 {
   if (!mInstance || !mJavaView)
     return;
 
-  GeckoAppShell::RemovePluginView((jobject)mJavaView, mFullScreen);
+  if (AndroidBridge::Bridge())
+    AndroidBridge::Bridge()->RemovePluginView((jobject)mJavaView, mFullScreen);
+
   AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView);
   mJavaView = nullptr;
 
   if (mFullScreen)
     sFullScreenInstance = nullptr;
 }
 
 void nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
--- a/dom/system/android/AndroidLocationProvider.cpp
+++ b/dom/system/android/AndroidLocationProvider.cpp
@@ -23,17 +23,17 @@ AndroidLocationProvider::~AndroidLocatio
     NS_IF_RELEASE(gLocationCallback);
 }
 
 NS_IMETHODIMP
 AndroidLocationProvider::Startup()
 {
     if (!AndroidBridge::Bridge())
         return NS_ERROR_NOT_IMPLEMENTED;
-    GeckoAppShell::EnableLocation(true);
+    AndroidBridge::Bridge()->EnableLocation(true);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
     NS_IF_RELEASE(gLocationCallback);
     gLocationCallback = aCallback;
@@ -41,20 +41,20 @@ AndroidLocationProvider::Watch(nsIGeoloc
     return NS_OK;
 }
 
 NS_IMETHODIMP
 AndroidLocationProvider::Shutdown()
 {
     if (!AndroidBridge::Bridge())
         return NS_ERROR_NOT_IMPLEMENTED;
-    GeckoAppShell::EnableLocation(false);
+    AndroidBridge::Bridge()->EnableLocation(false);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 AndroidLocationProvider::SetHighAccuracy(bool enable)
 {
     if (!AndroidBridge::Bridge())
         return NS_ERROR_NOT_IMPLEMENTED;
-    GeckoAppShell::EnableLocationHighAccuracy(enable);
+    AndroidBridge::Bridge()->EnableLocationHighAccuracy(enable);
     return NS_OK;
 }
--- a/dom/system/android/nsHapticFeedback.cpp
+++ b/dom/system/android/nsHapticFeedback.cpp
@@ -11,13 +11,13 @@ using namespace mozilla;
 
 NS_IMPL_ISUPPORTS1(nsHapticFeedback, nsIHapticFeedback)
 
 NS_IMETHODIMP
 nsHapticFeedback::PerformSimpleAction(int32_t aType)
 {
     AndroidBridge* bridge = AndroidBridge::Bridge();
     if (bridge) {
-        GeckoAppShell::PerformHapticFeedback(aType == LongPress);
+        bridge->PerformHapticFeedback(aType == LongPress);
         return NS_OK;
     }
     return NS_ERROR_FAILURE;
 }
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2413,17 +2413,17 @@ public:
 
 #ifdef MOZ_WIDGET_GONK
     virtual EGLImage CreateEGLImageForNativeBuffer(void* buffer) = 0;
     virtual void DestroyEGLImage(EGLImage image) = 0;
     virtual EGLImage GetNullEGLImage() = 0;
 #endif
 
     virtual already_AddRefed<TextureImage>
-    CreateDirectTextureImage(::android::GraphicBuffer* aBuffer, GLenum aWrapMode)
+    CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode)
     { return nullptr; }
 
     // Before reads from offscreen texture
     void GuaranteeResolve();
 
 protected:
     GLuint mTexBlit_Buffer;
     GLuint mTexBlit_VertShader;
--- a/gfx/thebes/nsSurfaceTexture.cpp
+++ b/gfx/thebes/nsSurfaceTexture.cpp
@@ -205,17 +205,17 @@ nsSurfaceTexture::~nsSurfaceTexture()
     mNativeWindow = nullptr;
   }
 
   JNIEnv* env = GetJNIForThread();
   if (!env)
     return;
 
   if (mSurfaceTexture && env) {
-    GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
+    AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
 
     env->DeleteGlobalRef(mSurfaceTexture);
     mSurfaceTexture = nullptr;
   }
 }
 
 void*
 nsSurfaceTexture::GetNativeWindow()
@@ -234,19 +234,19 @@ nsSurfaceTexture::GetTransformMatrix(gfx
 {
   return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix);
 }
 
 void
 nsSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
 {
   if (aRunnable)
-    GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
+    AndroidBridge::Bridge()->RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
   else
-    GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
+    AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
 
   mFrameAvailableCallback = aRunnable;
 }
 
 void
 nsSurfaceTexture::NotifyFrameAvailable()
 {
   if (mFrameAvailableCallback) {
--- a/hal/android/AndroidHal.cpp
+++ b/hal/android/AndroidHal.cpp
@@ -9,17 +9,16 @@
 #include "AndroidBridge.h"
 #include "mozilla/dom/network/Constants.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "nsIScreenManager.h"
 #include "nsServiceManagerUtils.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal;
-using namespace mozilla::widget::android;
 
 namespace mozilla {
 namespace hal_impl {
 
 void
 Vibrate(const nsTArray<uint32_t> &pattern, const WindowIdentifier &)
 {
   // Ignore the WindowIdentifier parameter; it's here only because hal::Vibrate,
@@ -50,65 +49,107 @@ Vibrate(const nsTArray<uint32_t> &patter
   b->Vibrate(pattern);
 }
 
 void
 CancelVibrate(const WindowIdentifier &)
 {
   // Ignore WindowIdentifier parameter.
 
-  GeckoAppShell::CancelVibrate();
+  AndroidBridge* b = AndroidBridge::Bridge();
+  if (b)
+    b->CancelVibrate();
 }
 
 void
 EnableBatteryNotifications()
 {
-  GeckoAppShell::EnableBatteryNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->EnableBatteryNotifications();
 }
 
 void
 DisableBatteryNotifications()
 {
-  GeckoAppShell::DisableBatteryNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->DisableBatteryNotifications();
 }
 
 void
 GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
 {
-  AndroidBridge::Bridge()->GetCurrentBatteryInformation(aBatteryInfo);
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->GetCurrentBatteryInformation(aBatteryInfo);
 }
 
 void
 EnableNetworkNotifications()
 {
-  GeckoAppShell::EnableNetworkNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->EnableNetworkNotifications();
 }
 
 void
 DisableNetworkNotifications()
 {
-  GeckoAppShell::DisableNetworkNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->DisableNetworkNotifications();
 }
 
 void
 GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo)
 {
-  AndroidBridge::Bridge()->GetCurrentNetworkInformation(aNetworkInfo);
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->GetCurrentNetworkInformation(aNetworkInfo);
 }
 
 void
 EnableScreenConfigurationNotifications()
 {
-  GeckoAppShell::EnableScreenOrientationNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->EnableScreenOrientationNotifications();
 }
 
 void
 DisableScreenConfigurationNotifications()
 {
-  GeckoAppShell::DisableScreenOrientationNotifications();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->DisableScreenOrientationNotifications();
 }
 
 void
 GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
 {
   AndroidBridge* bridge = AndroidBridge::Bridge();
   if (!bridge) {
     return;
@@ -135,36 +176,42 @@ GetCurrentScreenConfiguration(ScreenConf
 
   *aScreenConfiguration =
     hal::ScreenConfiguration(rect, orientation, colorDepth, pixelDepth);
 }
 
 bool
 LockScreenOrientation(const ScreenOrientation& aOrientation)
 {
-  if (!AndroidBridge::Bridge()) {
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
     return false;
   }
 
   switch (aOrientation) {
     // The Android backend only supports these orientations.
     case eScreenOrientation_PortraitPrimary:
     case eScreenOrientation_PortraitSecondary:
     case eScreenOrientation_PortraitPrimary | eScreenOrientation_PortraitSecondary:
     case eScreenOrientation_LandscapePrimary:
     case eScreenOrientation_LandscapeSecondary:
     case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary:
-      GeckoAppShell::LockScreenOrientation(aOrientation);
+      bridge->LockScreenOrientation(aOrientation);
       return true;
     default:
       return false;
   }
 }
 
 void
 UnlockScreenOrientation()
 {
-  GeckoAppShell::UnlockScreenOrientation();
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->UnlockScreenOrientation();
 }
 
 } // hal_impl
 } // mozilla
 
--- a/hal/android/AndroidSensor.cpp
+++ b/hal/android/AndroidSensor.cpp
@@ -8,18 +8,18 @@
 
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal_impl {
 
 void
 EnableSensorNotifications(SensorType aSensor) {
-  GeckoAppShell::EnableSensor(aSensor);
+  AndroidBridge::Bridge()->EnableSensor(aSensor);
 }
 
 void
 DisableSensorNotifications(SensorType aSensor) {
-  GeckoAppShell::DisableSensor(aSensor);
+  AndroidBridge::Bridge()->DisableSensor(aSensor);
 }
 
 } // hal_impl
 } // mozilla
--- a/ipc/glue/MessagePump.cpp
+++ b/ipc/glue/MessagePump.cpp
@@ -86,17 +86,17 @@ MessagePump::Run(MessagePump::Delegate* 
     // here.  To ensure that MessageLoop tasks and XPCOM events have
     // equal priority, we sensitively rely on processing exactly one
     // Task per DoWorkRunnable XPCOM event.
 
 #ifdef MOZ_WIDGET_ANDROID
     // This processes messages in the Android Looper. Note that we only
     // get here if the normal Gecko event loop has been awoken above.
     // Bug 750713
-    did_work |= GeckoAppShell::PumpMessageLoop();
+    did_work |= AndroidBridge::Bridge()->PumpMessageLoop();
 #endif
 
     did_work |= aDelegate->DoDelayedWork(&delayed_work_time_);
 
     if (did_work && delayed_work_time_.is_null())
       mDelayedWorkTimer->Cancel();
 
     if (!keep_running_)
--- a/mobile/android/components/build/nsAndroidHistory.cpp
+++ b/mobile/android/components/build/nsAndroidHistory.cpp
@@ -45,17 +45,20 @@ nsAndroidHistory::RegisterVisitedCallbac
 
   nsTArray<Link*>* list = mListeners.Get(uriString);
   if (! list) {
     list = new nsTArray<Link*>();
     mListeners.Put(uriString, list);
   }
   list->AppendElement(aContent);
 
- GeckoAppShell::CheckURIVisited(uriString);
+  AndroidBridge *bridge = AndroidBridge::Bridge();
+  if (bridge) {
+    bridge->CheckURIVisited(uriString);
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidHistory::UnregisterVisitedCallback(nsIURI *aURI, Link *aContent)
 {
   if (!aContent || !aURI)
@@ -88,35 +91,37 @@ nsAndroidHistory::VisitURI(nsIURI *aURI,
     return NS_OK;
 
   if (aFlags & VisitFlags::REDIRECT_SOURCE)
     return NS_OK;
 
   if (aFlags & VisitFlags::UNRECOVERABLE_ERROR)
     return NS_OK;
 
-  if (AndroidBridge::Bridge()) {
+  AndroidBridge *bridge = AndroidBridge::Bridge();
+  if (bridge) {
     nsAutoCString uri;
     nsresult rv = aURI->GetSpec(uri);
     if (NS_FAILED(rv)) return rv;
     NS_ConvertUTF8toUTF16 uriString(uri);
-    GeckoAppShell::MarkURIVisited(uriString);
+    bridge->MarkURIVisited(uriString);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidHistory::SetURITitle(nsIURI *aURI, const nsAString& aTitle)
 {
-  if (AndroidBridge::Bridge()) {
+  AndroidBridge *bridge = AndroidBridge::Bridge();
+  if (bridge) {
     nsAutoCString uri;
     nsresult rv = aURI->GetSpec(uri);
     if (NS_FAILED(rv)) return rv;
     NS_ConvertUTF8toUTF16 uriString(uri);
-    GeckoAppShell::SetURITitle(uriString, aTitle);
+    bridge->SetURITitle(uriString, aTitle);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidHistory::NotifyVisited(nsIURI *aURI)
 {
   if (aURI && sHistory) {
--- a/mobile/android/components/build/nsShellService.cpp
+++ b/mobile/android/components/build/nsShellService.cpp
@@ -3,27 +3,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsShellService.h"
 #include "nsString.h"
 
 #include "AndroidBridge.h"
 
-using namespace mozilla::widget::android;
-
 NS_IMPL_ISUPPORTS1(nsShellService, nsIShellService)
 
 NS_IMETHODIMP
 nsShellService::SwitchTask()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, const nsAString& aIconData, const nsAString& aIntent)
 {
   if (!aTitle.Length() || !aURI.Length() || !aIconData.Length())
     return NS_ERROR_FAILURE;
 
-  GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData, aIntent);
+  mozilla::AndroidBridge::Bridge()->CreateShortcut(aTitle, aURI, aIconData, aIntent);
   return NS_OK;
 }
--- a/netwerk/base/src/Tickler.cpp
+++ b/netwerk/base/src/Tickler.cpp
@@ -75,17 +75,17 @@ nsresult
 Tickler::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mTimer);
   MOZ_ASSERT(!mActive);
   MOZ_ASSERT(!mThread);
   MOZ_ASSERT(!mFD);
 
-  GeckoAppShell::EnableNetworkNotifications();
+  AndroidBridge::Bridge()->EnableNetworkNotifications();
 
   mFD = PR_OpenUDPSocket(PR_AF_INET);
   if (!mFD)
     return NS_ERROR_FAILURE;
 
   // make sure new socket has a ttl of 1
   // failure is not fatal.
   PRSocketOptionData opt;
--- a/netwerk/protocol/device/CameraStreamImpl.cpp
+++ b/netwerk/protocol/device/CameraStreamImpl.cpp
@@ -85,14 +85,14 @@ bool CameraStreamImpl::Init(const nsCStr
 {
     mCallback = aCallback;
     mWidth = width;
     mHeight = height;
     return AndroidBridge::Bridge()->InitCamera(contentType, camera, &mWidth, &mHeight, &mFps);
 }
 
 void CameraStreamImpl::Close() {
-    GeckoAppShell::CloseCamera();
+    AndroidBridge::Bridge()->CloseCamera();
     mCallback = nullptr;
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/system/android/nsAndroidNetworkLinkService.cpp
+++ b/netwerk/system/android/nsAndroidNetworkLinkService.cpp
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAndroidNetworkLinkService.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/Services.h"
 
 #include "AndroidBridge.h"
 
-using namespace mozilla::widget::android;
-
 NS_IMPL_ISUPPORTS1(nsAndroidNetworkLinkService,
                    nsINetworkLinkService)
 
 nsAndroidNetworkLinkService::nsAndroidNetworkLinkService()
 {
 }
 
 nsAndroidNetworkLinkService::~nsAndroidNetworkLinkService()
@@ -28,26 +26,26 @@ nsAndroidNetworkLinkService::GetIsLinkUp
 {
   if (!mozilla::AndroidBridge::Bridge()) {
     // Fail soft here and assume a connection exists
     NS_WARNING("GetIsLinkUp is not supported without a bridge connection");
     *aIsUp = true;
     return NS_OK;
   }
 
-  *aIsUp = GeckoAppShell::IsNetworkLinkUp();
+  *aIsUp = mozilla::AndroidBridge::Bridge()->IsNetworkLinkUp();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidNetworkLinkService::GetLinkStatusKnown(bool *aIsKnown)
 {
   NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_NOT_IMPLEMENTED);
 
-  *aIsKnown = GeckoAppShell::IsNetworkLinkKnown();
+  *aIsKnown = mozilla::AndroidBridge::Bridge()->IsNetworkLinkKnown();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidNetworkLinkService::GetLinkType(uint32_t *aLinkType)
 {
   NS_ENSURE_ARG_POINTER(aLinkType);
 
--- a/toolkit/components/alerts/nsAlertsService.cpp
+++ b/toolkit/components/alerts/nsAlertsService.cpp
@@ -5,17 +5,16 @@
 
 #include "mozilla/dom/ContentChild.h"
 #include "nsXULAppAPI.h"
 
 #include "nsAlertsService.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
-using namespace mozilla::widget::android;
 #else
 
 #include "nsXPCOM.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMWindow.h"
 #include "nsPromiseFlatString.h"
 #include "nsToolkitCompsCID.h"
 
@@ -119,17 +118,17 @@ NS_IMETHODIMP nsAlertsService::CloseAler
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild* cpc = ContentChild::GetSingleton();
     cpc->SendCloseAlert(nsAutoString(aAlertName));
     return NS_OK;
   }
 
 #ifdef MOZ_WIDGET_ANDROID
-  GeckoAppShell::CloseNotification(aAlertName);
+  mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName);
   return NS_OK;
 #else
 
   // Try the system notification service.
   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
   if (sysAlerts) {
     return sysAlerts->CloseAlert(aAlertName);
   }
@@ -140,24 +139,24 @@ NS_IMETHODIMP nsAlertsService::CloseAler
 
 
 NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName,
                                           int64_t aProgress,
                                           int64_t aProgressMax,
                                           const nsAString & aAlertText)
 {
 #ifdef MOZ_WIDGET_ANDROID
-  GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText);
+  mozilla::AndroidBridge::Bridge()->AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText);
   return NS_OK;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif // !MOZ_WIDGET_ANDROID
 }
 
 NS_IMETHODIMP nsAlertsService::OnCancel(const nsAString & aAlertName)
 {
 #ifdef MOZ_WIDGET_ANDROID
-  GeckoAppShell::CloseNotification(aAlertName);
+  mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName);
   return NS_OK;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif // !MOZ_WIDGET_ANDROID
 }
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -46,17 +46,16 @@
 #endif
 
 #ifdef XP_MACOSX
 #include <CoreFoundation/CoreFoundation.h>
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
-using namespace mozilla::widget::android;
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #include <gtk/gtk.h>
 #endif
 
 using namespace mozilla;
 using mozilla::downloads::GenerateGUID;
@@ -2771,17 +2770,17 @@ nsDownload::SetState(DownloadState aStat
 #ifdef MOZ_WIDGET_ANDROID
         nsCOMPtr<nsIMIMEInfo> mimeInfo;
         nsAutoCString contentType;
         GetMIMEInfo(getter_AddRefs(mimeInfo));
 
         if (mimeInfo)
           mimeInfo->GetMIMEType(contentType);
 
-        GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
+        mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
 #endif
       }
 
 #ifdef XP_WIN
       // Adjust file attributes so that by default, new files are indexed
       // by desktop search services. Skip off those that land in the temp
       // folder.
       nsCOMPtr<nsIFile> tempDir, fileDir;
--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
+++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
@@ -113,17 +113,17 @@ nsresult DownloadPlatform::DownloadDone(
                                              kCFStringEncodingUTF8);
     CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter();
     ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"),
                                            observedObject, NULL, TRUE);
     ::CFRelease(observedObject);
 #endif
 #ifdef MOZ_WIDGET_ANDROID
     if (!aContentType.IsEmpty()) {
-      mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType));
+      mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType));
     }
 #endif
   }
 
 #ifdef XP_WIN
   // Adjust file attributes so that by default, new files are indexed by
   // desktop search services. Skip off those that land in the temp folder.
   nsCOMPtr<nsIFile> tempDir, fileDir;
--- a/toolkit/xre/nsAndroidStartup.cpp
+++ b/toolkit/xre/nsAndroidStartup.cpp
@@ -70,14 +70,14 @@ GeckoStart(void *data, const nsXREAppDat
     }
     targs.AppendElement(static_cast<char *>(nullptr));
 
     int result = XRE_main(targs.Length() - 1, targs.Elements(), appData, 0);
 
     if (result)
         LOG("XRE_main returned %d", result);
 
-    mozilla::widget::android::GeckoAppShell::NotifyXreExit();
+    mozilla::AndroidBridge::Bridge()->NotifyXreExit();
 
     free(targs[0]);
     nsMemory::Free(data);
     return;
 }
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1642,17 +1642,17 @@ static nsresult LaunchChild(nsINativeApp
     gRestartArgc = 1;
     gRestartArgv[gRestartArgc] = nullptr;
 #endif
   }
 
   SaveToEnv("MOZ_LAUNCHED_CHILD=1");
 
 #if defined(MOZ_WIDGET_ANDROID)
-  mozilla::widget::android::GeckoAppShell::ScheduleRestart();
+  mozilla::AndroidBridge::Bridge()->ScheduleRestart();
 #else
 #if defined(XP_MACOSX)
   CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true);
   uint32_t restartMode = 0;
   restartMode = gRestartMode;
   LaunchChildMac(gRestartArgc, gRestartArgv, restartMode);
 #else
   nsCOMPtr<nsIFile> lf;
@@ -1754,17 +1754,17 @@ ProfileLockedDialog(nsIFile* aProfileDir
 
     nsCOMPtr<nsIPromptService> ps
       (do_GetService(NS_PROMPTSERVICE_CONTRACTID));
     NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE);
 
     if (aUnlocker) {
       int32_t button;
 #ifdef MOZ_WIDGET_ANDROID
-      mozilla::widget::android::GeckoAppShell::KillAnyZombies();
+      mozilla::AndroidBridge::Bridge()->KillAnyZombies();
       button = 1;
 #else
       const uint32_t flags =
         (nsIPromptService::BUTTON_TITLE_CANCEL * 
          nsIPromptService::BUTTON_POS_0) +
         (nsIPromptService::BUTTON_TITLE_IS_STRING * 
          nsIPromptService::BUTTON_POS_1) +
         nsIPromptService::BUTTON_POS_1_DEFAULT;
@@ -1781,17 +1781,17 @@ ProfileLockedDialog(nsIFile* aProfileDir
         if (NS_FAILED(rv)) 
           return rv;
 
         return NS_LockProfilePath(aProfileDir, aProfileLocalDir, 
                                   nullptr, aResult);
       }
     } else {
 #ifdef MOZ_WIDGET_ANDROID
-      if (mozilla::widget::android::GeckoAppShell::UnlockProfile()) {
+      if (mozilla::AndroidBridge::Bridge()->UnlockProfile()) {
         return NS_LockProfilePath(aProfileDir, aProfileLocalDir, 
                                   nullptr, aResult);
       }
 #else
       rv = ps->Alert(nullptr, killTitle, killMessage);
       NS_ENSURE_SUCCESS_LOG(rv, rv);
 #endif
     }
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -225,17 +225,17 @@ typename Builder::Object BuildJavaThread
         break;
       }
       if (!sample) {
         sample = b.CreateObject();
         frames = b.CreateArray();
         b.DefineProperty(sample, "frames", frames);
         b.ArrayPush(samples, sample);
 
-        double sampleTime = GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId);
+        double sampleTime = AndroidBridge::Bridge()->GetSampleTimeJavaProfiling(0, sampleId);
         b.DefineProperty(sample, "time", sampleTime);
       }
       typename Builder::RootedObject frame(b.context(), b.CreateObject());
       b.DefineProperty(frame, "location", result.BeginReading());
       b.ArrayPush(frames, frame);
       frameId++;
     }
     if (frameId == 0) {
@@ -277,22 +277,22 @@ void TableTicker::BuildJSObject(Builder&
       typename Builder::RootedObject threadSamples(b.context(), b.CreateObject());
       sRegisteredThreads->at(i)->Profile()->BuildJSObject(b, threadSamples);
       b.ArrayPush(threads, threadSamples);
     }
   }
 
 #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
   if (ProfileJava()) {
-    GeckoJavaSampler::PauseJavaProfiling();
+    AndroidBridge::Bridge()->PauseJavaProfiling();
 
     typename Builder::RootedObject javaThread(b.context(), BuildJavaThreadJSObject(b));
     b.ArrayPush(threads, javaThread);
 
-    GeckoJavaSampler::UnpauseJavaProfiling();
+    AndroidBridge::Bridge()->UnpauseJavaProfiling();
   }
 #endif
 
   SetPaused(false);
 
   // Send a event asking any subprocesses (plugins) to
   // give us their information
   SubprocessClosure<Builder> closure(&b, threads);
--- a/tools/profiler/platform.cpp
+++ b/tools/profiler/platform.cpp
@@ -22,17 +22,16 @@
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "mozilla/Services.h"
 #include "nsThreadUtils.h"
 #include "ProfilerMarkers.h"
 
 #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
   #include "AndroidBridge.h"
-  using namespace mozilla::widget::android;
 #endif
 
 mozilla::ThreadLocal<PseudoStack *> tlsPseudoStack;
 mozilla::ThreadLocal<TableTicker *> tlsTicker;
 mozilla::ThreadLocal<void *> tlsStackTop;
 // We need to track whether we've been initialized otherwise
 // we end up using tlsStack without initializing it.
 // Because tlsStack is totally opaque to us we can't reuse
@@ -594,17 +593,17 @@ void mozilla_sampler_start(int aProfileE
 
 #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
   if (t->ProfileJava()) {
     int javaInterval = aInterval;
     // Java sampling doesn't accuratly keep up with 1ms sampling
     if (javaInterval < 10) {
       aInterval = 10;
     }
-    GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000);
+    mozilla::AndroidBridge::Bridge()->StartJavaProfiling(javaInterval, 1000);
   }
 #endif
 
   if (t->AddMainThreadIO()) {
     if (!sInterposeObserver) {
       // Lazily create IO interposer observer
       sInterposeObserver = new mozilla::ProfilerIOInterposeObserver();
     }
--- a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
+++ b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAndroidHandlerApp.h"
 #include "AndroidBridge.h"
 
-using namespace mozilla::widget::android;
-
 
 NS_IMPL_ISUPPORTS2(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp)
 
 nsAndroidHandlerApp::nsAndroidHandlerApp(const nsAString& aName,
                                          const nsAString& aDescription,
                                          const nsAString& aPackageName,
                                          const nsAString& aClassName,
                                          const nsACString& aMimeType,
@@ -67,22 +65,24 @@ nsAndroidHandlerApp::Equals(nsIHandlerAp
 NS_IMETHODIMP
 nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext)
 {
   if (!mozilla::AndroidBridge::Bridge())
     return NS_ERROR_FAILURE;
 
   nsCString uriSpec;
   aURI->GetSpec(uriSpec);
-  return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? 
+  return mozilla::AndroidBridge::Bridge()->
+    OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? 
     NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title)
 {
   if (!mozilla::AndroidBridge::Bridge())
     return NS_ERROR_FAILURE;
 
-  return GeckoAppShell::OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, 
+  return mozilla::AndroidBridge::Bridge()->
+    OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, 
                     mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE;
 }
 
--- a/uriloader/exthandler/android/nsExternalSharingAppService.cpp
+++ b/uriloader/exthandler/android/nsExternalSharingAppService.cpp
@@ -27,18 +27,19 @@ nsExternalSharingAppService::~nsExternal
 NS_IMETHODIMP
 nsExternalSharingAppService::ShareWithDefault(const nsAString & data,
                                               const nsAString & mime,
                                               const nsAString & title)
 {
   NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND");
   const nsString emptyString = EmptyString();
   if (AndroidBridge::Bridge())
-    return GeckoAppShell::OpenUriExternal(data, mime,
-                                          emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE;
+    return AndroidBridge::Bridge()->
+      OpenUriExternal(data, mime,
+                      emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE;
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsExternalSharingAppService::GetSharingApps(const nsAString & aMIMEType,
                                             uint32_t *aLen,
                                             nsISharingHandlerApp ***aHandlers)
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
@@ -5,18 +5,16 @@
 #include "nsMIMEInfoAndroid.h"
 #include "AndroidBridge.h"
 #include "nsAndroidHandlerApp.h"
 #include "nsArrayUtils.h"
 #include "nsISupportsUtils.h"
 #include "nsStringEnumerator.h"
 #include "nsNetUtil.h"
 
-using namespace mozilla::widget::android;
-
 NS_IMPL_ISUPPORTS2(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo)
 
 NS_IMETHODIMP
 nsMIMEInfoAndroid::LaunchDefaultWithFile(nsIFile* aFile)
 {
   LaunchWithFile(aFile);
   return NS_OK;
 }
@@ -26,17 +24,18 @@ nsMIMEInfoAndroid::LoadUriInternal(nsIUR
 {
   nsCString uriSpec;
   aURI->GetSpec(uriSpec);
 
   nsCString uriScheme;
   aURI->GetScheme(uriScheme);
 
   if (mozilla::AndroidBridge::Bridge())
-    return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE;
+    return mozilla::AndroidBridge::Bridge()->
+      OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE;
 
   return NS_ERROR_FAILURE;
 }
 
 
 bool
 nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType,
                                           nsMIMEInfoAndroid** aMimeInfo)
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -32,18 +32,23 @@
 #include "nsPIDOMWindow.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDOMClientRect.h"
 #include "StrongPointer.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "nsPrintfCString.h"
 
+#ifdef DEBUG
+#define ALOG_BRIDGE(args...) ALOG(args)
+#else
+#define ALOG_BRIDGE(args...) ((void)0)
+#endif
+
 using namespace mozilla;
-using namespace mozilla::widget::android;
 
 NS_IMPL_ISUPPORTS0(nsFilePickerCallback)
 
 StaticRefPtr<AndroidBridge> AndroidBridge::sBridge;
 static unsigned sJavaEnvThreadIndex = 0;
 static jobject sGlobalContext = nullptr;
 static void JavaThreadDetachFunc(void *arg);
 
@@ -157,23 +162,24 @@ AndroidBridge::Init(JNIEnv *jEnv)
 {
     ALOG_BRIDGE("AndroidBridge::Init");
     jEnv->GetJavaVM(&mJavaVM);
 
     AutoLocalJNIFrame jniFrame(jEnv);
 
     mJNIEnv = nullptr;
     mThread = -1;
-    mGLControllerObj = NULL;
+    mGLControllerObj = nullptr;
     mOpenedGraphicsLibraries = false;
     mHasNativeBitmapAccess = false;
     mHasNativeWindowAccess = false;
     mHasNativeWindowFallback = false;
 
     initInit();
+    InitStubs(jEnv);
 
 #ifdef MOZ_WEBSMS_BACKEND
     mAndroidSmsMessageClass = getClassGlobalRef("android/telephony/SmsMessage");
     jCalculateLength = getStaticMethod("calculateLength", "(Ljava/lang/CharSequence;Z)[I");
 #endif
 
     jStringClass = getClassGlobalRef("java/lang/String");
 
@@ -261,62 +267,16 @@ jstring AndroidBridge::NewJavaString(Aut
 jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const char* string) {
     return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
 }
 
 jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string) {
     return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
 }
 
-extern "C" {
-    __attribute__ ((visibility("default")))
-    JNIEnv * GetJNIForThread()
-    {
-        JNIEnv *jEnv = NULL;
-        JavaVM *jVm  = mozilla::AndroidBridge::GetVM();
-        if (!jVm) {
-            __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM");
-            return NULL;
-        }
-        jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex));
-
-        if (jEnv)
-            return jEnv;
-
-        int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2);
-        if (status) {
-
-            status = jVm->AttachCurrentThread(&jEnv, NULL);
-            if (status) {
-                __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread",  "Could not attach");
-                return NULL;
-            }
-
-            PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv);
-        }
-        if (!jEnv) {
-            __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL");
-        }
-        return jEnv;
-    }
-}
-
-void AutoGlobalWrappedJavaObject::Dispose() {
-    if (isNull()) {
-        return;
-    }
-
-    GetJNIForThread()->DeleteGlobalRef(wrapped_obj);
-    wrapped_obj = NULL;
-}
-
-AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() {
-    Dispose();
-}
-
 static void
 getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
                            nsIMutableArray *aHandlersArray,
                            nsIHandlerApp **aDefaultApp,
                            const nsAString& aAction = EmptyString(),
                            const nsACString& aMimeType = EmptyCString())
 {
     nsString empty = EmptyString();
@@ -346,17 +306,17 @@ AndroidBridge::GetHandlersForMimeType(co
                                       const nsAString& aAction)
 {
     ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    jobjectArray arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction);
+    jobjectArray arr = GetHandlersForMimeTypeWrapper(aMimeType, aAction);
     if (!arr)
         return false;
 
     jsize len = env->GetArrayLength(arr);
 
     if (!aHandlersArray)
         return len > 0;
 
@@ -375,17 +335,17 @@ AndroidBridge::GetHandlersForURL(const n
                                  const nsAString& aAction)
 {
     ALOG_BRIDGE("AndroidBridge::GetHandlersForURL");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    jobjectArray arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction);
+    jobjectArray arr = GetHandlersForURLWrapper(aURL, aAction);
     if (!arr)
         return false;
 
     jsize len = env->GetArrayLength(arr);
 
     if (!aHandlersArray)
         return len > 0;
 
@@ -400,17 +360,17 @@ void
 AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType)
 {
     ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    jstring jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt));
+    jstring jstrType = GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt));
     if (!jstrType) {
         return;
     }
     nsJNIString jniStr(jstrType, env);
     CopyUTF16toUTF8(jniStr.get(), aMimeType);
 
     env->DeleteLocalRef(jstrType);
 }
@@ -419,17 +379,17 @@ void
 AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt)
 {
     ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    jstring jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType));
+    jstring jstrExt = GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType));
     if (!jstrExt) {
         return;
     }
     nsJNIString jniStr(jstrExt, env);
     CopyUTF16toUTF8(jniStr.get(), aFileExt);
 
     env->DeleteLocalRef(jstrExt);
 }
@@ -438,53 +398,83 @@ bool
 AndroidBridge::GetClipboardText(nsAString& aText)
 {
     ALOG_BRIDGE("AndroidBridge::GetClipboardText");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    jstring result = Clipboard::GetClipboardTextWrapper();
+    jstring result = GetClipboardTextWrapper();
     if (!result)
         return false;
 
     nsJNIString jniStr(result, env);
     aText.Assign(jniStr);
 
     env->DeleteLocalRef(result);
     return true;
 }
 
+bool
+AndroidBridge::ClipboardHasText()
+{
+    ALOG_BRIDGE("AndroidBridge::ClipboardHasText");
+
+    JNIEnv *env = GetJNIEnv();
+    if (!env)
+        return false;
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    jstring jStr = GetClipboardTextWrapper();
+    bool ret = jStr;
+
+    return ret;
+}
+
+void
+AndroidBridge::EmptyClipboard()
+{
+    ALOG_BRIDGE("AndroidBridge::EmptyClipboard");
+
+    JNIEnv *env = GetJNIEnv();
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env, 0);
+    env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, nullptr);
+}
+
 void
 AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl,
                                      const nsAString& aAlertTitle,
                                      const nsAString& aAlertText,
                                      const nsAString& aAlertCookie,
                                      nsIObserver *aAlertListener,
                                      const nsAString& aAlertName)
 {
     if (nsAppShell::gAppShell && aAlertListener) {
         // This will remove any observers already registered for this id
         nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener));
     }
 
-    GeckoAppShell::ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName);
+    ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName);
 }
 
 int
 AndroidBridge::GetDPI()
 {
     static int sDPI = 0;
     if (sDPI)
         return sDPI;
 
     const int DEFAULT_DPI = 160;
 
-    sDPI = GeckoAppShell::GetDpiWrapper();
+    sDPI = GetDpiWrapper();
     if (!sDPI) {
         return DEFAULT_DPI;
     }
 
     return sDPI;
 }
 
 int
@@ -493,60 +483,72 @@ AndroidBridge::GetScreenDepth()
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     static int sDepth = 0;
     if (sDepth)
         return sDepth;
 
     const int DEFAULT_DEPTH = 16;
 
-    sDepth = GeckoAppShell::GetScreenDepthWrapper();
+    sDepth = GetScreenDepthWrapper();
     if (!sDepth)
         return DEFAULT_DEPTH;
 
     return sDepth;
 }
 
 void
 AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions)
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions);
+    jstring jstr = ShowFilePickerForExtensionsWrapper(aExtensions);
     if (jstr == nullptr) {
         return;
     }
 
     aFilePath.Assign(nsJNIString(jstr, env));
     env->DeleteLocalRef(jstr);
 }
 
 void
 AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType)
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType);
+    jstring jstr = ShowFilePickerForMimeTypeWrapper(aMimeType);
     if (jstr == nullptr) {
         return;
     }
 
     aFilePath.Assign(nsJNIString(jstr, env));
     env->DeleteLocalRef(jstr);
 }
 
 void
 AndroidBridge::ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback)
 {
     callback->AddRef();
-    GeckoAppShell::ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback);
+    ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback);
+}
+
+void
+AndroidBridge::HideProgressDialogOnce()
+{
+    static bool once = false;
+    if (once)
+        return;
+
+    HideProgressDialog();
+
+    once = true;
 }
 
 void
 AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
 {
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     uint32_t len = aPattern.Length();
@@ -564,17 +566,17 @@ AndroidBridge::Vibrate(const nsTArray<ui
     // It's clear if this worth special-casing, but it creates less
     // java junk, so dodges the GC.
     if (len == 1) {
         jlong d = aPattern[0];
         if (d < 0) {
             ALOG_BRIDGE("  invalid vibration duration < 0");
             return;
         }
-        GeckoAppShell::Vibrate1(d);
+        Vibrate1(d);
         return;
     }
 
     // First element of the array vibrate() expects is how long to wait
     // *before* vibrating.  For us, this is always 0.
 
     jlongArray array = env->NewLongArray(len + 1);
     if (!array) {
@@ -590,34 +592,34 @@ AndroidBridge::Vibrate(const nsTArray<ui
             ALOG_BRIDGE("  invalid vibration duration < 0");
             env->ReleaseLongArrayElements(array, elts, JNI_ABORT);
             return;
         }
         elts[i + 1] = d;
     }
     env->ReleaseLongArrayElements(array, elts, 0);
 
-    GeckoAppShell::VibrateA(array, -1/*don't repeat*/);
+    VibrateA(array, -1/*don't repeat*/);
 }
 
 void
 AndroidBridge::GetSystemColors(AndroidSystemColors *aColors)
 {
 
     NS_ASSERTION(aColors != nullptr, "AndroidBridge::GetSystemColors: aColors is null!");
     if (!aColors)
         return;
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jintArray arr = GeckoAppShell::GetSystemColoursWrapper();
+    jintArray arr = GetSystemColoursWrapper();
     if (!arr)
         return;
 
     uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr));
     jint *elements = env->GetIntArrayElements(arr, 0);
 
     uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor);
     if (len < colorsCount)
@@ -645,17 +647,17 @@ AndroidBridge::GetIconForExtension(const
         return;
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jbyteArray arr = GeckoAppShell::GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize);
+    jbyteArray arr = GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize);
 
     NS_ASSERTION(arr != nullptr, "AndroidBridge::GetIconForExtension: Returned pixels array is null!");
     if (!arr)
         return;
 
     uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr));
     jbyte *elements = env->GetByteArrayElements(arr, 0);
 
@@ -673,60 +675,72 @@ AndroidBridge::SetLayerClient(JNIEnv* en
     // if resetting is true, that means Android destroyed our GeckoApp activity
     // and we had to recreate it, but all the Gecko-side things were not destroyed.
     // We therefore need to link up the new java objects to Gecko, and that's what
     // we do here.
     bool resetting = (mLayerClient != NULL);
 
     if (resetting) {
         // clear out the old layer client
+        env->DeleteGlobalRef(mLayerClient->wrappedObject());
         delete mLayerClient;
         mLayerClient = NULL;
     }
 
-    mLayerClient = GeckoLayerClient::Wrap(jobj);
+    AndroidGeckoLayerClient *client = new AndroidGeckoLayerClient();
+    client->Init(env->NewGlobalRef(jobj));
+    mLayerClient = client;
 
     if (resetting) {
         // since we are re-linking the new java objects to Gecko, we need to get
         // the viewport from the compositor (since the Java copy was thrown away)
         // and we do that by setting the first-paint flag.
         nsWindow::ForceIsFirstPaint();
     }
 }
 
 void
 AndroidBridge::RegisterCompositor(JNIEnv *env)
 {
-    if (mGLControllerObj != NULL && !mGLControllerObj->isNull()) {
+    ALOG_BRIDGE("AndroidBridge::RegisterCompositor");
+    if (mGLControllerObj) {
         // we already have this set up, no need to do it again
         return;
     }
 
-    jobject glController = LayerView::RegisterCompositorWrapper();
+    if (!env) {
+        env = GetJNIForThread();    // called on the compositor thread
+    }
+    if (!env) {
+        return;
+    }
+
+    jobject glController = RegisterCompositorWrapper();
     if (!glController) {
         return;
     }
 
-    mGLControllerObj = GLController::Wrap(glController);
+    mGLControllerObj = env->NewGlobalRef(glController);
+    env->DeleteLocalRef(glController);
 }
 
 EGLSurface
 AndroidBridge::ProvideEGLSurface()
 {
     if (!jEGLSurfacePointerField) {
         return NULL;
     }
     MOZ_ASSERT(mGLControllerObj, "AndroidBridge::ProvideEGLSurface called with a null GL controller ref");
 
     JNIEnv* env = GetJNIForThread(); // called on the compositor thread
     if (!env) {
         return NULL;
     }
 
-    jobject eglSurface = mGLControllerObj->ProvideEGLSurfaceWrapper();
+    jobject eglSurface = ProvideEGLSurfaceWrapper(mGLControllerObj);
     if (!eglSurface)
         return NULL;
 
     EGLSurface ret = reinterpret_cast<EGLSurface>(env->GetIntField(eglSurface, jEGLSurfacePointerField));
     env->DeleteLocalRef(eglSurface);
     return ret;
 }
 
@@ -788,16 +802,21 @@ AndroidBridge::GetStaticStringField(cons
 
 // Available for places elsewhere in the code to link to.
 bool
 mozilla_AndroidBridge_SetMainThread(pthread_t thr)
 {
     return AndroidBridge::Bridge()->SetMainThread(thr);
 }
 
+jclass GetGeckoAppShellClass()
+{
+    return mozilla::AndroidBridge::GetGeckoAppShellClass();
+}
+
 void*
 AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) {
     if (!env || !mHasNativeWindowFallback || !jSurfacePointerField)
         return nullptr;
 
     return (void*)env->GetIntField(surface, jSurfacePointerField);
 }
 
@@ -984,17 +1003,17 @@ AndroidBridge::ValidateBitmap(jobject bi
 bool
 AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps)
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
-    jintArray arr = GeckoAppShell::InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height);
+    jintArray arr = InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height);
 
     if (!arr)
         return false;
 
     jint *elements = env->GetIntArrayElements(arr, 0);
 
     *width = elements[1];
     *height = elements[2];
@@ -1015,17 +1034,17 @@ AndroidBridge::GetCurrentBatteryInformat
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     // To prevent calling too many methods through JNI, the Java method returns
     // an array of double even if we actually want a double and a boolean.
-    jdoubleArray arr = GeckoAppShell::GetCurrentBatteryInformationWrapper();
+    jdoubleArray arr = GetCurrentBatteryInformationWrapper();
     if (!arr || env->GetArrayLength(arr) != 3) {
         return;
     }
 
     jdouble* info = env->GetDoubleArrayElements(arr, 0);
 
     aBatteryInfo->level() = info[0];
     aBatteryInfo->charging() = info[1] == 1.0f;
@@ -1039,17 +1058,17 @@ AndroidBridge::HandleGeckoMessage(const 
 {
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage);
+    jstring returnMessage = HandleGeckoMessageWrapper(aMessage);
 
     if (!returnMessage)
         return;
 
     nsJNIString jniStr(returnMessage, env);
     aRet.Assign(jniStr);
     ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
 }
@@ -1106,41 +1125,41 @@ AndroidBridge::SendMessage(const nsAStri
                            nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::SendMessage");
 
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    GeckoAppShell::SendMessageWrapper(aNumber, aMessage, requestId);
+    SendMessageWrapper(aNumber, aMessage, requestId);
 }
 
 void
 AndroidBridge::GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::GetMessage");
 
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    GeckoAppShell::GetMessageWrapper(aMessageId, requestId);
+    GetMessageWrapper(aMessageId, requestId);
 }
 
 void
 AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::DeleteMessage");
 
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId);
+    DeleteMessageWrapper(aMessageId, requestId);
 }
 
 void
 AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter, bool aReverse,
                                  nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::CreateMessageList");
 
@@ -1159,31 +1178,31 @@ AndroidBridge::CreateMessageList(const d
                                           jStringClass,
                                           NewJavaString(&jniFrame, EmptyString()));
 
     for (uint32_t i = 0; i < aFilter.numbers().Length(); ++i) {
         env->SetObjectArrayElement(numbers, i,
                                    NewJavaString(&jniFrame, aFilter.numbers()[i]));
     }
 
-    GeckoAppShell::CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(),
+    CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(),
                              numbers, aFilter.numbers().Length(),
                              aFilter.delivery(), aReverse, requestId);
 }
 
 void
 AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::GetNextMessageInList");
 
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId);
+    GetNextMessageInListWrapper(aListId, requestId);
 }
 
 bool
 AndroidBridge::QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut)
 {
     MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
     MOZ_ASSERT(aRequest && aRequestIdOut);
 
@@ -1225,17 +1244,17 @@ AndroidBridge::GetCurrentNetworkInformat
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     // To prevent calling too many methods through JNI, the Java method returns
     // an array of double even if we actually want a double, two booleans, and an integer.
 
-    jdoubleArray arr = GeckoAppShell::GetCurrentNetworkInformationWrapper();
+    jdoubleArray arr = GetCurrentNetworkInformationWrapper();
     if (!arr || env->GetArrayLength(arr) != 4) {
         return;
     }
 
     jdouble* info = env->GetDoubleArrayElements(arr, 0);
 
     aNetworkInfo->bandwidth() = info[0];
     aNetworkInfo->canBeMetered() = info[1] == 1.0f;
@@ -1418,17 +1437,17 @@ jobject
 AndroidBridge::GetGlobalContextRef() {
     if (sGlobalContext == nullptr) {
         JNIEnv *env = GetJNIForThread();
         if (!env)
             return 0;
 
         AutoLocalJNIFrame jniFrame(env, 4);
 
-        jobject context = GeckoAppShell::GetContext();
+        jobject context = GetContext();
         if (!context) {
             ALOG_BRIDGE("%s: Could not GetContext()", __FUNCTION__);
             return 0;
         }
         jclass contextClass = env->FindClass("android/content/Context");
         if (!contextClass) {
             ALOG_BRIDGE("%s: Could not find Context class.", __FUNCTION__);
             return 0;
@@ -1469,109 +1488,58 @@ AndroidBridge::UnlockWindow(void* window
     }
 
     return true;
 }
 
 void
 AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
 {
-    GeckoLayerClient *client = mLayerClient;
+    AndroidGeckoLayerClient *client = mLayerClient;
     if (!client)
         return;
 
-    client->SetFirstPaintViewport((float)aOffset.x, (float)aOffset.y, aZoom.scale,
-                                  aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
+    client->SetFirstPaintViewport(aOffset, aZoom, aCssPageRect);
 }
 
 void
 AndroidBridge::SetPageRect(const CSSRect& aCssPageRect)
 {
-    GeckoLayerClient *client = mLayerClient;
+    AndroidGeckoLayerClient *client = mLayerClient;
     if (!client)
         return;
 
-    client->SetPageRect(aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
+    client->SetPageRect(aCssPageRect);
 }
 
 void
 AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
                                 bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
                                 LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
 {
-    ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__);
-    GeckoLayerClient *client = mLayerClient;
-    if (!client) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
+    AndroidGeckoLayerClient *client = mLayerClient;
+    if (!client)
         return;
-    }
-
-    jobject viewTransformJObj = client->SyncViewportInfo(aDisplayPort.x, aDisplayPort.y,
-                                aDisplayPort.width, aDisplayPort.height,
-                                aDisplayResolution.scale, aLayersUpdated);
-
-    NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!");
-    if (!viewTransformJObj) {
-        return;
-    }
 
-    ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj);
-
-    aScrollOffset = ScreenPoint(viewTransform->getx(), viewTransform->gety());
-    aScale.scale = viewTransform->getscale();
-
-    aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop();
-    aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight();
-    aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom();
-    aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft();
-
-    aOffset.x = viewTransform->getoffsetX();
-    aOffset.y = viewTransform->getoffsetY();
-
-    delete viewTransform;
-    ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__);
+    client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
+                             aScrollOffset, aScale, aFixedLayerMargins,
+                             aOffset);
 }
 
 void AndroidBridge::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
                                      bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
                                      bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
 {
-    ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__);
-    GeckoLayerClient *client = mLayerClient;
-    if (!client) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
+    AndroidGeckoLayerClient *client = mLayerClient;
+    if (!client)
         return;
-    }
-
-    // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels
-    LayerRect dpUnrounded = aDisplayPort * aDisplayResolution;
-    dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint());
-    LayerIntRect dp = gfx::RoundedToInt(dpUnrounded);
-
-    jobject viewTransformJObj = client->SyncFrameMetrics(aScrollOffset.x, aScrollOffset.y, aZoom,
-                                                         aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(),
-                                                         aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale,
-                                                         aIsFirstPaint);
 
-    NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!");
-    if (!viewTransformJObj) {
-        return;
-    }
-    ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj);
-
-    aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop();
-    aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight();
-    aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom();
-    aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft();
-
-    aOffset.x = viewTransform->getoffsetX();
-    aOffset.y = viewTransform->getoffsetY();
-
-    delete viewTransform;
-    ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__);
+    client->SyncFrameMetrics(aScrollOffset, aZoom, aCssPageRect,
+                             aLayersUpdated, aDisplayPort, aDisplayResolution,
+                             aIsFirstPaint, aFixedLayerMargins, aOffset);
 }
 
 AndroidBridge::AndroidBridge()
   : mLayerClient(NULL),
     mNativePanZoomController(NULL)
 {
 }
 
@@ -1626,22 +1594,55 @@ static void
 JavaThreadDetachFunc(void *arg)
 {
     JNIEnv *env = (JNIEnv*) arg;
     JavaVM *vm = NULL;
     env->GetJavaVM(&vm);
     vm->DetachCurrentThread();
 }
 
+extern "C" {
+    __attribute__ ((visibility("default")))
+    JNIEnv * GetJNIForThread()
+    {
+        JNIEnv *jEnv = NULL;
+        JavaVM *jVm  = mozilla::AndroidBridge::GetVM();
+        if (!jVm) {
+            __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM");
+            return NULL;
+        }
+        jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex));
+
+        if (jEnv)
+            return jEnv;
+
+        int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2);
+        if (status) {
+
+            status = jVm->AttachCurrentThread(&jEnv, NULL);
+            if (status) {
+                __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread",  "Could not attach");
+                return NULL;
+            }
+            
+            PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv);
+        }
+        if (!jEnv) {
+            __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL");
+        }
+        return jEnv;
+    }
+}
+
 uint32_t
 AndroidBridge::GetScreenOrientation()
 {
     ALOG_BRIDGE("AndroidBridge::GetScreenOrientation");
 
-    int16_t orientation = GeckoAppShell::GetScreenOrientationWrapper();
+    int16_t orientation = GetScreenOrientationWrapper();
 
     if (!orientation)
         return dom::eScreenOrientation_None;
 
     return static_cast<dom::ScreenOrientation>(orientation);
 }
 
 void
@@ -1655,17 +1656,17 @@ AndroidBridge::GetGfxInfoData(nsACString
 {
     ALOG_BRIDGE("AndroidBridge::GetGfxInfoData");
 
     JNIEnv* env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring jstrRet = GeckoAppShell::GetGfxInfoDataWrapper();
+    jstring jstrRet = GetGfxInfoDataWrapper();
 
     if (!jstrRet)
         return;
 
     nsJNIString jniStr(jstrRet, env);
     CopyUTF16toUTF8(jniStr, aRet);
 }
 
@@ -1676,17 +1677,17 @@ AndroidBridge::GetProxyForURI(const nsAC
                               const int32_t      aPort,
                               nsACString & aResult)
 {
     JNIEnv* env = GetJNIEnv();
     if (!env)
         return NS_ERROR_FAILURE;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
+    jstring jstrRet = GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
                                             NS_ConvertUTF8toUTF16(aScheme),
                                             NS_ConvertUTF8toUTF16(aHost),
                                             aPort);
 
     if (!jstrRet)
         return NS_ERROR_FAILURE;
 
     nsJNIString jniStr(jstrRet, env);
@@ -1712,34 +1713,34 @@ NS_IMETHODIMP nsAndroidBridge::SetBrowse
 
 void
 AndroidBridge::AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen) {
     nsWindow* win = nsWindow::TopWindow();
     if (!win)
         return;
 
     CSSRect cssRect = rect / win->GetDefaultScale();
-    GeckoAppShell::AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen);
+    AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen);
 }
 
 extern "C"
 __attribute__ ((visibility("default")))
 jobject JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size);
 
 bool
 AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult)
 {
     JNIEnv* env = GetJNIForThread();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jstring jstrThreadName = GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId);
+    jstring jstrThreadName = GetThreadNameJavaProfilingWrapper(aThreadId);
 
     if (!jstrThreadName)
         return false;
 
     nsJNIString jniStr(jstrThreadName, env);
     CopyUTF16toUTF8(jniStr.get(), aResult);
     return true;
 }
@@ -1749,17 +1750,17 @@ AndroidBridge::GetFrameNameJavaProfiling
                                           uint32_t aFrameId, nsCString & aResult)
 {
     JNIEnv* env = GetJNIForThread();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jstring jstrSampleName = GeckoJavaSampler::GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId);
+    jstring jstrSampleName = GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId);
 
     if (!jstrSampleName)
         return false;
 
     nsJNIString jniStr(jstrSampleName, env);
     CopyUTF16toUTF8(jniStr.get(), aResult);
     env->DeleteLocalRef(jstrSampleName);
     return true;
@@ -1857,144 +1858,71 @@ nsresult AndroidBridge::CaptureThumbnail
     }
     NS_ENSURE_SUCCESS(rv, rv);
     return NS_OK;
 }
 
 void
 AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort)
 {
-
-    ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__);
     JNIEnv* env = GetJNIEnv();
-    if (!env || !mLayerClient || mLayerClient->isNull()) {
-
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
+    if (!env || !mLayerClient)
         return;
-    }
     AutoLocalJNIFrame jniFrame(env, 0);
-
-    float x, y, width, height,
-        pageLeft, pageTop, pageRight, pageBottom,
-        cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
-        zoom;
-    metrics->GetX(&x);
-    metrics->GetY(&y);
-    metrics->GetWidth(&width);
-    metrics->GetHeight(&height);
-    metrics->GetPageLeft(&pageLeft);
-    metrics->GetPageTop(&pageTop);
-    metrics->GetPageRight(&pageRight);
-    metrics->GetPageBottom(&pageBottom);
-    metrics->GetCssPageLeft(&cssPageLeft);
-    metrics->GetCssPageTop(&cssPageTop);
-    metrics->GetCssPageRight(&cssPageRight);
-    metrics->GetCssPageBottom(&cssPageBottom);
-    metrics->GetZoom(&zoom);
-
-    ImmutableViewportMetrics jmetrics = ImmutableViewportMetrics(pageLeft, pageTop, pageRight, pageBottom,
-                                                                 cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
-                                                                 x, y, x + width, y + height,
-                                                                 zoom);
-
-    jobject jobj = mLayerClient->GetDisplayPort(aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics.wrappedObject());
-    if (!jobj) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
-        return;
-    }
-    DisplayPortMetrics* displayPortMetrics = DisplayPortMetrics::Wrap(jobj);
-
-    AndroidRectF rect(env, displayPortMetrics->getMPosition());
-    if (jniFrame.CheckForException()) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
-        return;
-    }
-
-    float resolution = displayPortMetrics->getResolution();
-    if (jniFrame.CheckForException()) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
-        return;
-    }
-
-    *displayPort = new nsAndroidDisplayport(rect, resolution);
-    (*displayPort)->AddRef();
-
-    delete displayPortMetrics;
-    ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__);
+    mLayerClient->GetDisplayPort(&jniFrame, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, metrics, displayPort);
 }
 
 void
 AndroidBridge::ContentDocumentChanged()
 {
-    if (!mLayerClient) {
+    JNIEnv* env = GetJNIEnv();
+    if (!env || !mLayerClient)
         return;
-    }
-    mLayerClient->ContentDocumentChanged();
+    AutoLocalJNIFrame jniFrame(env, 0);
+    mLayerClient->ContentDocumentChanged(&jniFrame);
 }
 
 bool
 AndroidBridge::IsContentDocumentDisplayed()
 {
     JNIEnv* env = GetJNIEnv();
     if (!env || !mLayerClient)
         return false;
-
-    return mLayerClient->IsContentDocumentDisplayed();
+    AutoLocalJNIFrame jniFrame(env, 0);
+    return mLayerClient->IsContentDocumentDisplayed(&jniFrame);
 }
 
 bool
 AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY)
 {
-    GeckoLayerClient *client = mLayerClient;
-    if (!client) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
+    AndroidGeckoLayerClient *client = mLayerClient;
+    if (!client)
         return false;
-    }
-
-    jobject progressiveUpdateDataJObj = client->ProgressiveUpdateCallback(aHasPendingNewThebesContent,
-                                                                   (float)aDisplayPort.x,
-                                                                   (float)aDisplayPort.y,
-                                                                   (float)aDisplayPort.width,
-                                                                   (float)aDisplayPort.height,
-                                                                          aDisplayResolution,
-                                                                         !aDrawingCritical);
 
-    NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!");
-
-    ProgressiveUpdateData* progressiveUpdateData = ProgressiveUpdateData::Wrap(progressiveUpdateDataJObj);
-
-    aViewport.x = progressiveUpdateData->getx();
-    aViewport.y = progressiveUpdateData->gety();
-    aViewport.width = progressiveUpdateData->getwidth();
-    aViewport.height = progressiveUpdateData->getheight();
-    aScaleX = aScaleY = progressiveUpdateData->getscale();
-
-    bool ret = progressiveUpdateData->getabort();
-    delete progressiveUpdateData;
-
-    return ret;
+    return client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, aDisplayPort, aDisplayResolution, aDrawingCritical, aViewport, aScaleX, aScaleY);
 }
 
-NativePanZoomController*
+jobject
 AndroidBridge::SetNativePanZoomController(jobject obj)
 {
-    NativePanZoomController* old = mNativePanZoomController;
-    mNativePanZoomController = NativePanZoomController::Wrap(obj);
+    jobject old = mNativePanZoomController;
+    mNativePanZoomController = obj;
     return old;
 }
 
 void
 AndroidBridge::RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics)
 {
     ALOG_BRIDGE("AndroidBridge::RequestContentRepaint");
 
     CSSToScreenScale resolution = aFrameMetrics.mZoom;
     ScreenRect dp = (aFrameMetrics.mDisplayPort + aFrameMetrics.mScrollOffset) * resolution;
 
-    mNativePanZoomController->RequestContentRepaintWrapper(dp.x, dp.y, dp.width, dp.height, resolution.scale);
+    RequestContentRepaintWrapper(mNativePanZoomController,
+        dp.x, dp.y, dp.width, dp.height, resolution.scale);
 }
 
 void
 AndroidBridge::HandleDoubleTap(const CSSIntPoint& aPoint)
 {
     nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y);
     nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent(
             NS_LITERAL_CSTRING("Gesture:DoubleTap"), data));
@@ -2041,17 +1969,17 @@ AndroidBridge::PostDelayedTask(Task* aTa
     if (i == mDelayedTaskQueue.Length()) {
         // this new task will run after all the existing tasks in the queue
         mDelayedTaskQueue.AppendElement(newTask);
     }
     if (i == 0) {
         // if we're inserting it at the head of the queue, notify Java because
         // we need to get a callback at an earlier time than the last scheduled
         // callback
-        mNativePanZoomController->PostDelayedCallbackWrapper((int64_t)aDelayMs);
+        PostDelayedCallbackWrapper(mNativePanZoomController, (int64_t)aDelayMs);
     }
 }
 
 int64_t
 AndroidBridge::RunDelayedTasks()
 {
     while (mDelayedTaskQueue.Length() > 0) {
         DelayedTask* nextTask = mDelayedTaskQueue[0];
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -9,17 +9,17 @@
 #include <jni.h>
 #include <android/log.h>
 #include <cstdlib>
 #include <pthread.h>
 
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 
-#include "GeneratedJNIWrappers.h"
+#include "AndroidJavaWrappers.h"
 
 #include "nsIMutableArray.h"
 #include "nsIMIMEInfo.h"
 #include "nsColor.h"
 #include "gfxRect.h"
 
 #include "nsIAndroidBridge.h"
 #include "nsIMobileMessageCallback.h"
@@ -36,25 +36,24 @@
 class nsWindow;
 class nsIDOMMozSmsMessage;
 class nsIObserver;
 
 /* See the comment in AndroidBridge about this function before using it */
 extern "C" JNIEnv * GetJNIForThread();
 
 extern bool mozilla_AndroidBridge_SetMainThread(pthread_t);
+extern jclass GetGeckoAppShellClass();
 
 namespace base {
 class Thread;
 } // end namespace base
 
 typedef void* EGLSurface;
 
-using namespace mozilla::widget::android;
-
 namespace mozilla {
 
 namespace hal {
 class BatteryInformation;
 class NetworkInformation;
 } // namespace hal
 
 namespace dom {
@@ -156,16 +155,20 @@ public:
                 return nullptr;
             }
             return sBridge->mJNIEnv;
 
         }
         return nullptr;
     }
 
+    static jclass GetGeckoAppShellClass() {
+        return sBridge->mGeckoAppShellClass;
+    }
+
     // The bridge needs to be constructed via ConstructBridge first,
     // and then once the Gecko main thread is spun up (Gecko side),
     // SetMainThread should be called which will create the JNIEnv for
     // us to use.  toolkit/xre/nsAndroidStartup.cpp calls
     // SetMainThread.
     bool SetMainThread(pthread_t thr);
 
     /* These are all implemented in Java */
@@ -175,32 +178,36 @@ public:
     nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
     void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
     void ContentDocumentChanged();
     bool IsContentDocumentDisplayed();
 
     bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
 
     void SetLayerClient(JNIEnv* env, jobject jobj);
-    GeckoLayerClient* GetLayerClient() { return mLayerClient; }
+    AndroidGeckoLayerClient &GetLayerClient() { return *mLayerClient; }
 
     bool GetHandlersForURL(const nsAString& aURL,
                            nsIMutableArray* handlersArray = nullptr,
                            nsIHandlerApp **aDefaultApp = nullptr,
                            const nsAString& aAction = EmptyString());
 
     bool GetHandlersForMimeType(const nsAString& aMimeType,
                                 nsIMutableArray* handlersArray = nullptr,
                                 nsIHandlerApp **aDefaultApp = nullptr,
                                 const nsAString& aAction = EmptyString());
 
     void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType);
     void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt);
 
     bool GetClipboardText(nsAString& aText);
+    
+    void EmptyClipboard();
+
+    bool ClipboardHasText();
 
     void ShowAlertNotification(const nsAString& aImageUrl,
                                const nsAString& aAlertTitle,
                                const nsAString& aAlertText,
                                const nsAString& aAlertData,
                                nsIObserver *aAlertListener,
                                const nsAString& aAlertName);
 
@@ -208,16 +215,18 @@ public:
     int GetScreenDepth();
 
     void ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions);
     void ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType);
     void ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback);
 
     void Vibrate(const nsTArray<uint32_t>& aPattern);
 
+    void HideProgressDialogOnce();
+
     void GetSystemColors(AndroidSystemColors *aColors);
 
     void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf);
 
     // Switch Java to composite with the Gecko Compositor thread
     void RegisterCompositor(JNIEnv* env = NULL);
     EGLSurface ProvideEGLSurface();
 
@@ -327,17 +336,17 @@ protected:
 
     // the global JavaVM
     JavaVM *mJavaVM;
 
     // the JNIEnv for the main thread
     JNIEnv *mJNIEnv;
     pthread_t mThread;
 
-    GeckoLayerClient *mLayerClient = NULL;
+    AndroidGeckoLayerClient *mLayerClient;
 
     // the android.telephony.SmsMessage class
     jclass mAndroidSmsMessageClass;
 
     AndroidBridge();
     ~AndroidBridge();
 
     void InitStubs(JNIEnv *jEnv);
@@ -368,17 +377,17 @@ protected:
 
     // For native surface stuff
     jclass jSurfaceClass;
     jfieldID jSurfacePointerField;
 
     jclass jLayerView;
 
     jfieldID jEGLSurfacePointerField;
-    GLController *mGLControllerObj;
+    jobject mGLControllerObj;
 
     // some convinient types to have around
     jclass jStringClass;
 
     // calls we've dlopened from libjnigraphics.so
     int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
     int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
     int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
@@ -392,24 +401,25 @@ protected:
     int (* ANativeWindow_unlockAndPost)(void *window);
 
     int (* Surface_lock)(void* surface, void* surfaceInfo, void* region, bool block);
     int (* Surface_unlockAndPost)(void* surface);
     void (* Region_constructor)(void* region);
     void (* Region_set)(void* region, void* rect);
 
 private:
-    NativePanZoomController* mNativePanZoomController;
+    jobject mNativePanZoomController;
     // This will always be accessed from one thread (the APZC "controller"
     // thread, which is the Java UI thread), so we don't need to do locking
     // to touch it
     nsTArray<DelayedTask*> mDelayedTaskQueue;
 
 public:
-    NativePanZoomController* SetNativePanZoomController(jobject obj);
+    #include "GeneratedJNIWrappers.h"
+    jobject SetNativePanZoomController(jobject obj);
     // GeckoContentController methods
     void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE;
     void HandleDoubleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void HandleSingleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void HandleLongTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId,
                                  const CSSRect& aContentRect,
                                  const CSSSize& aScrollableSize) MOZ_OVERRIDE;
--- a/widget/android/AndroidBridgeUtilities.h
+++ b/widget/android/AndroidBridgeUtilities.h
@@ -12,22 +12,8 @@
 #define getMethod(fname, ftype) \
     AndroidBridge::GetMethodID(jEnv, jClass, fname, ftype)
 
 #define getStaticField(fname, ftype) \
     AndroidBridge::GetStaticFieldID(jEnv, jClass, fname, ftype)
 
 #define getStaticMethod(fname, ftype) \
     AndroidBridge::GetStaticMethodID(jEnv, jClass, fname, ftype)
-
-#ifndef ALOG
-#if defined(DEBUG) || defined(FORCE_ALOG)
-#define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
-#else
-#define ALOG(args...) ((void)0)
-#endif
-#endif
-
-#ifdef DEBUG
-#define ALOG_BRIDGE(args...) ALOG(args)
-#else
-#define ALOG_BRIDGE(args...) ((void)0)
-#endif
--- a/widget/android/AndroidJNI.cpp
+++ b/widget/android/AndroidJNI.cpp
@@ -856,20 +856,20 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject instance)
 {
     if (!AndroidBridge::Bridge()) {
         return;
     }
 
-    NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(instance);
-    if (oldRef && !oldRef->isNull()) {
+    jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(env->NewGlobalRef(instance));
+    if (oldRef) {
         MOZ_ASSERT(false, "Registering a new NPZC when we already have one");
-        delete oldRef;
+        env->DeleteGlobalRef(oldRef);
     }
 }
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, jobject instance, jobject event)
 {
     APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
     if (controller) {
@@ -900,21 +900,21 @@ Java_org_mozilla_gecko_gfx_NativePanZoom
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject instance)
 {
     if (!AndroidBridge::Bridge()) {
         return;
     }
 
-    NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL);
-    if (!oldRef || oldRef->isNull()) {
+    jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL);
+    if (!oldRef) {
         MOZ_ASSERT(false, "Clearing a non-existent NPZC");
     } else {
-        delete oldRef;
+        env->DeleteGlobalRef(oldRef);
     }
 }
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv* env, jobject instance, jboolean prevented)
 {
     APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
     if (controller) {
--- a/widget/android/AndroidJNIWrapper.cpp
+++ b/widget/android/AndroidJNIWrapper.cpp
@@ -9,16 +9,22 @@
 #include <dlfcn.h>
 #include <prthread.h>
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Assertions.h"
 #include "nsThreadUtils.h"
 #include "AndroidBridge.h"
 
+#ifdef DEBUG
+#define ALOG_BRIDGE(args...) ALOG(args)
+#else
+#define ALOG_BRIDGE(args...)
+#endif
+
 extern "C" {
   jclass __jsjni_GetGlobalClassRef(const char *className);
 }
 
 class GetGlobalClassRefRunnable : public nsRunnable {
   public:
     GetGlobalClassRefRunnable(const char *className, jclass *foundClass) :
         mClassName(className), mResult(foundClass) {}
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -1,23 +1,23 @@
 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AndroidJavaWrappers.h"
 #include "AndroidBridge.h"
 #include "AndroidBridgeUtilities.h"
+#include "nsIAndroidBridge.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIWidget.h"
 #include "mozilla/TouchEvents.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::widget::android;
 
 jclass AndroidGeckoEvent::jGeckoEventClass = 0;
 jfieldID AndroidGeckoEvent::jActionField = 0;
 jfieldID AndroidGeckoEvent::jTypeField = 0;
 jfieldID AndroidGeckoEvent::jAckNeededField = 0;
 jfieldID AndroidGeckoEvent::jTimeField = 0;
 jfieldID AndroidGeckoEvent::jPoints = 0;
 jfieldID AndroidGeckoEvent::jPointIndicies = 0;
@@ -86,31 +86,77 @@ jclass AndroidLocation::jLocationClass =
 jmethodID AndroidLocation::jGetLatitudeMethod = 0;
 jmethodID AndroidLocation::jGetLongitudeMethod = 0;
 jmethodID AndroidLocation::jGetAltitudeMethod = 0;
 jmethodID AndroidLocation::jGetAccuracyMethod = 0;
 jmethodID AndroidLocation::jGetBearingMethod = 0;
 jmethodID AndroidLocation::jGetSpeedMethod = 0;
 jmethodID AndroidLocation::jGetTimeMethod = 0;
 
+jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0;
+jclass AndroidGeckoLayerClient::jViewportClass = 0;
+jclass AndroidGeckoLayerClient::jDisplayportClass = 0;
+jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0;
+jmethodID AndroidGeckoLayerClient::jSetPageRect = 0;
+jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0;
+jmethodID AndroidGeckoLayerClient::jSyncFrameMetricsMethod = 0;
+jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0;
+jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0;
+jmethodID AndroidGeckoLayerClient::jDeactivateProgramMethod = 0;
+jmethodID AndroidGeckoLayerClient::jGetDisplayPort = 0;
+jmethodID AndroidGeckoLayerClient::jContentDocumentChanged = 0;
+jmethodID AndroidGeckoLayerClient::jIsContentDocumentDisplayed = 0;
+jmethodID AndroidGeckoLayerClient::jViewportCtor = 0;
+jfieldID AndroidGeckoLayerClient::jDisplayportPosition = 0;
+jfieldID AndroidGeckoLayerClient::jDisplayportResolution = 0;
+jmethodID AndroidGeckoLayerClient::jProgressiveUpdateCallbackMethod = 0;
+
+jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0;
+jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0;
+jmethodID AndroidLayerRendererFrame::jDrawBackgroundMethod = 0;
+jmethodID AndroidLayerRendererFrame::jDrawForegroundMethod = 0;
+jmethodID AndroidLayerRendererFrame::jEndDrawingMethod = 0;
+
+jclass AndroidViewTransform::jViewTransformClass = 0;
+jfieldID AndroidViewTransform::jXField = 0;
+jfieldID AndroidViewTransform::jYField = 0;
+jfieldID AndroidViewTransform::jScaleField = 0;
+jfieldID AndroidViewTransform::jFixedLayerMarginLeft = 0;
+jfieldID AndroidViewTransform::jFixedLayerMarginTop = 0;
+jfieldID AndroidViewTransform::jFixedLayerMarginRight = 0;
+jfieldID AndroidViewTransform::jFixedLayerMarginBottom = 0;
+jfieldID AndroidViewTransform::jOffsetXField = 0;
+jfieldID AndroidViewTransform::jOffsetYField = 0;
+
+jclass AndroidProgressiveUpdateData::jProgressiveUpdateDataClass = 0;
+jfieldID AndroidProgressiveUpdateData::jXField = 0;
+jfieldID AndroidProgressiveUpdateData::jYField = 0;
+jfieldID AndroidProgressiveUpdateData::jWidthField = 0;
+jfieldID AndroidProgressiveUpdateData::jHeightField = 0;
+jfieldID AndroidProgressiveUpdateData::jScaleField = 0;
+jfieldID AndroidProgressiveUpdateData::jShouldAbortField = 0;
+
 RefCountedJavaObject::~RefCountedJavaObject() {
     if (mObject)
         GetJNIForThread()->DeleteGlobalRef(mObject);
     mObject = NULL;
 }
 
 void
 mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
 {
     AndroidGeckoEvent::InitGeckoEventClass(jEnv);
     AndroidPoint::InitPointClass(jEnv);
     AndroidLocation::InitLocationClass(jEnv);
     AndroidRect::InitRectClass(jEnv);
     AndroidRectF::InitRectFClass(jEnv);
-    InitStubs(jEnv);
+    AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv);
+    AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv);
+    AndroidViewTransform::InitViewTransformClass(jEnv);
+    AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(jEnv);
 }
 
 void
 AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
 {
     initInit();
 
     jGeckoEventClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent");
@@ -239,16 +285,92 @@ AndroidRectF::InitRectFClass(JNIEnv *jEn
     jRectClass = getClassGlobalRef("android/graphics/RectF");
 
     jBottomField = getField("bottom", "F");
     jLeftField = getField("left", "F");
     jTopField = getField("top", "F");
     jRightField = getField("right", "F");
 }
 
+void
+AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
+{
+    initInit();
+
+    jGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient");
+
+    jProgressiveUpdateCallbackMethod = getMethod("progressiveUpdateCallback",
+                                                 "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;");
+    jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V");
+    jSetPageRect = getMethod("setPageRect", "(FFFF)V");
+    jSyncViewportInfoMethod = getMethod("syncViewportInfo",
+                                        "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
+    jSyncFrameMetricsMethod = getMethod("syncFrameMetrics",
+                                        "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
+    jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
+    jActivateProgramMethod = getMethod("activateProgram", "()V");
+    jDeactivateProgramMethod = getMethod("deactivateProgram", "()V");
+    jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;");
+    jContentDocumentChanged = getMethod("contentDocumentChanged", "()V");
+    jIsContentDocumentDisplayed = getMethod("isContentDocumentDisplayed", "()Z");
+
+    jViewportClass = getClassGlobalRef("org/mozilla/gecko/gfx/ImmutableViewportMetrics");
+    jViewportCtor = getMethod("<init>", "(FFFFFFFFFFFFF)V");
+
+    jDisplayportClass = getClassGlobalRef("org/mozilla/gecko/gfx/DisplayPortMetrics");
+    jDisplayportPosition = getField("mPosition", "Landroid/graphics/RectF;");
+    jDisplayportResolution = getField("resolution", "F");
+}
+
+void
+AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv)
+{
+    initInit();
+
+    jLayerRendererFrameClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerRenderer$Frame");
+
+    jBeginDrawingMethod = getMethod("beginDrawing", "()V");
+    jDrawBackgroundMethod = getMethod("drawBackground", "()V");
+    jDrawForegroundMethod = getMethod("drawForeground", "()V");
+    jEndDrawingMethod = getMethod("endDrawing", "()V");
+}
+
+void
+AndroidViewTransform::InitViewTransformClass(JNIEnv *jEnv)
+{
+    initInit();
+
+    jViewTransformClass = getClassGlobalRef("org/mozilla/gecko/gfx/ViewTransform");
+
+    jXField = getField("x", "F");
+    jYField = getField("y", "F");
+    jScaleField = getField("scale", "F");
+    jFixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F");
+    jFixedLayerMarginTop = getField("fixedLayerMarginTop", "F");
+    jFixedLayerMarginRight = getField("fixedLayerMarginRight", "F");
+    jFixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F");
+    jOffsetXField = getField("offsetX", "F");
+    jOffsetYField = getField("offsetY", "F");
+}
+
+void
+AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(JNIEnv *jEnv)
+{
+    initInit();
+
+    jProgressiveUpdateDataClass = getClassGlobalRef("org/mozilla/gecko/gfx/ProgressiveUpdateData");
+
+    jXField = getField("x", "F");
+    jYField = getField("y", "F");
+    jWidthField = getField("width", "F");
+    jHeightField = getField("height", "F");
+    jScaleField = getField("scale", "F");
+    jShouldAbortField = getField("abort", "Z");
+}
+
 #undef initInit
 #undef initClassGlobalRef
 #undef getField
 #undef getMethod
 
 void
 AndroidGeckoEvent::ReadPointArray(nsTArray<nsIntPoint> &points,
                                   JNIEnv *jenv,
@@ -718,18 +840,471 @@ AndroidPoint::Init(JNIEnv *jenv, jobject
         mX = jenv->GetIntField(jobj, jXField);
         mY = jenv->GetIntField(jobj, jYField);
     } else {
         mX = 0;
         mY = 0;
     }
 }
 
+void
+AndroidGeckoLayerClient::Init(jobject jobj)
+{
+    NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
+    wrapped_obj = jobj;
+}
+
+void
+AndroidLayerRendererFrame::Init(JNIEnv *env, jobject jobj)
+{
+    if (!isNull()) {
+        Dispose(env);
+    }
+
+    wrapped_obj = env->NewGlobalRef(jobj);
+}
+
+void
+AndroidLayerRendererFrame::Dispose(JNIEnv *env)
+{
+    if (isNull()) {
+        return;
+    }
+
+    env->DeleteGlobalRef(wrapped_obj);
+    wrapped_obj = 0;
+}
+
+void
+AndroidViewTransform::Init(jobject jobj)
+{
+    NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
+    wrapped_obj = jobj;
+}
+
+void
+AndroidProgressiveUpdateData::Init(jobject jobj)
+{
+    NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
+    wrapped_obj = jobj;
+}
+
+void
+AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
+{
+    NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!");
+    JNIEnv *env = GetJNIForThread();    // this is called on the compositor thread
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env, 0);
+    return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom.scale,
+                               aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
+}
+
+void
+AndroidGeckoLayerClient::SetPageRect(const CSSRect& aCssPageRect)
+{
+    NS_ASSERTION(!isNull(), "SetPageRect called on null layer client!");
+    JNIEnv *env = GetJNIForThread();    // this is called on the compositor thread
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env, 0);
+    return env->CallVoidMethod(wrapped_obj, jSetPageRect,
+                               aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
+}
+
+void
+AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
+                                          bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
+                                          LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
+{
+    NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!");
+    JNIEnv *env = GetJNIForThread();    // this is called on the compositor thread
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncViewportInfoMethod,
+                                                      aDisplayPort.x, aDisplayPort.y,
+                                                      aDisplayPort.width, aDisplayPort.height,
+                                                      aDisplayResolution.scale, aLayersUpdated);
+    if (jniFrame.CheckForException())
+        return;
+
+    NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!");
+
+    AndroidViewTransform viewTransform;
+    viewTransform.Init(viewTransformJObj);
+
+    aScrollOffset = ScreenPoint(viewTransform.GetX(env), viewTransform.GetY(env));
+    aScale.scale = viewTransform.GetScale(env);
+    viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
+
+    aOffset.x = viewTransform.GetOffsetX(env);
+    aOffset.y = viewTransform.GetOffsetY(env);
+}
+
+void
+AndroidGeckoLayerClient::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
+                                          bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
+                                          bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
+{
+    NS_ASSERTION(!isNull(), "SyncFrameMetrics called on null layer client!");
+    JNIEnv *env = GetJNIForThread();    // this is called on the compositor thread
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels
+    LayerRect dpUnrounded = aDisplayPort * aDisplayResolution;
+    dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint());
+    LayerIntRect dp = gfx::RoundedToInt(dpUnrounded);
+
+    jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncFrameMetricsMethod,
+            aScrollOffset.x, aScrollOffset.y, aZoom,
+            aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(),
+            aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale,
+            aIsFirstPaint);
+
+    if (jniFrame.CheckForException())
+        return;
+
+    NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!");
+
+    AndroidViewTransform viewTransform;
+    viewTransform.Init(viewTransformJObj);
+    viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
+    aOffset.x = viewTransform.GetOffsetX(env);
+    aOffset.y = viewTransform.GetOffsetY(env);
+}
+
+bool
+AndroidGeckoLayerClient::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
+                                                   const LayerRect& aDisplayPort,
+                                                   float aDisplayResolution,
+                                                   bool aDrawingCritical,
+                                                   gfx::Rect& aViewport,
+                                                   float& aScaleX,
+                                                   float& aScaleY)
+{
+    JNIEnv *env = AndroidBridge::GetJNIEnv();
+    if (!env)
+        return false;
+
+    AutoJObject progressiveUpdateDataJObj(env, env->CallObjectMethod(wrapped_obj,
+                                                                     jProgressiveUpdateCallbackMethod,
+                                                                     aHasPendingNewThebesContent,
+                                                                     (float)aDisplayPort.x,
+                                                                     (float)aDisplayPort.y,
+                                                                     (float)aDisplayPort.width,
+                                                                     (float)aDisplayPort.height,
+                                                                     aDisplayResolution,
+                                                                     !aDrawingCritical));
+    if (env->ExceptionCheck()) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+        return false;
+    }
+
+    NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!");
+
+    AndroidProgressiveUpdateData progressiveUpdateData(progressiveUpdateDataJObj);
+
+    aViewport.x = progressiveUpdateData.GetX(env);
+    aViewport.y = progressiveUpdateData.GetY(env);
+    aViewport.width = progressiveUpdateData.GetWidth(env);
+    aViewport.height = progressiveUpdateData.GetHeight(env);
+    aScaleX = aScaleY = progressiveUpdateData.GetScale(env);
+
+    return progressiveUpdateData.GetShouldAbort(env);
+}
+
+jobject ConvertToJavaViewportMetrics(JNIEnv* env, nsIAndroidViewport* metrics) {
+    float x, y, width, height,
+        pageLeft, pageTop, pageRight, pageBottom,
+        cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
+        zoom;
+    metrics->GetX(&x);
+    metrics->GetY(&y);
+    metrics->GetWidth(&width);
+    metrics->GetHeight(&height);
+    metrics->GetPageLeft(&pageLeft);
+    metrics->GetPageTop(&pageTop);
+    metrics->GetPageRight(&pageRight);
+    metrics->GetPageBottom(&pageBottom);
+    metrics->GetCssPageLeft(&cssPageLeft);
+    metrics->GetCssPageTop(&cssPageTop);
+    metrics->GetCssPageRight(&cssPageRight);
+    metrics->GetCssPageBottom(&cssPageBottom);
+    metrics->GetZoom(&zoom);
+
+    jobject jobj = env->NewObject(AndroidGeckoLayerClient::jViewportClass, AndroidGeckoLayerClient::jViewportCtor,
+                                  pageLeft, pageTop, pageRight, pageBottom,
+                                  cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
+                                  x, y, x + width, y + height,
+                                  zoom);
+    return jobj;
+}
+
+class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport
+{
+public:
+    NS_DECL_ISUPPORTS
+    virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; }
+    virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; }
+    virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; }
+    virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; }
+    virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; }
+    virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; }
+    virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; }
+    virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; }
+    virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; }
+    virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; }
+
+    nsAndroidDisplayport(AndroidRectF aRect, float aResolution):
+        mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {}
+
+private:
+    ~nsAndroidDisplayport() {}
+    float mLeft, mTop, mRight, mBottom, mResolution;
+};
+
 NS_IMPL_ISUPPORTS1(nsAndroidDisplayport, nsIAndroidDisplayport)
 
+void createDisplayPort(AutoLocalJNIFrame *jniFrame, jobject jobj, nsIAndroidDisplayport** displayPort) {
+    JNIEnv* env = jniFrame->GetEnv();
+    AndroidRectF rect(env, env->GetObjectField(jobj, AndroidGeckoLayerClient::jDisplayportPosition));
+    if (jniFrame->CheckForException()) return;
+    float resolution = env->GetFloatField(jobj, AndroidGeckoLayerClient::jDisplayportResolution);
+    if (jniFrame->CheckForException()) return;
+    *displayPort = new nsAndroidDisplayport(rect, resolution);
+}
+
+void
+AndroidGeckoLayerClient::GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort)
+{
+    jobject jmetrics = ConvertToJavaViewportMetrics(jniFrame->GetEnv(), metrics);
+    if (jniFrame->CheckForException()) return;
+    if (!jmetrics)
+        return;
+    jobject jobj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetDisplayPort, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics);
+    if (jniFrame->CheckForException()) return;
+    createDisplayPort(jniFrame, jobj, displayPort);
+    (*displayPort)->AddRef();
+}
+
+void
+AndroidGeckoLayerClient::ContentDocumentChanged(AutoLocalJNIFrame *jniFrame)
+{
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jContentDocumentChanged);
+}
+
+bool
+AndroidGeckoLayerClient::IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame)
+{
+    return jniFrame->GetEnv()->CallBooleanMethod(wrapped_obj, jIsContentDocumentDisplayed);
+}
+
+bool
+AndroidGeckoLayerClient::CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jobject frameJObj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jCreateFrameMethod);
+    if (jniFrame->CheckForException())
+        return false;
+    NS_ABORT_IF_FALSE(frameJObj, "No frame object!");
+
+    aFrame.Init(jniFrame->GetEnv(), frameJObj);
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::ActivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jActivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::DeactivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+float
+AndroidViewTransform::GetX(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jXField);
+}
+
+float
+AndroidViewTransform::GetY(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jYField);
+}
+
+float
+AndroidViewTransform::GetScale(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jScaleField);
+}
+
+void
+AndroidViewTransform::GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins)
+{
+    if (!env)
+        return;
+
+    aFixedLayerMargins.top = env->GetFloatField(wrapped_obj, jFixedLayerMarginTop);
+    aFixedLayerMargins.right = env->GetFloatField(wrapped_obj, jFixedLayerMarginRight);
+    aFixedLayerMargins.bottom = env->GetFloatField(wrapped_obj, jFixedLayerMarginBottom);
+    aFixedLayerMargins.left = env->GetFloatField(wrapped_obj, jFixedLayerMarginLeft);
+}
+
+float
+AndroidViewTransform::GetOffsetX(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jOffsetXField);
+}
+
+float
+AndroidViewTransform::GetOffsetY(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jOffsetYField);
+}
+
+float
+AndroidProgressiveUpdateData::GetX(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jXField);
+}
+
+float
+AndroidProgressiveUpdateData::GetY(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jYField);
+}
+
+float
+AndroidProgressiveUpdateData::GetWidth(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jWidthField);
+}
+
+float
+AndroidProgressiveUpdateData::GetHeight(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jHeightField);
+}
+
+float
+AndroidProgressiveUpdateData::GetScale(JNIEnv *env)
+{
+    if (!env)
+        return 0.0f;
+    return env->GetFloatField(wrapped_obj, jScaleField);
+}
+
+bool
+AndroidProgressiveUpdateData::GetShouldAbort(JNIEnv *env)
+{
+    if (!env)
+        return false;
+    return env->GetBooleanField(wrapped_obj, jShouldAbortField);
+}
+
 void
 AndroidRect::Init(JNIEnv *jenv, jobject jobj)
 {
     NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
 
     wrapped_obj = jobj;
 
     if (jobj) {
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -18,22 +18,31 @@
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/EventForwards.h"
 #include "InputData.h"
 #include "Units.h"
 
 //#define FORCE_ALOG 1
 
+#ifndef ALOG
+#if defined(DEBUG) || defined(FORCE_ALOG)
+#define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
+#else
+#define ALOG(args...) ((void)0)
+#endif
+#endif
+
 class nsIAndroidDisplayport;
 class nsIAndroidViewport;
 class nsIWidget;
 
 namespace mozilla {
 
+class AndroidGeckoLayerClient;
 class AutoLocalJNIFrame;
 
 void InitAndroidJavaWrappers(JNIEnv *jEnv);
 
 /*
  * Note: do not store global refs to any WrappedJavaObject;
  * these are live only during a particular JNI method, as
  * NewGlobalRef is -not- called on the jobject.
@@ -61,61 +70,29 @@ public:
 private:
     int32_t mRefCnt;
     jobject mObject;
 };
 
 class WrappedJavaObject {
 public:
     WrappedJavaObject() :
-        wrapped_obj(NULL)
+        wrapped_obj(0)
     { }
 
-    WrappedJavaObject(jobject jobj) : wrapped_obj(NULL) {
+    WrappedJavaObject(jobject jobj) {
         Init(jobj);
     }
 
     void Init(jobject jobj) {
         wrapped_obj = jobj;
     }
 
     bool isNull() const {
-        return wrapped_obj == NULL;
-    }
-
-    jobject wrappedObject() const {
-        return wrapped_obj;
-    }
-
-protected:
-    jobject wrapped_obj;
-};
-
-class AutoGlobalWrappedJavaObject : protected WrappedJavaObject{
-public:
-    AutoGlobalWrappedJavaObject() :
-        wrapped_obj(NULL)
-    { }
-
-    AutoGlobalWrappedJavaObject(jobject jobj, JNIEnv* env) : wrapped_obj(NULL) {
-        Init(jobj, env);
-    }
-
-    virtual ~AutoGlobalWrappedJavaObject();
-    void Dispose();
-
-    void Init(jobject jobj, JNIEnv* env) {
-        if (!isNull()) {
-            env->DeleteGlobalRef(wrapped_obj);
-        }
-        wrapped_obj = env->NewGlobalRef(jobj);
-    }
-
-    bool isNull() const {
-        return wrapped_obj == NULL;
+        return wrapped_obj == 0;
     }
 
     jobject wrappedObject() const {
         return wrapped_obj;
     }
 
 protected:
     jobject wrapped_obj;
@@ -204,16 +181,138 @@ protected:
 
     static jclass jRectClass;
     static jfieldID jBottomField;
     static jfieldID jLeftField;
     static jfieldID jRightField;
     static jfieldID jTopField;
 };
 
+class AndroidViewTransform : public WrappedJavaObject {
+public:
+    static void InitViewTransformClass(JNIEnv *jEnv);
+
+    void Init(jobject jobj);
+
+    AndroidViewTransform() {}
+    AndroidViewTransform(jobject jobj) { Init(jobj); }
+
+    float GetX(JNIEnv *env);
+    float GetY(JNIEnv *env);
+    float GetScale(JNIEnv *env);
+    void GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins);
+    float GetOffsetX(JNIEnv *env);
+    float GetOffsetY(JNIEnv *env);
+
+private:
+    static jclass jViewTransformClass;
+    static jfieldID jXField;
+    static jfieldID jYField;
+    static jfieldID jScaleField;
+    static jfieldID jFixedLayerMarginLeft;
+    static jfieldID jFixedLayerMarginTop;
+    static jfieldID jFixedLayerMarginRight;
+    static jfieldID jFixedLayerMarginBottom;
+    static jfieldID jOffsetXField;
+    static jfieldID jOffsetYField;
+};
+
+class AndroidProgressiveUpdateData : public WrappedJavaObject {
+public:
+    static void InitProgressiveUpdateDataClass(JNIEnv *jEnv);
+
+    void Init(jobject jobj);
+
+    AndroidProgressiveUpdateData() {}
+    AndroidProgressiveUpdateData(jobject jobj) { Init(jobj); }
+
+    float GetX(JNIEnv *env);
+    float GetY(JNIEnv *env);
+    float GetWidth(JNIEnv *env);
+    float GetHeight(JNIEnv *env);
+    float GetScale(JNIEnv *env);
+    bool GetShouldAbort(JNIEnv *env);
+
+private:
+    static jclass jProgressiveUpdateDataClass;
+    static jfieldID jXField;
+    static jfieldID jYField;
+    static jfieldID jWidthField;
+    static jfieldID jHeightField;
+    static jfieldID jScaleField;
+    static jfieldID jShouldAbortField;
+};
+
+class AndroidLayerRendererFrame : public WrappedJavaObject {
+public:
+    static void InitLayerRendererFrameClass(JNIEnv *jEnv);
+
+    void Init(JNIEnv *env, jobject jobj);
+    void Dispose(JNIEnv *env);
+
+    bool BeginDrawing(AutoLocalJNIFrame *jniFrame);
+    bool DrawBackground(AutoLocalJNIFrame *jniFrame);
+    bool DrawForeground(AutoLocalJNIFrame *jniFrame);
+    bool EndDrawing(AutoLocalJNIFrame *jniFrame);
+
+private:
+    static jclass jLayerRendererFrameClass;
+    static jmethodID jBeginDrawingMethod;
+    static jmethodID jDrawBackgroundMethod;
+    static jmethodID jDrawForegroundMethod;
+    static jmethodID jEndDrawingMethod;
+};
+
+class AndroidGeckoLayerClient : public WrappedJavaObject {
+public:
+    static void InitGeckoLayerClientClass(JNIEnv *jEnv);
+
+    void Init(jobject jobj);
+
+    AndroidGeckoLayerClient() {}
+    AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
+
+    void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
+    void SetPageRect(const CSSRect& aCssPageRect);
+    void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
+                          bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
+                          LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
+    void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
+                          bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
+                          bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
+    bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
+    bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
+    bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
+    bool DeactivateProgram(AutoLocalJNIFrame *jniFrame);
+    void GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
+    void ContentDocumentChanged(AutoLocalJNIFrame *jniFrame);
+    bool IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame);
+
+protected:
+    static jclass jGeckoLayerClientClass;
+    static jmethodID jSetFirstPaintViewport;
+    static jmethodID jSetPageRect;
+    static jmethodID jSyncViewportInfoMethod;
+    static jmethodID jSyncFrameMetricsMethod;
+    static jmethodID jCreateFrameMethod;
+    static jmethodID jActivateProgramMethod;
+    static jmethodID jDeactivateProgramMethod;
+    static jmethodID jGetDisplayPort;
+    static jmethodID jContentDocumentChanged;
+    static jmethodID jIsContentDocumentDisplayed;
+    static jmethodID jProgressiveUpdateCallbackMethod;
+
+public:
+    static jclass jViewportClass;
+    static jclass jDisplayportClass;
+    static jmethodID jViewportCtor;
+    static jfieldID jDisplayportPosition;
+    static jfieldID jDisplayportResolution;
+};
+
 enum {
     // These keycode masks are not defined in android/keycodes.h:
     AKEYCODE_ESCAPE             = 111,
     AKEYCODE_FORWARD_DEL        = 112,
     AKEYCODE_CTRL_LEFT          = 113,
     AKEYCODE_CTRL_RIGHT         = 114,
     AKEYCODE_CAPS_LOCK          = 115,
     AKEYCODE_SCROLL_LOCK        = 116,
@@ -329,39 +428,16 @@ enum {
     AMETA_META_RIGHT_ON         = 0x00040000,
 
     AMETA_ALT_MASK              = AMETA_ALT_LEFT_ON   | AMETA_ALT_RIGHT_ON   | AMETA_ALT_ON,
     AMETA_CTRL_MASK             = AMETA_CTRL_LEFT_ON  | AMETA_CTRL_RIGHT_ON  | AMETA_CTRL_ON,
     AMETA_META_MASK             = AMETA_META_LEFT_ON  | AMETA_META_RIGHT_ON  | AMETA_META_ON,
     AMETA_SHIFT_MASK            = AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON,
 };
 
-class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport
-{
-public:
-    NS_DECL_ISUPPORTS
-    virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; }
-    virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; }
-    virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; }
-    virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; }
-    virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; }
-    virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; }
-    virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; }
-    virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; }
-    virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; }
-    virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; }
-
-    nsAndroidDisplayport(AndroidRectF aRect, float aResolution):
-        mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {}
-
-private:
-    ~nsAndroidDisplayport() {}
-    float mLeft, mTop, mRight, mBottom, mResolution;
-};
-
 class AndroidMotionEvent
 {
 public:
     enum {
         ACTION_DOWN = 0,
         ACTION_UP = 1,
         ACTION_MOVE = 2,
         ACTION_CANCEL = 3,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -30,17 +30,16 @@
 
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Hal.h"
 #include "prenv.h"
 
 #include "AndroidBridge.h"
-#include "AndroidBridgeUtilities.h"
 #include <android/log.h>
 #include <pthread.h>
 #include <wchar.h>
 
 #include "mozilla/dom/ScreenOrientation.h"
 
 #include "GeckoProfiler.h"
 #ifdef MOZ_ANDROID_HISTORY
@@ -79,45 +78,45 @@ public:
         mBrowserApp(aBrowserApp), mPoints(aPoints), mTabId(aTabId), mBuffer(aBuffer) {}
 
     virtual nsresult Run() {
         jobject buffer = mBuffer->GetObject();
         nsCOMPtr<nsIDOMWindow> domWindow;
         nsCOMPtr<nsIBrowserTab> tab;
         mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
         if (!tab) {
-            ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
+            AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, false);
             return NS_ERROR_FAILURE;
         }
 
         tab->GetWindow(getter_AddRefs(domWindow));
         if (!domWindow) {
-            ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
+            AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, false);
             return NS_ERROR_FAILURE;
         }
 
         NS_ASSERTION(mPoints.Length() == 1, "Thumbnail event does not have enough coordinates");
 
         nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer);
-        ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv));
+        AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv));
         return rv;
     }
 private:
     nsCOMPtr<nsIAndroidBrowserApp> mBrowserApp;
     nsTArray<nsIntPoint> mPoints;
     int mTabId;
     nsRefPtr<RefCountedJavaObject> mBuffer;
 };
 
 class WakeLockListener MOZ_FINAL : public nsIDOMMozWakeLockListener {
  public:
   NS_DECL_ISUPPORTS;
 
   nsresult Callback(const nsAString& topic, const nsAString& state) {
-    GeckoAppShell::NotifyWakeLockChanged(topic, state);
+    AndroidBridge::Bridge()->NotifyWakeLockChanged(topic, state);
     return NS_OK;
   }
 };
 
 NS_IMPL_ISUPPORTS1(WakeLockListener, nsIDOMMozWakeLockListener)
 nsCOMPtr<nsIPowerManagerService> sPowerManagerService = nullptr;
 StaticRefPtr<WakeLockListener> sWakeLockListener;
 
@@ -199,27 +198,27 @@ nsAppShell::Init()
 
     Preferences::AddStrongObservers(this, kObservedPrefs);
 
     bool match;
     rv = Preferences::GetBool(PREFNAME_MATCH_OS, &match);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (match) {
-        GeckoAppShell::SetSelectedLocale(EmptyString());
+        bridge->SetSelectedLocale(EmptyString());
         return NS_OK;
     }
 
     nsAutoString locale;
     rv = Preferences::GetLocalizedString(PREFNAME_UA_LOCALE, &locale);
     if (NS_FAILED(rv)) {
         rv = Preferences::GetString(PREFNAME_UA_LOCALE, &locale);
     }
 
-    GeckoAppShell::SetSelectedLocale(locale);
+    bridge->SetSelectedLocale(locale);
     mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
     return rv;
 }
 
 NS_IMETHODIMP
 nsAppShell::Observe(nsISupports* aSubject,
                     const char* aTopic,
                     const PRUnichar* aData)
@@ -241,27 +240,27 @@ nsAppShell::Observe(nsISupports* aSubjec
             return NS_OK;
         }
 
         bool match;
         nsresult rv = Preferences::GetBool(PREFNAME_MATCH_OS, &match);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (match) {
-            GeckoAppShell::SetSelectedLocale(EmptyString());
+            bridge->SetSelectedLocale(EmptyString());
             return NS_OK;
         }
 
         nsAutoString locale;
         if (NS_FAILED(Preferences::GetLocalizedString(PREFNAME_UA_LOCALE,
                                                       &locale))) {
             locale = Preferences::GetString(PREFNAME_UA_LOCALE);
         }
 
-        GeckoAppShell::SetSelectedLocale(locale);
+        bridge->SetSelectedLocale(locale);
 
         mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
         return NS_OK;
     }
     return NS_OK;
 }
 
 void
@@ -597,17 +596,17 @@ nsAppShell::ProcessNextNativeEvent(bool 
         break;
 
     default:
         nsWindow::OnGlobalAndroidEvent(curEvent);
         break;
     }
 
     if (curEvent->AckNeeded()) {
-        GeckoAppShell::AcknowledgeEvent();
+        AndroidBridge::Bridge()->AcknowledgeEvent();
     }
 
     EVLOG("nsAppShell: -- done event %p %d", (void*)curEvent.get(), curEvent->Type());
 
     return true;
 }
 
 void
--- a/widget/android/nsClipboard.cpp
+++ b/widget/android/nsClipboard.cpp
@@ -40,17 +40,17 @@ nsClipboard::SetData(nsITransferable *aT
   nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
   // No support for non-text data
   NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED);
   nsAutoString buffer;
   supportsString->GetData(buffer);
 
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     if (AndroidBridge::Bridge())
-      Clipboard::SetClipboardText(buffer);
+      AndroidBridge::Bridge()->SetClipboardText(buffer);
     else
       return NS_ERROR_NOT_IMPLEMENTED;
 
   } else {
     bool isPrivateData = false;
     aTransferable->GetIsPrivateData(&isPrivateData);
     ContentChild::GetSingleton()->SendSetClipboardText(buffer, isPrivateData,
                                                        aWhichClipboard);
@@ -97,17 +97,17 @@ nsClipboard::GetData(nsITransferable *aT
 
 NS_IMETHODIMP
 nsClipboard::EmptyClipboard(int32_t aWhichClipboard)
 {
   if (aWhichClipboard != kGlobalClipboard)
     return NS_ERROR_NOT_IMPLEMENTED;
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     if (AndroidBridge::Bridge())
-      Clipboard::ClearText();
+      AndroidBridge::Bridge()->EmptyClipboard();
   } else {
     ContentChild::GetSingleton()->SendEmptyClipboard();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -115,17 +115,17 @@ nsClipboard::HasDataMatchingFlavors(cons
                                     uint32_t aLength, int32_t aWhichClipboard,
                                     bool *aHasText)
 {
   *aHasText = false;
   if (aWhichClipboard != kGlobalClipboard)
     return NS_ERROR_NOT_IMPLEMENTED;
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     if (AndroidBridge::Bridge())
-      *aHasText = Clipboard::HasText();
+      *aHasText = AndroidBridge::Bridge()->ClipboardHasText();
   } else {
     ContentChild::GetSingleton()->SendClipboardHasText(aHasText);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboard::SupportsSelectionClipboard(bool *aIsSupported)
--- a/widget/android/nsIMEPicker.cpp
+++ b/widget/android/nsIMEPicker.cpp
@@ -17,11 +17,11 @@ nsIMEPicker::nsIMEPicker()
 nsIMEPicker::~nsIMEPicker()
 {
   /* destructor code */
 }
 
 /* void show (); */
 NS_IMETHODIMP nsIMEPicker::Show()
 {
-    GeckoAppShell::ShowInputMethodPicker();
+    AndroidBridge::Bridge()->ShowInputMethodPicker();
     return NS_OK;
 }
--- a/widget/android/nsLookAndFeel.cpp
+++ b/widget/android/nsLookAndFeel.cpp
@@ -460,17 +460,17 @@ nsLookAndFeel::GetFontImpl(FontID aID, n
 
 /*virtual*/
 bool
 nsLookAndFeel::GetEchoPasswordImpl()
 {
     if (!mInitializedShowPassword) {
         if (XRE_GetProcessType() == GeckoProcessType_Default) {
             if (AndroidBridge::Bridge())
-                mShowPassword = GeckoAppShell::GetShowPasswordSetting();
+                mShowPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
             else
                 NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available!");
         } else {
             ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword);
         }
         mInitializedShowPassword = true;
     }
     return mShowPassword;
--- a/widget/android/nsScreenManagerAndroid.cpp
+++ b/widget/android/nsScreenManagerAndroid.cpp
@@ -54,17 +54,17 @@ NS_IMETHODIMP
 nsScreenAndroid::GetColorDepth(int32_t *aColorDepth)
 {
     return GetPixelDepth(aColorDepth);
 }
 
 void
 nsScreenAndroid::ApplyMinimumBrightness(uint32_t aBrightness)
 {
-  GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
+  AndroidBridge::Bridge()->SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
 }
 
 NS_IMPL_ISUPPORTS1(nsScreenManagerAndroid, nsIScreenManager)
 
 nsScreenManagerAndroid::nsScreenManagerAndroid()
 {
     mOneScreen = new nsScreenAndroid(nullptr);
 }
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -47,17 +47,16 @@ using mozilla::unused;
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #include "nsTArray.h"
 
 #include "AndroidBridge.h"
-#include "AndroidBridgeUtilities.h"
 #include "android_npapi.h"
 
 #include "imgIEncoder.h"
 
 #include "nsString.h"
 #include "GeckoProfiler.h" // For PROFILER_LABEL
 
 using namespace mozilla;
@@ -350,17 +349,17 @@ nsWindow::GetDefaultScaleInternal()
 {
     static double density = 0.0;
 
     if (density != 0.0) {
         return density;
     }
 
     if (AndroidBridge::Bridge()) {
-        density = GeckoAppShell::GetDensity();
+        density = AndroidBridge::Bridge()->GetDensity();
     }
 
     if (!density) {
         density = 1.0;
     }
 
     return density;
 }
@@ -515,17 +514,17 @@ nsWindow::PlaceBehind(nsTopLevelWidgetZP
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::SetSizeMode(int32_t aMode)
 {
     switch (aMode) {
         case nsSizeMode_Minimized:
-            GeckoAppShell::MoveTaskToBack();
+            AndroidBridge::Bridge()->MoveTaskToBack();
             break;
         case nsSizeMode_Fullscreen:
             MakeFullScreen(true);
             break;
     }
     return NS_OK;
 }
 
@@ -696,17 +695,17 @@ nsWindow::DispatchEvent(nsGUIEvent *aEve
         return status;
     }
     return nsEventStatus_eIgnore;
 }
 
 NS_IMETHODIMP
 nsWindow::MakeFullScreen(bool aFullScreen)
 {
-    GeckoAppShell::SetFullScreen(aFullScreen);
+    AndroidBridge::Bridge()->SetFullScreen(aFullScreen);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::SetWindowClass(const nsAString& xulWinType)
 {
     return NS_OK;
 }
@@ -1244,26 +1243,26 @@ bool nsWindow::OnMultitouchEvent(Android
 
     // if the last event we got was a down event, then by now we know for sure whether
     // this block has been default-prevented or not. if we haven't already sent the
     // notification for this block, do so now.
     if (sLastWasDownEvent && !sDefaultPreventedNotified) {
         // if this event is a down event, that means it's the start of a new block, and the
         // previous block should not be default-prevented
         bool defaultPrevented = isDownEvent ? false : preventDefaultActions;
-        GeckoAppShell::NotifyDefaultPrevented(defaultPrevented);
+        AndroidBridge::Bridge()->NotifyDefaultPrevented(defaultPrevented);
         sDefaultPreventedNotified = true;
     }
 
     // now, if this event is a down event, then we might already know that it has been
     // default-prevented. if so, we send the notification right away; otherwise we wait
     // for the next event.
     if (isDownEvent) {
         if (preventDefaultActions) {
-            GeckoAppShell::NotifyDefaultPrevented(true);
+            AndroidBridge::Bridge()->NotifyDefaultPrevented(true);
             sDefaultPreventedNotified = true;
         } else {
             sDefaultPreventedNotified = false;
         }
     }
     sLastWasDownEvent = isDownEvent;
 
     return preventDefaultActions;
@@ -1855,44 +1854,44 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             mIMESelectionChanged = false;
             // NotifyIMEOfTextChange also notifies selection
             // Use 'INT32_MAX / 2' here because subsequent text changes might
             // combine with this text change, and overflow might occur if
             // we just use INT32_MAX
             NotifyIMEOfTextChange(0, INT32_MAX / 2, INT32_MAX / 2);
             FlushIMEChanges();
         }
-        GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
+        AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
         return;
     } else if (ae->Action() == AndroidGeckoEvent::IME_UPDATE_CONTEXT) {
-        GeckoAppShell::NotifyIMEContext(mInputContext.mIMEState.mEnabled,
+        AndroidBridge::NotifyIMEContext(mInputContext.mIMEState.mEnabled,
                                         mInputContext.mHTMLInputType,
                                         mInputContext.mHTMLInputInputmode,
                                         mInputContext.mActionHint);
         mIMEUpdatingContext = false;
         return;
     }
     if (mIMEMaskEventsCount > 0) {
         // Still reply to events, but don't do anything else
         if (ae->Action() == AndroidGeckoEvent::IME_SYNCHRONIZE ||
             ae->Action() == AndroidGeckoEvent::IME_REPLACE_TEXT) {
-            GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
+            AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
         }
         return;
     }
     switch (ae->Action()) {
     case AndroidGeckoEvent::IME_FLUSH_CHANGES:
         {
             FlushIMEChanges();
         }
         break;
     case AndroidGeckoEvent::IME_SYNCHRONIZE:
         {
             FlushIMEChanges();
-            GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
+            AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
         }
         break;
     case AndroidGeckoEvent::IME_REPLACE_TEXT:
         {
             /*
                 Replace text in Gecko thread from ae->Start() to ae->End()
                   with the string ae->Characters()
 
@@ -1914,17 +1913,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             }
 
             if (!mIMEKeyEvents.IsEmpty()) {
                 for (uint32_t i = 0; i < mIMEKeyEvents.Length(); i++) {
                     OnKeyEvent(&mIMEKeyEvents[i]);
                 }
                 mIMEKeyEvents.Clear();
                 FlushIMEChanges();
-                GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
+                AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
                 break;
             }
 
             {
                 nsCompositionEvent event(true, NS_COMPOSITION_START, this);
                 InitEvent(event, nullptr);
                 DispatchEvent(&event);
             }
@@ -1936,17 +1935,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             }
             {
                 nsCompositionEvent event(true, NS_COMPOSITION_END, this);
                 InitEvent(event, nullptr);
                 event.data = ae->Characters();
                 DispatchEvent(&event);
             }
             FlushIMEChanges();
-            GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
+            AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
         }
         break;
     case AndroidGeckoEvent::IME_SET_SELECTION:
         {
             /*
                 Set Gecko selection to ae->Start() to ae->End()
 
                 Selection updates are masked to prevent Java from being
@@ -2114,17 +2113,17 @@ nsWindow::UserActivity()
 
 NS_IMETHODIMP
 nsWindow::NotifyIME(NotificationToIME aNotification)
 {
     switch (aNotification) {
         case REQUEST_TO_COMMIT_COMPOSITION:
             //ALOGIME("IME: REQUEST_TO_COMMIT_COMPOSITION: s=%d", aState);
             RemoveIMEComposition();
-            GeckoAppShell::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
+            AndroidBridge::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
             return NS_OK;
         case REQUEST_TO_CANCEL_COMPOSITION:
             ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION");
 
             // Cancel composition on Gecko side
             if (mIMEComposing) {
                 nsRefPtr<nsWindow> kungFuDeathGrip(this);
 
@@ -2132,33 +2131,33 @@ nsWindow::NotifyIME(NotificationToIME aN
                 InitEvent(textEvent, nullptr);
                 DispatchEvent(&textEvent);
 
                 nsCompositionEvent compEvent(true, NS_COMPOSITION_END, this);
                 InitEvent(compEvent, nullptr);
                 DispatchEvent(&compEvent);
             }
 
-            GeckoAppShell::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
+            AndroidBridge::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
             return NS_OK;
         case NOTIFY_IME_OF_FOCUS:
             ALOGIME("IME: NOTIFY_IME_OF_FOCUS");
-            GeckoAppShell::NotifyIME(NOTIFY_IME_OF_FOCUS);
+            AndroidBridge::NotifyIME(NOTIFY_IME_OF_FOCUS);
             return NS_OK;
         case NOTIFY_IME_OF_BLUR:
             ALOGIME("IME: NOTIFY_IME_OF_BLUR");
 
             // Mask events because we lost focus. On the next focus event,
             // Gecko will notify Java, and Java will send an acknowledge focus
             // event back to Gecko. That is where we unmask event handling
             mIMEMaskEventsCount++;
             mIMEComposing = false;
             mIMEComposingText.Truncate();
 
-            GeckoAppShell::NotifyIME(NOTIFY_IME_OF_BLUR);
+            AndroidBridge::NotifyIME(NOTIFY_IME_OF_BLUR);
             return NS_OK;
         case NOTIFY_IME_OF_SELECTION_CHANGE:
             if (mIMEMaskSelectionUpdate) {
                 return NS_OK;
             }
 
             ALOGIME("IME: NOTIFY_IME_OF_SELECTION_CHANGE");
 
@@ -2208,17 +2207,17 @@ nsWindow::SetInputContext(const InputCon
         aContext.mIMEState.mOpen != IMEState::OPEN) {
         enabled = IMEState::DISABLED;
     }
 
     mInputContext.mIMEState.mEnabled = enabled;
 
     if (enabled == IMEState::ENABLED && aAction.UserMightRequestOpenVKB()) {
         // Don't reset keyboard when we should simply open the vkb
-        GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB);
+        AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB);
         return;
     }
 
     if (mIMEUpdatingContext) {
         return;
     }
     AndroidGeckoEvent *event = AndroidGeckoEvent::MakeIMEEvent(
             AndroidGeckoEvent::IME_UPDATE_CONTEXT);
@@ -2264,32 +2263,32 @@ nsWindow::FlushIMEChanges()
         nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, this);
         InitEvent(event, nullptr);
         event.InitForQueryTextContent(change.mStart,
                                       change.mNewEnd - change.mStart);
         DispatchEvent(&event);
         if (!event.mSucceeded)
             return;
 
-        GeckoAppShell::NotifyIMEChange(event.mReply.mString,
+        AndroidBridge::NotifyIMEChange(event.mReply.mString,
                                        change.mStart,
                                        change.mOldEnd,
                                        change.mNewEnd);
     }
     mIMETextChanges.Clear();
 
     if (mIMESelectionChanged) {
         nsQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, this);
         InitEvent(event, nullptr);
 
         DispatchEvent(&event);
         if (!event.mSucceeded)
             return;
 
-        GeckoAppShell::NotifyIMEChange(EmptyString(),
+        AndroidBridge::NotifyIMEChange(EmptyString(),
                              (int32_t) event.GetSelectionStart(),
                              (int32_t) event.GetSelectionEnd(), -1);
         mIMESelectionChanged = false;
     }
 }
 
 NS_IMETHODIMP
 nsWindow::NotifyIMEOfTextChange(uint32_t aStart,
@@ -2374,61 +2373,54 @@ nsWindow::GetIMEUpdatePreference()
     return nsIMEUpdatePreference(notifications, true);
 }
 
 void
 nsWindow::DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect)
 {
     JNIEnv *env = GetJNIForThread();
     NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowUnderlay()!");
-    if (!env) {
+    if (!env)
         return;
-    }
 
     AutoLocalJNIFrame jniFrame(env);
 
-    GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient();
-    if (!client || client->isNull()) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
-        return;
-    }
-
-    jobject frameObj = client->CreateFrame();
-    NS_ABORT_IF_FALSE(frameObj, "No frame object!");
-    if (!frameObj) {
-        ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
+    AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
+    if (!client.CreateFrame(&jniFrame, mLayerRendererFrame)) return;
+    
+    if (!WidgetPaintsBackground())
         return;
-    }
 
-    mLayerRendererFrame.Init(frameObj, env);
-    if (!WidgetPaintsBackground()) {
-        return;
-    }
-
-    client->ActivateProgram();
-    mLayerRendererFrame.BeginDrawing();
-    mLayerRendererFrame.DrawBackground();
-    client->DeactivateProgram(); // redundant, but in case somebody adds code after this...
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.BeginDrawing(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawBackground(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return; // redundant, but in case somebody adds code after this...
 }
 
 void
 nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
 {
     PROFILER_LABEL("nsWindow", "DrawWindowOverlay");
+    JNIEnv *env = GetJNIForThread();
+    NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowOverlay()!");
+    if (!env)
+        return;
+
+    AutoLocalJNIFrame jniFrame(env);
 
     NS_ABORT_IF_FALSE(!mLayerRendererFrame.isNull(),
                       "Frame should have been created in DrawWindowUnderlay()!");
 
-    GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient();
+    AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
 
-    client->ActivateProgram();
-    mLayerRendererFrame.DrawForeground();
-    mLayerRendererFrame.EndDrawing();
-    client->DeactivateProgram();
-    mLayerRendererFrame.Dispose();
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawForeground(&jniFrame)) return;
+    if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return;
+    mLayerRendererFrame.Dispose(env);
 }
 
 // off-main-thread compositor fields and functions
 
 StaticRefPtr<mozilla::layers::APZCTreeManager> nsWindow::sApzcTreeManager;
 StaticRefPtr<mozilla::layers::LayerManager> nsWindow::sLayerManager;
 StaticRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent;
 StaticRefPtr<mozilla::layers::CompositorChild> nsWindow::sCompositorChild;
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -6,17 +6,16 @@
 #ifndef NSWINDOW_H_
 #define NSWINDOW_H_
 
 #include "nsBaseWidget.h"
 #include "gfxPoint.h"
 #include "nsIIdleServiceInternal.h"
 #include "nsTArray.h"
 #include "AndroidJavaWrappers.h"
-#include "GeneratedJNIWrappers.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TextEvents.h"
 
 class gfxASurface;
 
 struct ANPEvent;
 
 namespace mozilla {
@@ -228,17 +227,17 @@ private:
                              mozilla::AndroidGeckoEvent *ae,
                              const nsIntPoint &refPoint);
     void DispatchGestureEvent(uint32_t msg, uint32_t direction, double delta,
                               const nsIntPoint &refPoint, uint64_t time);
     void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae);
     void CreateLayerManager(int aCompositorWidth, int aCompositorHeight);
     void RedrawAll();
 
-    mozilla::widget::android::LayerRendererFrame mLayerRendererFrame;
+    mozilla::AndroidLayerRendererFrame mLayerRendererFrame;
 
     static mozilla::StaticRefPtr<mozilla::layers::APZCTreeManager> sApzcTreeManager;
     static mozilla::StaticRefPtr<mozilla::layers::LayerManager> sLayerManager;
     static mozilla::StaticRefPtr<mozilla::layers::CompositorParent> sCompositorParent;
     static mozilla::StaticRefPtr<mozilla::layers::CompositorChild> sCompositorChild;
     static bool sCompositorPaused;
 };
 
--- a/xpcom/base/nsSystemInfo.cpp
+++ b/xpcom/base/nsSystemInfo.cpp
@@ -17,17 +17,16 @@
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #include <gtk/gtk.h>
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
-using namespace mozilla::widget::android;
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include <sys/system_properties.h>
 #endif
 
 #ifdef ANDROID
 extern "C" {
@@ -137,17 +136,17 @@ nsSystemInfo::Init()
         if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", str))
             SetPropertyAsAString(NS_LITERAL_STRING("release_version"), str);
         int32_t version;
         if (!mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &version))
             version = 0;
         android_sdk_version = version;
         if (version >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str))
             SetPropertyAsAString(NS_LITERAL_STRING("hardware"), str);
-        bool isTablet = GeckoAppShell::IsTablet();
+        bool isTablet = mozilla::AndroidBridge::Bridge()->IsTablet();
         SetPropertyAsBool(NS_LITERAL_STRING("tablet"), isTablet);
         // NSPR "version" is the kernel version. For Android we want the Android version.
         // Rename SDK version to version and put the kernel version into kernel_version.
         rv = GetPropertyAsAString(NS_LITERAL_STRING("version"), str);
         if (NS_SUCCEEDED(rv)) {
             SetPropertyAsAString(NS_LITERAL_STRING("kernel_version"), str);
         }
         SetPropertyAsInt32(NS_LITERAL_STRING("version"), android_sdk_version);
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -467,17 +467,17 @@ ParseManifest(NSLocationType type, FileL
 #elif defined(MOZ_WIDGET_GTK)
   nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
                                        gtk_major_version,
                                        gtk_minor_version);
 #elif defined(MOZ_WIDGET_ANDROID)
   bool isTablet = false;
   if (mozilla::AndroidBridge::Bridge()) {
     mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion);
-    isTablet = mozilla::widget::android::GeckoAppShell::IsTablet();
+    isTablet = mozilla::AndroidBridge::Bridge()->IsTablet();
   }
 #endif
 
   // Because contracts must be registered after CIDs, we save and process them
   // at the end.
   nsTArray<CachedDirective> contracts;
 
   char *token;
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -1804,17 +1804,18 @@ nsLocalFile::Launch()
     nsresult rv;
     nsAutoCString type;
     nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
     if (NS_SUCCEEDED(rv))
         rv = mimeService->GetTypeFromFile(this, type);
 
     nsDependentCString fileUri = NS_LITERAL_CSTRING("file://");
     fileUri.Append(mPath);
-    return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
+    mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
+    return bridge->OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
 #elif defined(MOZ_WIDGET_COCOA)
     CFURLRef url;
     if (NS_SUCCEEDED(GetCFURL(&url))) {
         nsresult rv = CocoaFileUtils::OpenURL(url);
         ::CFRelease(url);
         return rv;
     }
     return NS_ERROR_FAILURE;