* 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/environment/environment_jni.h"
#include "adapter/android/capability/java/jni/environment/environment_proxy_impl.h"
#include "adapter/android/entrance/java/jni/jni_environment.h"
#include "base/json/json_util.h"
#include "base/log/log.h"
#include "core/common/environment/environment_proxy.h"
namespace OHOS::Ace::Platform {
namespace {
static const char* const ENVIRONMENT_PLUGIN_CLASS_NAME = "ohos/ace/adapter/capability/environment/EnvironmentBase";
static const JNINativeMethod METHODS[] = {
{ "nativeInit", "()V", reinterpret_cast<void*>(EnvironmentJni::NativeInit) },
};
static const char* const METHOD_GET_ACCESSIBILITY_ENABLED = "getAccessibilityEnabled";
static const char* const SIGNATURE_GET_ACCESSIBILITY_ENABLED = "()Ljava/lang/String;";
JniEnvironment::JavaGlobalRef g_jobject(nullptr, nullptr);
struct {
jmethodID getAccessibilityEnabled;
} g_pluginClass;
}
bool EnvironmentJni::Register(std::shared_ptr<JNIEnv> env)
{
if (!env) {
LOGW("Environment JNI: env not ready");
return false;
}
jclass cls = env->FindClass(ENVIRONMENT_PLUGIN_CLASS_NAME);
if (!cls) {
LOGW("Environment JNI: ENVIRONMENT_PLUGIN_CLASS_NAME is null");
return false;
}
bool ret = env->RegisterNatives(cls, METHODS, sizeof(METHODS) / sizeof(METHODS[0])) == 0;
env->DeleteLocalRef(cls);
if (!ret) {
LOGW("Environment JNI: RegisterNatives failed.");
return false;
}
OnJniRegistered();
return true;
}
void EnvironmentJni::OnJniRegistered()
{
EnvironmentProxy::GetInstance()->SetDelegate(std::make_unique<EnvironmentProxyImpl>());
}
void EnvironmentJni::NativeInit(JNIEnv* env, jobject jobj)
{
if (!env) {
LOGW("Environment JNI: env not ready");
return;
}
g_jobject = JniEnvironment::MakeJavaGlobalRef(JniEnvironment::GetInstance().GetJniEnv(), jobj);
jclass cls = env->GetObjectClass(jobj);
if (cls == nullptr) {
LOGE("Environment JNI: get object class failed");
return;
}
g_pluginClass.getAccessibilityEnabled =
env->GetMethodID(cls, METHOD_GET_ACCESSIBILITY_ENABLED, SIGNATURE_GET_ACCESSIBILITY_ENABLED);
if (!g_pluginClass.getAccessibilityEnabled) {
LOGW("Environment JNI: method not found.");
}
env->DeleteLocalRef(cls);
}
std::string EnvironmentJni::GetAccessibilityEnabled()
{
auto env = JniEnvironment::GetInstance().GetJniEnv();
if (!env) {
LOGW("Environment JNI: env not ready");
return "";
}
if (!g_jobject || !g_pluginClass.getAccessibilityEnabled) {
return "";
}
std::string result;
jstring jResult =
static_cast<jstring>(env->CallObjectMethod(g_jobject.get(), g_pluginClass.getAccessibilityEnabled));
if (env->ExceptionCheck()) {
LOGE("Environment JNI: call GetAccessibilityEnabled has exception");
env->ExceptionDescribe();
env->ExceptionClear();
return result;
}
const char* content = env->GetStringUTFChars(jResult, nullptr);
if (content != nullptr) {
result.assign(content);
env->ReleaseStringUTFChars(jResult, content);
}
if (jResult != nullptr) {
env->DeleteLocalRef(jResult);
}
return result;
}
}