Bug 1305271 - 2. Add and use jni::IsFennec() for Fennec-only code; r=snorp
authorJim Chen <nchen@mozilla.com>
Wed, 28 Sep 2016 23:49:25 -0400
changeset 315699 41f3ef3587650a8c3e436b3b23b983aa07b68820
parent 315698 105160f6218d735ea8d897dc8e3ec8a9a669b242
child 315700 d700a47ef29500aeb3230ad8a1729d005c66644b
push idunknown
push userunknown
push dateunknown
reviewerssnorp
bugs1305271
milestone52.0a1
Bug 1305271 - 2. Add and use jni::IsFennec() for Fennec-only code; r=snorp Add jni::IsFennec() that returns whether we're in a Fennec environment (defined as the presence of the GeckoApp class). Then, add jni::IsFennec() checks to places where we use JNI for Fennec-only classes.
dom/media/platforms/android/RemoteDataDecoder.cpp
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/components/jsdownloads/src/DownloadPlatform.cpp
toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp
tools/profiler/core/GeckoSampler.cpp
tools/profiler/core/platform.cpp
uriloader/exthandler/nsExternalHelperAppService.cpp
widget/android/AndroidBridge.cpp
widget/android/jni/Utils.cpp
widget/android/jni/Utils.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -194,16 +194,21 @@ public:
   RefPtr<InitPromise> Init() override
   {
     mSurfaceTexture = AndroidSurfaceTexture::Create();
     if (!mSurfaceTexture) {
       NS_WARNING("Failed to create SurfaceTexture for video decode\n");
       return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
     }
 
+    if (!jni::IsFennec()) {
+      NS_WARNING("Remote decoding not supported in non-Fennec environment\n");
+      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+    }
+
     // Register native methods.
     JavaCallbacksSupport::Init();
 
     mJavaCallbacks = CodecProxy::NativeCallbacks::New();
     JavaCallbacksSupport::AttachNative(mJavaCallbacks,
                                        mozilla::MakeUnique<CallbacksSupport>(this, mCallback));
 
     mJavaDecoder = CodecProxy::Create(mFormat, mSurfaceTexture->JavaSurface(), mJavaCallbacks);
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -2790,17 +2790,19 @@ nsDownload::SetState(DownloadState aStat
           if (addToRecentDocs) {
             nsCOMPtr<nsIMIMEInfo> mimeInfo;
             nsAutoCString contentType;
             GetMIMEInfo(getter_AddRefs(mimeInfo));
 
             if (mimeInfo)
               mimeInfo->GetMIMEType(contentType);
 
-            java::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
+            if (jni::IsFennec()) {
+                java::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
+            }
           }
 #else
           if (addToRecentDocs && !mPrivate) {
 #ifdef XP_WIN
             ::SHAddToRecentDocs(SHARD_PATHW, path.get());
 #elif defined(MOZ_WIDGET_GTK)
             GtkRecentManager* manager = gtk_recent_manager_get_default();
 
--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
+++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
@@ -104,17 +104,17 @@ nsresult DownloadPlatform::DownloadDone(
   nsAutoString path;
   if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) {
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID)
     // On Windows and Gtk, add the download to the system's "recent documents"
     // list, with a pref to disable.
     {
       bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS);
 #ifdef MOZ_WIDGET_ANDROID
-      if (addToRecentDocs) {
+      if (jni::IsFennec() && addToRecentDocs) {
         java::DownloadsIntegration::ScanMedia(path, aContentType);
       }
 #else
       if (addToRecentDocs && !aIsPrivate) {
 #ifdef XP_WIN
         ::SHAddToRecentDocs(SHARD_PATHW, path.get());
 #elif defined(MOZ_WIDGET_GTK)
         GtkRecentManager* manager = gtk_recent_manager_get_default();
--- a/toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp
+++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceAndroid.cpp
@@ -10,17 +10,17 @@
 
 namespace java = mozilla::java;
 
 NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService)
 
 nsParentalControlsService::nsParentalControlsService() :
   mEnabled(false)
 {
-  if (mozilla::jni::IsAvailable()) {
+  if (mozilla::jni::IsFennec()) {
     mEnabled = java::Restrictions::IsUserRestricted();
   }
 }
 
 nsParentalControlsService::~nsParentalControlsService()
 {
 }
 
@@ -82,22 +82,22 @@ nsParentalControlsService::IsAllowed(int
 {
   nsresult rv = NS_OK;
   *_retval = true;
 
   if (!mEnabled) {
     return rv;
   }
 
-  if (mozilla::jni::IsAvailable()) {
+  if (mozilla::jni::IsFennec()) {
     nsAutoCString url;
     if (aUri) {
       rv = aUri->GetSpec(url);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     *_retval = java::Restrictions::IsAllowed(aAction,
-                                                    NS_ConvertUTF8toUTF16(url));
+                                             NS_ConvertUTF8toUTF16(url));
     return rv;
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
--- a/tools/profiler/core/GeckoSampler.cpp
+++ b/tools/profiler/core/GeckoSampler.cpp
@@ -187,17 +187,18 @@ GeckoSampler::GeckoSampler(double aInter
   , mSaveRequested(false)
 #if defined(XP_WIN)
   , mIntelPowerGadget(nullptr)
 #endif
 {
   mUseStackWalk = hasFeature(aFeatures, aFeatureCount, "stackwalk");
 
   mProfileJS = hasFeature(aFeatures, aFeatureCount, "js");
-  mProfileJava = hasFeature(aFeatures, aFeatureCount, "java");
+  mProfileJava = mozilla::jni::IsFennec() &&
+      hasFeature(aFeatures, aFeatureCount, "java");
   mProfileGPU = hasFeature(aFeatures, aFeatureCount, "gpu");
   mProfilePower = hasFeature(aFeatures, aFeatureCount, "power");
   // Users sometimes ask to filter by a list of threads but forget to request
   // profiling non main threads. Let's make it implificit if we have a filter
   mProfileThreads = hasFeature(aFeatures, aFeatureCount, "threads") || aFilterCount > 0;
   mAddLeafAddresses = hasFeature(aFeatures, aFeatureCount, "leaf");
   mPrivacyMode = hasFeature(aFeatures, aFeatureCount, "privacy");
   mAddMainThreadIO = hasFeature(aFeatures, aFeatureCount, "mainthreadio");
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -497,17 +497,17 @@ void mozilla_sampler_init(void* stackTop
   // platform specific initialization
   OS::Startup();
 
 #ifndef SPS_STANDALONE
   set_stderr_callback(mozilla_sampler_log);
 #endif
 
 #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
-  if (mozilla::jni::IsAvailable()) {
+  if (mozilla::jni::IsFennec()) {
     GeckoJavaSampler::Init();
   }
 #endif
 
   // We can't open pref so we use an environment variable
   // to know if we should trigger the profiler on startup
   // NOTE: Default
   const char *val = getenv("MOZ_PROFILER_STARTUP");
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -377,17 +377,20 @@ static nsresult GetDownloadDirectory(nsI
   dir = dsf->mFile;
 #elif defined(ANDROID)
   // We ask Java for the temporary download directory. The directory will be
   // different depending on whether we have the permission to write to the
   // public download directory or not.
   // In the case where we do not have the permission we will start the
   // download to the app cache directory and later move it to the final
   // destination after prompting for the permission.
-  auto downloadDir = java::DownloadsIntegration::GetTemporaryDownloadDirectory();
+  jni::String::LocalRef downloadDir;
+  if (jni::IsFennec()) {
+    downloadDir = java::DownloadsIntegration::GetTemporaryDownloadDirectory();
+  }
 
   nsresult rv;
   if (downloadDir) {
     nsCOMPtr<nsIFile> ldir;
     rv = NS_NewNativeLocalFile(downloadDir->ToCString(),
                                true, getter_AddRefs(ldir));
 
     NS_ENSURE_SUCCESS(rv, rv);
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -1201,27 +1201,31 @@ nsAndroidBridge::UpdateAudioPlayingWindo
 }
 
 void
 nsAndroidBridge::AddObservers()
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->AddObserver(this, "xpcom-shutdown", false);
-    obs->AddObserver(this, "media-playback", false);
+    if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment.
+        obs->AddObserver(this, "media-playback", false);
+    }
   }
 }
 
 void
 nsAndroidBridge::RemoveObservers()
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->RemoveObserver(this, "xpcom-shutdown");
-    obs->RemoveObserver(this, "media-playback");
+    if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment.
+        obs->RemoveObserver(this, "media-playback");
+    }
   }
 }
 
 uint32_t
 AndroidBridge::GetScreenOrientation()
 {
     ALOG_BRIDGE("AndroidBridge::GetScreenOrientation");
 
--- a/widget/android/jni/Utils.cpp
+++ b/widget/android/jni/Utils.cpp
@@ -68,16 +68,17 @@ JNIEnv* sGeckoThreadEnv;
 
 namespace {
 
 JavaVM* sJavaVM;
 pthread_key_t sThreadEnvKey;
 jclass sOOMErrorClass;
 jobject sClassLoader;
 jmethodID sClassLoaderLoadClass;
+bool sIsFennec;
 
 void UnregisterThreadEnv(void* env)
 {
     if (!env) {
         // We were never attached.
         return;
     }
     // The thread may have already been detached. In that case, it's still
@@ -109,16 +110,21 @@ void SetGeckoThreadEnv(JNIEnv* aEnv)
             aEnv->FindClass("java/lang/OutOfMemoryError"))).Forget();
     aEnv->ExceptionClear();
 
     sClassLoader = Object::GlobalRef(java::GeckoThread::ClsLoader()).Forget();
     sClassLoaderLoadClass = aEnv->GetMethodID(
             Class::LocalRef::Adopt(aEnv->GetObjectClass(sClassLoader)).Get(),
             "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
     MOZ_ASSERT(sClassLoader && sClassLoaderLoadClass);
+
+    auto geckoAppClass = Class::LocalRef::Adopt(
+            aEnv->FindClass("org/mozilla/gecko/GeckoApp"));
+    aEnv->ExceptionClear();
+    sIsFennec = !!geckoAppClass;
 }
 
 JNIEnv* GetEnvForThread()
 {
     MOZ_ASSERT(sGeckoThreadEnv);
 
     JNIEnv* env = static_cast<JNIEnv*>(pthread_getspecific(sThreadEnvKey));
     if (env) {
@@ -281,10 +287,15 @@ void DispatchToGeckoThread(UniquePtr<Abs
         {
             (*mCall)();
         }
     };
 
     nsAppShell::PostEvent(MakeUnique<AbstractCallEvent>(Move(aCall)));
 }
 
+bool IsFennec()
+{
+    return sIsFennec;
+}
+
 } // jni
 } // mozilla
--- a/widget/android/jni/Utils.h
+++ b/widget/android/jni/Utils.h
@@ -130,12 +130,18 @@ jclass GetClassRef(JNIEnv* aEnv, const c
 struct AbstractCall
 {
     virtual ~AbstractCall() {}
     virtual void operator()() = 0;
 };
 
 void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall);
 
+/**
+ * Returns whether Gecko is running in a Fennec environment, as determined by
+ * the presence of the GeckoApp class.
+ */
+bool IsFennec();
+
 } // jni
 } // mozilla
 
 #endif // mozilla_jni_Utils_h__
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -369,26 +369,29 @@ nsAppShell::nsAppShell()
         return;
     }
 
     if (jni::IsAvailable()) {
         // Initialize JNI and Set the corresponding state in GeckoThread.
         AndroidBridge::ConstructBridge();
         GeckoAppShellSupport::Init();
         GeckoThreadSupport::Init();
-        mozilla::ANRReporter::Init();
         mozilla::GeckoBatteryManager::Init();
         mozilla::GeckoNetworkManager::Init();
         mozilla::GeckoScreenOrientation::Init();
-        mozilla::MemoryMonitor::Init();
         mozilla::PrefsHelper::Init();
-        mozilla::widget::Telemetry::Init();
-        mozilla::ThumbnailHelper::Init();
         nsWindow::InitNatives();
 
+        if (jni::IsFennec()) {
+            mozilla::ANRReporter::Init();
+            mozilla::MemoryMonitor::Init();
+            mozilla::widget::Telemetry::Init();
+            mozilla::ThumbnailHelper::Init();
+        }
+
         java::GeckoThread::SetState(java::GeckoThread::State::JNI_READY());
     }
 
     sPowerManagerService = do_GetService(POWERMANAGERSERVICE_CONTRACTID);
 
     if (sPowerManagerService) {
         sWakeLockListener = new WakeLockListener();
     } else {
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1463,17 +1463,19 @@ nsWindow::GeckoViewSupport::LoadUri(jni:
 
 void
 nsWindow::InitNatives()
 {
     nsWindow::GeckoViewSupport::Base::Init();
     nsWindow::GeckoViewSupport::EditableBase::Init();
     nsWindow::LayerViewSupport::Init();
     nsWindow::NPZCSupport::Init();
-    nsWindow::PMPMSupport::Init();
+    if (jni::IsFennec()) {
+        nsWindow::PMPMSupport::Init();
+    }
 }
 
 nsWindow*
 nsWindow::TopWindow()
 {
     if (!gTopLevelWindows.IsEmpty())
         return gTopLevelWindows[0];
     return nullptr;