blob: 64e5553617c4059c96e9f1688d5e4323ad56adfb [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 "android/utils/params_utils.h"
#include "android/base/string/string_utils.h"
#include "android/utils/so_utils.h"
#include "base/android/jni_type.h"
#include "base/android/log_utils.h"
#include "core/config/core_environment.h"
namespace WeexCore {
WeexByteArray* genWeexByteArray(const char* str, size_t strLen) {
auto* ret = (WeexByteArray*)malloc(strLen + sizeof(WeexByteArray));
if (ret == nullptr) return nullptr;
memset(ret, 0, strLen + sizeof(WeexByteArray));
ret->length = strLen;
memcpy(ret->content, str, strLen);
ret->content[strLen] = '\0';
return ret;
}
INIT_FRAMEWORK_PARAMS* genInitFrameworkParams(const char* type,
const char* value) {
auto* init_framework_params =
(INIT_FRAMEWORK_PARAMS*)malloc(sizeof(INIT_FRAMEWORK_PARAMS));
if (init_framework_params == nullptr) return nullptr;
memset(init_framework_params, 0, sizeof(INIT_FRAMEWORK_PARAMS));
init_framework_params->type = genWeexByteArray(type, strlen(type));
init_framework_params->value = genWeexByteArray(value, strlen(value));
return init_framework_params;
}
WeexString* genWeexString(const uint16_t* str, size_t length) {
size_t byteSize = length * sizeof(uint16_t);
auto* string = (WeexString*)malloc(byteSize + sizeof(WeexString));
if (string == nullptr) return nullptr;
memset(string, 0, byteSize + sizeof(WeexString));
string->length = length;
memcpy(string->content, str, byteSize);
return string;
}
WeexString* jstring2WeexString(JNIEnv* env, jstring fromJString) {
if (fromJString != nullptr) {
ScopedJString scopedString(env, fromJString);
return genWeexString(scopedString.getChars(),
scopedString.getCharsLength());
} else {
uint16_t tmp = 0;
return genWeexString(&tmp, 0);
}
}
VALUE_WITH_TYPE* getValueWithTypePtr() {
auto* param = (VALUE_WITH_TYPE*)malloc(sizeof(VALUE_WITH_TYPE));
if (param == nullptr) return nullptr;
memset(param, 0, sizeof(VALUE_WITH_TYPE));
return param;
}
void addParamsToIPCSerializer(IPCSerializer *serializer, VALUE_WITH_TYPE* param) {
if (param == nullptr) {
serializer->addJSUndefined();
} else if (param->type == ParamsType::DOUBLE) {
serializer->add(param->value.doubleValue);
} else if (param->type == ParamsType::STRING) {
if(param->value.string == nullptr) {
uint16_t tmp = 0;
serializer->add(&tmp, 0);
} else {
serializer->add(param->value.string->content,
param->value.string->length);
}
} else if(param->type == ParamsType::JSONSTRING) {
if(param->value.string == nullptr) {
uint16_t tmp = 0;
serializer->addJSON(&tmp, 0);
} else {
serializer->addJSON(param->value.string->content,
param->value.string->length);
}
}else if (param->type == ParamsType::BYTEARRAY) {
if (param->value.byteArray == nullptr) {
char tmp = '\0';
serializer->add(&tmp, 0);
} else {
serializer->add(param->value.byteArray->content,
param->value.byteArray->length);
}
} else {
serializer->addJSUndefined();
}
};
bool g_is_single_process = false;
bool isSingleProcess() { return g_is_single_process; }
std::vector<INIT_FRAMEWORK_PARAMS*> initFromParam(
JNIEnv* env, jobject params,
const std::function<void(const char*, const char*)>&
ReportNativeInitStatus) {
LOGE("initFromParam is running ");
std::vector<INIT_FRAMEWORK_PARAMS*> initFrameworkParams;
#define ADDSTRING(name) \
{ \
if (name == nullptr) { \
initFrameworkParams.clear(); \
} else { \
const char* myname = #name; \
ScopedJStringUTF8 scopedString(env, (jstring)name); \
const char* chars = scopedString.getChars(); \
initFrameworkParams.push_back(genInitFrameworkParams(myname, chars)); \
} \
}
jclass c_params = env->GetObjectClass(params);
if (c_params == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get c_params failed");
return initFrameworkParams;
}
jmethodID m_platform =
env->GetMethodID(c_params, "getPlatform", "()Ljava/lang/String;");
if (m_platform == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_platform failed");
return initFrameworkParams;
}
jobject platform = env->CallObjectMethod(params, m_platform);
if (platform == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get platform failed");
return initFrameworkParams;
}
if (!WXCoreEnvironment::getInstance()->SetPlatform(
jString2StrFast(env, reinterpret_cast<jstring&>(platform)))) {
LOGD("setPlatform");
}
ADDSTRING(platform);
env->DeleteLocalRef(platform);
jmethodID m_layoutDirection =
env->GetMethodID(c_params, "getLayoutDirection", "()Ljava/lang/String;");
if (m_layoutDirection == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_layoutDirection failed");
return initFrameworkParams;
}
jobject layoutDirection = env->CallObjectMethod(params, m_layoutDirection);
if (layoutDirection == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get layoutDirection failed");
return initFrameworkParams;
}
ADDSTRING(layoutDirection);
env->DeleteLocalRef(layoutDirection);
jmethodID m_use_single_process =
env->GetMethodID(c_params, "getUseSingleProcess", "()Ljava/lang/String;");
if (m_use_single_process == nullptr) {
LOGE("getUseSingleProcess method is missing");
} else {
jobject j_use_single_process =
env->CallObjectMethod(params, m_use_single_process);
const char* use_single_process =
env->GetStringUTFChars((jstring)(j_use_single_process), nullptr);
LOGE("g_use_single_process is %s ", use_single_process);
if (use_single_process == nullptr) {
g_is_single_process = false;
} else {
g_is_single_process = strstr(use_single_process, "true") != nullptr;
env->DeleteLocalRef(j_use_single_process);
}
}
jmethodID m_get_jsc_so_path =
env->GetMethodID(c_params, "getLibJscPath", "()Ljava/lang/String;");
if (m_get_jsc_so_path != nullptr) {
jobject j_get_jsc_so_path =
env->CallObjectMethod(params, m_get_jsc_so_path);
if (j_get_jsc_so_path != nullptr) {
SoUtils::set_jsc_so_path(const_cast<char*>(
env->GetStringUTFChars((jstring)(j_get_jsc_so_path), nullptr)));
LOGE("g_jscSoPath is %s ", SoUtils::jsc_so_path());
env->DeleteLocalRef(j_get_jsc_so_path);
}
}
jmethodID m_get_jss_so_path =
env->GetMethodID(c_params, "getLibJssPath", "()Ljava/lang/String;");
if (m_get_jss_so_path != nullptr) {
jobject j_get_jss_so_path =
env->CallObjectMethod(params, m_get_jss_so_path);
if (j_get_jss_so_path != nullptr) {
SoUtils::set_jss_so_path(const_cast<char*>(
env->GetStringUTFChars((jstring)(j_get_jss_so_path), nullptr)));
LOGE("g_jssSoPath is %s ", SoUtils::jss_so_path());
env->DeleteLocalRef(j_get_jss_so_path);
}
}
jmethodID m_get_crash_file_path = env->GetMethodID(c_params, "getCrashFilePath", "()Ljava/lang/String;");
if (m_get_jss_so_path != nullptr) {
jobject j_get_crash_file_path = env->CallObjectMethod(params, m_get_crash_file_path);
if (j_get_crash_file_path != nullptr) {
SoUtils::set_crash_file_path(const_cast<char *>(env->GetStringUTFChars(
(jstring) (j_get_crash_file_path),
nullptr)));
LOGE("g_crashFilePath is %s ", SoUtils::crash_file_path());
env->DeleteLocalRef(j_get_crash_file_path);
}
}
jmethodID m_get_jss_icu_path =
env->GetMethodID(c_params, "getLibIcuPath", "()Ljava/lang/String;");
if (m_get_jss_icu_path != nullptr) {
jobject j_get_jss_icu_path =
env->CallObjectMethod(params, m_get_jss_icu_path);
if (j_get_jss_icu_path != nullptr) {
SoUtils::set_jss_icu_path(const_cast<char*>(
env->GetStringUTFChars((jstring)(j_get_jss_icu_path), nullptr)));
LOGE("g_jssIcuPath is %s ", SoUtils::jss_icu_path());
env->DeleteLocalRef(j_get_jss_icu_path);
}
}
jmethodID m_get_lib_ld_path =
env->GetMethodID(c_params, "getLibLdPath", "()Ljava/lang/String;");
if (m_get_lib_ld_path != nullptr) {
jobject j_get_lib_ld_path =
env->CallObjectMethod(params, m_get_lib_ld_path);
if (j_get_lib_ld_path != nullptr) {
SoUtils::set_lib_ld_path(const_cast<char*>(
env->GetStringUTFChars((jstring)(j_get_lib_ld_path), nullptr)));
LOGE("lib_ld_path is %s ", SoUtils::lib_ld_path());
env->DeleteLocalRef(j_get_lib_ld_path);
}
}
jmethodID m_osVersion =
env->GetMethodID(c_params, "getOsVersion", "()Ljava/lang/String;");
if (m_osVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_osVersion failed");
return initFrameworkParams;
}
jobject osVersion = env->CallObjectMethod(params, m_osVersion);
if (osVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get osVersion failed");
return initFrameworkParams;
}
ADDSTRING(osVersion);
env->DeleteLocalRef(osVersion);
jmethodID m_cacheMethod =
env->GetMethodID(c_params, "getCacheDir", "()Ljava/lang/String;");
if (m_cacheMethod != nullptr) {
jobject cacheDir = env->CallObjectMethod(params, m_cacheMethod);
if (cacheDir != nullptr) {
ADDSTRING(cacheDir);
env->DeleteLocalRef(cacheDir);
}
}
jmethodID m_appVersion =
env->GetMethodID(c_params, "getAppVersion", "()Ljava/lang/String;");
if (m_appVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_appVersion failed");
return initFrameworkParams;
}
jobject appVersion = env->CallObjectMethod(params, m_appVersion);
if (appVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get appVersion failed");
return initFrameworkParams;
}
ADDSTRING(appVersion);
env->DeleteLocalRef(appVersion);
jmethodID m_weexVersion =
env->GetMethodID(c_params, "getWeexVersion", "()Ljava/lang/String;");
if (m_weexVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_weexVersion failed");
return initFrameworkParams;
}
jobject weexVersion = env->CallObjectMethod(params, m_weexVersion);
if (weexVersion == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get weexVersion failed");
return initFrameworkParams;
}
ADDSTRING(weexVersion);
env->DeleteLocalRef(weexVersion);
jmethodID m_deviceModel =
env->GetMethodID(c_params, "getDeviceModel", "()Ljava/lang/String;");
if (m_deviceModel == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_deviceModel failed");
return initFrameworkParams;
}
jobject deviceModel = env->CallObjectMethod(params, m_deviceModel);
if (deviceModel == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get deviceModel failed");
return initFrameworkParams;
}
ADDSTRING(deviceModel);
env->DeleteLocalRef(deviceModel);
jmethodID m_appName =
env->GetMethodID(c_params, "getAppName", "()Ljava/lang/String;");
if (m_appName == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_appName failed");
return initFrameworkParams;
}
jobject appName = env->CallObjectMethod(params, m_appName);
if (appName == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get appName failed");
return initFrameworkParams;
}
ADDSTRING(appName);
env->DeleteLocalRef(appName);
jmethodID m_deviceWidth =
env->GetMethodID(c_params, "getDeviceWidth", "()Ljava/lang/String;");
if (m_deviceWidth == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_deviceWidth failed");
return initFrameworkParams;
}
jobject deviceWidth = env->CallObjectMethod(params, m_deviceWidth);
if (deviceWidth == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get deviceWidth failed");
return initFrameworkParams;
}
if (!WXCoreEnvironment::getInstance()->SetDeviceWidth(
jString2StrFast(env, reinterpret_cast<jstring&>(deviceWidth)))) {
LOGD("setDeviceWidth");
}
ADDSTRING(deviceWidth);
env->DeleteLocalRef(deviceWidth);
jmethodID m_deviceHeight =
env->GetMethodID(c_params, "getDeviceHeight", "()Ljava/lang/String;");
if (m_deviceHeight == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_deviceHeight failed");
return initFrameworkParams;
}
jobject deviceHeight = env->CallObjectMethod(params, m_deviceHeight);
if (deviceHeight == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get deviceHeight failed");
return initFrameworkParams;
}
if (!WXCoreEnvironment::getInstance()->SetDeviceHeight(
jString2StrFast(env, reinterpret_cast<jstring&>(deviceHeight)))) {
LOGD("setDeviceHeight");
}
ADDSTRING(deviceHeight);
env->DeleteLocalRef(deviceHeight);
jmethodID m_options =
env->GetMethodID(c_params, "getOptions", "()Ljava/lang/Object;");
if (m_options == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get m_options failed");
return initFrameworkParams;
}
jobject options = env->CallObjectMethod(params, m_options);
if (options == nullptr) {
ADDSTRING(nullptr);
ReportNativeInitStatus("-1012", "get options failed");
return initFrameworkParams;
}
jclass jmapclass = env->FindClass("java/util/Map");
jmethodID jkeysetmid =
env->GetMethodID(jmapclass, "keySet", "()Ljava/util/Set;");
jmethodID jgetmid = env->GetMethodID(
jmapclass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
jobject jsetkey = env->CallObjectMethod(options, jkeysetmid);
jclass jsetclass = env->FindClass("java/util/Set");
jmethodID jtoArraymid =
env->GetMethodID(jsetclass, "toArray", "()[Ljava/lang/Object;");
jobjectArray jobjArray =
(jobjectArray)env->CallObjectMethod(jsetkey, jtoArraymid);
env->DeleteLocalRef(jsetkey);
if (jobjArray != NULL) {
jsize arraysize = env->GetArrayLength(jobjArray);
for (int i = 0; i < arraysize; i++) {
jstring jkey = (jstring)env->GetObjectArrayElement(jobjArray, i);
jstring jvalue = (jstring)env->CallObjectMethod(options, jgetmid, jkey);
if (jkey != NULL) {
ScopedJStringUTF8 c_key(env, jkey);
ScopedJStringUTF8 c_value(env, jvalue);
const char* c_key_chars = c_key.getChars();
int c_key_len = strlen(c_key_chars);
const char* c_value_chars = c_value.getChars();
int c_value_len = strlen(c_value_chars);
initFrameworkParams.push_back(
genInitFrameworkParams(c_key_chars, c_value_chars));
const std::string& key = jString2Str(env, jkey);
if (key != "") {
WXCoreEnvironment::getInstance()->AddOption(key,
jString2Str(env, jvalue));
}
}
}
env->DeleteLocalRef(jobjArray);
}
env->DeleteLocalRef(options);
return initFrameworkParams;
}
jstring getJsonData(JNIEnv* env, jobjectArray jargs, int index) {
int length = 0;
if (jargs != NULL) {
length = env->GetArrayLength(jargs);
}
jstring ret = NULL;
if (length < (index + 1)) {
return ret;
}
auto jArg = std::unique_ptr<WXJSObject>(
new WXJSObject(env, base::android::ScopedLocalJavaRef<jobject>(
env, env->GetObjectArrayElement(jargs, index))
.Get()));
jint jTypeInt = jArg->GetType(env);
auto jDataObj = jArg->GetData(env);
if (jTypeInt == 3) {
ret = (jstring)jDataObj.Release();
}
return ret;
}
void addParamsFromJArgs(std::vector<VALUE_WITH_TYPE*>& params,
VALUE_WITH_TYPE* param, JNIEnv* env,
std::unique_ptr<WXJSObject>& wx_js_object) {
jint jTypeInt = wx_js_object->GetType(env);
auto jDataObj = wx_js_object->GetData(env);
if (jTypeInt == 1) {
jdouble jDoubleObj =
base::android::JNIType::DoubleValue(env, jDataObj.Get());
param->type = ParamsType::DOUBLE;
param->value.doubleValue = jDoubleObj;
} else if (jTypeInt == 2) {
jstring jDataStr = (jstring)jDataObj.Get();
param->type = ParamsType::STRING;
param->value.string = jstring2WeexString(env, jDataStr);
} else if (jTypeInt == 3) {
jstring jDataStr = (jstring)jDataObj.Get();
param->type = ParamsType::JSONSTRING;
param->value.string = jstring2WeexString(env, jDataStr);
} else if (jTypeInt == 4) {
jbyteArray dataArray = (jbyteArray)jDataObj.Get();
param->type = ParamsType::BYTEARRAY;
jbyte* data = env->GetByteArrayElements(dataArray, 0);
size_t length = env->GetArrayLength(dataArray);
param->value.byteArray = genWeexByteArray((const char*)data, length);
env->ReleaseByteArrayElements(dataArray, data, 0);
} else {
param->type = ParamsType::JSUNDEFINED;
}
if (param != nullptr) {
params.push_back(param);
}
}
void freeValueWithType(VALUE_WITH_TYPE* param) {
if (param->type == ParamsType::STRING ||
param->type == ParamsType::JSONSTRING) {
free(param->value.string);
}
if (param->type == ParamsType::BYTEARRAY) {
free(param->value.byteArray);
}
}
void freeParams(std::vector<VALUE_WITH_TYPE*>& params) {
for (auto& param : params) {
freeValueWithType(param);
free(param);
}
}
void freeParams(std::vector<InitFrameworkParams*>& params) {
for (auto& param : params) {
if (param->type != nullptr) {
free(param->type);
}
if (param->value != nullptr) {
free(param->value);
}
free(param);
}
}
} // namespace WeexCore