blob: 3dfdfa09b2914bfbb75bb40cd660976b852035af [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <android/base/jni/jbytearray_ref.h>
#include "jsfunction_impl_android.h"
#include "../../base/string/string_utils.h"
#include "../../jniprebuild/jniheader/WXJsFunctions_jni.h"
#include "bridge_impl_android.h"
#include "../../../core/render/manager/render_manager.h"
using namespace WeexCore;
extern jobject jThis;
extern jclass jBridgeClazz;
namespace WeexCore {
bool RegisterWXJsFunction(JNIEnv *env) {
RegisterNativesImpl(env);
}
}
static const char *getCharFromJByte(JNIEnv *env, jbyteArray jbyteArray1) {
if (jbyteArray1 == nullptr)
return "";
return jByteArray2Str(env, jbyteArray1).c_str();
}
static const int getJByteArraySize(JNIEnv *env, jbyteArray array){
if(array == nullptr){
return 0;
}
jsize size = env->GetArrayLength(array);
return size;
}
static const char *getCharFromJString(JNIEnv *env, jstring string) {
if (string == nullptr)
return "";
return env->GetStringUTFChars(string, nullptr);
}
void initWxBridge(JNIEnv *env, jobject object, jobject bridge, jstring className) {
jThis = env->NewGlobalRef(bridge);
const char *classNameChar = env->GetStringUTFChars(className, 0);
jclass tempClass = env->FindClass(classNameChar);
jBridgeClazz = (jclass) env->NewGlobalRef(tempClass);
Bridge_Impl_Android::getInstance()->setGlobalRef(jThis);
}
void jsHandleSetJSVersion(JNIEnv *env, jobject object, jstring jsVersion) {
Bridge_Impl_Android::getInstance()->setJSVersion(getCharFromJString(env, jsVersion));
}
void jsHandleReportException(JNIEnv *env, jobject object, jstring instanceId, jstring func,
jstring exceptionjstring) {
Bridge_Impl_Android::getInstance()->reportException(getCharFromJString(env, instanceId),
getCharFromJString(env, func),
getCharFromJString(env,
exceptionjstring));
}
void jsHandleCallNative(JNIEnv *env, jobject object, jstring instanceId, jbyteArray tasks,
jstring callback) {
std::string pageId = jString2StrFast(env, instanceId);
std::string task = jByteArray2Str(env, tasks);
#if JSAPI_LOG
LOGD("[ExtendJSApi] handleCallNative >>>> pageId: %s, task: %s", pageId.c_str(), task.c_str());
#endif
if (task == "[{\"module\":\"dom\",\"method\":\"createFinish\",\"args\":[]}]") {
RenderManager::GetInstance()->CreateFinish(pageId) ? 0 : -1;
env->DeleteLocalRef(instanceId);
env->DeleteLocalRef(tasks);
env->DeleteLocalRef(callback);
} else {
Bridge_Impl_Android::getInstance()->callNative(getCharFromJString(env, instanceId),
task.c_str(),
getCharFromJString(env, callback));
}
}
void
jsHandleCallNativeModule(JNIEnv *env, jobject object, jstring instanceId, jstring module,
jstring method, jbyteArray
arguments, jbyteArray options, jboolean from) {
#if JSAPI_LOG
LOGD("[ExtendJSApi] handleCallNativeModule >>>> pageId: %s, module: %s, method: %s, arg: %s",
jString2StrFast(env, instanceId).c_str(), jString2StrFast(env, module).c_str(),
jString2StrFast(env, method).c_str(), jByteArray2Str(env, arguments).c_str());
#endif
JByteArrayRef argumentsRef(env, arguments);
JByteArrayRef optionsRef(env, options);
// add for android support
jobject result;
result = static_cast<jobject>(Bridge_Impl_Android::getInstance()->callNativeModule(
getCharFromJString(env, instanceId),
getCharFromJString(env, module),
getCharFromJString(env, method),
argumentsRef.getBytes(),
argumentsRef.length(),
optionsRef.getBytes(),
optionsRef.length()));
jfieldID jTypeId = env->GetFieldID(jWXJSObject, "type", "I");
jint jTypeInt = env->GetIntField(result, jTypeId);
jfieldID jDataId = env->GetFieldID(jWXJSObject, "data", "Ljava/lang/Object;");
jobject jDataObj = env->GetObjectField(result, 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);
} else if (jTypeInt == 2) {
jstring jDataStr = (jstring) jDataObj;
//ret = std::move(createStringResult(env, jDataStr));
} else if (jTypeInt == 3) {
jstring jDataStr = (jstring) jDataObj;
//ret = std::move(createJSONStringResult(env, jDataStr));
} else if (jTypeInt == 4) {
jbyteArray array = (jbyteArray)jDataObj;
if(array != nullptr){
int length = env->GetArrayLength(array);
void* data = env->GetByteArrayElements(array, 0);
//ret = std::move(createByteArrayResult((const char*)data, length));
env->ReleaseByteArrayElements(array, (jbyte*)data, 0);
}
}
env->DeleteLocalRef(jDataObj);
if(result != nullptr){
env->DeleteLocalRef(result);
}
//return ret;
}
void
jsHandleCallNativeComponent(JNIEnv *env, jobject object, jstring instanceId, jstring componentRef,
jstring method,
jbyteArray arguments, jbyteArray options, jboolean from) {
JByteArrayRef argumentsRef(env, arguments);
JByteArrayRef optionsRef(env, options);
Bridge_Impl_Android::getInstance()->callNativeComponent(getCharFromJString(env, instanceId),
getCharFromJString(env, componentRef),
getCharFromJString(env, method),
argumentsRef.getBytes(),
argumentsRef.length(),
optionsRef.getBytes(),
optionsRef.length());
}
void
jsHandleCallAddElement(JNIEnv *env, jobject object, jstring instanceId, jstring ref, jbyteArray dom,
jstring index) {
const char *instanceChar = env->GetStringUTFChars(instanceId, 0);
const char *refChar = env->GetStringUTFChars(ref, 0);
JByteArrayRef domRef(env, dom);
const char *indexChar = env->GetStringUTFChars(index, 0);
int indexI = atoi(indexChar);
if (instanceChar == nullptr || refChar == nullptr || domRef.length() == 0 ||
indexChar == nullptr ||
indexI < -1)
return;
RenderManager::GetInstance()->AddRenderObject(instanceChar, refChar, indexI, domRef.getBytes());
}
void jsHandleSetTimeout(JNIEnv *env, jobject object, jstring callbackId, jstring time) {
Bridge_Impl_Android::getInstance()->setTimeout(getCharFromJString(env, callbackId),
getCharFromJString(env, time));
}
void jsHandleCallNativeLog(JNIEnv *env, jobject object, jbyteArray str_array) {
Bridge_Impl_Android::getInstance()->callNativeLog(getCharFromJByte(env, str_array));
}
void jsFunctionCallCreateBody(JNIEnv *env, jobject object, jstring pageId, jbyteArray domStr, jboolean from) {
if (pageId == nullptr || domStr == nullptr)
return;
const char *page = env->GetStringUTFChars(pageId, NULL);
JByteArrayRef dom(env, domStr);
if (page == nullptr || dom.length() == 0)
return;
RenderManager::GetInstance()->CreatePage(page, dom.getBytes());
}
void
jsFunctionCallUpdateFinish(JNIEnv *env, jobject object, jstring instanceId, jbyteArray tasks,
jstring callback) {
Bridge_Impl_Android::getInstance()->callUpdateFinish(getCharFromJString(env, instanceId),
getCharFromJByte(env, tasks),
getCharFromJString(env, callback));
}
void jsFunctionCallCreateFinish(JNIEnv *env, jobject object, jstring pageId) {
RenderManager::GetInstance()->CreateFinish(env->GetStringUTFChars(pageId, 0));
}
void
jsFunctionCallRefreshFinish(JNIEnv *env, jobject object, jstring instanceId, jbyteArray tasks,
jstring callback) {
Bridge_Impl_Android::getInstance()->callRefreshFinish(getCharFromJString(env, instanceId),
getCharFromJByte(env, tasks),
getCharFromJString(env, callback));
}
void
jsFunctionCallUpdateAttrs(JNIEnv *env, jobject object, jstring pageId, jstring ref, jbyteArray data, jboolean from) {
JByteArrayRef dataRef(env, data);
RenderManager::GetInstance()->UpdateAttr(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0),
dataRef.getBytes());
}
void
jsFunctionCallUpdateStyle(JNIEnv *env, jobject object, jstring pageId, jstring ref, jbyteArray data, jboolean from) {
JByteArrayRef dataRef(env, data);
RenderManager::GetInstance()->UpdateStyle(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0),
dataRef.getBytes());
}
void jsFunctionCallRemoveElement(JNIEnv *env, jobject object, jstring pageId, jstring ref) {
RenderManager::GetInstance()->RemoveRenderObject(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0));
}
void
jsFunctionCallMoveElement(JNIEnv *env, jobject object, jstring pageId, jstring ref,
jstring parentRef, jstring index_str) {
int index = atoi(env->GetStringUTFChars(index_str, 0));
RenderManager::GetInstance()->MoveRenderObject(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0),
env->GetStringUTFChars(parentRef, 0), index);
}
void
jsFunctionCallAddEvent(JNIEnv *env, jobject object, jstring pageId, jstring ref, jstring event) {
RenderManager::GetInstance()->AddEvent(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0),
env->GetStringUTFChars(event, 0));
}
void
jsFunctionCallRemoveEvent(JNIEnv *env, jobject object, jstring pageId, jstring ref,
jstring event) {
RenderManager::GetInstance()->RemoveEvent(env->GetStringUTFChars(pageId, 0),
env->GetStringUTFChars(ref, 0),
env->GetStringUTFChars(event, 0));
}
void jsHandleSetInterval(JNIEnv *env, jobject object, jstring instanceId, jstring callbackId,
jstring time) {}
void
jsHandleClearInterval(JNIEnv *env, jobject object, jstring instanceId, jstring callbackId) {}
void jsHandleCallGCanvasLinkNative(JNIEnv *env, jobject object, jstring contextId, int type,
jstring val) {}