Bug 959237 - Add AndroidBridge::HasEnv checks; r=blassey
authorJim Chen <nchen@mozilla.com>
Fri, 17 Jan 2014 23:32:24 -0600
changeset 164123 3f69ca51a4e84d05c6ef1550886a824eb7abf24f
parent 164122 ae1c7e26a97dbb4ae49f78504ec10189982d6dbb
child 164124 0ed7f1bad6e301e9bdd7fa968846eaaca5226eef
push id26026
push userphilringnalda@gmail.com
push dateSat, 18 Jan 2014 23:17:27 +0000
treeherdermozilla-central@61fd0f987cf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey
bugs959237
milestone29.0a1
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
Bug 959237 - Add AndroidBridge::HasEnv checks; r=blassey For certain tests, the AndroidBridge is not initialized, but some GeckoAppShell functions are still called indirectly. For now, this patch adds checks to skip these calls if there's no AndroidBridge. However, in the future, most of the affected code should be refactored to not require these checks.
ipc/glue/MessagePump.cpp
mobile/android/components/build/nsAndroidHistory.cpp
netwerk/base/src/Tickler.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
--- a/ipc/glue/MessagePump.cpp
+++ b/ipc/glue/MessagePump.cpp
@@ -100,17 +100,19 @@ 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();
+    if (MOZ_LIKELY(AndroidBridge::HasEnv())) {
+        did_work |= GeckoAppShell::PumpMessageLoop();
+    }
 #endif
 
     did_work |= aDelegate->DoDelayedWork(&delayed_work_time_);
 
 if (did_work && delayed_work_time_.is_null()
 #ifdef MOZ_NUWA_PROCESS
     && (!IsNuwaReady() || !IsNuwaProcess())
 #endif
--- a/mobile/android/components/build/nsAndroidHistory.cpp
+++ b/mobile/android/components/build/nsAndroidHistory.cpp
@@ -57,17 +57,19 @@ nsAndroidHistory::RegisterVisitedCallbac
 
   nsTArray<Link*>* list = mListeners.Get(uriString);
   if (! list) {
     list = new nsTArray<Link*>();
     mListeners.Put(uriString, list);
   }
   list->AppendElement(aContent);
 
- GeckoAppShell::CheckURIVisited(uriString);
+  if (AndroidBridge::HasEnv()) {
+    GeckoAppShell::CheckURIVisited(uriString);
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidHistory::UnregisterVisitedCallback(nsIURI *aURI, Link *aContent)
 {
   if (!aContent || !aURI)
@@ -168,21 +170,23 @@ nsAndroidHistory::VisitURI(nsIURI *aURI,
   }
 
   if (aFlags & VisitFlags::REDIRECT_SOURCE)
     return NS_OK;
 
   if (aFlags & VisitFlags::UNRECOVERABLE_ERROR)
     return NS_OK;
 
-  nsAutoCString uri;
-  rv = aURI->GetSpec(uri);
-  if (NS_FAILED(rv)) return rv;
-  NS_ConvertUTF8toUTF16 uriString(uri);
-  GeckoAppShell::MarkURIVisited(uriString);
+  if (AndroidBridge::HasEnv()) {
+    nsAutoCString uri;
+    rv = aURI->GetSpec(uri);
+    if (NS_FAILED(rv)) return rv;
+    NS_ConvertUTF8toUTF16 uriString(uri);
+    GeckoAppShell::MarkURIVisited(uriString);
+  }
 
   AppendToRecentlyVisitedURIs(aURI);
 
   // Finally, notify that we've been visited.
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   if (obsService) {
     obsService->NotifyObservers(aURI, NS_LINK_VISITED_EVENT_TOPIC, nullptr);
@@ -201,17 +205,17 @@ nsAndroidHistory::SetURITitle(nsIURI *aU
   if (!canAdd) {
     return NS_OK;
   }
 
   if (IsEmbedURI(aURI)) {
     return NS_OK;
   }
 
-  if (AndroidBridge::Bridge()) {
+  if (AndroidBridge::HasEnv()) {
     nsAutoCString uri;
     nsresult rv = aURI->GetSpec(uri);
     if (NS_FAILED(rv)) return rv;
     NS_ConvertUTF8toUTF16 uriString(uri);
     GeckoAppShell::SetURITitle(uriString, aTitle);
   }
   return NS_OK;
 }
--- a/netwerk/base/src/Tickler.cpp
+++ b/netwerk/base/src/Tickler.cpp
@@ -75,17 +75,19 @@ nsresult
 Tickler::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mTimer);
   MOZ_ASSERT(!mActive);
   MOZ_ASSERT(!mThread);
   MOZ_ASSERT(!mFD);
 
-  GeckoAppShell::EnableNetworkNotifications();
+  if (AndroidBridge::HasEnv()) {
+      GeckoAppShell::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/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -469,17 +469,19 @@ AndroidBridge::GetScreenDepth()
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     static int sDepth = 0;
     if (sDepth)
         return sDepth;
 
     const int DEFAULT_DEPTH = 16;
 
-    sDepth = GeckoAppShell::GetScreenDepthWrapper();
+    if (HasEnv()) {
+        sDepth = GeckoAppShell::GetScreenDepthWrapper();
+    }
     if (!sDepth)
         return DEFAULT_DEPTH;
 
     return sDepth;
 }
 
 void
 AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions)
@@ -694,16 +696,19 @@ AndroidBridge::CreateEGLSurfaceForCompos
 }
 
 bool
 AndroidBridge::GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* jEnv /* = nullptr */)
 {
     ALOG_BRIDGE("AndroidBridge::GetStaticIntField %s", fieldName);
 
     if (!jEnv) {
+        if (!HasEnv()) {
+            return false;
+        }
         jEnv = GetJNIEnv();
     }
 
     initInit();
     getClassGlobalRef(className);
     jfieldID field = getStaticField(fieldName, "I");
 
     if (!field) {
@@ -718,16 +723,19 @@ AndroidBridge::GetStaticIntField(const c
 }
 
 bool
 AndroidBridge::GetStaticStringField(const char *className, const char *fieldName, nsAString &result, JNIEnv* jEnv /* = nullptr */)
 {
     ALOG_BRIDGE("AndroidBridge::GetStaticStringField %s", fieldName);
 
     if (!jEnv) {
+        if (!HasEnv()) {
+            return false;
+        }
         jEnv = GetJNIEnv();
     }
 
     AutoLocalJNIFrame jniFrame(jEnv, 1);
     initInit();
     getClassGlobalRef(className);
     jfieldID field = getStaticField(fieldName, "Ljava/lang/String;");
 
@@ -1584,16 +1592,19 @@ AndroidBridge::ScheduleComposite()
 
 nsresult
 AndroidBridge::GetProxyForURI(const nsACString & aSpec,
                               const nsACString & aScheme,
                               const nsACString & aHost,
                               const int32_t      aPort,
                               nsACString & aResult)
 {
+    if (!HasEnv()) {
+        return NS_ERROR_FAILURE;
+    }
     JNIEnv* env = GetJNIEnv();
 
     AutoLocalJNIFrame jniFrame(env, 1);
     jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
                                             NS_ConvertUTF8toUTF16(aScheme),
                                             NS_ConvertUTF8toUTF16(aHost),
                                             aPort);
 
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -150,16 +150,20 @@ public:
         MOZ_ASSERT(sBridge);
         if (MOZ_UNLIKELY(!pthread_equal(pthread_self(), sBridge->mThread))) {
             MOZ_CRASH();
         }
         MOZ_ASSERT(sBridge->mJNIEnv);
         return sBridge->mJNIEnv;
     }
 
+    static bool HasEnv() {
+        return sBridge && sBridge->mJNIEnv;
+    }
+
     // 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 */