blob: 7b97f8e0aac4811bb8a36b34c24e13896af418ba [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/bridge/platform/android_side.h"
#include "android/base/string/string_utils.h"
#include "android/utils/ipc_string_result.h"
#include "android/utils/cache_utils.h"
#include "android/utils/params_utils.h"
#include "android/wrap/hash_set.h"
#include "android/wrap/log_utils.h"
#include "android/wrap/wml_bridge.h"
#include "android/wrap/wx_js_object.h"
#include "android/wrap/wx_map.h"
#include "base/android/jni/android_jni.h"
#include "base/android/jni/jbytearray_ref.h"
#include "base/android/jni_type.h"
#include "base/log_defines.h"
#include "core/layout/layout.h"
#include "core/layout/measure_func_adapter.h"
#include "core/manager/weex_core_manager.h"
#include "third_party/IPC/IPCResult.h"
namespace WeexCore {
AndroidSide::AndroidSide()
: wml_bridge_(WMLBridge::Instance()), wx_bridge_(WXBridge::Instance()) {}
AndroidSide::~AndroidSide() {}
WXCoreSize AndroidSide::InvokeMeasureFunction(const char *page_id,
long render_ptr, float width,
int width_measure_mode,
float height,
int height_measure_mode) {
return WeexCoreManager::Instance()->measure_function_adapter()->Measure(
page_id, render_ptr, width, static_cast<MeasureMode>(width_measure_mode),
height, static_cast<MeasureMode>(height_measure_mode));
}
void AndroidSide::InvokeLayoutBefore(const char *page_id, long render_ptr) {
WeexCoreManager::Instance()->measure_function_adapter()->LayoutBefore(
page_id, render_ptr);
}
void AndroidSide::InvokeLayoutPlatform(const char* page_id, long render_ptr) {
// do nothing
}
void AndroidSide::TriggerVSync(const char* page_id) {
// do nothing
}
void AndroidSide::InvokeLayoutAfter(const char *page_id, long render_ptr,
float width, float height) {
WeexCoreManager::Instance()->measure_function_adapter()->LayoutAfter(
page_id, render_ptr, width, height);
}
void AndroidSide::SetJSVersion(const char *version) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->SetJSFrmVersion(env, version);
}
void AndroidSide::ReportException(const char *page_id, const char *func,
const char *exception_string) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->ReportException(env, page_id, func, exception_string);
}
void AndroidSide::ReportServerCrash(const char *instance_id) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
std::string crash_file;
crash_file.assign("/crash_dump.log");
wx_bridge_->ReportServerCrash(env, instance_id, crash_file.c_str());
}
void AndroidSide::ReportNativeInitStatus(const char *status_code,
const char *error_msg) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->ReportNativeInitStatus(env, status_code, error_msg);
}
int AndroidSide::CallNative(const char *page_id, const char *task,
const char *callback) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->CallNative(env, page_id, task, callback);
if (flag == -1) {
LOGE("instance destroy JFM must stop callNative");
}
return flag;
}
int AndroidSide::AddChildToRichtext(const char *pageId, const char *nodeType, const char *ref, const char *parentRef,
const char *richtextRef, std::map<std::string, std::string> *styles,
std::map<std::string, std::string> *attributes) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->AddChildToRichtext(env, pageId, nodeType, ref, parentRef, richtextRef, styles ,attributes);
if (flag == -1) {
LOGE("instance destroy JFM must stop AddChildToRichtext");
}
return flag;
}
int AndroidSide::RemoveChildFromRichtext(const char *pageId, const char *ref, const char *parent_ref,
const char *richtext_ref) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->RemoveChildFromRichtext(env, pageId, ref, parent_ref, richtext_ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop RemoveChildFromRichtext");
}
return flag;
}
int AndroidSide::UpdateRichtextStyle(const char *pageId, const char *ref,
std::vector<std::pair<std::string, std::string>> *styles, const char *parent_ref,
const char *richtext_ref) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->UpdateRichtextStyle(env, pageId, ref, styles, parent_ref, richtext_ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop UpdateRichtextStyle");
}
return flag;
}
int AndroidSide::UpdateRichtextChildAttr(const char *pageId, const char *ref,
std::vector<std::pair<std::string, std::string>> *attributes,
const char *parent_ref, const char *richtext_ref) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->UpdateRichtextChildAttr(env, pageId, ref, attributes, parent_ref, richtext_ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop UpdateRichtextChildAttr");
}
return flag;
}
std::unique_ptr<ValueWithType> AndroidSide::CallNativeModule(
const char *page_id, const char *module, const char *method,
const char *arguments, int arguments_length, const char *options,
int options_length) {
std::unique_ptr<ValueWithType> ipc_result(new ValueWithType());
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return ipc_result;
auto result =
wx_bridge_->CallNativeModule(env, page_id, module, method, arguments,
arguments_length, options, options_length);
ipc_result->type = ParamsType::INT32;
ipc_result->value.int32Value = -1;
if (result.IsNull()) {
return ipc_result;
}
auto wx_js_object_result =
std::unique_ptr<WXJSObject>(new WXJSObject(env, result.Get()));
jint jTypeInt = wx_js_object_result->GetType(env);
auto jDataObj = wx_js_object_result->GetData(env);
if (jTypeInt == 1) {
ipc_result->type = ParamsType::DOUBLE;
ipc_result->value.doubleValue =
base::android::JNIType::DoubleValue(env, jDataObj.Get());
} else if (jTypeInt == 2) {
jstring jDataStr = (jstring)jDataObj.Get();
ipc_result->type = ParamsType::STRING;
ipc_result->value.string = jstring2WeexString(env, jDataStr);
} else if (jTypeInt == 3) {
jstring jDataStr = (jstring)jDataObj.Get();
ipc_result->type = ParamsType::JSONSTRING;
ipc_result->value.string = jstring2WeexString(env, jDataStr);
} else if (jTypeInt == 4) {
jbyteArray array = (jbyteArray)jDataObj.Get();
if (array != nullptr) {
int length = env->GetArrayLength(array);
void *data = env->GetByteArrayElements(array, 0);
ipc_result->type = ParamsType::BYTEARRAY;
ipc_result->value.byteArray =
genWeexByteArray((const char *)data, length);
env->ReleaseByteArrayElements(array, (jbyte *)data, 0);
}
}
return ipc_result;
}
void AndroidSide::CallNativeComponent(const char *page_id, const char *ref,
const char *method, const char *arguments,
int arguments_length, const char *options,
int options_length) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->CallNativeComponent(env, page_id, ref, method, arguments,
arguments_length, options, options_length);
}
void AndroidSide::SetTimeout(const char *callback_id, const char *time) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->SetTimeout(env, callback_id, time);
}
void AndroidSide::NativeLog(const char *str_array) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
LogUtils::NativeLog(env, str_array);
}
int AndroidSide::UpdateFinish(const char *page_id, const char *task,
int taskLen, const char *callback,
int callbackLen) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->UpdateFinish(env, page_id, task, callback);
if (flag == -1) {
LOGE("instance destroy JFM must stop callUpdateFinish");
}
return flag;
}
int AndroidSide::RefreshFinish(const char *page_id, const char *task,
const char *callback) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->RefreshFinish(env, page_id, task, callback);
if (flag == -1) {
LOGE("instance destroy JFM must stop callNative");
}
return flag;
}
int AndroidSide::AddEvent(const char *page_id, const char *ref,
const char *event) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->AddEvent(env, page_id, ref, event);
if (flag == -1) {
LOGE("instance destroy JFM must stop callAddEvent");
}
return flag;
}
int AndroidSide::RemoveEvent(const char *page_id, const char *ref,
const char *event) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->RemoveEvent(env, page_id, ref, event);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
}
return flag;
}
int AndroidSide::CreateBody(const char *page_id, const char *component_type,
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 = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag =
wx_bridge_->CreateBody(env, page_id, component_type, ref, styles,
attributes, events, margins, paddings, borders);
if (flag == -1) {
LOGE("instance destroy JFM must stop callCreateBody");
}
return flag;
}
int AndroidSide::AddElement(const char *page_id, const char *component_type,
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, bool willLayout) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->AddElement(env, page_id, component_type, ref, index,
parentRef, styles, attributes, events,
margins, paddings, borders, willLayout);
if (flag == -1) {
LOGE("instance destroy JFM must stop callAddElement");
}
return flag;
}
int AndroidSide::Layout(const char *page_id, const char *ref, float top,
float bottom, float left, float right, float height,
float width, bool isRTL, int index) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = 0;
wx_bridge_->Layout(env, page_id, ref, top, bottom, left, right,
height, width, isRTL, index);
if (flag == -1) {
LOGE("instance destroy JFM must stop callLayout");
}
return flag;
}
int AndroidSide::UpdateStyle(
const char *page_id, 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 = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->UpdateStyle(env, page_id, ref, style, margin, padding,
border);
if (flag == -1) {
LOGE("instance destroy JFM must stop callUpdateStyle");
}
return flag;
}
int AndroidSide::UpdateAttr(
const char *page_id, const char *ref,
std::vector<std::pair<std::string, std::string>> *attrs) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = 0;
flag = wx_bridge_->UpdateAttr(env, page_id, ref, attrs);
if (flag == -1) {
LOGE("instance destroy JFM must stop callUpdateStyle");
}
return flag;
}
int AndroidSide::CreateFinish(const char *page_id) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->CreateFinish(env, page_id);
if (flag == -1) {
LOGE("instance destroy JFM must stop callCreateFinish");
}
return flag;
}
int AndroidSide::RenderSuccess(const char *page_id) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->RenderSuccess(env, page_id);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRenderFinish");
}
return flag;
}
int AndroidSide::RemoveElement(const char *page_id, const char *ref) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->RemoveElement(env, page_id, ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
}
return flag;
}
int AndroidSide::MoveElement(const char *page_id, const char *ref,
const char *parent_ref, int index) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
int flag = wx_bridge_->MoveElement(env, page_id, ref, parent_ref, index);
if (flag == -1) {
LOGE("instance destroy JFM must stop callRemoveElement");
}
return flag;
}
int AndroidSide::AppendTreeCreateFinish(const char *page_id, const char *ref) {
JNIEnv *env = base::android::AttachCurrentThread();
int flag = wx_bridge_->AppendTreeCreateFinish(env, page_id, ref);
if (flag == -1) {
LOGE("instance destroy JFM must stop callAppendTreeCreateFinish");
}
return flag;
}
int AndroidSide::HasTransitionPros(
const char *page_id, const char *ref,
std::vector<std::pair<std::string, std::string>> *style) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return -1;
if (style != nullptr) {
return wx_bridge_->HasTransitionPros(env, page_id, ref, *style);
} else {
return wx_bridge_->HasTransitionPros(
env, page_id, ref, std::vector<std::pair<std::string, std::string>>());
}
}
void AndroidSide::PostMessage(const char *vm_id, const char *data, int dataLength) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wml_bridge_->PostMessage(env, vm_id, data, dataLength);
}
void AndroidSide::DispatchMessage(const char *client_id,
const char *data, int dataLength, const char *callback, const char *vm_id) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wml_bridge_->DispatchMessage(env, client_id, data, dataLength, callback, vm_id);
}
std::unique_ptr<WeexJSResult> AndroidSide::DispatchMessageSync(
const char *client_id, const char *data, int dataLength,
const char *vm_id) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return std::unique_ptr<WeexJSResult>();
auto jni_result =
wml_bridge_->DispatchMessageSync(env, client_id, data, dataLength, vm_id);
JByteArrayRef byte_array(env, jni_result.Get());
char *copy = nullptr;
if (byte_array.length() > 0) {
copy = new char[byte_array.length()];
strcpy(copy, byte_array.getBytes());
}
return std::unique_ptr<WeexJSResult>(
new WeexJSResult(std::unique_ptr<char[]>(copy), byte_array.length()));
}
void AndroidSide::OnReceivedResult(long callback_id, std::unique_ptr<WeexJSResult>& result) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->OnReceivedResult(env, callback_id, result);
}
jobject AndroidSide::getMeasureFunc(const char *pageId, jlong renderObjectPtr) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return nullptr;
return wx_bridge_->GetMeasureFunc(env, pageId, renderObjectPtr).Release();
}
void AndroidSide::SetPageDirty(const char *page_id, bool dirty) {
JNIEnv *env = base::android::AttachCurrentThread();
if (env == nullptr)
return;
wx_bridge_->SetPageDirty(env, page_id, dirty);
}
} // namespace WeexCore