You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2018/05/10 07:40:20 UTC
[2/3] incubator-weex git commit: [WEEX-349][jsengine] Make weex core
can run on single process mode
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/547da26a/weex_core/Source/android/jsengine/multiprocess/WeexProxy.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/jsengine/multiprocess/WeexProxy.cpp b/weex_core/Source/android/jsengine/multiprocess/WeexProxy.cpp
index 472727f..2d19683 100644
--- a/weex_core/Source/android/jsengine/multiprocess/WeexProxy.cpp
+++ b/weex_core/Source/android/jsengine/multiprocess/WeexProxy.cpp
@@ -23,199 +23,552 @@
#include <android/base/string/string_utils.h>
#include <core/config/core_environment.h>
#include <android/jsengine/multiprocess/ExtendJSApi.h>
+#include <core/api/WeexJSCoreApi.h>
+#include <dlfcn.h>
const char *s_cacheDir;
bool s_start_pie = true;
static IPCSender *sSender;
-static std::unique_ptr <IPCHandler> sHandler;
-static std::unique_ptr <WeexJSConnection> sConnection;
-
+static std::unique_ptr<IPCHandler> sHandler;
+static std::unique_ptr<WeexJSConnection> sConnection;
+static WEEX_CORE_JS_SERVER_API_FUNCTIONS *js_server_api_functions = nullptr;
+bool g_use_single_process = true;
namespace WeexCore {
-void WeexProxy::reset() {
- sConnection.reset();
- sHandler.reset();
-}
-
-jint WeexProxy::doInitFramework(JNIEnv *env, jobject object,
- jstring script, jobject params,
- jstring cacheDir, jboolean pieSupport) {
- const char *cache = env->GetStringUTFChars(
- reinterpret_cast<jstring>(cacheDir), nullptr);
- if (strlen(cache) > 0) {
- s_cacheDir = cache;
- }
- s_start_pie = pieSupport;
- return doInitFramework(env, jThis, script, params);
-}
-
-jint WeexProxy::doInitFramework(JNIEnv *env,
- jobject object,
- jstring script,
- jobject params) {
- bool reinit = false;
- startInitFrameWork:
- try {
- sHandler = std::move(createIPCHandler());
- sConnection.reset(new WeexJSConnection());
- sSender = sConnection->start(sHandler.get(), reinit);
- if (sSender == nullptr) {
- LOGE("JSFreamwork init start sender is null");
- if (!reinit) {
- reinit = true;
- goto startInitFrameWork;
- } else {
- return false;
- }
- } else {
- // initHandler(sHandler.get());
- ExtendJSApi *pExtensionJSApi = new ExtendJSApi();
- Bridge_Impl_Android::getInstance()->setGlobalRef(jThis);
- pExtensionJSApi->initFunction(sHandler.get());
-
- // using base::debug::TraceEvent;
- // TraceEvent::StartATrace(env);
- std::unique_ptr <IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::INITFRAMEWORK));
- initFromParam(env, script, params, serializer.get());
- std::unique_ptr <IPCBuffer> buffer = serializer->finish();
- std::unique_ptr <IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::INT32) {
- LOGE("initFramework Unexpected result type");
- reportException("", "initFramework",
- "error, initFramework Unexpected result type");
+ void WeexProxy::reset() {
+ sConnection.reset();
+ sHandler.reset();
+ }
+
+ static 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;
+ }
+
+ static 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;
+ }
+
+ static 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));
+
+ // LOGE("genInitFrameworkParams and type is %s and length is %d", init_framework_params->type->content,
+ // init_framework_params->type->length);
+ // LOGE("genInitFrameworkParams and value is %s and length is %d", init_framework_params->value->content,
+ // init_framework_params->value->length);
+
+ return init_framework_params;
+ }
+
+ static 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);
+ }
+ }
+
+ static 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;
+ }
+
+ jint WeexProxy::doInitFramework(JNIEnv *env, jobject object,
+ jstring script, jobject params,
+ jstring cacheDir, jboolean pieSupport) {
+ const char *cache = env->GetStringUTFChars(
+ reinterpret_cast<jstring>(cacheDir), nullptr);
+ if (strlen(cache) > 0) {
+ s_cacheDir = cache;
+ }
+ s_start_pie = pieSupport;
+ return doInitFramework(env, jThis, script, params);
+ }
+
+ jint
+ WeexProxy::initFrameworkInMultiProcess(JNIEnv *env, jstring script, IPCSerializer *serializer) {
+ bool reinit = false;
+ startInitFrameWork:
+ try {
+ sHandler = std::move(createIPCHandler());
+ sConnection.reset(new WeexJSConnection());
+ sSender = sConnection->start(sHandler.get(), reinit);
+ if (sSender == nullptr) {
+ LOGE("JSFreamwork init start sender is null");
+ if (!reinit) {
+ reinit = true;
+ goto startInitFrameWork;
+ } else {
+ return false;
+ }
+ } else {
+ // initHandler(sHandler.get());
+ ExtendJSApi *pExtensionJSApi = new ExtendJSApi();
+
+ pExtensionJSApi->initFunction(sHandler.get());
+
+ // using base::debug::TraceEvent;
+ // TraceEvent::StartATrace(env);
+
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::INITFRAMEWORK));
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("initFramework Unexpected result type");
+ reportException("", "initFramework",
+ "error, initFramework Unexpected result type");
+ return false;
+ }
+ return result->get<jint>();
+ }
+ } catch (IPCException &e) {
+ LOGE("WeexProxy catch:%s", e.msg());
+ if (!reinit) {
+ reinit = true;
+ goto startInitFrameWork;
+ } else {
+ LOGE("%s", e.msg());
+ reportException("", "initFramework", e.msg());
+ return false;
+ }
+ }
+ }
+
+ jint WeexProxy::doInitFramework(JNIEnv *env,
+ jobject object,
+ jstring script,
+ jobject params) {
+
+ Bridge_Impl_Android::getInstance()->setGlobalRef(jThis);
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ const std::vector<INIT_FRAMEWORK_PARAMS *> &initFrameworkParams = initFromParam(env, script,
+ params,
+ serializer.get());
+ LOGE("doInitFramework is running");
+ if (g_use_single_process) {
+ if (initFrameworkInSingleProcess(env, script, initFrameworkParams)) {
+ //reportNativeInitStatus("-1011", "init Single Process Success");
+ return true;
+ }
+
+ if (initFrameworkInMultiProcess(env, script, serializer.get())) {
+ return true;
+ }
+ } else {
+ if (initFrameworkInMultiProcess(env, script, serializer.get())) {
+ return true;
+ }
+
+ if (initFrameworkInSingleProcess(env, script, initFrameworkParams)) {
+ reportNativeInitStatus("-1011", "init Single Process Success");
+ return true;
+ }
+ }
+ reportNativeInitStatus("-1010", "init Failed");
return false;
- }
- return result->get<jint>();
- }
- } catch (IPCException &e) {
- LOGE("WeexProxy catch:%s", e.msg());
- if (!reinit) {
- reinit = true;
- goto startInitFrameWork;
- } else {
- LOGE("%s", e.msg());
- reportException("", "initFramework", e.msg());
- return false;
- }
- }
-}
-
-bool WeexProxy::execJSService(JNIEnv *env, jobject object, jstring script) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- try {
- std::unique_ptr <IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSSERVICE));
- addString(env, serializer.get(), script);
- std::unique_ptr <IPCBuffer> buffer = serializer->finish();
- std::unique_ptr <IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::INT32) {
- LOGE("execJSService Unexpected result type");
- return false;
- }
- return result->get<jint>();
- } catch (IPCException &e) {
- LOGE("%s", e.msg());
- return false;
- }
- return true;
-}
-
-bool WeexProxy::execJS(JNIEnv *env,
- jobject jthis,
- jstring jinstanceid,
- jstring jnamespace,
- jstring jfunction,
- jobjectArray jargs) {
- std::string mMessage = "";
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- int length = 0;
- if (jargs != NULL) {
- length = env->GetArrayLength(jargs);
- }
- try {
- std::unique_ptr <IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJS));
- addString(env, serializer.get(), jinstanceid);
- if (jnamespace) {
- addString(env, serializer.get(), jnamespace);
- } else {
- uint16_t tmp = 0;
- serializer->add(&tmp, 0);
- }
- addString(env, serializer.get(), jfunction);
-
- for (int i = 0; i < length; i++) {
- jobject jArg = env->GetObjectArrayElement(jargs, i);
-
- jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
- jint jTypeInt = env->GetIntField(jArg, jTypeId);
-
- jfieldID jDataId = env->GetFieldID(jWXJSObject,
- "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
- if (jTypeInt == 1) {
- if (jDoubleValueMethodId == NULL) {
- jclass jDoubleClazz = env->FindClass("java/lang/Double");
- jDoubleValueMethodId = env->GetMethodID(jDoubleClazz,
- "doubleValue", "()D");
- env->DeleteLocalRef(jDoubleClazz);
- }
- jdouble jDoubleObj = env->CallDoubleMethod(jDataObj,
- jDoubleValueMethodId);
- serializer->add(jDoubleObj);
-
- } else if (jTypeInt == 2) {
- jstring jDataStr = (jstring) jDataObj;
- addString(env, serializer.get(), jDataStr);
- } else if (jTypeInt == 3) {
- jstring jDataStr = (jstring) jDataObj;
- addJSONString(env, serializer.get(), jDataStr);
- } else {
- serializer->addJSUndefined();
- }
- env->DeleteLocalRef(jDataObj);
- env->DeleteLocalRef(jArg);
- }
-
- std::unique_ptr <IPCBuffer> buffer = serializer->finish();
-
- std::unique_ptr <IPCResult> result = sSender->send(buffer.get());
-
- if (result->getType() != IPCType::INT32) {
- LOGE("execJS Unexpected result type");
- return false;
- }
-
- return result->get<jint>();
- } catch (IPCException &e) {
- LOGE("%s", e.msg());
- // report crash here
- WeexProxy::reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-
-void WeexProxy::initFromParam(JNIEnv *env,
- jstring script,
- jobject params,
- IPCSerializer *serializer) {
- {
- ScopedJString scopedString(env, script);
- const jchar *chars = scopedString.getChars();
- int charLength = scopedString.getCharsLength();
- serializer->add(chars, charLength);
- }
+
+ }
+
+ bool WeexProxy::execJSService(JNIEnv *env, jobject object, jstring script) {
+ if (!sSender && !js_server_api_functions) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 source(env, script);
+ js_server_api_functions->funcExeJsService(source.getChars());
+ return true;
+ } else {
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSSERVICE));
+ addString(env, serializer.get(), script);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("execJSService Unexpected result type");
+ return false;
+ }
+ return result->get<jint>();
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ return false;
+ }
+ return true;
+ }
+ }
+
+ bool WeexProxy::execJS(JNIEnv *env,
+ jobject jthis,
+ jstring jinstanceid,
+ jstring jnamespace,
+ jstring jfunction,
+ jobjectArray jargs) {
+ std::string mMessage = "";
+ if (!sSender && !js_server_api_functions) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+ if (jfunction == nullptr || jinstanceid == nullptr) {
+ LOGE("native_execJS function is NULL");
+ return false;
+ }
+ int length = 0;
+ if (jargs != nullptr) {
+ length = env->GetArrayLength(jargs);
+ }
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ std::vector<VALUE_WITH_TYPE *> params;
+ if (js_server_api_functions == nullptr) {
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJS));
+ addString(env, serializer.get(), jinstanceid);
+ if (jnamespace)
+ addString(env, serializer.get(), jnamespace);
+ else {
+ uint16_t tmp = 0;
+ serializer->add(&tmp, 0);
+ }
+ addString(env, serializer.get(), jfunction);
+ }
+
+ for (int i = 0; i < length; i++) {
+ VALUE_WITH_TYPE *param = nullptr;
+
+ if (js_server_api_functions != nullptr) {
+ param = getValueWithTypePtr();
+ if (param == nullptr)
+ return false;
+ }
+
+ jobject jArg = env->GetObjectArrayElement(jargs, i);
+
+ jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
+ jint jTypeInt = env->GetIntField(jArg, jTypeId);
+
+ jfieldID jDataId = env->GetFieldID(jWXJSObject,
+ "data", "Ljava/lang/Object;");
+ jobject jDataObj = env->GetObjectField(jArg, jDataId);
+ if (jTypeInt == 1) {
+ if (jDoubleValueMethodId == NULL) {
+ jclass jDoubleClazz = env->FindClass("java/lang/Double");
+ jDoubleValueMethodId = env->GetMethodID(jDoubleClazz,
+ "doubleValue", "()D");
+ env->DeleteLocalRef(jDoubleClazz);
+ }
+ jdouble jDoubleObj = env->CallDoubleMethod(jDataObj,
+ jDoubleValueMethodId);
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::DOUBLE;
+ param->value.doubleValue = jDoubleObj;
+ } else {
+ serializer->add(jDoubleObj);
+ }
+
+ } else if (jTypeInt == 2) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::STRING;
+ param->value.string = jstring2WeexString(env, jDataStr);
+ } else {
+ addString(env, serializer.get(), jDataStr);
+ }
+ } else if (jTypeInt == 3) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::JSONSTRING;
+ param->value.string = jstring2WeexString(env, jDataStr);
+ } else {
+ addJSONString(env, serializer.get(), jDataStr);
+ }
+ } else {
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::JSUNDEFINED;
+ } else {
+ serializer->addJSUndefined();
+ }
+ }
+ if (param != nullptr)
+ params.push_back(param);
+ env->DeleteLocalRef(jDataObj);
+ env->DeleteLocalRef(jArg);
+ }
+
+ if (js_server_api_functions != nullptr) {
+
+ ScopedJStringUTF8 idChar(env, jinstanceid);
+ const char *name;
+ if (jnamespace) {
+ ScopedJStringUTF8 nameSpaceChar(env, jnamespace);
+ name = nameSpaceChar.getChars();
+ } else {
+ name = nullptr;
+ }
+ ScopedJStringUTF8 funcChar(env, jfunction);
+
+ int i = js_server_api_functions->funcExeJS(idChar.getChars(),
+ name,
+ funcChar.getChars(),
+ params);
+ for (auto ¶m : params) {
+ if (param->type == ParamsType::STRING ||
+ param->type == ParamsType::JSONSTRING) {
+ free(param->value.string);
+ }
+ free(param);
+ }
+ return static_cast<bool>(i);
+ } else {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("execJS Unexpected result type");
+ return false;
+ }
+
+ return result->get<jint>();
+ }
+
+
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ WeexProxy::reportServerCrash(jinstanceid);
+ return false;
+ }
+ return true;
+ }
+
+ static std::string findPath() {
+ std::string executablePath = "";
+ unsigned long target = reinterpret_cast<unsigned long>(__builtin_return_address(0));
+ FILE *f = fopen("/proc/self/maps", "r");
+ if (!f) {
+ return "";
+ }
+ char buffer[256];
+ char *line;
+ while ((line = fgets(buffer, 256, f))) {
+ char *end;
+ unsigned long val;
+ errno = 0;
+ val = strtoul(line, &end, 16);
+ if (errno)
+ continue;
+ if (val > target)
+ continue;
+ end += 1;
+ errno = 0;
+ val = strtoul(end, &end, 16);
+ if (errno)
+ continue;
+ if (val > target) {
+ char *s = strstr(end, "/");
+ if (s != nullptr)
+ executablePath.assign(s);
+ std::size_t found = executablePath.rfind('/');
+ if (found != std::string::npos) {
+ executablePath = executablePath.substr(0, found);
+ }
+ }
+ if (!executablePath.empty()) {
+ break;
+ }
+ }
+ fclose(f);
+ return executablePath;
+ }
+
+ static WEEX_CORE_JS_API_FUNCTIONS *getWeexCoreApiFunctions() {
+ WEEX_CORE_JS_API_FUNCTIONS tempFunctions = {
+ _setJSVersion,
+ _reportException,
+ _callNative,
+ _callNativeModule,
+ _callNativeComponent,
+ _callAddElement,
+ _setTimeout,
+ _callNativeLog,
+ _callCreateBody,
+ _callUpdateFinish,
+ _callCreateFinish,
+ _callRefreshFinish,
+ _callUpdateAttrs,
+ _callUpdateStyle,
+ _callRemoveElement,
+ _callMoveElement,
+ _callAddEvent,
+ _callRemoveEvent,
+ _setInterval,
+ _clearInterval,
+ _callGCanvasLinkNative,
+ _t3dLinkNative,
+ callHandlePostMessage,
+ callDIspatchMessage
+ };
+
+ auto *functions = (WEEX_CORE_JS_API_FUNCTIONS *) malloc(sizeof(WEEX_CORE_JS_API_FUNCTIONS));
+
+ if (!functions) {
+ return nullptr;
+ }
+
+ memset(functions, 0, sizeof(WEEX_CORE_JS_API_FUNCTIONS));
+ memcpy(functions, &tempFunctions, sizeof(WEEX_CORE_JS_API_FUNCTIONS));
+
+ return functions;
+ }
+
+ typedef WEEX_CORE_JS_SERVER_API_FUNCTIONS *(*InitMethodFunc)(
+ WEEX_CORE_JS_API_FUNCTIONS *functions);
+
+ jint
+ WeexProxy::initFrameworkInSingleProcess(JNIEnv *env, jstring script,
+ std::vector<INIT_FRAMEWORK_PARAMS *> initFrameworkParams) {
+
+ std::string soPath = "";
+
+ // -----------------------------------------------
+ // use find path to get lib path
+ // use set path is better idea, should change in future
+ soPath = findPath();
+
+ std::string::size_type pos = std::string::npos;
+ LOGE("find so path: %s", soPath.c_str());
+ // dynamic deploy
+ if (!soPath.empty() && soPath.find(".maindex") != std::string::npos) {
+ std::string libs[] = {"/opt", "/oat/arm"};
+ auto libsCount = sizeof(libs) / sizeof(std::string);
+ for (int i = 0; i < libsCount; ++i) {
+ auto lib = libs[i];
+ pos = soPath.find(lib);
+ if (pos != std::string::npos) {
+ soPath.replace(pos, lib.length(), "/lib");
+ break;
+ }
+ }
+ soPath += "/libweexjss.so";
+ } else {
+ soPath += "libweexjss.so";
+ }
+ // -------------------------------------------------
+ // -------------------------------------------------
+ if (access(soPath.c_str(), 00) != 0) {
+ LOGE("so path: %s is not exsist, use full package lib", soPath.c_str());
+ const char *error = soPath.c_str();
+ soPath = s_cacheDir;
+ std::string lib = "/cache";
+ if ((pos = soPath.find(lib)) != std::string::npos) {
+ soPath.replace(pos, lib.length(), "/lib");
+ }
+ soPath += "/libweexjss.so";
+ if (access(soPath.c_str(), 00) != 0) {
+ LOGE("so path: %s is not exsist", soPath.c_str());
+ //reportNativeInitStatus("-1004", error);
+ //return false;
+ //use libweexjss.so directly
+ soPath = "libweexjss.so";
+ }
+ }
+
+ LOGE("final executablePath:%s", soPath.c_str());
+
+ void *handle = dlopen(soPath.c_str(), RTLD_NOW);
+ if (!handle) {
+ const char *error = dlerror();
+ LOGE("load libweexjss.so failed,error=%s\n", error);
+// reportNativeInitStatus("-1005", error);
+ // try again use current path
+ dlclose(handle);
+ return false;
+ }
+
+ //clear dlopen error message
+ dlerror();
+
+ LOGE("dlopen so and call function");
+ auto initMethod = (InitMethodFunc) dlsym(handle, "exchangeMethod");
+ if (!initMethod) {
+ const char *error = dlerror();
+ LOGE("load External_InitFrameWork failed,error=%s\n", error);
+// reportNativeInitStatus("-1006", error);
+ dlclose(handle);
+ return false;
+ }
+
+ //clear dlopen error message
+ dlerror();
+
+ WEEX_CORE_JS_API_FUNCTIONS *pFunctions = getWeexCoreApiFunctions();
+
+ js_server_api_functions = initMethod(pFunctions);
+
+ if (js_server_api_functions != nullptr) {
+ js_server_api_functions->funcInitFramework(env->GetStringUTFChars(script, nullptr),
+ std::move(initFrameworkParams));
+ return true;
+ } else {
+ dlclose(handle);
+ free(pFunctions);
+ free(js_server_api_functions);
+ //reportNativeInitStatus("-1007", "Init Functions failed");
+ return false;
+ }
+ }
+
+
+ std::vector<INIT_FRAMEWORK_PARAMS *> WeexProxy::initFromParam(JNIEnv *env,
+ jstring script,
+ jobject params,
+ IPCSerializer *serializer) {
+ {
+ ScopedJString scopedString(env, script);
+ const jchar *chars = scopedString.getChars();
+ int charLength = scopedString.getCharsLength();
+ serializer->add(chars, charLength);
+ }
+ LOGE("initFromParam is running ");
+ std::vector<INIT_FRAMEWORK_PARAMS *> initFrameworkParams;
+
#define ADDSTRING(name) \
{ \
const char* myname = #name; \
@@ -224,732 +577,977 @@ void WeexProxy::initFromParam(JNIEnv *env,
const char* chars = scopedString.getChars(); \
int charLength = strlen(chars); \
serializer->add(chars, charLength); \
+ initFrameworkParams.push_back(genInitFrameworkParams(myname,chars));\
+ }
+ jclass c_params = env->GetObjectClass(params);
+
+ jmethodID m_platform = env->GetMethodID(c_params,
+ "getPlatform",
+ "()Ljava/lang/String;");
+ jobject platform = env->CallObjectMethod(params, m_platform);
+ if (!WXCoreEnvironment::getInstance()->SetPlatform(
+ jString2StrFast(env, reinterpret_cast<jstring &>(platform)))) {
+ LOGD("setPlatform");
+ }
+ ADDSTRING(platform);
+
+
+ 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);
+ g_use_single_process = strstr(use_single_process, "true") != nullptr;
+ }
+
+ jmethodID m_osVersion = env->GetMethodID(
+ c_params, "getOsVersion", "()Ljava/lang/String;");
+ jobject osVersion = env->CallObjectMethod(params, m_osVersion);
+ ADDSTRING(osVersion);
+
+ // use param ti get cacheDir
+ jmethodID m_cacheMethod = env->GetMethodID(
+ c_params, "getCacheDir", "()Ljava/lang/String;");
+ if (m_cacheMethod != NULL) {
+ jobject cacheDir = env->CallObjectMethod(params, m_cacheMethod);
+ if (cacheDir != NULL) {
+ ADDSTRING(cacheDir);
+ }
+ }
+
+ jmethodID m_appVersion = env->GetMethodID(
+ c_params, "getAppVersion", "()Ljava/lang/String;");
+ jobject appVersion = env->CallObjectMethod(params, m_appVersion);
+ ADDSTRING(appVersion);
+
+ jmethodID m_weexVersion = env->GetMethodID(
+ c_params, "getWeexVersion", "()Ljava/lang/String;");
+ jobject weexVersion = env->CallObjectMethod(params, m_weexVersion);
+ ADDSTRING(weexVersion);
+
+ jmethodID m_deviceModel = env->GetMethodID(
+ c_params, "getDeviceModel", "()Ljava/lang/String;");
+ jobject deviceModel = env->CallObjectMethod(params, m_deviceModel);
+ ADDSTRING(deviceModel);
+
+ jmethodID m_appName = env->GetMethodID(
+ c_params, "getAppName", "()Ljava/lang/String;");
+ jobject appName = env->CallObjectMethod(params, m_appName);
+ ADDSTRING(appName);
+
+ jmethodID m_deviceWidth = env->GetMethodID(
+ c_params, "getDeviceWidth", "()Ljava/lang/String;");
+ jobject deviceWidth = env->CallObjectMethod(params, m_deviceWidth);
+ if (!WXCoreEnvironment::getInstance()->SetDeviceWidth(
+ jString2StrFast(env, reinterpret_cast<jstring &>(deviceWidth)))) {
+ LOGD("setDeviceWidth");
+ }
+ ADDSTRING(deviceWidth);
+
+ jmethodID m_deviceHeight = env->GetMethodID(
+ c_params, "getDeviceHeight", "()Ljava/lang/String;");
+ jobject deviceHeight = env->CallObjectMethod(params, m_deviceHeight);
+ if (!WXCoreEnvironment::getInstance()->SetDeviceHeight(
+ jString2StrFast(env, reinterpret_cast<jstring &>(deviceHeight)))) {
+ LOGD("setDeviceHeight");
+ }
+ ADDSTRING(deviceHeight);
+
+ jmethodID m_options = env->GetMethodID(
+ c_params, "getOptions", "()Ljava/lang/Object;");
+ jobject options = env->CallObjectMethod(params, m_options);
+ jclass jmapclass = env->FindClass("java/util/HashMap");
+ 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) {
+ // const char* c_key = env->GetStringUTFChars(jkey, NULL);
+ // addString(vm, WXEnvironment, c_key, jString2String(env, jvalue));
+ // serializer->add(c_key, strlen(c_key));
+ // env->DeleteLocalRef(jkey);
+ // if (jvalue != NULL) {
+ // env->DeleteLocalRef(jvalue);
+ // }
+ 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);
+ serializer->add(c_key_chars, c_key_len);
+ serializer->add(c_value_chars, c_value_len);
+ WXCoreEnvironment::getInstance()->AddOption(jString2Str(env, jkey),
+ jString2Str(env, jvalue));
+ }
+ }
+ env->DeleteLocalRef(jobjArray);
+ }
+ env->DeleteLocalRef(options);
+ return initFrameworkParams;
+ }
+
+ void
+ WeexProxy::reportException(const char *instanceID,
+ const char *func,
+ const char *exception_string) {
+ _reportException(instanceID, func, exception_string);
+// JNIEnv *env = getJNIEnv();
+// jstring jExceptionString = env->NewStringUTF(exception_string);
+// jstring jInstanceId = env->NewStringUTF(instanceID);
+// jstring jFunc = env->NewStringUTF(func);
+// jmethodID tempMethodId = env->GetMethodID(
+// jBridgeClazz,
+// "reportJSException",
+// "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+// env->CallVoidMethod(jThis,
+// tempMethodId,
+// jInstanceId,
+// jFunc,
+// jExceptionString);
+// env->DeleteLocalRef(jExceptionString);
+// env->DeleteLocalRef(jInstanceId);
+// env->DeleteLocalRef(jFunc);
+ }
+
+ void WeexProxy::reportServerCrash(jstring jinstanceid) {
+ JNIEnv *env = getJNIEnv();
+ jmethodID reportMethodId;
+ jstring crashFile;
+ std::string crashFileStr;
+ reportMethodId = env->GetMethodID(jBridgeClazz,
+ "reportServerCrash",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (!reportMethodId)
+ goto no_method;
+
+ crashFileStr.assign("/jsserver_crash/jsserver_crash_info.log");
+
+ crashFile = env->NewStringUTF(crashFileStr.c_str());
+ env->CallVoidMethod(jThis, reportMethodId, jinstanceid, crashFile);
+ env->DeleteLocalRef(crashFile);
+ no_method:
+ env->ExceptionClear();
+ }
+
+ void WeexProxy::reportNativeInitStatus(const char *statusCode, const char *errorMsg) {
+ JNIEnv *env = getJNIEnv();
+ jmethodID reportMethodId;
+ jstring errorCodeString = env->NewStringUTF(statusCode);
+
+ std::string m_errorMsgString = "useSingleProcess is ";
+ m_errorMsgString.append(g_use_single_process ? "true" : "false");
+ m_errorMsgString.append(" And Error Msg is ");
+ m_errorMsgString.append(errorMsg);
+
+
+ LOGE("reportNativeInitStatus error msg is %s ", m_errorMsgString.c_str());
+
+ jstring errorMsgString = env->NewStringUTF(m_errorMsgString.c_str());
+ reportMethodId = env->GetMethodID(jBridgeClazz,
+ "reportNativeInitStatus",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+
+
+ if (!reportMethodId)
+ goto no_method;
+
+
+ env->CallVoidMethod(jThis, reportMethodId, errorCodeString, errorMsgString);
+
+ no_method:
+ env->DeleteLocalRef(errorCodeString);
+ env->DeleteLocalRef(errorMsgString);
+ env->ExceptionClear();
+ }
+
+ const char *WeexProxy::getCacheDir(JNIEnv *env) {
+ jclass activityThreadCls, applicationCls, fileCls;
+ jobject applicationObj, fileObj, pathStringObj;
+ jmethodID currentApplicationMethodId,
+ getCacheDirMethodId,
+ getAbsolutePathMethodId;
+ static std::string storage;
+ const char *tmp;
+ const char *ret = nullptr;
+ if (!storage.empty()) {
+ ret = storage.c_str();
+ goto no_empty;
+ }
+ activityThreadCls = env->FindClass("android/app/ActivityThread");
+ if (!activityThreadCls || env->ExceptionOccurred()) {
+ goto no_class;
+ }
+ currentApplicationMethodId = env->GetStaticMethodID(
+ activityThreadCls,
+ "currentApplication",
+ "()Landroid/app/Application;");
+ if (!currentApplicationMethodId || env->ExceptionOccurred()) {
+ goto no_currentapplication_method;
+ }
+ applicationObj = env->CallStaticObjectMethod(activityThreadCls,
+ currentApplicationMethodId,
+ nullptr);
+ if (!applicationObj || env->ExceptionOccurred()) {
+ goto no_application;
+ }
+ applicationCls = env->GetObjectClass(applicationObj);
+ getCacheDirMethodId = env->GetMethodID(applicationCls,
+ "getCacheDir",
+ "()Ljava/io/File;");
+ if (!getCacheDirMethodId || env->ExceptionOccurred()) {
+ goto no_getcachedir_method;
+ }
+ fileObj = env->CallObjectMethod(applicationObj, getCacheDirMethodId, nullptr);
+ if (!fileObj || env->ExceptionOccurred()) {
+ goto no_file_obj;
+ }
+ fileCls = env->GetObjectClass(fileObj);
+ getAbsolutePathMethodId = env->GetMethodID(fileCls,
+ "getAbsolutePath",
+ "()Ljava/lang/String;");
+ if (!getAbsolutePathMethodId || env->ExceptionOccurred()) {
+ goto no_getabsolutepath_method;
+ }
+ pathStringObj = env->CallObjectMethod(fileObj,
+ getAbsolutePathMethodId,
+ nullptr);
+ if (!pathStringObj || env->ExceptionOccurred()) {
+ goto no_path_string;
+ }
+ tmp = env->GetStringUTFChars(reinterpret_cast<jstring>(pathStringObj),
+ nullptr);
+ storage.assign(tmp);
+ env->ReleaseStringUTFChars(reinterpret_cast<jstring>(pathStringObj),
+ tmp);
+ ret = storage.c_str();
+ no_path_string:
+ no_getabsolutepath_method:
+ env->DeleteLocalRef(fileCls);
+ env->DeleteLocalRef(fileObj);
+ no_file_obj:
+ no_getcachedir_method:
+ env->DeleteLocalRef(applicationCls);
+ env->DeleteLocalRef(applicationObj);
+ no_application:
+ no_currentapplication_method:
+ env->DeleteLocalRef(activityThreadCls);
+ no_class:
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ no_empty:
+ return ret;
+ }
+
+ void WeexProxy::setCacheDir(JNIEnv *env) {
+ s_cacheDir = getCacheDir(env);
+ }
+
+ jbyteArray WeexProxy::execJSWithResult(JNIEnv *env, jobject jthis,
+ jstring jinstanceid,
+ jstring jnamespace,
+ jstring jfunction,
+ jobjectArray jargs) {
+ if (!sSender && !js_server_api_functions) {
+ LOGE("have not connected to a js server");
+ return NULL;
+ }
+ if (jfunction == NULL || jinstanceid == NULL) {
+ LOGE("native_execJS function is NULL");
+ return NULL;
+ }
+
+ int length = 0;
+ if (jargs != NULL) {
+ length = env->GetArrayLength(jargs);
+ }
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ std::vector<VALUE_WITH_TYPE *> params;
+ if (js_server_api_functions == nullptr) {
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSWITHRESULT));
+ addString(env, serializer.get(), jinstanceid);
+ if (jnamespace)
+ addString(env, serializer.get(), jnamespace);
+ else {
+ uint16_t tmp = 0;
+ serializer->add(&tmp, 0);
+ }
+ addString(env, serializer.get(), jfunction);
+ }
+
+ for (int i = 0; i < length; i++) {
+ VALUE_WITH_TYPE *param = nullptr;
+
+ if (js_server_api_functions != nullptr) {
+ param = getValueWithTypePtr();
+ if (param == nullptr)
+ return false;
+ }
+
+ jobject jArg = env->GetObjectArrayElement(jargs, i);
+
+ jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
+ jint jTypeInt = env->GetIntField(jArg, jTypeId);
+
+ jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
+ jobject jDataObj = env->GetObjectField(jArg, jDataId);
+ if (jTypeInt == 1) {
+ if (jDoubleValueMethodId == NULL) {
+ jclass jDoubleClazz = env->FindClass("java/lang/Double");
+ jDoubleValueMethodId = env->GetMethodID(jDoubleClazz, "doubleValue", "()D");
+ env->DeleteLocalRef(jDoubleClazz);
+ }
+ jdouble jDoubleObj = env->CallDoubleMethod(jDataObj, jDoubleValueMethodId);
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::DOUBLE;
+ param->value.doubleValue = jDoubleObj;
+ } else {
+ serializer->add(jDoubleObj);
+ }
+
+ } else if (jTypeInt == 2) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::STRING;
+ param->value.string = jstring2WeexString(env, jDataStr);
+ } else {
+ addString(env, serializer.get(), jDataStr);
+ }
+ } else if (jTypeInt == 3) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::JSONSTRING;
+ param->value.string = jstring2WeexString(env, jDataStr);
+ } else {
+ addJSONString(env, serializer.get(), jDataStr);
+ }
+ } else {
+ if (js_server_api_functions != nullptr) {
+ param->type = ParamsType::JSUNDEFINED;
+ } else {
+ serializer->addJSUndefined();
+ }
+ }
+ if (param != nullptr)
+ params.push_back(param);
+ env->DeleteLocalRef(jDataObj);
+ env->DeleteLocalRef(jArg);
+ }
+
+ if (js_server_api_functions != nullptr) {
+ char *result = js_server_api_functions->funcExeJSWithResult(
+ env->GetStringUTFChars(jinstanceid,
+ nullptr),
+ env->GetStringUTFChars(jnamespace,
+ nullptr),
+ env->GetStringUTFChars(jfunction,
+ nullptr),
+ params);
+ for (auto ¶m : params) {
+ if (param->type == ParamsType::STRING ||
+ param->type == ParamsType::JSONSTRING) {
+ free(param->value.string);
+ }
+ free(param);
+ }
+ return newJByteArray(env, result);
+ } else {
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::BYTEARRAY) {
+ return NULL;
+ }
+ if (result->getByteArrayLength() == 0) {
+ return NULL;
+ }
+ jbyteArray array = env->NewByteArray(result->getByteArrayLength());
+ env->SetByteArrayRegion(array, 0, result->getByteArrayLength(),
+ reinterpret_cast<const jbyte *>(result->getByteArrayContent()));
+ return array;
+ }
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ reportServerCrash(jinstanceid);
+ return NULL;
+ }
+ return NULL;
+ }
+
+ void WeexProxy::updateGlobalConfig(JNIEnv *env, jobject jcaller, jstring config) {
+ if (!sSender && js_server_api_functions == nullptr) {
+ LOGE("have not connected to a js server");
+ return;
+ }
+ if (config == NULL) {
+ LOGE("native_execJS function is NULL");
+ return;
+ }
+
+ if (js_server_api_functions != nullptr) {
+ js_server_api_functions->funcUpdateGlobalConfig(
+ env->GetStringUTFChars(config, nullptr));
+ return;
+ } else {
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::UPDATEGLOBALCONFIG));
+ addString(env, serializer.get(), config);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ }
+ }
+ }
+
+ static 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;
+ }
+ jobject jArg = env->GetObjectArrayElement(jargs, index);
+
+ jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
+ jint jTypeInt = env->GetIntField(jArg, jTypeId);
+ jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
+ jobject jDataObj = env->GetObjectField(jArg, jDataId);
+ if (jTypeInt == 3) {
+ ret = (jstring) jDataObj;
+ }
+ // env->DeleteLocalRef(jDataObj);
+ env->DeleteLocalRef(jArg);
+ return ret;
+ }
+
+ jint
+ WeexProxy::createInstanceContext(JNIEnv *env, jobject jcaller, jstring jinstanceid,
+ jstring name,
+ jstring jfunction, jobjectArray jargs) {
+ if (!sSender && js_server_api_functions == nullptr) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+ if (jfunction == NULL || jinstanceid == NULL) {
+ LOGE("native_createInstanceContext function is NULL");
+ return false;
+ }
+
+ int length = 0;
+ if (jargs != NULL) {
+ length = env->GetArrayLength(jargs);
+ }
+ if (length < 4) {
+ LOGE("native_createInstanceContext jargs format error");
+ return false;
+ }
+// get temp data, such as js bundle
+ jobject jArg = env->GetObjectArrayElement(jargs, 1);
+ jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
+ jobject jDataObj = env->GetObjectField(jArg, jDataId);
+ jstring jscript = (jstring) jDataObj;
+ jstring opts = getJsonData(env, jargs, 2);
+ // init jsonData
+ jstring initData = getJsonData(env, jargs, 3);
+ // get extend api data, such as rax-api
+ jArg = env->GetObjectArrayElement(jargs, 4);
+ jDataObj = env->GetObjectField(jArg, jDataId);
+ jstring japi = (jstring) jDataObj;
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 idChar(env, jinstanceid);
+ ScopedJStringUTF8 funcChar(env, jfunction);
+ ScopedJStringUTF8 scriptChar(env, jscript);
+ ScopedJStringUTF8 optsChar(env, opts);
+ ScopedJStringUTF8 initDataChar(env, initData);
+ ScopedJStringUTF8 apiChar(env, japi);
+
+ return js_server_api_functions->funcCreateInstance(
+ idChar.getChars(),
+ funcChar.getChars(),
+ scriptChar.getChars(),
+ optsChar.getChars(),
+ initDataChar.getChars(),
+ apiChar.getChars());
+ } else {
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::CREATEINSTANCE));
+ addString(env, serializer.get(), jinstanceid);
+ addString(env, serializer.get(), jfunction);
+ addString(env, serializer.get(), jscript);
+ addJSONString(env, serializer.get(), opts);
+ addJSONString(env, serializer.get(), initData);
+ addString(env, serializer.get(), japi);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ env->DeleteLocalRef(jArg);
+ env->DeleteLocalRef(jDataObj);
+ env->DeleteLocalRef(opts);
+ if (result->getType() != IPCType::INT32) {
+ LOGE("createInstanceContext Unexpected result type");
+ return false;
+ }
+ return result->get<jint>();
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ reportServerCrash(jinstanceid);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ jint WeexProxy::destoryInstance(JNIEnv *env, jobject jcaller, jstring jinstanceid,
+ jstring jnamespace,
+ jstring jfunction, jobjectArray jargs) {
+ int ret = execJS(env, nullptr, jinstanceid, jnamespace, jfunction, jargs);
+ if (jfunction == NULL || jinstanceid == NULL) {
+ LOGE("native_destoryInstance function is NULL");
+ return false;
+ }
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 idChar(env, jinstanceid);
+ return js_server_api_functions->funcDestroyInstance(idChar.getChars());
+ } else {
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::DESTORYINSTANCE));
+ addString(env, serializer.get(), jinstanceid);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::INT32) {
+ LOGE("destoryInstance Unexpected result type");
+ return false;
+ }
+ return result->get<jint>();
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ reportServerCrash(jinstanceid);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ jstring
+ WeexProxy::execJSOnInstance(JNIEnv *env, jobject jcaller, jstring instanceId, jstring script,
+ jint type) {
+ if (instanceId == NULL || script == NULL) {
+ return env->NewStringUTF("");
+ }
+
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 idChar(env, instanceId);
+ ScopedJStringUTF8 scriptChar(env, script);
+ char *string = js_server_api_functions->funcExeJSOnInstance(
+ idChar.getChars(),
+ scriptChar.getChars());
+ return env->NewStringUTF(string);
+ } else {
+ try {
+ // base::debug::TraceScope traceScope("weex", "native_execJSOnInstance");
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSONINSTANCE));
+
+ addString(env, serializer.get(), instanceId);
+ addString(env, serializer.get(), script);
+
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ if (result->getType() != IPCType::BYTEARRAY) {
+ // LOGE("native_execJSOnInstance return type error");
+ return env->NewStringUTF("");
+ }
+ return env->NewStringUTF(result->getByteArrayContent());
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ reportServerCrash(instanceId);
+ return env->NewStringUTF("");
+ }
+ }
}
- jclass c_params = env->GetObjectClass(params);
-
- jmethodID m_platform = env->GetMethodID(c_params,
- "getPlatform",
- "()Ljava/lang/String;");
- jobject platform = env->CallObjectMethod(params, m_platform);
- if (!WXCoreEnvironment::getInstance()->SetPlatform(
- jString2StrFast(env, reinterpret_cast<jstring &>(platform)))) {
- LOGD("setPlatform");
- }
- ADDSTRING(platform);
-
- jmethodID m_osVersion = env->GetMethodID(
- c_params, "getOsVersion", "()Ljava/lang/String;");
- jobject osVersion = env->CallObjectMethod(params, m_osVersion);
- ADDSTRING(osVersion);
-
- // use param ti get cacheDir
- jmethodID m_cacheMethod = env->GetMethodID(
- c_params, "getCacheDir", "()Ljava/lang/String;");
- if (m_cacheMethod != NULL) {
- jobject cacheDir = env->CallObjectMethod(params, m_cacheMethod);
- if (cacheDir != NULL) {
- ADDSTRING(cacheDir);
- }
- }
-
- jmethodID m_appVersion = env->GetMethodID(
- c_params, "getAppVersion", "()Ljava/lang/String;");
- jobject appVersion = env->CallObjectMethod(params, m_appVersion);
- ADDSTRING(appVersion);
-
- jmethodID m_weexVersion = env->GetMethodID(
- c_params, "getWeexVersion", "()Ljava/lang/String;");
- jobject weexVersion = env->CallObjectMethod(params, m_weexVersion);
- ADDSTRING(weexVersion);
-
- jmethodID m_deviceModel = env->GetMethodID(
- c_params, "getDeviceModel", "()Ljava/lang/String;");
- jobject deviceModel = env->CallObjectMethod(params, m_deviceModel);
- ADDSTRING(deviceModel);
-
- jmethodID m_appName = env->GetMethodID(
- c_params, "getAppName", "()Ljava/lang/String;");
- jobject appName = env->CallObjectMethod(params, m_appName);
- ADDSTRING(appName);
-
- jmethodID m_deviceWidth = env->GetMethodID(
- c_params, "getDeviceWidth", "()Ljava/lang/String;");
- jobject deviceWidth = env->CallObjectMethod(params, m_deviceWidth);
- if (!WXCoreEnvironment::getInstance()->SetDeviceWidth(
- jString2StrFast(env, reinterpret_cast<jstring &>(deviceWidth)))) {
- LOGD("setDeviceWidth");
- }
- ADDSTRING(deviceWidth);
-
- jmethodID m_deviceHeight = env->GetMethodID(
- c_params, "getDeviceHeight", "()Ljava/lang/String;");
- jobject deviceHeight = env->CallObjectMethod(params, m_deviceHeight);
- if (!WXCoreEnvironment::getInstance()->SetDeviceHeight(
- jString2StrFast(env, reinterpret_cast<jstring &>(deviceHeight)))) {
- LOGD("setDeviceHeight");
- }
- ADDSTRING(deviceHeight);
-
- jmethodID m_options = env->GetMethodID(
- c_params, "getOptions", "()Ljava/lang/Object;");
- jobject options = env->CallObjectMethod(params, m_options);
- jclass jmapclass = env->FindClass("java/util/HashMap");
- 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) {
- // const char* c_key = env->GetStringUTFChars(jkey, NULL);
- // addString(vm, WXEnvironment, c_key, jString2String(env, jvalue));
- // serializer->add(c_key, strlen(c_key));
- // env->DeleteLocalRef(jkey);
- // if (jvalue != NULL) {
- // env->DeleteLocalRef(jvalue);
- // }
- 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);
- serializer->add(c_key_chars, c_key_len);
- serializer->add(c_value_chars, c_value_len);
- WXCoreEnvironment::getInstance()->AddOption(jString2Str(env, jkey), jString2Str(env, jvalue));
- }
- }
- env->DeleteLocalRef(jobjArray);
- }
- env->DeleteLocalRef(options);
-}
-
-void
-WeexProxy::reportException(const char *instanceID,
- const char *func,
- const char *exception_string) {
- JNIEnv *env = getJNIEnv();
- jstring jExceptionString = env->NewStringUTF(exception_string);
- jstring jInstanceId = env->NewStringUTF(instanceID);
- jstring jFunc = env->NewStringUTF(func);
- jmethodID tempMethodId = env->GetMethodID(
- jBridgeClazz,
- "reportJSException",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- env->CallVoidMethod(jThis,
- tempMethodId,
- jInstanceId,
- jFunc,
- jExceptionString);
- env->DeleteLocalRef(jExceptionString);
- env->DeleteLocalRef(jInstanceId);
- env->DeleteLocalRef(jFunc);
-}
-
-void WeexProxy::reportServerCrash(jstring jinstanceid) {
- JNIEnv *env = getJNIEnv();
- jmethodID reportMethodId;
- jstring crashFile;
- std::string crashFileStr;
- reportMethodId = env->GetMethodID(jBridgeClazz,
- "reportServerCrash",
- "(Ljava/lang/String;Ljava/lang/String;)V");
- if (!reportMethodId)
- goto no_method;
-
- crashFileStr.assign("/jsserver_crash/jsserver_crash_info.log");
-
- crashFile = env->NewStringUTF(crashFileStr.c_str());
- env->CallVoidMethod(jThis, reportMethodId, jinstanceid, crashFile);
- env->DeleteLocalRef(crashFile);
- no_method:
- env->ExceptionClear();
-}
-
-const char *WeexProxy::getCacheDir(JNIEnv *env) {
- jclass activityThreadCls, applicationCls, fileCls;
- jobject applicationObj, fileObj, pathStringObj;
- jmethodID currentApplicationMethodId,
- getCacheDirMethodId,
- getAbsolutePathMethodId;
- static std::string storage;
- const char *tmp;
- const char *ret = nullptr;
- if (!storage.empty()) {
- ret = storage.c_str();
- goto no_empty;
- }
- activityThreadCls = env->FindClass("android/app/ActivityThread");
- if (!activityThreadCls || env->ExceptionOccurred()) {
- goto no_class;
- }
- currentApplicationMethodId = env->GetStaticMethodID(
- activityThreadCls,
- "currentApplication",
- "()Landroid/app/Application;");
- if (!currentApplicationMethodId || env->ExceptionOccurred()) {
- goto no_currentapplication_method;
- }
- applicationObj = env->CallStaticObjectMethod(activityThreadCls,
- currentApplicationMethodId,
- nullptr);
- if (!applicationObj || env->ExceptionOccurred()) {
- goto no_application;
- }
- applicationCls = env->GetObjectClass(applicationObj);
- getCacheDirMethodId = env->GetMethodID(applicationCls,
- "getCacheDir",
- "()Ljava/io/File;");
- if (!getCacheDirMethodId || env->ExceptionOccurred()) {
- goto no_getcachedir_method;
- }
- fileObj = env->CallObjectMethod(applicationObj, getCacheDirMethodId, nullptr);
- if (!fileObj || env->ExceptionOccurred()) {
- goto no_file_obj;
- }
- fileCls = env->GetObjectClass(fileObj);
- getAbsolutePathMethodId = env->GetMethodID(fileCls,
- "getAbsolutePath",
- "()Ljava/lang/String;");
- if (!getAbsolutePathMethodId || env->ExceptionOccurred()) {
- goto no_getabsolutepath_method;
- }
- pathStringObj = env->CallObjectMethod(fileObj,
- getAbsolutePathMethodId,
- nullptr);
- if (!pathStringObj || env->ExceptionOccurred()) {
- goto no_path_string;
- }
- tmp = env->GetStringUTFChars(reinterpret_cast<jstring>(pathStringObj),
- nullptr);
- storage.assign(tmp);
- env->ReleaseStringUTFChars(reinterpret_cast<jstring>(pathStringObj),
- tmp);
- ret = storage.c_str();
- no_path_string:
- no_getabsolutepath_method:
- env->DeleteLocalRef(fileCls);
- env->DeleteLocalRef(fileObj);
- no_file_obj:
- no_getcachedir_method:
- env->DeleteLocalRef(applicationCls);
- env->DeleteLocalRef(applicationObj);
- no_application:
- no_currentapplication_method:
- env->DeleteLocalRef(activityThreadCls);
- no_class:
- env->ExceptionDescribe();
- env->ExceptionClear();
- no_empty:
- return ret;
-}
-
-void WeexProxy::setCacheDir(JNIEnv *env) {
- s_cacheDir = getCacheDir(env);
-}
-
-jbyteArray WeexProxy::execJSWithResult(JNIEnv* env, jobject jthis,
- jstring jinstanceid,
- jstring jnamespace,
- jstring jfunction,
- jobjectArray jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return NULL;
- }
- if (jfunction == NULL || jinstanceid == NULL) {
- LOGE("native_execJS function is NULL");
- return NULL;
- }
-
- int length = 0;
- if (jargs != NULL) {
- length = env->GetArrayLength(jargs);
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSWITHRESULT));
- addString(env, serializer.get(), jinstanceid);
- if (jnamespace)
- addString(env, serializer.get(), jnamespace);
- else {
- uint16_t tmp = 0;
- serializer->add(&tmp, 0);
- }
- addString(env, serializer.get(), jfunction);
-
- for (int i = 0; i < length; i++) {
- jobject jArg = env->GetObjectArrayElement(jargs, i);
-
- jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
- jint jTypeInt = env->GetIntField(jArg, jTypeId);
-
- jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
- if (jTypeInt == 1) {
- if (jDoubleValueMethodId == NULL) {
- jclass jDoubleClazz = env->FindClass("java/lang/Double");
- jDoubleValueMethodId = env->GetMethodID(jDoubleClazz, "doubleValue", "()D");
- env->DeleteLocalRef(jDoubleClazz);
- }
- jdouble jDoubleObj = env->CallDoubleMethod(jDataObj, jDoubleValueMethodId);
- serializer->add(jDoubleObj);
-
- } else if (jTypeInt == 2) {
- jstring jDataStr = (jstring)jDataObj;
- addString(env, serializer.get(), jDataStr);
- } else if (jTypeInt == 3) {
- jstring jDataStr = (jstring)jDataObj;
- addJSONString(env, serializer.get(), jDataStr);
- } else {
- serializer->addJSUndefined();
- }
- env->DeleteLocalRef(jDataObj);
- env->DeleteLocalRef(jArg);
- }
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::BYTEARRAY) {
- return NULL;
- }
- if(result->getByteArrayLength() == 0){
- return NULL;
- }
- jbyteArray array = env->NewByteArray(result->getByteArrayLength());
- env->SetByteArrayRegion(array, 0, result->getByteArrayLength(), reinterpret_cast<const jbyte*>(result->getByteArrayContent()));
- return array;
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return NULL;
- }
- return NULL;
-}
-
-void WeexProxy::updateGlobalConfig(JNIEnv *env, jobject jcaller, jstring config) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return;
- }
- if (config == NULL) {
- LOGE("native_execJS function is NULL");
- return;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::UPDATEGLOBALCONFIG));
- addString(env, serializer.get(), config);
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- }
-}
-
-static 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;
- }
- jobject jArg = env->GetObjectArrayElement(jargs, index);
-
- jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
- jint jTypeInt = env->GetIntField(jArg, jTypeId);
- jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
- if (jTypeInt == 3) {
- ret = (jstring) jDataObj;
- }
- // env->DeleteLocalRef(jDataObj);
- env->DeleteLocalRef(jArg);
- return ret;
-}
-
-jint
-WeexProxy::createInstanceContext(JNIEnv *env, jobject jcaller, jstring jinstanceid, jstring name,
- jstring jfunction, jobjectArray jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- if (jfunction == NULL || jinstanceid == NULL) {
- LOGE("native_createInstanceContext function is NULL");
- return false;
- }
-
- int length = 0;
- if (jargs != NULL) {
- length = env->GetArrayLength(jargs);
- }
- if (length < 4) {
- LOGE("native_createInstanceContext jargs format error");
- return false;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::CREATEINSTANCE));
- addString(env, serializer.get(), jinstanceid);
- addString(env, serializer.get(), jfunction);
-
- // get temp data, such as js bundle
- jobject jArg = env->GetObjectArrayElement(jargs,1);
- jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
- jstring jscript = (jstring) jDataObj;
- addString(env, serializer.get(), jscript);
- jstring opts = getJsonData(env, jargs, 2);
- addJSONString(env, serializer.get(), opts);
- // init jsonData
- jstring initData = getJsonData(env, jargs, 3);
- addJSONString(env, serializer.get(), initData);
-
- // get extend api data, such as rax-api
- jArg = env->GetObjectArrayElement(jargs, 4);
- jDataObj = env->GetObjectField(jArg, jDataId);
- jstring japi = (jstring) jDataObj;
- addString(env, serializer.get(), japi);
-
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- env->DeleteLocalRef(jArg);
- env->DeleteLocalRef(jDataObj);
- env->DeleteLocalRef(opts);
- if (result->getType() != IPCType::INT32) {
- LOGE("createInstanceContext Unexpected result type");
- return false;
- }
- return result->get<jint>();
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-jint WeexProxy::destoryInstance(JNIEnv *env, jobject jcaller, jstring jinstanceid, jstring jnamespace,
- jstring jfunction, jobjectArray jargs) {
- int ret = execJS(env, nullptr, jinstanceid, jnamespace, jfunction, jargs);
- if (jfunction == NULL || jinstanceid == NULL) {
- LOGE("native_destoryInstance function is NULL");
- return false;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::DESTORYINSTANCE));
- addString(env, serializer.get(), jinstanceid);
-
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::INT32) {
- LOGE("destoryInstance Unexpected result type");
- return false;
- }
- return result->get<jint>();
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-jstring
-WeexProxy::execJSOnInstance(JNIEnv *env, jobject jcaller, jstring instanceId, jstring script,
- jint type) {
- if (instanceId == NULL || script == NULL) {
- return env->NewStringUTF("");
- }
- try {
- // base::debug::TraceScope traceScope("weex", "native_execJSOnInstance");
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSONINSTANCE));
-
- addString(env, serializer.get(), instanceId);
- addString(env, serializer.get(), script);
-
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::BYTEARRAY) {
- // LOGE("native_execJSOnInstance return type error");
- return env->NewStringUTF("");
- }
- return env->NewStringUTF(result->getByteArrayContent());
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(instanceId);
- return env->NewStringUTF("");
- }
-}
-
-jint WeexProxy::initAppFramework(JNIEnv* env,
- jobject jcaller,
- jstring jinstanceid,
- jstring jframwork,
- jobjectArray jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- if (jframwork == NULL && jargs == NULL) {
- LOGE("native_initAppFramework jframwork is NULL");
- return false;
- }
- int length = 0;
- if (jargs != NULL) {
- length = env->GetArrayLength(jargs);
- }
- try {
-
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::INITAPPFRAMEWORK));
- addString(env, serializer.get(), jinstanceid);
- addString(env, serializer.get(), jframwork);
- for (int i = 0; i < length; i++) {
- jobject jArg = env->GetObjectArrayElement(jargs, i);
-
- jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
- jint jTypeInt = env->GetIntField(jArg, jTypeId);
-
- jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
-
- jfieldID jKeyId = env->GetFieldID(jWXJSObject, "key", "Ljava/lang/String;");
- jobject jKeyObj = env->GetObjectField(jArg, jKeyId);
- addString(env, serializer.get(), (jstring) jKeyObj);
-
- if (jTypeInt == 1) {
- if (jDoubleValueMethodId == NULL) {
- jclass jDoubleClazz = env->FindClass("java/lang/Double");
- jDoubleValueMethodId = env->GetMethodID(jDoubleClazz, "doubleValue", "()D");
- env->DeleteLocalRef(jDoubleClazz);
- }
- jdouble jDoubleObj = env->CallDoubleMethod(jDataObj, jDoubleValueMethodId);
- serializer->add(jDoubleObj);
- } else if (jTypeInt == 2) {
- jstring jDataStr = (jstring)jDataObj;
- addString(env, serializer.get(), jDataStr);
- } else if (jTypeInt == 3) {
- jstring jDataStr = (jstring)jDataObj;
- addJSONString(env, serializer.get(), jDataStr);
- }
+
+ jint WeexProxy::initAppFramework(JNIEnv *env,
+ jobject jcaller,
+ jstring jinstanceid,
+ jstring jframwork,
+ jobjectArray jargs) {
+ if (!sSender && js_server_api_functions == nullptr) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+ if (jframwork == NULL && jargs == NULL) {
+ LOGE("native_initAppFramework jframwork is NULL");
+ return false;
+ }
+ int length = 0;
+ if (jargs != NULL) {
+ length = env->GetArrayLength(jargs);
+ }
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ std::vector<INIT_FRAMEWORK_PARAMS *> params;
+ if (js_server_api_functions == nullptr) {
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::INITAPPFRAMEWORK));
+ addString(env, serializer.get(), jinstanceid);
+ addString(env, serializer.get(), jframwork);
+ }
+
+
+ for (int i = 0; i < length; i++) {
+ jobject jArg = env->GetObjectArrayElement(jargs, i);
+
+ jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
+ jint jTypeInt = env->GetIntField(jArg, jTypeId);
+
+ jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
+ jobject jDataObj = env->GetObjectField(jArg, jDataId);
+
+ jfieldID jKeyId = env->GetFieldID(jWXJSObject, "key", "Ljava/lang/String;");
+ jobject jKeyObj = env->GetObjectField(jArg, jKeyId);
+ jstring jKeyStr = (jstring) jKeyObj;
+ if (js_server_api_functions == nullptr) {
+
+ addByteArrayString(env, serializer.get(), jKeyStr);
+ }
+
+ if (jTypeInt == 1) {
+ if (jDoubleValueMethodId == NULL) {
+ jclass jDoubleClazz = env->FindClass("java/lang/Double");
+ jDoubleValueMethodId = env->GetMethodID(jDoubleClazz, "doubleValue", "()D");
+ env->DeleteLocalRef(jDoubleClazz);
+ }
+ jdouble jDoubleObj = env->CallDoubleMethod(jDataObj, jDoubleValueMethodId);
+
+ serializer->add(jDoubleObj);
+
+ } else if (jTypeInt == 2) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions == nullptr) {
+ addByteArrayString(env, serializer.get(), jDataStr);
+ } else {
+ params.push_back(genInitFrameworkParams(env->GetStringUTFChars(jKeyStr,
+ nullptr),
+ env->GetStringUTFChars(jDataStr,
+ nullptr)));
+ }
+ } else if (jTypeInt == 3) {
+ jstring jDataStr = (jstring) jDataObj;
+ if (js_server_api_functions == nullptr) {
+ addByteArrayString(env, serializer.get(), jDataStr);
+ } else {
+ params.push_back(genInitFrameworkParams(env->GetStringUTFChars(jKeyStr,
+ nullptr),
+ env->GetStringUTFChars(jDataStr,
+ nullptr)));
+ }
+ }
// else if (jTypeInt == 4) {
// jbyteArray array = (jbyteArray)jDataObj;
// addWSONByteArray(env, serializer.get(), array);
// }
- else {
- serializer->addJSUndefined();
- }
-
- env->DeleteLocalRef(jKeyObj);
- env->DeleteLocalRef(jDataObj);
- env->DeleteLocalRef(jArg);
- }
-
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- return result->get<jint>();
- } catch (IPCException& e) {
- LOGE("initAppFramework error %s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-jint WeexProxy::destoryAppContext(JNIEnv* env,
- jobject jcaller,
- jstring jinstanceid) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- if (jinstanceid == NULL) {
- LOGE("createAppContext jbundle is NULL");
- return false;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::DESTORYAPPCONTEXT));
- addString(env, serializer.get(), jinstanceid);
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- return true;
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-jint WeexProxy::createAppContext(JNIEnv* env,
- jobject jcaller,
- jstring jinstanceid,
- jstring jbundle,
- jobject jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- if (jinstanceid == NULL || jbundle == NULL) {
- LOGE("createAppContext jbundle is NULL");
- return false;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::CREATEAPPCONTEXT));
- addString(env, serializer.get(), jinstanceid);
- addString(env, serializer.get(), jbundle);
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- return result->get<jint>();
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return false;
- }
- return true;
-}
-
-jbyteArray WeexProxy::execJsOnAppWithResult(JNIEnv* env,
- jobject jcaller,
- jstring jinstanceid,
- jstring jbundle,
- jobject jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return NULL;
- }
- if (jinstanceid == NULL || jbundle == NULL) {
- LOGE("native_execJsOnApp jbundle is NULL");
- return NULL;
- }
- try {
- std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::EXECJSONAPPWITHRESULT));
- addString(env, serializer.get(), jinstanceid);
- addString(env, serializer.get(), jbundle);
- std::unique_ptr<IPCBuffer> buffer = serializer->finish();
- std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
- if (result->getType() != IPCType::BYTEARRAY) {
- return NULL;
- }
- if(result->getByteArrayLength() == 0){
- return NULL;
- }
- jbyteArray array = env->NewByteArray(result->getByteArrayLength());
- env->SetByteArrayRegion(array, 0, result->getByteArrayLength(),
- reinterpret_cast<const jbyte*>(result->getByteArrayContent()));
- return array;
- } catch (IPCException& e) {
- LOGE("%s", e.msg());
- // report crash here
- reportServerCrash(jinstanceid);
- return NULL;
- }
- return NULL;
-}
-
-jint WeexProxy::execJsOnApp(JNIEnv* env,
- jobject jcaller,
- jstring jinstanceid,
- jstring jfunction,
- jobjectArray jargs) {
- if (!sSender) {
- LOGE("have not connected to a js server");
- return false;
- }
- if (jinstanceid == NULL || jfunction == NULL) {
- LOGE("native_execJsOnApp jbundle is NULL");
- return false;
- }
- int length = 0;
- if (jargs != NULL) {
- length = env->GetArrayLength(jargs);
- }
- try {
- std::unique_ptr <IPCSerializer> serializer(createIPCSerializer());
- serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::CALLJSONAPPCONTEXT));
- addString(env, serializer.get(), jinstanceid);
- addString(env, serializer.get(), jfunction);
-
- for (int i = 0; i < length; i++) {
- jobject jArg = env->GetObjectArrayElement(jargs, i);
-
- jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
- jint jTypeInt = env->GetIntField(jArg, jTypeId);
-
- jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
- jobject jDataObj = env->GetObjectField(jArg, jDataId);
- if (jTypeInt == 1) {
- if (jDoubleValueMethodId == NULL) {
- jclass jDoubleClazz = env->FindClass("java/lang/Double");
- jDoubleValueMethodId = env->GetMethodID(jDoubleClazz, "doubleValue", "()D");
- env->DeleteLocalRef(jDoubleClazz);
- }
- jdouble jDoubleObj = env->CallDoubleMethod(jDataObj, jDoubleValueMethodId);
- serializer->add(jDoubleObj);
- } else if (jTypeInt == 2) {
- jstring jDataStr = (jstring)jDataObj;
- addString(env, serializer.get(), jDataStr);
- } else if (jTypeInt == 3) {
- jstring jDataStr = (jstring)jDataObj;
- addJSONString(env, serializer.get(), jDataStr);
- }
+ else {
+ serializer->addJSUndefined();
+ }
+
+ env->DeleteLocalRef(jKeyObj);
+ env->DeleteLocalRef(jDataObj);
+ env->DeleteLocalRef(jArg);
+ }
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 idChar(env, jinstanceid);
+ ScopedJStringUTF8 frameworkChar(env, jframwork);
+ return js_server_api_functions->funcInitAppFramework(
+ idChar.getChars(),
+ frameworkChar.getChars(),
+ params);
+ } else {
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ return result->get<jint>();
+ }
+
+ } catch (IPCException &e) {
+ LOGE("initAppFramework error %s", e.msg());
+ // report crash here
+ reportServerCrash(jinstanceid);
+ return false;
+ }
+ return true;
+ }
+
+ jint WeexProxy::destoryAppContext(JNIEnv *env,
+ jobject jcaller,
+ jstring jinstanceid) {
+ if (!sSender && js_server_api_functions == nullptr) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+ if (jinstanceid == NULL) {
+ LOGE("createAppContext jbundle is NULL");
+ return false;
+ }
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 scopedJStringUTF8(env, jinstanceid);
+ js_server_api_functions->funcDestroyAppContext(scopedJStringUTF8.getChars());
+ return true;
+ } else {
+ try {
+ std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
+ serializer->setMsg(static_cast<uint32_t>(IPCJSMsg::DESTORYAPPCONTEXT));
+ addString(env, serializer.get(), jinstanceid);
+ std::unique_ptr<IPCBuffer> buffer = serializer->finish();
+ std::unique_ptr<IPCResult> result = sSender->send(buffer.get());
+ return true;
+ } catch (IPCException &e) {
+ LOGE("%s", e.msg());
+ // report crash here
+ reportServerCrash(jinstanceid);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ jint WeexProxy::createAppContext(JNIEnv *env,
+ jobject jcaller,
+ jstring jinstanceid,
+ jstring jbundle,
+ jobject jargs) {
+ if (!sSender && js_server_api_functions == nullptr) {
+ LOGE("have not connected to a js server");
+ return false;
+ }
+ if (jinstanceid == NULL || jbundle == NULL) {
+ LOGE("createAppContext jbundle is NULL");
+ return false;
+ }
+
+ if (js_server_api_functions != nullptr) {
+ ScopedJStringUTF8 instanceIdChar(env, jinstanceid);
+
<TRUNCATED>