From 54f9c572a1f6a41e73dc4a17d54d339104f298d0 Mon Sep 17 00:00:00 2001 From: Hao <131711973+haozheng-cobalt@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:23:52 -0800 Subject: [PATCH] Migrate StarboardBridge JNI functions in android_main.cc (#4632) Remove @UsedByNative annotations for beforeStartOrResume and beforeSuspend, for they are no longer needed in ApplicationAndroid. Reference b/377042903. Remove getLocalInterfaceAddressAndNetmask and isCurrentNetworkWireless, for it's not used in Chrobalt. Remove @UsedByNative annotations for getDisplaySize, for it's never used in native code. Change UA related fields getIsAmatiDevice, getBuildFingerprint, getPlayServicesVersion to @CalledByNative, we are currently not using them in UserAgentPlatformInfo::ToString(), but might need them for cobalt/browser/client_hint_headers.cc in the future. Migrate the rest of JNI calls in starboard/android/shared/android_main.cc to Chromium standard JNI, When testing locally: startDeepLink is set with empty string. GetArgs retrieves url. 01-02 22:06:07.303 13993 13993 I starboard: [dev.cobalt.coat/13993:0103/060607.300538(UTC):INFO:android_main.cc(76)] Test GetArgs: android_main--url=https://www.youtube.com/tv b/372559388 --- .../java/dev/cobalt/coat/StarboardBridge.java | 155 +++++++----------- starboard/android/shared/android_main.cc | 50 ++---- .../android/shared/application_android.cc | 8 +- .../android/shared/application_android.h | 4 +- starboard/android/shared/starboard_bridge.cc | 42 ++++- starboard/android/shared/starboard_bridge.h | 13 +- 6 files changed, 121 insertions(+), 151 deletions(-) diff --git a/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java b/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java index 7a1a9d1cca4..7d7336e095d 100644 --- a/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java +++ b/cobalt/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java @@ -26,11 +26,7 @@ import android.hardware.input.InputManager; import android.media.AudioDeviceInfo; import android.media.AudioManager; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; import android.os.Build; -import android.util.Pair; import android.util.Size; import android.util.SizeF; import android.view.Display; @@ -44,11 +40,7 @@ import dev.cobalt.util.Log; import dev.cobalt.util.UsedByNative; import java.lang.reflect.Method; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; import java.util.Calendar; -import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; import java.util.TimeZone; @@ -200,8 +192,6 @@ protected void onServiceDestroy(Service service) { } } - @SuppressWarnings("unused") - @UsedByNative protected void beforeStartOrResume() { Log.i(TAG, "Prepare to resume"); // Bring our platform services to life before resuming so that they're ready to deal with @@ -215,8 +205,6 @@ protected void beforeStartOrResume() { advertisingId.refresh(); } - @SuppressWarnings("unused") - @UsedByNative protected void beforeSuspend() { try { Log.i(TAG, "Prepare to suspend"); @@ -242,7 +230,7 @@ private void closeAllServices() { // Warning: "Stopped" refers to Starboard "Stopped" event, it's different from Android's "onStop". @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected void afterStopped() { applicationStopped = true; closeAllServices(); @@ -271,6 +259,8 @@ protected void applicationStopping() { applicationStopped = true; } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_request_conceal.cc @SuppressWarnings("unused") @UsedByNative public void requestSuspend() { @@ -291,6 +281,7 @@ public boolean onSearchRequested() { // private native boolean nativeOnSearchRequested(); + // TODO: (cobalt b/372559388) remove or migrate JNI? @SuppressWarnings("unused") @UsedByNative public Context getApplicationContext() { @@ -300,6 +291,8 @@ public Context getApplicationContext() { return appContext; } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_platform_error.cc @SuppressWarnings("unused") @UsedByNative void raisePlatformError(@PlatformError.ErrorType int errorType, long data) { @@ -321,7 +314,7 @@ protected Holder getActivityHolder() { } @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected String[] getArgs() { if (args == null) { throw new IllegalArgumentException("args cannot be null"); @@ -331,7 +324,7 @@ protected String[] getArgs() { /** Returns the URL from the Intent that started the app. */ @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected String getStartDeepLink() { if (startDeepLink == null) { throw new IllegalArgumentException("startDeepLink cannot be null"); @@ -354,6 +347,8 @@ private void nativeHandleDeepLink(String url) { // TODO(b/374147993): Implement deep link } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/file_internal.cc /** * Returns the absolute path to the directory where application specific files should be written. * May be overridden for use cases that need to segregate storage. @@ -364,6 +359,8 @@ protected String getFilesAbsolutePath() { return appContext.getFilesDir().getAbsolutePath(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/file_internal.cc /** * Returns the absolute path to the application specific cache directory on the filesystem. May be * overridden for use cases that need to segregate storage. @@ -374,62 +371,8 @@ protected String getCacheAbsolutePath() { return appContext.getCacheDir().getAbsolutePath(); } - /** - * Returns non-loopback network interface address and its netmask, or null if none. - * - *

A Java function to help implement Starboard's SbSocketGetLocalInterfaceAddress. - */ - @SuppressWarnings("unused") - @UsedByNative - // TODO: (cobalt b/372559388) Migrate complicated returned type functions to JNI zero. - // The @UsedByNative annotation has strict signature parsing rules, - // and Pair is not be supported well. - Pair getLocalInterfaceAddressAndNetmask(boolean wantIPv6) { - try { - Enumeration it = NetworkInterface.getNetworkInterfaces(); - - while (it.hasMoreElements()) { - NetworkInterface ni = it.nextElement(); - if (ni.isLoopback()) { - continue; - } - if (!ni.isUp()) { - continue; - } - if (ni.isPointToPoint()) { - continue; - } - - for (InterfaceAddress ia : ni.getInterfaceAddresses()) { - byte[] address = ia.getAddress().getAddress(); - boolean isIPv6 = (address.length > 4); - if (isIPv6 == wantIPv6) { - // Convert the network prefix length to a network mask. - int prefix = ia.getNetworkPrefixLength(); - byte[] netmask = new byte[address.length]; - for (int i = 0; i < netmask.length; i++) { - if (prefix == 0) { - netmask[i] = 0; - } else if (prefix >= 8) { - netmask[i] = (byte) 0xFF; - prefix -= 8; - } else { - netmask[i] = (byte) (0xFF << (8 - prefix)); - prefix = 0; - } - } - return new Pair<>(address, netmask); - } - } - } - } catch (SocketException ex) { - // TODO should we have a logging story that strips logs for production? - Log.w(TAG, "sbSocketGetLocalInterfaceAddress exception", ex); - return null; - } - return null; - } - + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/speech_synthesis_speak.cc @SuppressWarnings("unused") @UsedByNative CobaltTextToSpeechHelper getTextToSpeechHelper() { @@ -439,6 +382,8 @@ CobaltTextToSpeechHelper getTextToSpeechHelper() { return ttsHelper; } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/accessibility_get_caption_settings.cc /** * @return A new CaptionSettings object with the current system caption settings. */ @@ -450,6 +395,8 @@ CaptionSettings getCaptionSettings() { return new CaptionSettings(cm); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_get_locale_id.cc /** Java-layer implementation of SbSystemGetLocaleId. */ @SuppressWarnings("unused") @UsedByNative @@ -457,6 +404,8 @@ String systemGetLocaleId() { return Locale.getDefault().toLanguageTag(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/time_zone_get_name.cc @SuppressWarnings("unused") @UsedByNative String getTimeZoneId() { @@ -469,18 +418,19 @@ String getTimeZoneId() { return timeZone.getID(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/window_get_diagonal_size_in_inches.cc @SuppressWarnings("unused") @UsedByNative SizeF getDisplayDpi() { return DisplayUtil.getDisplayDpi(); } - @SuppressWarnings("unused") - @UsedByNative Size getDisplaySize() { return DisplayUtil.getSystemDisplaySize(); } + // TODO: (cobalt b/372559388) migrate JNI. @SuppressWarnings("unused") @UsedByNative public ResourceOverlay getResourceOverlay() { @@ -503,6 +453,8 @@ private static String getSystemProperty(String name) { } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/window_get_size.cc @SuppressWarnings("unused") @UsedByNative Size getDeviceResolution() { @@ -527,6 +479,8 @@ Size getDeviceResolution() { } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_network_is_disconnected.cc @SuppressWarnings("unused") @UsedByNative boolean isNetworkConnected() { @@ -536,6 +490,8 @@ boolean isNetworkConnected() { return networkStatus.isConnected(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/microphone_impl.cc /** * Checks if there is no microphone connected to the system. * @@ -565,6 +521,8 @@ public boolean isMicrophoneDisconnected() { return true; } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/microphone_impl.cc /** * Checks if the microphone is muted. * @@ -577,26 +535,8 @@ public boolean isMicrophoneMute() { return audioManager.isMicrophoneMute(); } - /** - * @return true if we have an active network connection and it's on an wireless network. - */ - @SuppressWarnings("unused") - @UsedByNative - boolean isCurrentNetworkWireless() { - ConnectivityManager connMgr = - (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE); - Network activeNetwork = connMgr.getActiveNetwork(); - if (activeNetwork == null) { - return false; - } - NetworkCapabilities activeCapabilities = connMgr.getNetworkCapabilities(activeNetwork); - if (activeCapabilities == null) { - return false; - } - // Consider anything that's not definitely wired to be wireless. - return !activeCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET); - } - + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/accessibility_get_display_settings.cc /** * @return true if the user has enabled accessibility high contrast text in the operating system. */ @@ -615,6 +555,8 @@ boolean isAccessibilityHighContrastTextEnabled() { } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/android_media_session_client.cc @SuppressWarnings("unused") @UsedByNative void updateMediaSession( @@ -634,6 +576,8 @@ void updateMediaSession( // playbackState, actions, positionMs, speed, title, artist, album, artwork, duration); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/android_media_session_client.cc @SuppressWarnings("unused") @UsedByNative public void deactivateMediaSession() { @@ -642,6 +586,8 @@ public void deactivateMediaSession() { // cobaltMediaSession.deactivateMediaSession(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_get_property.cc /** Returns string for kSbSystemPropertyUserAgentAuxField */ @SuppressWarnings("unused") @UsedByNative @@ -670,6 +616,8 @@ protected String getUserAgentAuxField() { return sb.toString(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_get_property.cc /** Returns string for kSbSystemPropertyAdvertisingId */ @SuppressWarnings("unused") @UsedByNative @@ -677,6 +625,8 @@ protected String getAdvertisingId() { return this.advertisingId.getId(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/system_get_property.cc /** Returns boolean for kSbSystemPropertyLimitAdTracking */ @SuppressWarnings("unused") @UsedByNative @@ -684,6 +634,8 @@ protected boolean getLimitAdTracking() { return this.advertisingId.isLimitAdTrackingEnabled(); } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/audio_track_bridge.cc @SuppressWarnings("unused") @UsedByNative AudioOutputManager getAudioOutputManager() { @@ -704,6 +656,8 @@ AudioOutputManager getAudioOutputManager() { // audioPermissionRequester.onRequestPermissionsResult(requestCode, permissions, grantResults); // } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/video_window.cc @SuppressWarnings("unused") @UsedByNative public void resetVideoSurface() { @@ -713,6 +667,8 @@ public void resetVideoSurface() { } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/player_set_bounds.cc @SuppressWarnings("unused") @UsedByNative public void setVideoSurfaceBounds(final int x, final int y, final int width, final int height) { @@ -722,6 +678,8 @@ public void setVideoSurfaceBounds(final int x, final int y, final int width, fin } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/media_capabilities_cache.cc /** Return supported hdr types. */ @SuppressWarnings("unused") @UsedByNative @@ -800,6 +758,7 @@ public byte[] sendToCobaltService(String serviceName, byte [] data) { return response.data; } + // TODO: (cobalt b/372559388) remove or migrate JNI? /** Returns the application start timestamp. */ @SuppressWarnings("unused") @CalledByNative @@ -815,6 +774,8 @@ protected long getAppStartTimestamp() { return 0; } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/graphics.cc @SuppressWarnings("unused") @UsedByNative void reportFullyDrawn() { @@ -824,6 +785,8 @@ void reportFullyDrawn() { } } + // TODO: (cobalt b/372559388) remove or migrate JNI? + // Used in starboard/android/shared/crash_handler.cc @SuppressWarnings("unused") @UsedByNative public void setCrashContext(String key, String value) { @@ -843,19 +806,19 @@ public void registerCrashContextUpdateHandler(CrashContextUpdateHandler handler) } @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected boolean getIsAmatiDevice() { return this.isAmatiDevice; } @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected String getBuildFingerprint() { return Build.FINGERPRINT; } @SuppressWarnings("unused") - @UsedByNative + @CalledByNative protected long getPlayServicesVersion() { try { if (android.os.Build.VERSION.SDK_INT < 28) { diff --git a/starboard/android/shared/android_main.cc b/starboard/android/shared/android_main.cc index 92b6632332e..1a42ab2c65e 100644 --- a/starboard/android/shared/android_main.cc +++ b/starboard/android/shared/android_main.cc @@ -18,11 +18,11 @@ #include #include -// #include "game-activity/GameActivity.h" #include "starboard/android/shared/application_android.h" #include "starboard/android/shared/jni_env_ext.h" #include "starboard/android/shared/jni_utils.h" #include "starboard/android/shared/log_internal.h" +#include "starboard/android/shared/starboard_bridge.h" #include "starboard/common/file.h" #include "starboard/common/semaphore.h" #include "starboard/common/string.h" @@ -36,8 +36,6 @@ #include "starboard/crashpad_wrapper/wrapper.h" // nogncheck #endif -#include "starboard/android/shared/starboard_bridge.h" - namespace starboard { namespace android { namespace shared { @@ -64,40 +62,14 @@ std::atomic_bool g_app_running{false}; std::vector GetArgs() { std::vector args; // Fake program name as args[0] - args.push_back(strdup("android_main")); - - JniEnvExt* env = JniEnvExt::Get(); + args.push_back("android_main"); - ScopedLocalJavaRef args_array( - env->CallStarboardObjectMethodOrAbort("getArgs", - "()[Ljava/lang/String;")); - jint argc = !args_array ? 0 : env->GetArrayLength(args_array.Get()); - - for (jint i = 0; i < argc; i++) { - ScopedLocalJavaRef element( - env->GetObjectArrayElementOrAbort(args_array.Get(), i)); - args.push_back(env->GetStringStandardUTFOrAbort(element.Get())); - } + JNIEnv* env = base::android::AttachCurrentThread(); + StarboardBridge::GetInstance()->AppendArgs(env, &args); return args; } -std::string GetStartDeepLink() { - JniEnvExt* env = JniEnvExt::Get(); - std::string start_url; - - ScopedLocalJavaRef j_url(env->CallStarboardObjectMethodOrAbort( - "getStartDeepLink", "()Ljava/lang/String;")); - if (j_url) { - auto j_url_str = j_url.Get(); - if (env->GetStringLength(j_url_str) != 0) { - start_url = env->GetStringStandardUTFOrAbort(j_url_str); - } - } - SB_LOG(INFO) << "GetStartDeepLink: " << start_url; - return start_url; -} - #if SB_IS(EVERGREEN_COMPATIBLE) bool CopyDirContents(const std::string& src_dir_path, const std::string& dst_dir_path) { @@ -255,9 +227,8 @@ void* ThreadEntryPoint(void* context) { // Inform StarboardBridge that the run loop has exited so it can cleanup and // kill the process. - JniEnvExt* env = JniEnvExt::Get(); - env->CallStarboardVoidMethodOrAbort("afterStopped", "()V"); - + JNIEnv* env = base::android::AttachCurrentThread(); + StarboardBridge::GetInstance()->AfterStopped(env); return NULL; } #endif // SB_IS(EVERGREEN_COMPATIBLE) @@ -303,7 +274,8 @@ extern "C" SB_EXPORT_PLATFORM void Java_dev_cobalt_coat_StarboardBridge_initJNI( JniEnvExt::Initialize(env, starboard_bridge); // Initialize the singleton instance of StarboardBridge - StarboardBridge::GetInstance()->Initialize(env, starboard_bridge); + JNIEnv* jni_env = base::android::AttachCurrentThread(); + StarboardBridge::GetInstance()->Initialize(jni_env, starboard_bridge); } extern "C" SB_EXPORT_PLATFORM jlong @@ -381,8 +353,10 @@ extern "C" int SbRunStarboardMain(int argc, g_app_created_semaphore->Put(); // Enter the Starboard run loop until stopped. - int error_level = - app.Run(std::move(command_line), GetStartDeepLink().c_str()); + JNIEnv* env = base::android::AttachCurrentThread(); + std::string start_url = StarboardBridge::GetInstance()->GetStartDeepLink(env); + SB_LOG(INFO) << "GetStartDeepLink: " << start_url; + int error_level = app.Run(std::move(command_line), start_url.c_str()); // Mark the app not running before informing StarboardBridge that the app is // stopped so that we won't send any more AndroidCommands as a result of diff --git a/starboard/android/shared/application_android.cc b/starboard/android/shared/application_android.cc index 8d5122bc375..1e29cb0a075 100644 --- a/starboard/android/shared/application_android.cc +++ b/starboard/android/shared/application_android.cc @@ -70,13 +70,15 @@ ApplicationAndroid::ApplicationAndroid( ::starboard::shared::starboard::audio_sink::SbAudioSinkImpl::Initialize(); - app_start_timestamp_ = starboard_bridge_->GetAppStartTimestamp(); + JNIEnv* jni_env = base::android::AttachCurrentThread(); + app_start_timestamp_ = starboard_bridge_->GetAppStartTimestamp(jni_env); - starboard_bridge_->ApplicationStarted(); + starboard_bridge_->ApplicationStarted(jni_env); } ApplicationAndroid::~ApplicationAndroid() { - starboard_bridge_->ApplicationStopping(); + JNIEnv* env = base::android::AttachCurrentThread(); + starboard_bridge_->ApplicationStopping(env); // The application is exiting. // Release the global reference. diff --git a/starboard/android/shared/application_android.h b/starboard/android/shared/application_android.h index 0585457bef3..abf11b6734f 100644 --- a/starboard/android/shared/application_android.h +++ b/starboard/android/shared/application_android.h @@ -20,7 +20,7 @@ #include #include -#include "starboard/android/shared/jni_env_ext.h" +#include "starboard/android/shared/starboard_bridge.h" #include "starboard/common/log.h" #include "starboard/common/mutex.h" #include "starboard/shared/internal_only.h" @@ -29,8 +29,6 @@ #include "starboard/shared/starboard/queue_application.h" #include "starboard/types.h" -#include "starboard/android/shared/starboard_bridge.h" - namespace starboard { namespace android { namespace shared { diff --git a/starboard/android/shared/starboard_bridge.cc b/starboard/android/shared/starboard_bridge.cc index 5dcd951b471..60cf0fa2bbe 100644 --- a/starboard/android/shared/starboard_bridge.cc +++ b/starboard/android/shared/starboard_bridge.cc @@ -20,6 +20,8 @@ #include "starboard/shared/starboard/audio_sink/audio_sink_internal.h" // Must come after all headers that specialize FromJniType() / ToJniType(). +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" #include "cobalt/android/jni_headers/StarboardBridge_jni.h" namespace starboard { @@ -36,6 +38,10 @@ JNI_StarboardBridge_CurrentMonotonicTime(JNIEnv* env) { return CurrentMonotonicTime(); } +// StarboardBridge::GetInstance() should not be inlined in the +// header. This makes sure that when source files from multiple targets include +// this header they don't end up with different copies of the inlined code +// creating multiple copies of the singleton. // static StarboardBridge* StarboardBridge::GetInstance() { return base::Singleton::get(); @@ -45,22 +51,42 @@ void StarboardBridge::Initialize(JNIEnv* env, jobject obj) { j_starboard_bridge_.Reset(env, obj); } -long StarboardBridge::GetAppStartTimestamp() { - JNIEnv* env = base::android::AttachCurrentThread(); +long StarboardBridge::GetAppStartTimestamp(JNIEnv* env) { CHECK(env); return Java_StarboardBridge_getAppStartTimestamp(env, j_starboard_bridge_); } -void StarboardBridge::ApplicationStarted() { - JNIEnv* env = base::android::AttachCurrentThread(); +void StarboardBridge::ApplicationStarted(JNIEnv* env) { CHECK(env); - return Java_StarboardBridge_applicationStarted(env, j_starboard_bridge_); + Java_StarboardBridge_applicationStarted(env, j_starboard_bridge_); } -void StarboardBridge::ApplicationStopping() { - JNIEnv* env = base::android::AttachCurrentThread(); +void StarboardBridge::ApplicationStopping(JNIEnv* env) { CHECK(env); - return Java_StarboardBridge_applicationStopping(env, j_starboard_bridge_); + Java_StarboardBridge_applicationStopping(env, j_starboard_bridge_); +} + +void StarboardBridge::AfterStopped(JNIEnv* env) { + CHECK(env); + Java_StarboardBridge_afterStopped(env, j_starboard_bridge_); +} + +void StarboardBridge::AppendArgs(JNIEnv* env, + std::vector* args_vector) { + CHECK(env); + base::android::ScopedJavaLocalRef args_java = + Java_StarboardBridge_getArgs(env, j_starboard_bridge_); + base::android::AppendJavaStringArrayToStringVector(env, args_java, + args_vector); +} + +std::string StarboardBridge::GetStartDeepLink(JNIEnv* env) { + CHECK(env); + base::android::ScopedJavaLocalRef start_deep_link_java = + Java_StarboardBridge_getStartDeepLink(env, j_starboard_bridge_); + std::string start_deep_link = + base::android::ConvertJavaStringToUTF8(env, start_deep_link_java); + return start_deep_link; } } // namespace shared } // namespace android diff --git a/starboard/android/shared/starboard_bridge.h b/starboard/android/shared/starboard_bridge.h index fec41feb88f..798eda8b597 100644 --- a/starboard/android/shared/starboard_bridge.h +++ b/starboard/android/shared/starboard_bridge.h @@ -17,6 +17,7 @@ #include +#include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "base/memory/singleton.h" @@ -33,11 +34,17 @@ class StarboardBridge { void Initialize(JNIEnv* env, jobject obj); - long GetAppStartTimestamp(); + long GetAppStartTimestamp(JNIEnv* env); - void ApplicationStarted(); + void ApplicationStarted(JNIEnv* env); - void ApplicationStopping(); + void ApplicationStopping(JNIEnv* env); + + void AfterStopped(JNIEnv* env); + + void AppendArgs(JNIEnv* env, std::vector* args_vector); + + std::string GetStartDeepLink(JNIEnv* env); private: StarboardBridge() = default;