* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "adapter/android/capability/java/jni/plugin/plugin_manager_jni.h"
#include "adapter/android/entrance/java/jni/jni_environment.h"
#include "base/log/log.h"
#include "base/utils/utils.h"
namespace OHOS::Ace::Platform {
namespace {
const char PLUGIN_MANAGER_PLUGIN_CLASS_NAME[] = "ohos/ace/adapter/capability/plugin/PluginManager";
const JNINativeMethod METHODS[] = {
{ "nativeInit", "()V", reinterpret_cast<void*>(PluginManagerJni::NativeInit) },
{ "nativeRegister", "(JLjava/lang/String;)V", reinterpret_cast<void*>(PluginManagerJni::NativeRegister) },
};
const char METHOD_INIT_PLUGIN[] = "initPlugin";
const char METHOD_REGISTER_PLUGIN[] = "registerPlugin";
const char SIGNATURE_INIT_PLUGIN[] = "(Ljava/lang/String;)V";
const char SIGNATURE_REGISTER_PLUGIN[] = "(JLjava/lang/String;)V";
JniEnvironment::JavaGlobalRef g_jobject(nullptr, nullptr);
struct {
jmethodID initPlugin;
jmethodID registerPlugin;
} g_pluginClass;
}
bool PluginManagerJni::Register(std::shared_ptr<JNIEnv> env)
{
CHECK_NULL_RETURN(env, false);
jclass cls = env->FindClass(PLUGIN_MANAGER_PLUGIN_CLASS_NAME);
CHECK_NULL_RETURN(cls, false);
bool ret = env->RegisterNatives(cls, METHODS, ArraySize(METHODS)) == 0;
env->DeleteLocalRef(cls);
if (!ret) {
LOGW("PluginManager JNI: RegisterNatives failed.");
return false;
}
return true;
}
void PluginManagerJni::NativeInit(JNIEnv* env, jobject jobj)
{
CHECK_NULL_VOID(env);
g_jobject = JniEnvironment::MakeJavaGlobalRef(JniEnvironment::GetInstance().GetJniEnv(), jobj);
jclass cls = env->GetObjectClass(jobj);
CHECK_NULL_VOID(cls);
g_pluginClass.initPlugin = env->GetMethodID(cls, METHOD_INIT_PLUGIN, SIGNATURE_INIT_PLUGIN);
CHECK_NULL_VOID(g_pluginClass.initPlugin);
g_pluginClass.registerPlugin = env->GetMethodID(cls, METHOD_REGISTER_PLUGIN, SIGNATURE_REGISTER_PLUGIN);
CHECK_NULL_VOID(g_pluginClass.registerPlugin);
env->DeleteLocalRef(cls);
}
void PluginManagerJni::NativeRegister(JNIEnv* env, jobject jobj, jlong jPluginRegisterFunc, jstring jPluginPackageName)
{
CHECK_NULL_VOID(env);
bool status = reinterpret_cast<RegisterCallback>(jPluginRegisterFunc)(env);
if (!status) {
LOGW("PluginManager NativeRegister JNI: register failed");
return;
}
const char* pluginPackageNameStr = env->GetStringUTFChars(jPluginPackageName, nullptr);
if (pluginPackageNameStr != nullptr) {
auto pluginPackageName = std::string(pluginPackageNameStr);
InitPlugin(pluginPackageName);
}
env->ReleaseStringUTFChars(jPluginPackageName, pluginPackageNameStr);
}
void PluginManagerJni::RegisterPlugin(RegisterCallback pluginFunc, const std::string& pluginPackageName)
{
auto env = JniEnvironment::GetInstance().GetJniEnv();
CHECK_NULL_VOID(env);
CHECK_NULL_VOID(g_jobject);
CHECK_NULL_VOID(g_pluginClass.registerPlugin);
jlong jPluginFunc = reinterpret_cast<int64_t>(pluginFunc);
jstring jPluginPackageName = env->NewStringUTF(pluginPackageName.c_str());
env->CallVoidMethod(g_jobject.get(), g_pluginClass.registerPlugin, jPluginFunc, jPluginPackageName);
if (env->ExceptionCheck()) {
LOGE("PluginManager JNI: registerPlugin failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
env->DeleteLocalRef(jPluginPackageName);
}
void PluginManagerJni::InitPlugin(const std::string& packageName)
{
auto env = JniEnvironment::GetInstance().GetJniEnv();
CHECK_NULL_VOID(env);
CHECK_NULL_VOID(g_jobject);
CHECK_NULL_VOID(g_pluginClass.initPlugin);
jstring jParams = env->NewStringUTF(packageName.c_str());
env->CallVoidMethod(g_jobject.get(), g_pluginClass.initPlugin, jParams);
if (env->ExceptionCheck()) {
LOGE("PluginManager JNI: initPlugin failed");
env->ExceptionDescribe();
env->ExceptionClear();
}
env->DeleteLocalRef(jParams);
}
}