blob: 706686fa8d5125f49126147cc93a6c26c951cf01 [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 "script_bridge_in_multi_so.h"
#include <dlfcn.h>
#include <malloc.h>
#include "android/bridge/multi_so_initializer.h"
#include "android/bridge/script/script_side_in_multi_so.h"
#include "android/utils/ipc_string_result.h"
#include "android/utils/params_utils.h"
#include "base/android/log_utils.h"
#include "base/make_copyable.h"
#include "base/thread/waitable_event.h"
#include "core/bridge/script/core_side_in_script.h"
#include "core/manager/weex_core_manager.h"
namespace WeexCore {
inline static char *copyStr(const char *str, int length = 0) {
char *ret = nullptr;
if (str == nullptr) return ret;
int strLen = length == 0 ? strlen(str) : length;
ret = new char[strLen + 1];
memcpy(ret, str, static_cast<size_t>(strLen));
ret[strLen] = '\0';
return ret;
}
ScriptBridgeInMultiSo::ScriptBridgeInMultiSo() {
set_core_side(new CoreSideInScript);
set_script_side(new bridge::script::ScriptSideInMultiSo);
std::unique_ptr<MultiSoInitializer> initializer(new MultiSoInitializer);
bool passable = initializer->Init(
[this](void *handle) {
LOGE("dlopen so and call function");
typedef FunctionsExposedByJS *(*ExchangeJSBridgeFunctions)(
FunctionsExposedByCore *);
auto exchange_script_bridge_functions =
(ExchangeJSBridgeFunctions)dlsym(handle,
"ExchangeJSBridgeFunctions");
if (!exchange_script_bridge_functions) {
return false;
}
FunctionsExposedByCore *platform_expose_functions =
GetExposedFunctions();
auto script_side_functions =
exchange_script_bridge_functions(platform_expose_functions);
static_cast<bridge::script::ScriptSideInMultiSo *>(script_side())
->set_script_side_functions(script_side_functions);
return true;
},
[this](const char *status_code, const char *error_msg) {
WeexCoreManager::Instance()
->getPlatformBridge()
->platform_side()
->ReportNativeInitStatus(status_code, error_msg);
});
set_is_passable(passable);
}
ScriptBridgeInMultiSo::~ScriptBridgeInMultiSo() {}
static void CallNative(const char *page_id, const char *task,
const char *callback) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->CallNative(
// page_id, task, callback);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
task = std::string(task),
callback = std::string(callback)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->CallNative(
page_id.c_str(), task.c_str(), callback.c_str());
}));
}
static std::unique_ptr<ValueWithType> CallNativeModule(
const char *page_id, const char *module, const char *method,
const char *arguments, int arguments_length, const char *options,
int options_length) {
// auto ret = WeexCoreManager::Instance()
// ->script_bridge()
// ->core_side()
// ->CallNativeModule(page_id, module, method, arguments,
// arguments_length,
// options, options_length);
weex::base::WaitableEvent event;
std::unique_ptr<ValueWithType> ret;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id), module = std::string(module),
method = std::string(method),
arguments =
std::unique_ptr<char[]>(copyStr(arguments, arguments_length)),
arguments_length = arguments_length,
options = std::unique_ptr<char[]>(copyStr(options, options_length)),
options_length = options_length, e = &event, ret = &ret] {
*ret = WeexCoreManager::Instance()
->script_bridge()
->core_side()
->CallNativeModule(page_id.c_str(), module.c_str(),
method.c_str(), arguments.get(),
arguments_length, options.get(),
options_length);
e->Signal();
}));
event.Wait();
return ret;
}
static void CallNativeComponent(const char *page_id, const char *ref,
const char *method, const char *arguments,
int arguments_length, const char *options,
int options_length) {
// WeexCoreManager::Instance()
// ->script_bridge()
// ->core_side()
// ->CallNativeComponent(page_id, ref, method, arguments,
// arguments_length,
// options, options_length);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id), ref = std::string(ref),
method = std::string(method),
arguments =
std::unique_ptr<char[]>(copyStr(arguments, arguments_length)),
arguments_length = arguments_length,
options = std::unique_ptr<char[]>(copyStr(options, options_length)),
options_length = options_length] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->CallNativeComponent(page_id.c_str(), ref.c_str(),
method.c_str(), arguments.get(),
arguments_length, options.get(),
options_length);
}));
}
static void AddElement(const char *page_id, const char *parent_ref,
const char *dom_str, int domLen, const char *index_str) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->AddElement(
// page_id, parent_ref, dom_str, domLen, index_str);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
parent_ref = std::string(parent_ref),
dom_str = std::unique_ptr<char[]>(
copyStr(dom_str, domLen)),
dom_len = domLen,
index_str = std::string(index_str)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->AddElement(
page_id.c_str(), parent_ref.c_str(), dom_str.get(), dom_len,
index_str.c_str());
}));
}
static void SetTimeout(const char *callback_id, const char *time) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->SetTimeout(
// callback_id, time);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([callback_id = std::string(callback_id),
time = std::string(time)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->SetTimeout(
callback_id.c_str(), time.c_str());
}));
}
static void NativeLog(const char *str_array) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->NativeLog(
// str_array);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([str_array = std::string(str_array)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->NativeLog(
str_array.c_str());
}));
}
static void CreateBody(const char *page_id, const char *dom_str, int domLen) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->CreateBody(
// page_id, dom_str, domLen);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
dom_str = std::unique_ptr<char[]>(
copyStr(dom_str, domLen)),
dom_len = domLen] {
WeexCoreManager::Instance()->script_bridge()->core_side()->CreateBody(
page_id.c_str(), dom_str.get(), dom_len);
}));
}
static int UpdateFinish(const char *page_id, const char *task, int taskLen,
const char *callback, int callbackLen) {
// return WeexCoreManager::Instance()
// ->script_bridge()
// ->core_side()
// ->UpdateFinish(page_id, task, taskLen, callback, callbackLen);
weex::base::WaitableEvent event;
int result = -1;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id),
task = std::unique_ptr<char[]>(copyStr(task, taskLen)),
task_len = taskLen,
callback = std::unique_ptr<char[]>(copyStr(callback, callbackLen)),
callback_len = callbackLen, event = &event, result = &result] {
*result = WeexCoreManager::Instance()
->script_bridge()
->core_side()
->UpdateFinish(page_id.c_str(), task.get(), task_len,
callback.get(), callback_len);
event->Signal();
}));
event.Wait();
return result;
}
static void CreateFinish(const char *page_id) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->CreateFinish(
// page_id);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->CreateFinish(
page_id.c_str());
}));
}
static int RefreshFinish(const char *page_id, const char *task,
const char *callback) {
// return WeexCoreManager::Instance()
// ->script_bridge()
// ->core_side()
// ->RefreshFinish(page_id, task, callback);
int result = -1;
weex::base::WaitableEvent event;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id), task = std::string(task),
callback = std::string(callback), event = &event] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->RefreshFinish(page_id.c_str(), task.c_str(),
callback.c_str());
event->Signal();
}));
event.Wait();
return result;
}
static void UpdateAttrs(const char *page_id, const char *ref, const char *data,
int dataLen) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateAttrs(
// page_id, ref, data, dataLen);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
ref = std::string(ref),
data = std::unique_ptr<char[]>(
copyStr(data, dataLen)),
data_len = dataLen] {
WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateAttrs(
page_id.c_str(), ref.c_str(), data.get(), data_len);
}));
}
static void UpdateStyle(const char *page_id, const char *ref, const char *data,
int dataLen) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateStyle(
// page_id, ref, data, dataLen);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
ref = std::string(ref),
data = std::unique_ptr<char[]>(
copyStr(data, dataLen)),
data_len = dataLen] {
WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateStyle(
page_id.c_str(), ref.c_str(), data.get(), data_len);
}));
}
static void RemoveElement(const char *page_id, const char *ref) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveElement(
// page_id, ref);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id), ref = std::string(ref)] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->RemoveElement(page_id.c_str(), ref.c_str());
}));
}
static void MoveElement(const char *page_id, const char *ref,
const char *parent_ref, int index) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->MoveElement(
// page_id, ref, parent_ref, index);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
ref = std::string(ref),
parent_ref = std::string(parent_ref),
index = index] {
WeexCoreManager::Instance()->script_bridge()->core_side()->MoveElement(
page_id.c_str(), ref.c_str(), parent_ref.c_str(), index);
}));
}
static void AddEvent(const char *page_id, const char *ref, const char *event) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->AddEvent(
// page_id, ref, event);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
ref = std::string(ref),
event = std::string(event)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->AddEvent(
page_id.c_str(), ref.c_str(), event.c_str());
}));
}
static void RemoveEvent(const char *page_id, const char *ref,
const char *event) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveEvent(
// page_id, ref, event);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
ref = std::string(ref),
event = std::string(event)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveEvent(
page_id.c_str(), ref.c_str(), event.c_str());
}));
}
static const char *CallGCanvasLinkNative(const char *context_id, int type,
const char *arg) {
weex::base::WaitableEvent event;
char *ret = nullptr;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(context_id),
t = type,
args = std::string(arg), e = &event, ret = &ret] {
*ret = const_cast<char *>(WeexCoreManager::Instance()
->script_bridge()
->core_side()
->CallGCanvasLinkNative(page_id.c_str(), t, args.c_str()));
e->Signal();
}));
event.Wait();
return ret;
}
static int SetInterval(const char *page_id, const char *callback_id,
const char *time) {
return WeexCoreManager::Instance()->script_bridge()->core_side()->SetInterval(
page_id, callback_id, time);
}
static void ClearInterval(const char *page_id, const char *callback_id) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->ClearInterval(
// page_id, callback_id);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
callback_id = std::string(callback_id)] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->ClearInterval(page_id.c_str(), callback_id.c_str());
}));
}
static const char *CallT3DLinkNative(int type, const char *arg) {
weex::base::WaitableEvent event;
char *ret = nullptr;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([
t = type,
args = std::string(arg), e = &event, ret = &ret] {
*ret = const_cast<char *>(WeexCoreManager::Instance()
->script_bridge()
->core_side()
->CallT3DLinkNative(t, args.c_str()));
e->Signal();
}));
event.Wait();
return ret;
}
static void PostMessage(const char *vim_id, const char *data, int dataLength) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->PostMessage(vim_id,
// data);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([vim_id = std::string(vim_id),
data = std::string(data), length = dataLength] {
WeexCoreManager::Instance()->script_bridge()->core_side()->PostMessage(
vim_id.c_str(), data.c_str(),length);
}));
}
static void DispatchMessage(const char *client_id, const char *data, int dataLength,
const char *callback, const char *vm_id) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->DispatchMessage(
// client_id, data, callback, vm_id);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[client_id = std::string(client_id), data = std::string(data),
callback = std::string(callback), vm_id = std::string(vm_id), length = dataLength] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->DispatchMessage(client_id.c_str(), data.c_str(),length,
callback.c_str(), vm_id.c_str());
}));
}
static std::unique_ptr<WeexJSResult> DispatchMessageSync(const char *client_id,
const char *data,
int dataLength,
const char *vm_id) {
weex::base::WaitableEvent event;
std::unique_ptr<WeexJSResult> result;
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([client_id = std::string(client_id),
data = std::string(data),
vm_id = std::string(vm_id), length = dataLength,
e = &event, r = &result]() {
*r = WeexCoreManager::Instance()
->script_bridge()
->core_side()
->DispatchMessageSync(client_id.c_str(), data.c_str(), length,
vm_id.c_str());
e->Signal();
}));
event.Wait();
return result;
}
static void OnReceivedResult(long callback_id,
std::unique_ptr<WeexJSResult> &result) {
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([callback_id, result = std::move(result)]() {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->OnReceivedResult(
callback_id,
const_cast<std::unique_ptr<WeexJSResult> &>(result));
}));
}
static void UpdateComponentData(const char* page_id,
const char* cid,
const char* json_data) {
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable(
[page_id = std::string(page_id), cid = std::string(cid), json_data = std::string(json_data)]() {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->UpdateComponentData(page_id.c_str(), cid.c_str(), json_data.c_str());
}));
}
static void ReportException(const char *page_id, const char *func,
const char *exception_string) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->ReportException(
// page_id, func, exception_string);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([page_id = std::string(page_id),
func = std::string(func),
exception = std::string(exception_string)] {
WeexCoreManager::Instance()
->script_bridge()
->core_side()
->ReportException(page_id.c_str(), func.c_str(), exception.c_str());
}));
}
static void SetJSVersion(const char *js_version) {
// WeexCoreManager::Instance()->script_bridge()->core_side()->SetJSVersion(
// js_version);
WeexCoreManager::Instance()->script_thread()->message_loop()->PostTask(
weex::base::MakeCopyable([version = std::string(js_version)] {
WeexCoreManager::Instance()->script_bridge()->core_side()->SetJSVersion(
version.c_str());
}));
}
FunctionsExposedByCore *ScriptBridgeInMultiSo::GetExposedFunctions() {
FunctionsExposedByCore temp = {SetJSVersion,
ReportException,
CallNative,
CallNativeModule,
CallNativeComponent,
AddElement,
SetTimeout,
NativeLog,
CreateBody,
UpdateFinish,
CreateFinish,
RefreshFinish,
UpdateAttrs,
UpdateStyle,
RemoveElement,
MoveElement,
AddEvent,
RemoveEvent,
SetInterval,
ClearInterval,
CallGCanvasLinkNative,
CallT3DLinkNative,
PostMessage,
DispatchMessage,
DispatchMessageSync,
OnReceivedResult,
UpdateComponentData};
auto functions =
(FunctionsExposedByCore *)malloc(sizeof(FunctionsExposedByCore));
memset(functions, 0, sizeof(FunctionsExposedByCore));
memcpy(functions, &temp, sizeof(FunctionsExposedByCore));
return functions;
}
} // namespace WeexCore