Skip to content

Commit

Permalink
Migrate JNI functions in StarboardBridge
Browse files Browse the repository at this point in the history
b/389117681
  • Loading branch information
haozheng-cobalt committed Jan 15, 2025
1 parent 1637768 commit ff52b2e
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,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
@CalledByNative
public void requestSuspend() {
Activity activity = activityHolder.get();
if (activity != null) {
Expand All @@ -278,20 +276,17 @@ public boolean onSearchRequested() {

// private native boolean nativeOnSearchRequested();

// TODO: (cobalt b/372559388) remove or migrate JNI?
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
public Context getApplicationContext() {
if (appContext == null) {
throw new IllegalArgumentException("appContext cannot be null");
}
return appContext;
}

// TODO: (cobalt b/372559388) remove or migrate JNI?
// Used in starboard/android/shared/system_platform_error.cc
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
void raisePlatformError(@PlatformError.ErrorType int errorType, long data) {
PlatformError error = new PlatformError(activityHolder, errorType, data);
error.raise();
Expand Down Expand Up @@ -344,26 +339,22 @@ 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.
*/
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
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.
*/
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
protected String getCacheAbsolutePath() {
return appContext.getCacheDir().getAbsolutePath();
}
Expand Down Expand Up @@ -587,7 +578,7 @@ public void deactivateMediaSession() {
// Used in starboard/android/shared/system_get_property.cc
/** Returns string for kSbSystemPropertyUserAgentAuxField */
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
protected String getUserAgentAuxField() {
StringBuilder sb = new StringBuilder();

Expand Down
63 changes: 26 additions & 37 deletions starboard/android/shared/file_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
#include <jni.h>
#include <string>

#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/jni_utils.h"
// #include "starboard/android/shared/jni_env_ext.h"
// #include "starboard/android/shared/jni_utils.h"
#include "starboard/android/shared/starboard_bridge.h"
#include "starboard/common/log.h"
#include "starboard/common/string.h"

Expand All @@ -35,60 +36,48 @@ const char* g_app_cache_dir = NULL;
const char* g_app_lib_dir = NULL;

namespace {
jobject g_java_asset_manager;
ScopedJavaGlobalRef<jobject> g_java_asset_manager;
AAssetManager* g_asset_manager;

// Copies the characters from a jstring and returns a newly allocated buffer
// with the result.
const char* DuplicateJavaString(JniEnvExt* env, jstring j_string) {
SB_DCHECK(j_string);
std::string utf_str = env->GetStringStandardUTFOrAbort(j_string);
const char* result = strdup(utf_str.c_str());
return result;
}

} // namespace

void SbFileAndroidInitialize() {
JniEnvExt* env = JniEnvExt::Get();
JNIEnv* env = base::android::AttachCurrentThread();
StarboardBridge* starbooard_bridge = StarboardBridge::GetInstance();

SB_DCHECK(g_java_asset_manager == NULL);
SB_DCHECK(g_java_asset_manager.is_null());
SB_DCHECK(g_asset_manager == NULL);
ScopedLocalJavaRef<jstring> j_app(env->CallStarboardObjectMethodOrAbort(
"getApplicationContext", "()Landroid/content/Context;"));
g_java_asset_manager =
env->ConvertLocalRefToGlobalRef(env->CallObjectMethodOrAbort(
j_app.Get(), "getAssets", "()Landroid/content/res/AssetManager;"));
g_asset_manager = AAssetManager_fromJava(env, g_java_asset_manager);

ScopedJavaLocalRef<jobject> context =
starbooard_bridge->GetApplicationContext(env);

g_java_asset_manager = starbooard_bridge->GetAssetsFromContext(env, context);

g_asset_manager = AAssetManager_fromJava(env, g_java_asset_manager.obj());

std::string app_files_dir = starbooard_bridge->GetFilesAbsolutePath(env);
SB_DCHECK(g_app_files_dir == NULL);
ScopedLocalJavaRef<jstring> j_string(env->CallStarboardObjectMethodOrAbort(
"getFilesAbsolutePath", "()Ljava/lang/String;"));
g_app_files_dir = DuplicateJavaString(env, j_string.Get());
g_app_files_dir = new char[app_files_dir.size() + 1];
std::strcpy(const_cast<char*>(g_app_files_dir), app_files_dir.c_str());

SB_DLOG(INFO) << "Files dir: " << g_app_files_dir;

std::string app_cache_dir = starbooard_bridge->GetCacheAbsolutePath(env);
SB_DCHECK(g_app_cache_dir == NULL);
j_string.Reset(env->CallStarboardObjectMethodOrAbort("getCacheAbsolutePath",
"()Ljava/lang/String;"));
g_app_cache_dir = DuplicateJavaString(env, j_string.Get());
g_app_cache_dir = new char[app_cache_dir.size() + 1];
std::strcpy(const_cast<char*>(g_app_cache_dir), app_cache_dir.c_str());
SB_DLOG(INFO) << "Cache dir: " << g_app_cache_dir;

std::string app_lib_dir =
starbooard_bridge->GetNativeLibraryDir(env, context);
SB_DCHECK(g_app_lib_dir == NULL);
ScopedLocalJavaRef<jobject> j_app_info(
env->CallObjectMethodOrAbort(j_app.Get(), "getApplicationInfo",
"()Landroid/content/pm/ApplicationInfo;"));
j_string.Reset(
env->GetStringFieldOrAbort(j_app_info.Get(), "nativeLibraryDir"));
g_app_lib_dir = DuplicateJavaString(env, j_string.Get());
g_app_lib_dir = new char[app_lib_dir.size() + 1];
std::strcpy(const_cast<char*>(g_app_lib_dir), app_lib_dir.c_str());
SB_DLOG(INFO) << "Lib dir: " << g_app_lib_dir;
}

void SbFileAndroidTeardown() {
JniEnvExt* env = JniEnvExt::Get();

if (g_java_asset_manager) {
env->DeleteGlobalRef(g_java_asset_manager);
g_java_asset_manager = NULL;
g_java_asset_manager.Reset();
g_asset_manager = NULL;
}

Expand Down
99 changes: 89 additions & 10 deletions starboard/android/shared/starboard_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ namespace starboard {
namespace android {
namespace shared {

// TODO: (cobalt b/372559388) Update namespace to jni_zero.
using base::android::AppendJavaStringArrayToStringVector;
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF8;
using base::android::GetClass;

namespace {
#if SB_IS(EVERGREEN_COMPATIBLE)
void StarboardThreadLaunch() {
Expand Down Expand Up @@ -64,7 +70,7 @@ std::vector<std::string> GetArgs() {
// Fake program name as args[0]
args.push_back("android_main");

JNIEnv* env = base::android::AttachCurrentThread();
JNIEnv* env = AttachCurrentThread();
StarboardBridge::GetInstance()->AppendArgs(env, &args);

return args;
Expand All @@ -87,10 +93,10 @@ JNI_StarboardBridge_StartNativeStarboard(JNIEnv* env) {
#else
auto command_line = std::make_unique<CommandLine>(GetArgs());
LogInit(*command_line);
auto* nativeApp = new ApplicationAndroid(std::move(command_line));
auto* native_app = new ApplicationAndroid(std::move(command_line));
// Ensure application init happens here
ApplicationAndroid::Get();
return reinterpret_cast<jlong>(nativeApp);
return reinterpret_cast<jlong>(native_app);
#endif // SB_IS(EVERGREEN_COMPATIBLE)
}

Expand Down Expand Up @@ -130,26 +136,99 @@ void StarboardBridge::AfterStopped(JNIEnv* env) {
void StarboardBridge::AppendArgs(JNIEnv* env,
std::vector<std::string>* args_vector) {
SB_DCHECK(env);
base::android::ScopedJavaLocalRef<jobjectArray> args_java =
ScopedJavaLocalRef<jobjectArray> args_java =
Java_StarboardBridge_getArgs(env, j_starboard_bridge_);
base::android::AppendJavaStringArrayToStringVector(env, args_java,
args_vector);
AppendJavaStringArrayToStringVector(env, args_java, args_vector);
}

std::string StarboardBridge::GetStartDeepLink(JNIEnv* env) {
SB_DCHECK(env);
base::android::ScopedJavaLocalRef<jstring> start_deep_link_java =
ScopedJavaLocalRef<jstring> start_deep_link_java =
Java_StarboardBridge_getStartDeepLink(env, j_starboard_bridge_);
std::string start_deep_link =
base::android::ConvertJavaStringToUTF8(env, start_deep_link_java);
ConvertJavaStringToUTF8(env, start_deep_link_java);
return start_deep_link;
}

base::android::ScopedJavaLocalRef<jintArray>
StarboardBridge::GetSupportedHdrTypes(JNIEnv* env) {
ScopedJavaLocalRef<jintArray> StarboardBridge::GetSupportedHdrTypes(
JNIEnv* env) {
SB_DCHECK(env);
return Java_StarboardBridge_getSupportedHdrTypes(env, j_starboard_bridge_);
}

void StarboardBridge::RaisePlatformError(JNIEnv* env,
jint errorType,
jlong data) {
SB_DCHECK(env);
Java_StarboardBridge_raisePlatformError(env, j_starboard_bridge_, errorType,
data);
}

void StarboardBridge::RequestSuspend(JNIEnv* env) {
SB_DCHECK(env);
Java_StarboardBridge_requestSuspend(env, j_starboard_bridge_);
}

ScopedJavaLocalRef<jobject> StarboardBridge::GetApplicationContext(
JNIEnv* env) {
SB_DCHECK(env);
return Java_StarboardBridge_getApplicationContext(env, j_starboard_bridge_);
}

ScopedJavaGlobalRef<jobject> StarboardBridge::GetAssetsFromContext(
JNIEnv* env,
ScopedJavaLocalRef<jobject>& context) {
SB_DCHECK(env);
ScopedJavaLocalRef<jclass> context_class(
GetClass(env, "android/content/Context"));
jmethodID get_assets_method = env->GetMethodID(
context_class.obj(), "getAssets", "()Landroid/content/res/AssetManager;");
ScopedJavaLocalRef<jobject> assets(
env, env->CallObjectMethod(context.obj(), get_assets_method));
ScopedJavaGlobalRef<jobject> global_assets;
global_assets.Reset(assets);
return global_assets;
}

std::string StarboardBridge::GetNativeLibraryDir(
JNIEnv* env,
ScopedJavaLocalRef<jobject>& context) {
SB_DCHECK(env);
ScopedJavaLocalRef<jclass> context_class(
GetClass(env, "android/content/Context"));
jmethodID get_application_info_method =
env->GetMethodID(context_class.obj(), "getApplicationInfo",
"()Landroid/content/pm/ApplicationInfo;");
ScopedJavaLocalRef<jobject> application_info(
env, env->CallObjectMethod(context.obj(), get_application_info_method));

ScopedJavaLocalRef<jclass> application_info_class(
env, env->GetObjectClass(application_info.obj()));
jfieldID native_library_dir_field = env->GetFieldID(
application_info_class.obj(), "nativeLibraryDir", "Ljava/lang/String;");
ScopedJavaLocalRef<jstring> native_library_dir_java(
env, static_cast<jstring>(env->GetObjectField(application_info.obj(),
native_library_dir_field)));
std::string native_library_dir =
ConvertJavaStringToUTF8(env, native_library_dir_java.obj());
return native_library_dir.c_str();
}

std::string StarboardBridge::GetFilesAbsolutePath(JNIEnv* env) {
SB_DCHECK(env);
ScopedJavaLocalRef<jstring> file_path_java =
Java_StarboardBridge_getFilesAbsolutePath(env, j_starboard_bridge_);
std::string file_path = ConvertJavaStringToUTF8(env, file_path_java);
return file_path;
}

std::string StarboardBridge::GetCacheAbsolutePath(JNIEnv* env) {
SB_DCHECK(env);
ScopedJavaLocalRef<jstring> file_path_java =
Java_StarboardBridge_getCacheAbsolutePath(env, j_starboard_bridge_);
std::string file_path = ConvertJavaStringToUTF8(env, file_path_java);
return file_path;
}
} // namespace shared
} // namespace android
} // namespace starboard
27 changes: 24 additions & 3 deletions starboard/android/shared/starboard_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace starboard {
namespace android {
namespace shared {

// TODO: (cobalt b/372559388) Update namespace to jni_zero.
using base::android::JavaParamRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;

// This class serves as a bridge between the native code and Android
// StarboardBridge Java class.
class StarboardBridge {
Expand All @@ -46,8 +51,24 @@ class StarboardBridge {

std::string GetStartDeepLink(JNIEnv* env);

base::android::ScopedJavaLocalRef<jintArray> GetSupportedHdrTypes(
JNIEnv* env);
ScopedJavaLocalRef<jintArray> GetSupportedHdrTypes(JNIEnv* env);

void RaisePlatformError(JNIEnv* env, jint errorType, jlong data);

void RequestSuspend(JNIEnv* env);

ScopedJavaLocalRef<jobject> GetApplicationContext(JNIEnv* env);

ScopedJavaGlobalRef<jobject> GetAssetsFromContext(
JNIEnv* env,
ScopedJavaLocalRef<jobject>& context);

std::string GetNativeLibraryDir(JNIEnv* env,
ScopedJavaLocalRef<jobject>& context);

std::string GetFilesAbsolutePath(JNIEnv* env);

std::string GetCacheAbsolutePath(JNIEnv* env);

private:
StarboardBridge() = default;
Expand All @@ -60,7 +81,7 @@ class StarboardBridge {
friend struct base::DefaultSingletonTraits<StarboardBridge>;

// Java StarboardBridge instance.
base::android::ScopedJavaGlobalRef<jobject> j_starboard_bridge_;
ScopedJavaGlobalRef<jobject> j_starboard_bridge_;
};

} // namespace shared
Expand Down
11 changes: 5 additions & 6 deletions starboard/android/shared/system_platform_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
#include <functional>

#include "starboard/android/shared/application_android.h"
#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/starboard_bridge.h"

using starboard::android::shared::ApplicationAndroid;
using starboard::android::shared::JniEnvExt;

namespace {

Expand All @@ -50,7 +49,7 @@ bool SbSystemRaisePlatformError(SbSystemPlatformErrorType type,
return false;
}

JniEnvExt* env = JniEnvExt::Get();
JNIEnv* env = base::android::AttachCurrentThread();

auto send_response_callback =
callback ? new SendResponseCallback(
Expand All @@ -60,9 +59,9 @@ bool SbSystemRaisePlatformError(SbSystemPlatformErrorType type,
})
: nullptr;

env->CallStarboardVoidMethodOrAbort(
"raisePlatformError", "(IJ)V", jni_error_type,
reinterpret_cast<jlong>(send_response_callback));
starboard::android::shared::StarboardBridge::GetInstance()
->RaisePlatformError(env, jni_error_type,
reinterpret_cast<jlong>(send_response_callback));
return true;
}

Expand Down
Loading

0 comments on commit ff52b2e

Please sign in to comment.