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 14, 2025
1 parent 1637768 commit 1f8126c
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 71 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
82 changes: 49 additions & 33 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,75 @@ 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;
}
// // 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();
SB_DLOG(INFO) << "haoo";
SB_LOG(INFO) << "haooo";

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

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;"));

// ScopedLocalJavaRef<jstring> j_app(env->CallStarboardObjectMethodOrAbort(
// "getApplicationContext", "()Landroid/content/Context;"));
ScopedJavaLocalRef<jobject> j_app =
StarboardBridge::GetInstance()->GetApplicationContext(env);

// g_java_asset_manager =
// env->ConvertLocalRefToGlobalRef(env->CallObjectMethodOrAbort(
// j_app.Get(), "getAssets", "()Landroid/content/res/AssetManager;"));
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);
StarboardBridge::GetInstance()->GetAssetsFromContext(env, j_app);

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

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());
// ScopedLocalJavaRef<jstring> j_string(env->CallStarboardObjectMethodOrAbort(
// "getFilesAbsolutePath", "()Ljava/lang/String;"));
// g_app_files_dir = DuplicateJavaString(env, j_string.Get());
g_app_files_dir = StarboardBridge::GetInstance()->GetFilesAbsolutePath(env);

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

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());
// j_string.Reset(env->CallStarboardObjectMethodOrAbort("getCacheAbsolutePath",
// "()Ljava/lang/String;"));
// g_app_cache_dir = DuplicateJavaString(env, j_string.Get());
g_app_cache_dir = StarboardBridge::GetInstance()->GetCacheAbsolutePath(env);
SB_DLOG(INFO) << "Cache dir: " << g_app_cache_dir;

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());
// 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 =
StarboardBridge::GetInstance()->GetNativeLibraryDir(env, j_app);
SB_DLOG(INFO) << "Lib dir: " << g_app_lib_dir;
}

void SbFileAndroidTeardown() {
JniEnvExt* env = JniEnvExt::Get();
// JniEnvExt* env = JniEnvExt::Get();
JNIEnv* env = base::android::AttachCurrentThread();

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
94 changes: 84 additions & 10 deletions starboard/android/shared/starboard_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ 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;

namespace {
#if SB_IS(EVERGREEN_COMPATIBLE)
void StarboardThreadLaunch() {
Expand Down Expand Up @@ -64,7 +69,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 +92,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 +135,95 @@ 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);
jclass context_class = env->FindClass("android/content/Context");
jmethodID get_assets_method = env->GetMethodID(
context_class, "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;
}

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

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

const char* 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.c_str();
}

const char* 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.c_str();
}
} // 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);

const char* GetNativeLibraryDir(JNIEnv* env,
ScopedJavaLocalRef<jobject>& context);

const char* GetFilesAbsolutePath(JNIEnv* env);

const char* 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
Loading

0 comments on commit 1f8126c

Please sign in to comment.