http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/string/string_utils.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/base/string/string_utils.h b/weex_core/Source/android/base/string/string_utils.h new file mode 100644 index 0000000..3bd18dd --- /dev/null +++ b/weex_core/Source/android/base/string/string_utils.h @@ -0,0 +1,132 @@ +#ifndef _STRING_UTILS_H_ +#define _STRING_UTILS_H_ + +#include <jni.h> +#include <IPC/IPCArguments.h> +#include <IPC/Serializing/IPCSerializer.h> +#include <IPC/IPCString.h> +#include <IPC/IPCByteArray.h> +#include <malloc.h> +#include "scoped_jstring.h" +#include <iostream> +#include <sstream> +#include <string> + +namespace WeexCore { + +static inline std::string jString2Str(JNIEnv *env, const jstring &jstr) { + char *rtn = NULL; + jclass clsstring = env->FindClass("java/lang/String"); + jstring strencode = env->NewStringUTF("GB2312"); + jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); + jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode); + jsize alen = env->GetArrayLength(barr); + jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE); + if (alen > 0) { + rtn = (char *) malloc(alen + 1); + memcpy(rtn, ba, alen); + rtn[alen] = 0; + } + env->ReleaseByteArrayElements(barr, ba, 0); + + env->DeleteLocalRef(clsstring); + env->DeleteLocalRef(strencode); + env->DeleteLocalRef(barr); + + std::string stemp(rtn); + free(rtn); + return stemp; +} + +static inline std::string jString2StrFast(JNIEnv *env, const jstring &jstr){ + const char *nativeString = env->GetStringUTFChars(jstr, JNI_FALSE); + return std::string(nativeString); +} + +static std::string jByteArray2Str(JNIEnv *env, jbyteArray barr) { + char *rtn = NULL; + jsize alen = env->GetArrayLength(barr); + jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE); + if (alen > 0) { + rtn = (char *) malloc(alen + 1); + memcpy(rtn, ba, alen); + rtn[alen] = 0; + } else { + return ""; + } + env->ReleaseByteArrayElements(barr, ba, 0); + + std::string stemp(rtn); + free(rtn); + return stemp; +} + +static inline jbyteArray newJByteArray(JNIEnv *env, const char* pat) { + jbyteArray jarray = nullptr; + if (pat == nullptr) + return jarray; + int byteSize = strlen(pat); + jbyte *jb = (jbyte*) pat; + jarray = env->NewByteArray(byteSize); + env->SetByteArrayRegion(jarray, 0, byteSize, jb); + return jarray; +} + +static inline jstring newJString(JNIEnv* env, const char* pat) { + jstring jstr = nullptr; + if (pat == nullptr) + return jstr; + return env->NewStringUTF(pat); +} + +static inline char* getArumentAsCStr(IPCArguments *arguments, int argument) { + char* ret = nullptr; + + if (argument >= arguments->getCount()) + return nullptr; + if (arguments->getType(argument) == IPCType::BYTEARRAY) { + const IPCByteArray *ipcBA = arguments->getByteArray(argument); + int strLen = ipcBA->length; + ret = new char[strLen+1]; + for (int i = 0; i < strLen; ++i) { + ret[i] = ipcBA->content[i]; + } + ret[strLen] = '\0'; + } + + return ret; +} + +static inline jstring getArgumentAsJString(JNIEnv *env, IPCArguments *arguments, int argument) { + jstring ret = nullptr; + if (arguments->getType(argument) == IPCType::STRING) { + const IPCString *s = arguments->getString(argument); + ret = env->NewString(s->content, s->length); + } + return ret; +} + +static inline int getArgumentAsInt32(JNIEnv* env, IPCArguments* arguments, int argument) { + int ret = 0; + if (arguments->getType(argument) == IPCType::INT32) { + const int32_t type = arguments->get<int32_t>(argument); + ret = type; + } + return ret; +} + +static inline void addString(JNIEnv *env, IPCSerializer *serializer, jstring str) { + ScopedJString scopedString(env, str); + const uint16_t *chars = scopedString.getChars(); + size_t charsLength = scopedString.getCharsLength(); + serializer->add(chars, charsLength); +} + +static inline void addJSONString(JNIEnv *env, IPCSerializer *serializer, jstring str) { + ScopedJString scopedString(env, str); + const uint16_t *chars = scopedString.getChars(); + size_t charsLength = scopedString.getCharsLength(); + serializer->addJSON(chars, charsLength); +} +} +#endif //_STRING_UTILS_H_
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp new file mode 100644 index 0000000..99da625 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.cpp @@ -0,0 +1,875 @@ +#include <core/render/manager/render_manager.h> +#include <core/render/page/render_page.h> +#include <core/render/node/render_object.h> +#include <base/TimeUtils.h> +#include <android/base/string/string_utils.h> +#include "bridge_impl_android.h" +#include <core/layout/style.h> +#include <map> + +static jmethodID jSetJSFrmVersionMethodId; +static jmethodID jReportExceptionMethodId; +static jmethodID jCallNativeMethodId; +static jmethodID jCallNativeModuleMethodId; +static jmethodID jCallNativeComponentMethodId; + +static jmethodID jSetTimeoutNativeMethodId; +static jmethodID jLogMethodId; +static jmethodID jCallUpdateFinishMethodId; + +static jmethodID jCallRefreshFinishMethodId; +static jmethodID jCallRemoveElementMethodId; +static jmethodID jCallMoveElementMethodId; +static jmethodID jCallAddEventMethodId; +static jmethodID jCallRemoveEventMethodId; + +static jmethodID jMapConstructorMethodId; +static jmethodID jMapPutMethodId; +static jmethodID jSetConstructorMethodId; +static jmethodID jSetAddMethodId; + +static jmethodID jCallCreateBodyMethodId; +static jmethodID jCallAddElementMethodId; +static jmethodID jCallUpdateStyleMethodId; +static jmethodID jCallHasTransitionProsMethodId; +static jmethodID jCallUpdateAttrsMethodId; +static jmethodID jCallLayoutMethodId; +static jmethodID jCallCreateFinishMethodId; + +namespace WeexCore { + + Bridge_Impl_Android *Bridge_Impl_Android::m_instance = nullptr; + + Bridge_Impl_Android::Bridge_Impl_Android() {} + + Bridge_Impl_Android::~Bridge_Impl_Android() {} + + void Bridge_Impl_Android::setGlobalRef(jobject &jRef) { + jThis = jRef; + jSetJSFrmVersionMethodId = NULL; + jReportExceptionMethodId = NULL; + jCallNativeMethodId = NULL; + jCallNativeModuleMethodId = NULL; + jCallNativeComponentMethodId = NULL; + + jSetTimeoutNativeMethodId = NULL; + jLogMethodId = NULL; + jCallUpdateFinishMethodId = NULL; + + jCallRefreshFinishMethodId = NULL; + jCallRemoveElementMethodId = NULL; + jCallMoveElementMethodId = NULL; + jCallAddEventMethodId = NULL; + jCallRemoveEventMethodId = NULL; + + jMapConstructorMethodId = NULL; + jMapPutMethodId = NULL; + jSetConstructorMethodId = NULL; + jSetAddMethodId = NULL; + + jCallCreateBodyMethodId = NULL; + jCallAddElementMethodId = NULL; + jCallUpdateStyleMethodId = NULL; + jCallHasTransitionProsMethodId = NULL; + jCallUpdateAttrsMethodId = NULL; + jCallLayoutMethodId = NULL; + jCallCreateFinishMethodId = NULL; + } + + void static cpyCMap2JMap(std::map<std::string, std::string> *cMap, jobject &jMap, JNIEnv *env) { + std::map<std::string, std::string>::const_iterator it = cMap->begin(); + std::map<std::string, std::string>::const_iterator end = cMap->end(); + jstring jKey; + jstring jValue; + + for (; it != end; ++it) { + jKey = getStyleKeyFromCache(it->first.c_str()); + if (jKey == nullptr) { + jKey = putStyleKeyToCache(it->first.c_str()); + } + + jValue = env->NewStringUTF(it->second.c_str()); + env->CallObjectMethod(jMap, jMapPutMethodId, jKey, jValue); + env->DeleteLocalRef(jValue); + } + } + + void static cpyCVector2JMap(std::vector<std::pair<std::string, std::string>> *cVector, jobject &jMap, JNIEnv *env) { + jstring jKey; + jstring jValue; + + for (int i = 0; i < cVector->size(); ++i) { + jKey = env->NewStringUTF((*cVector)[i].first.c_str()); + jValue = env->NewStringUTF((*cVector)[i].second.c_str()); + env->CallObjectMethod(jMap, jMapPutMethodId, jKey, jValue); + env->DeleteLocalRef(jKey); + env->DeleteLocalRef(jValue); + } + } + + void static cpyCSet2JSet(std::set<std::string> *cSet, jobject &jSet, JNIEnv *env) { + jstring jValue; + std::set<std::string>::const_iterator it = cSet->begin(); + std::set<std::string>::const_iterator end = cSet->end(); + + for (; it != end; ++it) { + jValue = env->NewStringUTF((*it).c_str()); + env->CallBooleanMethod(jSet, jSetAddMethodId, jValue); + env->DeleteLocalRef(jValue); + } + } + + void Bridge_Impl_Android::setJSVersion(const char* version) { + JNIEnv *env = getJNIEnv(); + jstring jVersion = env->NewStringUTF(version); + + if (jSetJSFrmVersionMethodId == NULL) { + jSetJSFrmVersionMethodId = env->GetMethodID(jBridgeClazz, + "setJSFrmVersion", + "(Ljava/lang/String;)V"); + } + env->CallVoidMethod(jThis, jSetJSFrmVersionMethodId, jVersion); + + if (jVersion != nullptr) + env->DeleteLocalRef(jVersion); + } + + void Bridge_Impl_Android::reportException(const char* pageId, const char *func, const char *exception_string) { + JNIEnv *env = getJNIEnv(); + jstring jFunc = env->NewStringUTF(func); + jstring jExceptionString = env->NewStringUTF(exception_string); + jstring jPageId = env->NewStringUTF(pageId); + + if (jReportExceptionMethodId == NULL) { + jReportExceptionMethodId = env->GetMethodID(jBridgeClazz, + "reportJSException", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + } + env->CallVoidMethod(jThis, jReportExceptionMethodId, jPageId, jFunc, jExceptionString); + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jFunc != nullptr) + env->DeleteLocalRef(jFunc); + if (jExceptionString != nullptr) + env->DeleteLocalRef(jExceptionString); + } + + int Bridge_Impl_Android::callNative(const char* pageId, const char *task, const char *callback) { + JNIEnv *env = getJNIEnv(); + jbyteArray jTask = newJByteArray(env, task); + jstring jCallback = env->NewStringUTF(callback); + jstring jPageId = env->NewStringUTF(pageId); + + int flag = -1; + + if (jTask != nullptr) { + if (jCallNativeMethodId == NULL) { + jCallNativeMethodId = env->GetMethodID(jBridgeClazz, + "callNative", + "(Ljava/lang/String;[BLjava/lang/String;)I"); + } + + flag = env->CallIntMethod(jThis, jCallNativeMethodId, jPageId, jTask, jCallback); + } + + if (flag == -1) { + LOGE("instance destroy JFM must stop callNative"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jTask != nullptr) + env->DeleteLocalRef(jTask); + if (jCallback != nullptr) + env->DeleteLocalRef(jCallback); + return flag; + } + + jobject Bridge_Impl_Android::callNativeModule(const char* pageId, const char *module, const char *method, + const char *argString, const char *optString) { + JNIEnv *env = getJNIEnv(); + jstring jModule = env->NewStringUTF(module); + jstring jMethod = env->NewStringUTF(method); + jbyteArray jArgString = newJByteArray(env, argString); + jbyteArray jOptString = newJByteArray(env, optString); + jstring jPageId = env->NewStringUTF(pageId); + + jobject result = nullptr; + + if (jModule != nullptr && jMethod != nullptr) { + if (jCallNativeModuleMethodId == NULL) { + jCallNativeModuleMethodId = env->GetMethodID(jBridgeClazz, + "callNativeModule", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B[B)Ljava/lang/Object;"); + } + + result = env->CallObjectMethod(jThis, jCallNativeModuleMethodId, jPageId, jModule, jMethod, jArgString, jOptString); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jModule != nullptr) + env->DeleteLocalRef(jModule); + if (jMethod != nullptr) + env->DeleteLocalRef(jMethod); + if (jArgString != nullptr) + env->DeleteLocalRef(jArgString); + if (jOptString != nullptr) + env->DeleteLocalRef(jOptString); + return result; + } + + void Bridge_Impl_Android::callNativeComponent(const char* pageId, const char* ref, + const char *method, const char *argString, + const char *optString) { + JNIEnv *env = getJNIEnv(); + jstring jMethod = env->NewStringUTF(method); + jbyteArray jArgString = newJByteArray(env, argString); + jbyteArray jOptString = newJByteArray(env, optString); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + if (jMethod != nullptr) { + if (jCallNativeComponentMethodId == NULL) { + jCallNativeComponentMethodId = env->GetMethodID(jBridgeClazz, + "callNativeComponent", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B[B)V"); + } + env->CallVoidMethod(jThis, jCallNativeComponentMethodId, jPageId, jRef, jMethod, jArgString, jOptString); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + if (jMethod != nullptr) + env->DeleteLocalRef(jMethod); + if (jArgString != nullptr) + env->DeleteLocalRef(jArgString); + if (jOptString != nullptr) + env->DeleteLocalRef(jOptString); + } + + void Bridge_Impl_Android::setTimeout(const char* callbackID, const char* time) { + JNIEnv *env = getJNIEnv(); + jstring jCallbackID = env->NewStringUTF(callbackID); + jstring jTime = env->NewStringUTF(time); + + if (jCallbackID == nullptr || jTime == nullptr) + return; + + if (jSetTimeoutNativeMethodId == NULL) { + jSetTimeoutNativeMethodId = env->GetMethodID(jBridgeClazz, + "setTimeoutNative", + "(Ljava/lang/String;Ljava/lang/String;)V"); + } + + env->CallVoidMethod(jThis, jSetTimeoutNativeMethodId, jCallbackID, jTime); + + if (jCallbackID != nullptr) + env->DeleteLocalRef(jCallbackID); + if (jTime != nullptr) + env->DeleteLocalRef(jTime); + } + + void Bridge_Impl_Android::callNativeLog(const char* str_array) { + JNIEnv *env = getJNIEnv(); + if (jWXLogUtils != NULL) { + if (jLogMethodId == NULL) { + jLogMethodId = env->GetStaticMethodID(jWXLogUtils, "d", + "(Ljava/lang/String;[B)V"); + } + if (jLogMethodId != NULL) { + jstring str_tag = env->NewStringUTF("jsLog"); + jbyteArray str_msg = newJByteArray(env, str_array); + env->CallStaticVoidMethod(jWXLogUtils, jLogMethodId, str_tag, str_msg); + env->DeleteLocalRef(str_tag); + env->DeleteLocalRef(str_msg); + } + } + } + + int Bridge_Impl_Android::callUpdateFinish(const char* pageId, const char *task, const char *callback) { + JNIEnv *env = getJNIEnv(); + jbyteArray jTask = newJByteArray(env, task); + jstring jCallback = env->NewStringUTF(callback); + jstring jPageId = env->NewStringUTF(pageId); + + if (jCallUpdateFinishMethodId == NULL) { + jCallUpdateFinishMethodId = env->GetMethodID(jBridgeClazz, + "callUpdateFinish", + "(Ljava/lang/String;[BLjava/lang/String;)I"); + } + + int flag = env->CallIntMethod(jThis, jCallUpdateFinishMethodId, jPageId, jTask, jCallback); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callUpdateFinish"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jTask != nullptr) + env->DeleteLocalRef(jTask); + if (jCallback != nullptr) + env->DeleteLocalRef(jCallback); + return flag; + } + + int Bridge_Impl_Android::callRefreshFinish(const char* pageId, const char *task, const char *callback) { + JNIEnv *env = getJNIEnv(); + jbyteArray jTask = newJByteArray(env, task); + jstring jCallback = env->NewStringUTF(callback); + jstring jPageId = env->NewStringUTF(pageId); + + if (jCallRefreshFinishMethodId == NULL) { + jCallRefreshFinishMethodId = env->GetMethodID(jBridgeClazz, + "callRefreshFinish", + "(Ljava/lang/String;[BLjava/lang/String;)I"); + } + int flag = env->CallIntMethod(jThis, jCallRefreshFinishMethodId, jPageId, jTask, jCallback); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callNative"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jTask != nullptr) + env->DeleteLocalRef(jTask); + if (jCallback != nullptr) + env->DeleteLocalRef(jCallback); + return flag; + } + + int Bridge_Impl_Android::callCreateBody(const char* pageId, const char *componentType, const char* ref, + std::map<std::string, std::string> *styles, + std::map<std::string, std::string> *attributes, + std::set<std::string> *events, + const WXCoreMargin &margins, + const WXCorePadding &paddings, + const WXCoreBorderWidth &borders) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTime = getCurrentTime(); + + if (jMapConstructorMethodId == NULL) + jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V"); + if (jMapPutMethodId == NULL) + jMapPutMethodId = env->GetMethodID(jMapClazz, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + if (jSetConstructorMethodId == NULL) + jSetConstructorMethodId = env->GetMethodID(jSetClazz, "<init>", "()V"); + if (jSetAddMethodId == NULL) + jSetAddMethodId = env->GetMethodID(jSetClazz, "add", + "(Ljava/lang/Object;)Z"); + + jobject jStyles = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jAttributes = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jEvents = env->NewObject(jSetClazz, jSetConstructorMethodId); + + cpyCMap2JMap(styles, jStyles, env); + cpyCMap2JMap(attributes, jAttributes, env); + cpyCSet2JSet(events, jEvents, env); + + page->CreateJMapJNITime(getCurrentTime() - startTime); + + float c_margins[4]; + float c_paddings[4]; + float c_borders[4]; + jfloatArray jMargins = env->NewFloatArray(4); + jfloatArray jPaddings = env->NewFloatArray(4); + jfloatArray jBorders = env->NewFloatArray(4); + + c_margins[0] = margins.getMargin(kMarginTop); + c_margins[1] = margins.getMargin(kMarginBottom); + c_margins[2] = margins.getMargin(kMarginLeft); + c_margins[3] = margins.getMargin(kMarginRight); + env->SetFloatArrayRegion(jMargins, 0, 4, c_margins); + + c_paddings[0] = paddings.getPadding(kPaddingTop); + c_paddings[1] = paddings.getPadding(kPaddingBottom); + c_paddings[2] = paddings.getPadding(kPaddingLeft); + c_paddings[3] = paddings.getPadding(kPaddingRight); + env->SetFloatArrayRegion(jPaddings, 0, 4, c_paddings); + + c_borders[0] = borders.getBorderWidth(kBorderWidthTop); + c_borders[1] = borders.getBorderWidth(kBorderWidthBottom); + c_borders[2] = borders.getBorderWidth(kBorderWidthLeft); + c_borders[3] = borders.getBorderWidth(kBorderWidthRight); + env->SetFloatArrayRegion(jBorders, 0, 4, c_borders); + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallCreateBodyMethodId == NULL) + jCallCreateBodyMethodId = env->GetMethodID(jBridgeClazz, + "callCreateBody", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashSet;[F[F[F)I"); + + + jstring jComponentType = getComponentTypeFromCache(componentType); + if (jComponentType == nullptr) { + jComponentType = putComponentTypeToCache(componentType); + } + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallCreateBodyMethodId, jPageId, + jComponentType, jRef, jStyles, jAttributes, + jEvents, jMargins, jPaddings, jBorders); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callCreateBody"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jStyles); + env->DeleteLocalRef(jAttributes); + env->DeleteLocalRef(jEvents); + env->DeleteLocalRef(jMargins); + env->DeleteLocalRef(jPaddings); + env->DeleteLocalRef(jBorders); + return flag; + } + + int Bridge_Impl_Android::callAddElement(const char* pageId, const char *componentType, + const char* ref, int &index, const char* parentRef, + std::map<std::string, std::string> *styles, + std::map<std::string, std::string> *attributes, + std::set<std::string> *events, + const WXCoreMargin &margins, + const WXCorePadding &paddings, + const WXCoreBorderWidth &borders) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + jstring jParentRef = env->NewStringUTF(parentRef); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTime = getCurrentTime(); + + if (jMapConstructorMethodId == NULL) + jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V"); + if (jMapPutMethodId == NULL) + jMapPutMethodId = env->GetMethodID(jMapClazz, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + if (jSetConstructorMethodId == NULL) + jSetConstructorMethodId = env->GetMethodID(jSetClazz, "<init>", "()V"); + if (jSetAddMethodId == NULL) + jSetAddMethodId = env->GetMethodID(jSetClazz, "add", + "(Ljava/lang/Object;)Z"); + + jobject jStyles = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jAttributes = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jEvents = env->NewObject(jSetClazz, jSetConstructorMethodId); + + cpyCMap2JMap(styles, jStyles, env); + cpyCMap2JMap(attributes, jAttributes, env); + cpyCSet2JSet(events, jEvents, env); + + page->CreateJMapJNITime(getCurrentTime() - startTime); + + float c_margins[4]; + float c_paddings[4]; + float c_borders[4]; + jfloatArray jMargins = env->NewFloatArray(4); + jfloatArray jPaddings = env->NewFloatArray(4); + jfloatArray jBorders = env->NewFloatArray(4); + + c_margins[0] = margins.getMargin(kMarginTop); + c_margins[1] = margins.getMargin(kMarginBottom); + c_margins[2] = margins.getMargin(kMarginLeft); + c_margins[3] = margins.getMargin(kMarginRight); + env->SetFloatArrayRegion(jMargins, 0, 4, c_margins); + + c_paddings[0] = paddings.getPadding(kPaddingTop); + c_paddings[1] = paddings.getPadding(kPaddingBottom); + c_paddings[2] = paddings.getPadding(kPaddingLeft); + c_paddings[3] = paddings.getPadding(kPaddingRight); + env->SetFloatArrayRegion(jPaddings, 0, 4, c_paddings); + + c_borders[0] = borders.getBorderWidth(kBorderWidthTop); + c_borders[1] = borders.getBorderWidth(kBorderWidthBottom); + c_borders[2] = borders.getBorderWidth(kBorderWidthLeft); + c_borders[3] = borders.getBorderWidth(kBorderWidthRight); + env->SetFloatArrayRegion(jBorders, 0, 4, c_borders); + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallAddElementMethodId == NULL) + jCallAddElementMethodId = env->GetMethodID(jBridgeClazz, + "callAddElement", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashSet;[F[F[F)I"); + + jstring jComponentType = getComponentTypeFromCache(componentType); + if (jComponentType == nullptr) { + jComponentType = putComponentTypeToCache(componentType); + } + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallAddElementMethodId, jPageId, jComponentType, jRef, index, + jParentRef, jStyles, jAttributes, jEvents, jMargins, jPaddings, jBorders); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callAddElement"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + if (jParentRef != nullptr) + env->DeleteLocalRef(jParentRef); + env->DeleteLocalRef(jStyles); + env->DeleteLocalRef(jAttributes); + env->DeleteLocalRef(jEvents); + env->DeleteLocalRef(jMargins); + env->DeleteLocalRef(jPaddings); + env->DeleteLocalRef(jBorders); + return flag; + } + + int Bridge_Impl_Android::callRemoveElement(const char* pageId, const char* ref) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + if (jCallRemoveElementMethodId == NULL) { + jCallRemoveElementMethodId = env->GetMethodID(jBridgeClazz, + "callRemoveElement", + "(Ljava/lang/String;Ljava/lang/String;)I"); + } + + int flag = env->CallIntMethod(jThis, jCallRemoveElementMethodId, jPageId, jRef); + if (flag == -1) { + LOGE("instance destroy JFM must stop callRemoveElement"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + return 0; + } + + int Bridge_Impl_Android::callMoveElement(const char* pageId, const char* ref, const char* parentRef, int index) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + jstring jParentRef = env->NewStringUTF(parentRef); + + if (jCallMoveElementMethodId == NULL) { + jCallMoveElementMethodId = env->GetMethodID(jBridgeClazz, + "callMoveElement", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I"); + } + + int flag = env->CallIntMethod(jThis, jCallMoveElementMethodId, jPageId, jRef, jParentRef, index); + if (flag == -1) { + LOGE("instance destroy JFM must stop callRemoveElement"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + if (jParentRef != nullptr) + env->DeleteLocalRef(jParentRef); + return 0; + } + + int Bridge_Impl_Android::callAddEvent(const char* pageId, const char* ref, const char *event) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + if (jCallAddEventMethodId == NULL) { + jCallAddEventMethodId = env->GetMethodID(jBridgeClazz, + "callAddEvent", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"); + } + jstring jEventId = env->NewStringUTF(event); + + int flag = env->CallIntMethod(jThis, jCallAddEventMethodId, jPageId, jRef, jEventId); + if (flag == -1) { + LOGE("instance destroy JFM must stop callAddEvent"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jEventId); + return flag; + } + + int Bridge_Impl_Android::callRemoveEvent(const char* pageId, const char* ref, const char *event) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + if (jCallRemoveEventMethodId == NULL) { + jCallRemoveEventMethodId = env->GetMethodID(jBridgeClazz, + "callRemoveEvent", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"); + } + jstring jEventId = env->NewStringUTF(event); + + int flag = env->CallIntMethod(jThis, jCallRemoveEventMethodId, jPageId, jRef, jEventId); + if (flag == -1) { + LOGE("instance destroy JFM must stop callRemoveElement"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jEventId); + return flag; + } + + int Bridge_Impl_Android::callUpdateStyle(const char* pageId, const char* ref, + std::vector<std::pair<std::string, std::string>> *style, + std::vector<std::pair<std::string, std::string>> *margin, + std::vector<std::pair<std::string, std::string>> *padding, + std::vector<std::pair<std::string, std::string>> *border) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTime = getCurrentTime(); + + if (jMapConstructorMethodId == NULL) + jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V"); + if (jMapPutMethodId == NULL) + jMapPutMethodId = env->GetMethodID(jMapClazz, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + jobject jStyles = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jMargins = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jPaddings = env->NewObject(jMapClazz, jMapConstructorMethodId); + jobject jBorders = env->NewObject(jMapClazz, jMapConstructorMethodId); + + if (style != nullptr) { + cpyCVector2JMap(style, jStyles, env); + } + + if (margin != nullptr) { + cpyCVector2JMap(margin, jMargins, env); + } + + if (padding != nullptr) { + cpyCVector2JMap(padding, jPaddings, env); + } + + if (border != nullptr) { + cpyCVector2JMap(border, jBorders, env); + } + + page->CreateJMapJNITime(getCurrentTime() - startTime); + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallUpdateStyleMethodId == NULL) + jCallUpdateStyleMethodId = env->GetMethodID(jBridgeClazz, + "callUpdateStyle", + "(Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;Ljava/util/HashMap;)I"); + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallUpdateStyleMethodId, jPageId, jRef, jStyles, jMargins, jPaddings, jBorders); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callUpdateStyle"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jStyles); + env->DeleteLocalRef(jMargins); + env->DeleteLocalRef(jPaddings); + env->DeleteLocalRef(jBorders); + return flag; + } + + int Bridge_Impl_Android::callUpdateAttr(const char* pageId, const char* ref, std::vector<std::pair<std::string, std::string>> *attrs) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTime = getCurrentTime(); + + if (jMapConstructorMethodId == NULL) + jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V"); + if (jMapPutMethodId == NULL) + jMapPutMethodId = env->GetMethodID(jMapClazz, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + jobject jAttrs = env->NewObject(jMapClazz, jMapConstructorMethodId); + + if (attrs != nullptr) { + cpyCVector2JMap(attrs, jAttrs, env); + } + + page->CreateJMapJNITime(getCurrentTime() - startTime); + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallUpdateAttrsMethodId == NULL) { + jCallUpdateAttrsMethodId = env->GetMethodID(jBridgeClazz, + "callUpdateAttrs", + "(Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;)I"); + } + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallUpdateAttrsMethodId, jPageId, jRef, jAttrs); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callUpdateStyle"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jAttrs); + return flag; + } + + int Bridge_Impl_Android::callLayout(const char* pageId, const char* ref, + int top, int bottom, int left, int right, + int height, int width, int index) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallLayoutMethodId == NULL) + jCallLayoutMethodId = env->GetMethodID(jBridgeClazz, + "callLayout", + "(Ljava/lang/String;Ljava/lang/String;IIIIIII)I"); + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallLayoutMethodId, jPageId, + jRef, top, bottom, left, right, height, width, index); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callLayout"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + return flag; + } + + int Bridge_Impl_Android::callCreateFinish(const char* pageId) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallCreateFinishMethodId == NULL) + jCallCreateFinishMethodId = env->GetMethodID(jBridgeClazz, + "callCreateFinish", + "(Ljava/lang/String;)I"); + + int flag = env->CallIntMethod(jThis, jCallCreateFinishMethodId, jPageId); + + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (flag == -1) { + LOGE("instance destroy JFM must stop callCreateFinish"); + } + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + return flag; + } + + int Bridge_Impl_Android::callHasTransitionPros(const char* pageId, const char* ref, std::vector<std::pair<std::string, std::string>> *style) { + JNIEnv *env = getJNIEnv(); + jstring jPageId = env->NewStringUTF(pageId); + jstring jRef = env->NewStringUTF(ref); + + RenderPage *page = RenderManager::GetInstance()->GetPage(pageId); + if (page == nullptr) + return -1; + + long long startTime = getCurrentTime(); + + if (jMapConstructorMethodId == NULL) + jMapConstructorMethodId = env->GetMethodID(jMapClazz, "<init>", "()V"); + if (jMapPutMethodId == NULL) + jMapPutMethodId = env->GetMethodID(jMapClazz, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + jobject jStyles = env->NewObject(jMapClazz, jMapConstructorMethodId); + + if (style != nullptr) { + cpyCVector2JMap(style, jStyles, env); + } + + page->CreateJMapJNITime(getCurrentTime() - startTime); + + long long startTimeCallBridge = getCurrentTime(); + + if (jCallHasTransitionProsMethodId == NULL) + jCallHasTransitionProsMethodId = env->GetMethodID(jBridgeClazz, + "callHasTransitionPros", + "(Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;)I"); + + int flag = 0; + flag = env->CallIntMethod(jThis, jCallHasTransitionProsMethodId, jPageId, jRef, jStyles); + page->CallBridgeTime(getCurrentTime() - startTimeCallBridge); + + if (jPageId != nullptr) + env->DeleteLocalRef(jPageId); + if (jRef != nullptr) + env->DeleteLocalRef(jRef); + env->DeleteLocalRef(jStyles); + return flag; + } + +} //end WeexCore \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/bridge_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/bridge_impl_android.h b/weex_core/Source/android/bridge/impl/bridge_impl_android.h new file mode 100644 index 0000000..c30b08e --- /dev/null +++ b/weex_core/Source/android/bridge/impl/bridge_impl_android.h @@ -0,0 +1,106 @@ +#ifndef BridgeAndroid_h +#define BridgeAndroid_h + +#include <core/bridge/bridge.h> +#include "weexcore_impl_android.h" + +namespace WeexCore { + + class Bridge_Impl_Android : public Bridge { + + private: + jobject jThis; + + public: + static Bridge_Impl_Android *m_instance; + + //just to release singleton object + class Garbo { + public: + ~Garbo() { + if (Bridge_Impl_Android::m_instance) { + delete Bridge_Impl_Android::m_instance; + } + } + }; + + static Garbo garbo; + + Bridge_Impl_Android(); + + ~Bridge_Impl_Android(); + + static Bridge_Impl_Android *getInstance() { + if (m_instance == nullptr) { + m_instance = new Bridge_Impl_Android(); + } + return m_instance; + } + + void setGlobalRef(jobject &jRef); + + void setJSVersion(const char* version); + + void reportException(const char* pageId, const char *func, const char *exception_string); + + int callNative(const char* pageId, const char *task, const char *callback); + + jobject callNativeModule(const char* pageId, const char *module, const char *method, + const char *argString, const char *optString); + + void callNativeComponent(const char* pageId, const char* ref, const char *method, + const char *argString, const char *optString); + + void setTimeout(const char* callbackID, const char* time); + + void callNativeLog(const char* str_array); + + int callUpdateFinish(const char* pageId, const char *task, const char *callback); + + int callRefreshFinish(const char* pageId, const char *task, const char *callback); + + int callAddEvent(const char* pageId, const char* ref, const char *event); + + int callRemoveEvent(const char* pageId, const char* ref, const char *event); + + int callCreateBody(const char* pageId, const char *componentType, const char* ref, + std::map<std::string, std::string> *styles, + std::map<std::string, std::string> *attributes, + std::set<std::string> *events, + const WXCoreMargin &margins, + const WXCorePadding &paddings, + const WXCoreBorderWidth &borders); + + int callAddElement(const char* pageId, const char *componentType, + const char* ref, int &index, const char* parentRef, + std::map<std::string, std::string> *styles, + std::map<std::string, std::string> *attributes, + std::set<std::string> *events, + const WXCoreMargin &margins, + const WXCorePadding &paddings, + const WXCoreBorderWidth &borders); + + int callRemoveElement(const char* pageId, const char* ref); + + int callMoveElement(const char* pageId, const char* ref, const char* parentRef, int index); + + int callLayout(const char* pageId, const char* ref, + int top, int bottom, int left, int right, + int height, int width, int index); + + int callUpdateStyle(const char* pageId, const char* ref, + std::vector<std::pair<std::string, std::string>> *style, + std::vector<std::pair<std::string, std::string>> *margin, + std::vector<std::pair<std::string, std::string>> *padding, + std::vector<std::pair<std::string, std::string>> *border); + + int callUpdateAttr(const char* pageId, const char* ref, + std::vector<std::pair<std::string, std::string>> *attrs); + + int callCreateFinish(const char* pageId); + + int callHasTransitionPros(const char* pageId, const char* ref, + std::vector<std::pair<std::string, std::string>> *style); + }; +} //end WeexCore +#endif //BridgeAndroid_h \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.cpp b/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.cpp new file mode 100644 index 0000000..abfbf74 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.cpp @@ -0,0 +1,36 @@ +#include <android/base/jni/android_jni.h> +#include <android/jniprebuild/jniheader/ContentBoxMeasurement_jni.h> +#include "content_box_measurement_impl_android.h" +#include "measure_mode_impl_android.h" + +namespace WeexCore { + bool RegisterJNIContentBoxMeasurement(JNIEnv *env) { + RegisterNativesImpl(env); + } + + void cumsmeasure_Imple_Android(JNIEnv *env, jobject measureFunc_Impl_Android, + float width, float height, int widthMeasureMode, int heightMeasureMode) { + if (measureFunc_Impl_Android != nullptr) + Java_ContentBoxMeasurement_measure(env, measureFunc_Impl_Android, width, height, widthMeasureMode, heightMeasureMode); + } + + void LayoutBeforeImplAndroid(JNIEnv *env, jobject measureFunc_impl_android) { + if (measureFunc_impl_android != nullptr) + Java_ContentBoxMeasurement_layoutBefore(env, measureFunc_impl_android); + } + + void LayoutAfterImplAndroid(JNIEnv *env, jobject measureFunc_impl_android, float width, float height) { + if (measureFunc_impl_android != nullptr) + Java_ContentBoxMeasurement_layoutAfter(env, measureFunc_impl_android, width, height); + } + + float GetLayoutWidth(JNIEnv *env, jobject measureFunc_impl_android) { + if (measureFunc_impl_android != nullptr) + Java_ContentBoxMeasurement_getWidth(env, measureFunc_impl_android); + } + + float GetLayoutHeight(JNIEnv *env, jobject measureFunc_impl_android) { + if (measureFunc_impl_android != nullptr) + Java_ContentBoxMeasurement_getHeight(env, measureFunc_impl_android); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.h b/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.h new file mode 100644 index 0000000..f66346d --- /dev/null +++ b/weex_core/Source/android/bridge/impl/content_box_measurement_impl_android.h @@ -0,0 +1,23 @@ +#ifndef WEEX_PROJECT_CONTENTBOXMEASUREMENT_IMPL_ANDROID_H +#define WEEX_PROJECT_CONTENTBOXMEASUREMENT_IMPL_ANDROID_H + +#include <jni.h> +#include <android/base/jni/android_jni.h> + +namespace WeexCore { + bool RegisterJNIContentBoxMeasurement(JNIEnv *env); + + void cumsmeasure_Imple_Android(JNIEnv *env, jobject measureFunc_Impl_Android, + float width, float height, + int widthMeasureMode, int heightMeasureMode); + + void LayoutBeforeImplAndroid(JNIEnv *env, jobject measureFunc_impl_android); + + void LayoutAfterImplAndroid(JNIEnv *env, jobject measureFunc_impl_android, float width, float height); + + float GetLayoutWidth(JNIEnv *env, jobject measureFunc_impl_android); + + float GetLayoutHeight(JNIEnv *env, jobject measureFunc_impl_android); +} + +#endif //WEEX_PROJECT_CONTENTBOXMEASUREMENT_IMPL_ANDROID_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/measure_mode_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/measure_mode_impl_android.cpp b/weex_core/Source/android/bridge/impl/measure_mode_impl_android.cpp new file mode 100644 index 0000000..042ffa0 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/measure_mode_impl_android.cpp @@ -0,0 +1,18 @@ +#include <android/base/jni/android_jni.h> +#include "measure_mode_impl_android.h" +#include <android/jniprebuild/jniheader/MeasureMode_jni.h> + +namespace WeexCore { + bool RegisterJNIMeasureMode(JNIEnv *env) { + RegisterNativesImpl(env); + } + + jint Exactly(JNIEnv *env) { + return Java_MeasureMode_getEXACTLY(env); + } + + jint Unspecified(JNIEnv *env) { + return Java_MeasureMode_getUNSPECIFIED(env); + } +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/measure_mode_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/measure_mode_impl_android.h b/weex_core/Source/android/bridge/impl/measure_mode_impl_android.h new file mode 100644 index 0000000..9f5ff1c --- /dev/null +++ b/weex_core/Source/android/bridge/impl/measure_mode_impl_android.h @@ -0,0 +1,15 @@ +#ifndef WEEX_PROJECT_MEASUREMODE_H +#define WEEX_PROJECT_MEASUREMODE_H + +#include <jni.h> + +namespace WeexCore { + bool RegisterJNIMeasureMode(JNIEnv *env); + + jint Exactly(JNIEnv *env); + + jint Unspecified(JNIEnv *env); +} + + +#endif //WEEX_PROJECT_MEASUREMODE_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp new file mode 100644 index 0000000..0306e70 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/weexcore_impl_android.cpp @@ -0,0 +1,443 @@ +#include "weexcore_impl_android.h" +#include <android/jsengine/multiprocess/WeexProxy.h> +#include <android/base/jni/android_jni.h> +#include <android/jniprebuild/jniheader/WXBridge_jni.h> +#include <android/base/string/string_utils.h> +#include <core/render/manager/render_manager.h> +#include <core/render/page/render_page.h> +#include <core/render/node/render_object.h> +#include <core/config/core_environment.h> +#include <map> + +using namespace WeexCore; + +jclass jBridgeClazz; +jclass jWXJSObject; +jclass jWXLogUtils; +jclass jMapClazz; +jclass jSetClazz; +jmethodID jDoubleValueMethodId; +jobject jThis; +std::map<std::string, jobject> componentTypeCache; +std::map<std::string, jobject> styleKeyCache; + +static JavaVM *sVm = NULL; + +JNIEnv *getJNIEnv() { + JNIEnv *env = NULL; + if ((sVm)->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) { + return JNI_FALSE; + } + return env; +} + +jstring getComponentTypeFromCache(const std::string type) { + std::map<std::string, jobject>::const_iterator iter = componentTypeCache.find(type); + if (iter != componentTypeCache.end()) { + return (jstring)(iter->second); + } else { + return nullptr; + } +} + +jstring putComponentTypeToCache(const std::string type) { + JNIEnv *env = getJNIEnv(); + jstring jType = env->NewStringUTF(type.c_str()); + jobject jGlobalType = env->NewGlobalRef(jType); + componentTypeCache.insert(std::pair<std::string, jobject>(type, jGlobalType)); + env->DeleteLocalRef(jType); + return (jstring) jGlobalType; +} + +jstring getStyleKeyFromCache(const std::string key) { + std::map<std::string, jobject>::const_iterator iter = styleKeyCache.find(key); + if (iter != styleKeyCache.end()) { + return (jstring)(iter->second); + } else { + return nullptr; + } +} + +jstring putStyleKeyToCache(const std::string key) { + JNIEnv *env = getJNIEnv(); + jstring jKey = env->NewStringUTF(key.c_str()); + jobject jGlobalKey = env->NewGlobalRef(jKey); + styleKeyCache.insert(std::pair<std::string, jobject>(key, jGlobalKey)); + env->DeleteLocalRef(jKey); + return (jstring) jGlobalKey; +} + +static jint InitFrameworkEnv(JNIEnv *env, jobject jcaller, + jstring framework, + jobject params, + jstring cacheDir, + jboolean pieSupport) { + jThis = env->NewGlobalRef(jcaller); + jclass tempClass = env->FindClass( + "com/taobao/weex/bridge/WXBridge"); + jBridgeClazz = (jclass) env->NewGlobalRef(tempClass); + env->DeleteLocalRef(tempClass); + return WeexProxy::doInitFramework(env, jThis, framework, params, cacheDir, pieSupport); +} + +static void BindMeasurementToWXCore(JNIEnv *env, jobject jcaller, jstring instanceId, jstring ref, jobject contentBoxMeasurement) { + if (contentBoxMeasurement == nullptr) + return; + + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + render->BindMeasureFuncImplAndroid(contentBoxMeasurement); +} + +static void OnInstanceClose(JNIEnv *env, jobject jcaller, jstring instanceId) { + RenderManager::GetInstance()->ClosePage(jString2StrFast(env, instanceId)); +} + +static void SetDefaultHeightAndWidthIntoRootDom(JNIEnv *env, jobject jcaller, + jstring instanceId, jfloat defaultWidth, jfloat defaultHeight, + jboolean isWidthWrapContent, jboolean isHeightWrapContent) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + +#if RENDER_LOG + LOGD("[JNI] SetDefaultHeightAndWidthIntoRootDom >>>> pageId: %s, defaultWidth: %f, defaultHeight: %f", + page->PageId().c_str(), defaultWidth,defaultHeight); +#endif + + page->SetDefaultHeightAndWidthIntoRootRender(defaultWidth, defaultHeight, isWidthWrapContent, isHeightWrapContent); +} + +static void SetRenderContainerWrapContent(JNIEnv* env, jobject jcaller, jboolean wrap, jstring instanceId) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + page->SetRenderContainerWidthWrapContent(wrap); +} + +static jint PrintFirstScreenRenderTime(JNIEnv *env, jobject jcaller, jstring instanceId) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return 0; + + return page->PrintFirstScreenLog(); +} + +static jint PrintRenderFinishTime(JNIEnv *env, jobject jcaller, jstring instanceId) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return 0; + + return page->PrintRenderSuccessLog(); +} + +//Notice that this method is invoked from main thread. +static jboolean NotifyLayout(JNIEnv* env, jobject jcaller, jstring instanceId) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page != nullptr) { + +#if RENDER_LOG + LOGD("[JNI] NotifyLayout >>>> pageId: %s, needForceLayout: %s, dirty: %s", jString2StrFast(env, instanceId).c_str(), + page->needLayout.load() ? "true" : "false", page->isDirty() ? "true" : "false"); +#endif + + if (!page->needLayout.load()) { + page->needLayout.store(true); + } + + bool ret = !page->hasForeLayoutAction.load() && page->isDirty(); + if (ret) { + page->hasForeLayoutAction.store(true); + } + return ret ? JNI_TRUE : JNI_FALSE; + } +} + +//Notice that this method is invoked from JS thread. +static void ForceLayout(JNIEnv *env, jobject jcaller, jstring instanceId) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page != nullptr) { + +#if RENDER_LOG + LOGD("[JNI] ForceLayout >>>> pageId: %s, needForceLayout: %s", jString2StrFast(env, instanceId).c_str(), page->hasForeLayoutAction.load()?"true":"false"); +#endif + + page->LayoutImmediately(); + page->hasForeLayoutAction.store(false); + } +} + +static void SetStyleWidth(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jfloat value) { + + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + render->setStyleWidthLevel(CSS_STYLE); + render->setStyleWidth(value, true); + page->updateDirty(true); +} + +static void SetStyleHeight(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jfloat value) { + + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + render->setStyleHeightLevel(CSS_STYLE); + render->setStyleHeight(value); + page->updateDirty(true); +} + +static void SetMargin(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jint edge, jfloat value) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + if (edge == 0) { + render->setMargin(kMarginTop, value); + } else if (edge == 1) { + render->setMargin(kMarginBottom, value); + } else if (edge == 2) { + render->setMargin(kMarginLeft, value); + } else if (edge == 3) { + render->setMargin(kMarginRight, value); + } else if (edge == 4) { + render->setMargin(kMarginALL, value); + } + page->updateDirty(true); +} + +static void SetPadding(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jint edge, jfloat value) { + + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + if (edge == 0) { + render->setPadding(kPaddingTop, value); + } else if (edge == 1) { + render->setPadding(kPaddingBottom, value); + } else if (edge == 2) { + render->setPadding(kPaddingLeft, value); + } else if (edge == 3) { + render->setPadding(kPaddingRight, value); + } else if (edge == 4) { + render->setPadding(kPaddingALL, value); + } + page->updateDirty(true); +} + + +static void SetPosition(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jint edge, jfloat value) { + + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + + if (edge == 0) { + render->setStylePosition(kPositionEdgeTop, value); + } else if (edge == 1) { + render->setStylePosition(kPositionEdgeBottom, value); + } else if (edge == 2) { + render->setStylePosition(kPositionEdgeLeft, value); + } else if (edge == 3) { + render->setStylePosition(kPositionEdgeRight, value); + } + page->updateDirty(true); +} + +static void MarkDirty(JNIEnv *env, jobject jcaller, + jstring instanceId, jstring ref, jboolean dirty) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + if (dirty) { + + RenderObject *render = page->GetRenderObject(jString2StrFast(env, ref)); + if (render == nullptr) + return; + render->markDirty(); + } +} + +static void RegisterCoreEnv(JNIEnv *env, jobject jcaller, jstring key, jstring value) { + LOGE("RegisterCoreEnvï¼key: %s, value: %s", jString2StrFast(env, key).c_str(), + jString2StrFast(env, value).c_str()); + WXCoreEnvironment::getInstance()->AddOption(jString2StrFast(env, key), jString2StrFast(env, value)); +} + +static void SetViewPortWidth(JNIEnv *env, jobject jcaller, jstring instanceId, jfloat value) { + RenderPage *page = RenderManager::GetInstance()->GetPage(jString2StrFast(env, instanceId)); + if (page == nullptr) + return; + + page->SetViewPortWidth(value); +} + + +static jint InitFramework(JNIEnv *env, jobject object, jstring script, jobject params) { + jThis = env->NewGlobalRef(object); + jclass tempClass = env->FindClass( + "com/taobao/weex/bridge/WXBridge"); + jBridgeClazz = (jclass) env->NewGlobalRef(tempClass); + env->DeleteLocalRef(tempClass); + return WeexProxy::doInitFramework(env, jThis, script, params); +} + +static jint ExecJSService(JNIEnv *env, jobject object, jstring script) { + if (script == nullptr) + return false; + return WeexProxy::execJSService(env, object, script); +} + +static void TakeHeapSnapshot(JNIEnv *env, jobject object, jstring name) { +} + +/** + * Called to execute JavaScript such as . createInstance(),destroyInstance ext. + * + */ +static jint ExecJS(JNIEnv *env, jobject jthis, jstring jinstanceid, jstring jnamespace, jstring jfunction, jobjectArray jargs) { + if (jfunction == NULL || jinstanceid == NULL) { + LOGE("native_execJS function is NULL"); + return false; + } + + return WeexProxy::execJS(env, jThis, jinstanceid, jnamespace, jfunction, jargs); +} + +static jbyteArray ExecJSWithResult(JNIEnv* env, jobject jcaller, jstring instanceId, jstring _namespace, jstring _function, jobjectArray args) { + if (_function == NULL || instanceId == NULL) { + LOGE("native_execJS function is NULL"); + return NULL; + } + + return WeexProxy::execJSWithResult(env, jcaller, instanceId, _namespace, _function, args); +} + +static void UpdateGlobalConfig(JNIEnv* env, jobject jcaller, jstring config) { + WeexProxy::updateGlobalConfig(env, jcaller, config); +} + + +static jint CreateInstanceContext(JNIEnv* env, jobject jcaller, jstring instanceId, jstring name, jstring function, jobjectArray args) { + return WeexProxy::createInstanceContext(env, jcaller, instanceId, name, function, args); +} + +static jint DestoryInstance(JNIEnv* env, jobject jcaller, jstring instanceId, jstring name, jstring function, jobjectArray args) { + return WeexProxy::destoryInstance(env, jcaller, instanceId, name, function, args); +} + +static jstring ExecJSOnInstance(JNIEnv* env, jobject jcaller, jstring instanceId, jstring script, jint type) { + return WeexProxy::execJSOnInstance(env, jcaller, instanceId, script, type); +} + +namespace WeexCore { + bool RegisterJNIUtils(JNIEnv *env) { + return RegisterNativesImpl(env); + } + + jint OnLoad(JavaVM *vm, void *reserved) { + LOGD("begin JNI_OnLoad"); + JNIEnv *env; + /* Get environment */ + if ((vm)->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) { + return JNI_FALSE; + } + try { + throw 1; + } catch (int) { + } + sVm = vm; + jclass tempClass = env->FindClass( + "com/taobao/weex/bridge/WXBridge"); + jBridgeClazz = (jclass) env->NewGlobalRef(tempClass); + + tempClass = env->FindClass("com/taobao/weex/bridge/WXJSObject"); + jWXJSObject = (jclass) env->NewGlobalRef(tempClass); + + tempClass = env->FindClass("com/taobao/weex/utils/WXLogUtils"); + jWXLogUtils = (jclass) env->NewGlobalRef(tempClass); + + tempClass = env->FindClass("java/util/HashMap"); + jMapClazz = (jclass) env->NewGlobalRef(tempClass); + + tempClass = env->FindClass("java/util/HashSet"); + jSetClazz = (jclass) env->NewGlobalRef(tempClass); + + env->DeleteLocalRef(tempClass); + + LOGD("end JNI_OnLoad"); + WeexProxy::setCacheDir(env); + return JNI_VERSION_1_4; + } + + void Unload(JavaVM *vm, void *reserved) { + LOGD("beigin JNI_OnUnload"); + JNIEnv *env; + + /* Get environment */ + if ((vm)->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) { + return; + } + env->DeleteGlobalRef(jBridgeClazz); + env->DeleteGlobalRef(jWXJSObject); + env->DeleteGlobalRef(jWXLogUtils); + env->DeleteGlobalRef(jMapClazz); + + for (auto iter = componentTypeCache.begin(); iter != componentTypeCache.end(); iter++) { + if (iter->second != nullptr) { + env->DeleteGlobalRef(iter->second); + iter->second = nullptr; + } + } + componentTypeCache.clear(); + + for (auto iter = styleKeyCache.begin(); iter != styleKeyCache.end(); iter++) { + if (iter->second != nullptr) { + env->DeleteGlobalRef(iter->second); + iter->second = nullptr; + } + } + styleKeyCache.clear(); + + if (jThis) + env->DeleteGlobalRef(jThis); + WeexProxy::reset(); + LOGD(" end JNI_OnUnload"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/bridge/impl/weexcore_impl_android.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/bridge/impl/weexcore_impl_android.h b/weex_core/Source/android/bridge/impl/weexcore_impl_android.h new file mode 100644 index 0000000..b43af31 --- /dev/null +++ b/weex_core/Source/android/bridge/impl/weexcore_impl_android.h @@ -0,0 +1,37 @@ +#ifndef _WEEX_CORE_H_ +#define _WEEX_CORE_H_ + +#include <android/base/log_utils.h> +#include <android/base/string/scoped_jstring.h> +#include <android/base/string/scoped_jstring_utf8.h> +#include <android/jsengine/multiprocess/WeexJSConnection.h> +#include <jni.h> +#include <string> +#include <unistd.h> +#include <map> +#include <string> + +extern jclass jBridgeClazz; +extern jclass jWXJSObject; +extern jclass jWXLogUtils; +extern jmethodID jDoubleValueMethodId; +extern jobject jThis; +extern jclass jMapClazz; +extern jclass jSetClazz; +extern JNIEnv *getJNIEnv(); +extern jstring getComponentTypeFromCache(const std::string type); +extern jstring putComponentTypeToCache(const std::string type); +extern jstring getStyleKeyFromCache(const std::string key); +extern jstring putStyleKeyToCache(const std::string key); + +namespace WeexCore { + +bool RegisterJNIUtils(JNIEnv *env); + +jint OnLoad(JavaVM *vm, void *reserved); + +void Unload(JavaVM *vm, void *reserved); + +} + +#endif //_WEEX_CORE_H_ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/jniprebuild/__init__.py ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/__init__.py b/weex_core/Source/android/jniprebuild/__init__.py new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/jniprebuild/android_jar.classes ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/android_jar.classes b/weex_core/Source/android/jniprebuild/android_jar.classes new file mode 100644 index 0000000..7d412ce --- /dev/null +++ b/weex_core/Source/android/jniprebuild/android_jar.classes @@ -0,0 +1,98 @@ +java/lang/AbstractMethodError.class +java/lang/AbstractStringBuilder.class +java/lang/Appendable.class +java/lang/ArithmeticException.class +java/lang/ArrayIndexOutOfBoundsException.class +java/lang/ArrayStoreException.class +java/lang/AssertionError.class +java/lang/AutoCloseable.class +java/lang/Boolean.class +java/lang/Byte.class +java/lang/Character.class +java/lang/Character$Subset.class +java/lang/Character$UnicodeBlock.class +java/lang/CharSequence.class +java/lang/ClassCastException.class +java/lang/ClassCircularityError.class +java/lang/Class.class +java/lang/ClassFormatError.class +java/lang/ClassLoader.class +java/lang/ClassNotFoundException.class +java/lang/Cloneable.class +java/lang/CloneNotSupportedException.class +java/lang/Comparable.class +java/lang/Compiler.class +java/lang/Deprecated.class +java/lang/Double.class +java/lang/Enum.class +java/lang/EnumConstantNotPresentException.class +java/lang/Error.class +java/lang/Exception.class +java/lang/ExceptionInInitializerError.class +java/lang/Float.class +java/lang/IllegalAccessError.class +java/lang/IllegalAccessException.class +java/lang/IllegalArgumentException.class +java/lang/IllegalMonitorStateException.class +java/lang/IllegalStateException.class +java/lang/IncompatibleClassChangeError.class +java/lang/IndexOutOfBoundsException.class +java/lang/InheritableThreadLocal.class +java/lang/InstantiationError.class +java/lang/InstantiationException.class +java/lang/Integer.class +java/lang/InternalError.class +java/lang/InterruptedException.class +java/lang/Iterable.class +java/lang/LinkageError.class +java/lang/Long.class +java/lang/Math.class +java/lang/NegativeArraySizeException.class +java/lang/NoClassDefFoundError.class +java/lang/NoSuchFieldError.class +java/lang/NoSuchFieldException.class +java/lang/NoSuchMethodError.class +java/lang/NoSuchMethodException.class +java/lang/NullPointerException.class +java/lang/Number.class +java/lang/NumberFormatException.class +java/lang/Object.class +java/lang/OutOfMemoryError.class +java/lang/Override.class +java/lang/Package.class +java/lang/ProcessBuilder.class +java/lang/Process.class +java/lang/Readable.class +java/lang/ReflectiveOperationException.class +java/lang/Runnable.class +java/lang/Runtime.class +java/lang/RuntimeException.class +java/lang/RuntimePermission.class +java/lang/SafeVarargs.class +java/lang/SecurityException.class +java/lang/SecurityManager.class +java/lang/Short.class +java/lang/StackOverflowError.class +java/lang/StackTraceElement.class +java/lang/StrictMath.class +java/lang/StringBuffer.class +java/lang/StringBuilder.class +java/lang/String.class +java/lang/StringIndexOutOfBoundsException.class +java/lang/SuppressWarnings.class +java/lang/System.class +java/lang/Thread.class +java/lang/ThreadDeath.class +java/lang/ThreadGroup.class +java/lang/ThreadLocal.class +java/lang/Thread$State.class +java/lang/Thread$UncaughtExceptionHandler.class +java/lang/Throwable.class +java/lang/TypeNotPresentException.class +java/lang/UnknownError.class +java/lang/UnsatisfiedLinkError.class +java/lang/UnsupportedClassVersionError.class +java/lang/UnsupportedOperationException.class +java/lang/VerifyError.class +java/lang/VirtualMachineError.class +java/lang/Void.class http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/jniprebuild/jni_files ---------------------------------------------------------------------- diff --git a/weex_core/Source/android/jniprebuild/jni_files b/weex_core/Source/android/jniprebuild/jni_files new file mode 100644 index 0000000..5aadd44 --- /dev/null +++ b/weex_core/Source/android/jniprebuild/jni_files @@ -0,0 +1,5 @@ +com/taobao/weex/base/SystemMessageHandler.java +com/taobao/weex/bridge/WXBridge.java +com/taobao/weex/layout/MeasureMode.java +com/taobao/weex/layout/ContentBoxMeasurement.java +com/taobao/weex/bridge/WXJsFunctions.java \ No newline at end of file
