Bug 1458020 - 3. Set JavaVM when actually using video capture; r?jib draft
authorJim Chen <nchen@mozilla.com>
Thu, 17 May 2018 19:41:13 -0400
changeset 796618 938c6251bc126f71c815a70164f676de0271360f
parent 796617 a78b60c944304e8cfd1cc8b9bd5e0cdcfd2285ab
child 796619 b1e93eb179a9bcf156021be26241c7afc3138c18
push id110315
push userbmo:nchen@mozilla.com
push dateThu, 17 May 2018 23:41:44 +0000
reviewersjib
bugs1458020
milestone62.0a1
Bug 1458020 - 3. Set JavaVM when actually using video capture; r?jib We currently set the Android JavaVM pointer in MediaEngineWebRTC. However, because of that, we end up setting the pointer in the child process, even though we really want to set the pointer in the parent process because that's where the camera will be accessed. This patch makes us set JavaVM inside VideoEngine itself, where we actually access the camera in the parent process. MozReview-Commit-ID: 3TeLiiK2vyh
dom/media/systemservices/VideoEngine.cpp
dom/media/systemservices/VideoEngine.h
dom/media/webrtc/MediaEngineWebRTC.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
--- a/dom/media/systemservices/VideoEngine.cpp
+++ b/dom/media/systemservices/VideoEngine.cpp
@@ -6,32 +6,36 @@
 
 #include "VideoEngine.h"
 #include "webrtc/video_engine/browser_capture_impl.h"
 #include "webrtc/system_wrappers/include/clock.h"
 #ifdef WEBRTC_ANDROID
 #include "webrtc/modules/video_capture/video_capture.h"
 #endif
 
+#ifdef MOZ_WIDGET_ANDROID
+#include "mozilla/jni/Utils.h"
+#endif
 
 namespace mozilla {
 namespace camera {
 
 #undef LOG
 #undef LOG_ENABLED
 mozilla::LazyLogModule gVideoEngineLog("VideoEngine");
 #define LOG(args) MOZ_LOG(gVideoEngineLog, mozilla::LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gVideoEngineLog, mozilla::LogLevel::Debug)
 
 int VideoEngine::sId = 0;
 #if defined(ANDROID)
-int VideoEngine::SetAndroidObjects(JavaVM* javaVM) {
+int VideoEngine::SetAndroidObjects() {
   LOG((__PRETTY_FUNCTION__));
 
-  if (webrtc::SetCaptureAndroidVM(javaVM) != 0) {
+  JavaVM* const javaVM = mozilla::jni::GetVM();
+  if (!javaVM || webrtc::SetCaptureAndroidVM(javaVM) != 0) {
     LOG(("Could not set capture Android VM"));
     return -1;
   }
 #ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
   if (webrtc::SetRenderAndroidVM(javaVM) != 0) {
     LOG(("Could not set render Android VM"));
     return -1;
   }
@@ -141,16 +145,22 @@ VideoEngine::GetOrCreateVideoCaptureDevi
    LOG(("Fetched current time of: %" PRId64, currentTime));
   }
   mExpiryTimeInMs = currentTime + kCacheExpiryPeriodMs;
   LOG(("new device cache expiration is %" PRId64, mExpiryTimeInMs));
   LOG(("creating a new VideoCaptureDeviceInfo of type %s", capDevTypeName));
 
   switch (mCaptureDevInfo.type) {
     case webrtc::CaptureDeviceType::Camera: {
+#ifdef MOZ_WIDGET_ANDROID
+      if (SetAndroidObjects()) {
+        LOG(("VideoEngine::SetAndroidObjects Failed"));
+        break;
+      }
+#endif
       mDeviceInfo.reset(webrtc::VideoCaptureFactory::CreateDeviceInfo());
       LOG(("webrtc::CaptureDeviceType::Camera: Finished creating new device."));
       break;
     }
     case webrtc::CaptureDeviceType::Browser: {
       mDeviceInfo.reset(webrtc::BrowserDeviceInfoImpl::CreateDeviceInfo());
       LOG(("webrtc::CaptureDeviceType::Browser: Finished creating new device."));
       break;
--- a/dom/media/systemservices/VideoEngine.h
+++ b/dom/media/systemservices/VideoEngine.h
@@ -32,17 +32,17 @@ private:
   static const int64_t kCacheExpiryPeriodMs = 2000;
 
 public:
   VideoEngine (){};
   NS_INLINE_DECL_REFCOUNTING(VideoEngine)
 
   static already_AddRefed<VideoEngine> Create(UniquePtr<const webrtc::Config>&& aConfig);
 #if defined(ANDROID)
-  static int SetAndroidObjects(JavaVM* javaVM);
+  static int SetAndroidObjects();
 #endif
   void CreateVideoCapture(int32_t& id, const char* deviceUniqueIdUTF8);
 
   int ReleaseVideoCapture(const int32_t id);
 
   // VideoEngine is responsible for any cleanup in its modules
   static void Delete(VideoEngine * engine) { }
 
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -14,21 +14,16 @@
 #include "MediaTrackConstraints.h"
 #include "mozilla/Logging.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsITabSource.h"
 #include "prenv.h"
 
-#ifdef MOZ_WIDGET_ANDROID
-#include "AndroidBridge.h"
-#include "VideoEngine.h"
-#endif
-
 static mozilla::LazyLogModule sGetUserMediaLog("GetUserMedia");
 #undef LOG
 #define LOG(args) MOZ_LOG(sGetUserMediaLog, mozilla::LogLevel::Debug, args)
 
 namespace mozilla {
 
 // statics from AudioInputCubeb
 nsTArray<int>* AudioInputCubeb::mDeviceIndexes;
@@ -131,27 +126,16 @@ void
 MediaEngineWebRTC::EnumerateVideoDevices(uint64_t aWindowId,
                                          dom::MediaSourceEnum aMediaSource,
                                          nsTArray<RefPtr<MediaEngineSource> >* aSources)
 {
   mMutex.AssertCurrentThreadOwns();
 
   mozilla::camera::CaptureEngine capEngine = mozilla::camera::InvalidEngine;
 
-#ifdef MOZ_WIDGET_ANDROID
-  // get the JVM
-  JavaVM* jvm;
-  JNIEnv* const env = jni::GetEnvForThread();
-  MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm));
-
-  if (!jvm || mozilla::camera::VideoEngine::SetAndroidObjects(jvm)) {
-    LOG(("VideoEngine::SetAndroidObjects Failed"));
-    return;
-  }
-#endif
   bool scaryKind = false; // flag sources with cross-origin exploit potential
 
   switch (aMediaSource) {
     case dom::MediaSourceEnum::Window:
       capEngine = mozilla::camera::WinEngine;
       break;
     case dom::MediaSourceEnum::Application:
       capEngine = mozilla::camera::AppEngine;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -1184,19 +1184,17 @@ WebrtcVideoConduit::InitMain()
       }
       Unused << NS_WARN_IF(NS_FAILED(branch->GetBoolPref(
         "media.peerconnection.video.denoising", &mDenoising)));
       Unused << NS_WARN_IF(NS_FAILED(branch->GetBoolPref(
         "media.peerconnection.video.lock_scaling", &mLockScaling)));
     }
   }
 #ifdef MOZ_WIDGET_ANDROID
-  JavaVM* jvm = mozilla::jni::GetVM();
-
-  if (mozilla::camera::VideoEngine::SetAndroidObjects(jvm) != 0) {
+  if (mozilla::camera::VideoEngine::SetAndroidObjects() != 0) {
     CSFLogError(LOGTAG,  "%s: could not set Android objects", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 #endif  //MOZ_WIDGET_ANDROID
   return kMediaConduitNoError;
 }
 
 /**