From 2770c3df91861693ecb2ae805db84c7edbb1fc1a Mon Sep 17 00:00:00 2001 From: George Zhou Date: Wed, 7 Mar 2018 09:58:54 -0800 Subject: [PATCH] Synced webrtc_unity_plugin to the latest webrtc and fixed bugs. 1, Let targets libwebrtc_unity and webrtc_unity_plugin built with Ninja -C out/***. 2, Fixed compile issue of libwebrtc_unity. 3, Built libwebrtc_unity classes into Java 7 instead of Java 8 for android. 4, Added an interface to enable peerconnectionFactory for android in Unity. Bug: webrtc:8986 Change-Id: I2a206a77ab38895ec9ac845ce89507d61076d396 Reviewed-on: https://webrtc-review.googlesource.com/59000 Reviewed-by: Qiang Chen Commit-Queue: George Zhou Cr-Commit-Position: refs/heads/master@{#22373} --- examples/BUILD.gn | 14 ++++++++++--- examples/unityplugin/ANDROID_INSTRUCTION | 20 ++++++++----------- examples/unityplugin/DEPS | 1 + .../java/src/org/webrtc/UnityUtility.java | 5 +++++ .../unityplugin/simple_peer_connection.cc | 10 ++++++---- 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/examples/BUILD.gn b/examples/BUILD.gn index 65fc9379c3..561c245257 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -27,6 +27,7 @@ group("examples") { ":AppRTCMobile", ":AppRTCMobileTest", ":AppRTCMobileTestStubbedVideoIO", + ":libwebrtc_unity", ] } @@ -47,6 +48,10 @@ group("examples") { ":turnserver", ] } + + if (is_android || is_win) { + deps += [ ":webrtc_unity_plugin" ] + } } if (is_android) { @@ -733,7 +738,10 @@ if (is_win || is_android) { "../system_wrappers:runtime_enabled_features_default", ] if (is_android) { - deps += [ "../sdk/android:libjingle_peerconnection_jni" ] + deps += [ + "../modules/utility:utility", + "../sdk/android:libjingle_peerconnection_jni", + ] } } } @@ -750,9 +758,9 @@ if (is_android) { dist_jar("libwebrtc_unity") { _target_dir_name = get_label_info(":$target_name", "dir") output = "${root_out_dir}/lib.java${_target_dir_name}/${target_name}.jar" - direct_deps_only = true + direct_deps_only = false use_interface_jars = false - use_unprocessed_jars = true + use_unprocessed_jars = false requires_android = true deps = [ ":webrtc_unity_java", diff --git a/examples/unityplugin/ANDROID_INSTRUCTION b/examples/unityplugin/ANDROID_INSTRUCTION index 7f69faa834..f0149eb953 100644 --- a/examples/unityplugin/ANDROID_INSTRUCTION +++ b/examples/unityplugin/ANDROID_INSTRUCTION @@ -1,29 +1,25 @@ -Instruction of Running webrtc_unity_plugin on Android Unity +Instruction of running webrtc_unity_plugin on Android Unity 1. On Linux machine, compile target webrtc_unity_plugin. Checkout WebRTC codebase: fetch --no-hooks webrtc_android If you already have a checkout for linux, add target_os=”android” into .gclient file. Run gclient sync - Modify files src/build/android/android_only_jni_exports.lst and src/build/android/android_only_explicit_jni_exports.lst to expose all functions. Namely, change "global" section to "*", and remove "local" section. Otherwise, Unity C# code will not be able to access the functions defined in the plugin. If you do this step after you create a build folder, you may have to clean and recreate the build folder. Run gn args out/Android, and again set target_os=”android” in the args.gn Run ninja -C out/Android webrtc_unity_plugin -2. On Linux machine, compile target libwebrtc_unity under webrtc checkout. This is the java code for webrtc to work on Android. +2. On Linux machine, build target libwebrtc_unity under webrtc checkout. This is the java code for webrtc to work on Android. 3. Copy libwebrtc_unity.jar and libwebrtc_unity_plugin.so into Unity project folder, under Assets/Plugins/Android folder. -4. Rename libwebrtc_unity_plugin.so to libjingle_peerconnection_so.so. Again, this is hacky, and the purpose is to let the java code in libwebrtc.jar to find their JNI implementation. And simultaneously, in your C# wrapper script for the native plugin libjingle_peerconnection_so.so, the dll_path should be set to “jingle_peerconnection_so”. +4. Rename libwebrtc_unity_plugin.so to libjingle_peerconnection_so.so. This is hacky, and the purpose is to let the java code in libwebrtc_unity.jar to find their JNI implementations. Simultaneously, in your C# wrapper script for the native plugin libjingle_peerconnection_so.so, the dll_path should be set to “jingle_peerconnection_so”. 5. In the Unity Main Scene’s Start method, write the following code to initialize the Java environment for webrtc (otherwise, webrtc will not be able to access audio device or camera from C++ code): #if UNITY_ANDROID - AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); - AndroidJavaObject activity = playerClass.GetStatic("currentActivity"); - AndroidJavaClass webrtcClass = new AndroidJavaClass("org.webrtc.PeerConnectionFactory"); - if (webrtcClass != null) - { - webrtcClass.CallStatic("initializeAndroidGlobals", new object[2] { activity, false }); - } + AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + AndroidJavaObject activity = playerClass.GetStatic("currentActivity"); + AndroidJavaClass utilityClass = new AndroidJavaClass("org.webrtc.UnityUtility"); + utilityClass.CallStatic("InitializePeerConncectionFactory", new object[1] { activity }); #endif 6. Compile the unity project into an APK, and decompile the apk using apktool that you can download from https://ibotpeaches.github.io/Apktool/ @@ -32,6 +28,6 @@ Then copy the AndroidManifest.xml in the decompiled folder to the Assets/Plugins - The purpose of using apktool is to get a well-written android manifest xml file. If you know how to write manifest file from scratch, you can skip using apktool. +The purpose of using apktool is to get a well-written android manifest xml file. If you know how to write manifest file from scratch, you can skip using apktool. 7. Compile the unity project into an APK again and deploy it to an android device. diff --git a/examples/unityplugin/DEPS b/examples/unityplugin/DEPS index 608c6ade4b..604005ac73 100644 --- a/examples/unityplugin/DEPS +++ b/examples/unityplugin/DEPS @@ -1,3 +1,4 @@ include_rules = [ + "+modules/utility", "+sdk", ] diff --git a/examples/unityplugin/java/src/org/webrtc/UnityUtility.java b/examples/unityplugin/java/src/org/webrtc/UnityUtility.java index b16d20ad40..d2ca8a5386 100644 --- a/examples/unityplugin/java/src/org/webrtc/UnityUtility.java +++ b/examples/unityplugin/java/src/org/webrtc/UnityUtility.java @@ -61,4 +61,9 @@ public class UnityUtility { camera.stopCapture(); camera.dispose(); } + + public static void InitializePeerConncectionFactory(Context context) throws InterruptedException { + PeerConnectionFactory.initialize( + PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions()); + } } diff --git a/examples/unityplugin/simple_peer_connection.cc b/examples/unityplugin/simple_peer_connection.cc index abe911d7a9..a830f91b37 100644 --- a/examples/unityplugin/simple_peer_connection.cc +++ b/examples/unityplugin/simple_peer_connection.cc @@ -29,6 +29,7 @@ #if defined(WEBRTC_ANDROID) #include "examples/unityplugin/classreferenceholder.h" +#include "modules/utility/include/helpers_android.h" #include "sdk/android/src/jni/androidvideotracksource.h" #include "sdk/android/src/jni/jni_helpers.h" #endif @@ -180,7 +181,7 @@ void SimplePeerConnection::DeletePeerConnection() { JNIEnv* env = webrtc::jni::GetEnv(); jclass pc_factory_class = unity_plugin::FindClass(env, "org/webrtc/UnityUtility"); - jmethodID stop_camera_method = webrtc::jni::GetStaticMethodID( + jmethodID stop_camera_method = webrtc::GetStaticMethodID( env, pc_factory_class, "StopCamera", "(Lorg/webrtc/VideoCapturer;)V"); env->CallStaticVoidMethod(pc_factory_class, stop_camera_method, g_camera); @@ -435,7 +436,7 @@ void SimplePeerConnection::AddStreams(bool audio_only) { JNIEnv* env = webrtc::jni::GetEnv(); jclass pc_factory_class = unity_plugin::FindClass(env, "org/webrtc/UnityUtility"); - jmethodID load_texture_helper_method = webrtc::jni::GetStaticMethodID( + jmethodID load_texture_helper_method = webrtc::GetStaticMethodID( env, pc_factory_class, "LoadSurfaceTextureHelper", "()Lorg/webrtc/SurfaceTextureHelper;"); jobject texture_helper = env->CallStaticObjectMethod( @@ -446,13 +447,14 @@ void SimplePeerConnection::AddStreams(bool audio_only) { rtc::scoped_refptr source( new rtc::RefCountedObject( - g_signaling_thread.get(), env, texture_helper, false)); + g_signaling_thread.get(), env, + webrtc::JavaParamRef(texture_helper), false)); rtc::scoped_refptr proxy_source = webrtc::VideoTrackSourceProxy::Create(g_signaling_thread.get(), g_worker_thread.get(), source); // link with VideoCapturer (Camera); - jmethodID link_camera_method = webrtc::jni::GetStaticMethodID( + jmethodID link_camera_method = webrtc::GetStaticMethodID( env, pc_factory_class, "LinkCamera", "(JLorg/webrtc/SurfaceTextureHelper;)Lorg/webrtc/VideoCapturer;"); jobject camera_tmp =