blob: 3a4391115c749ae8991bebc749b7d3f12d927898 [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 "third_party/json11/json11.hpp"
#include "core/bridge/eagle_bridge.h"
#include "base/string_util.h"
#include "base/closure.h"
#include "core/render/node/render_object.h"
#include "core/render/node/factory/render_creator.h"
#include "core/render/manager/render_manager.h"
#include "core/manager/weex_core_manager.h"
#include "core/network/http_module.h"
namespace WeexCore {
EagleBridge* EagleBridge::g_instance = nullptr;// NOLINT(cert-err58-cpp)
void EagleBridge::CreatePage(const char* plugin_type,
const char* instanceId,
const char* func,
const char* script,
int script_length,
const char* opts,
const char* initData,
const char* extendsApi, std::function<void(const char*, const char*)> callback) {
const auto& it = pages_.find(instanceId);
if (it == pages_.end()){
DataRenderHandler* plugin = get_data_render_handler(plugin_type);
if (!plugin) {
std::string err = std::string("EagleBridge plugin not exist: ") + plugin_type;
weex_core_handler()->ReportException(instanceId, "CreateInstance", err.c_str());
LOGE("%s", err.c_str());
return;
}
pages_[instanceId] = plugin;
plugin->CreatePage(instanceId, func, script, script_length, opts, initData, extendsApi, callback);
} else {
LOGE("ReCreate Page of InstanceId: %s", instanceId);
}
}
EagleBridge::EagleBridge() : weex_core_handler_(new WeexCoreHandler()) {
}
EagleBridge::DataRenderHandler* EagleBridge::data_render_handler(const std::string& instance_id) const {
const auto& it = pages_.find(instance_id);
if (it == pages_.end()){
return nullptr;
} else {
return it->second;
}
}
void EagleBridge::set_data_render_handler(const std::string& plugin_type,
DataRenderHandler* data_render_handler) {
std::lock_guard<std::mutex> lock(plugin_mutex_);
plugins_[plugin_type] = data_render_handler;
}
EagleBridge::DataRenderHandler* EagleBridge::get_data_render_handler(const std::string& plugin_type) {
std::lock_guard<std::mutex> lock(plugin_mutex_);
const auto& it = plugins_.find(plugin_type);
if (it == plugins_.end()) {
return nullptr;
} else {
return it->second;
}
}
EagleBridge* EagleBridge::GetInstance() {
static std::once_flag s_flag;
std::call_once(s_flag, []() {
g_instance = new EagleBridge();
});
return g_instance;
}
EagleModeReturn EagleBridge::DestroyPage(const char* instanceId) {
const auto& it = pages_.find(instanceId);
if (it == pages_.end()){
return EagleModeReturn::NOT_EAGLE;
} else {
EagleModeReturn mode = it->second->DestroyInstance(instanceId);
pages_.erase(it);
return mode;
}
}
EagleModeReturn EagleBridge::RefreshPage(const char* instanceId, const char* initData) {
const auto& it = pages_.find(instanceId);
if (it == pages_.end()){
return EagleModeReturn::NOT_EAGLE;
} else {
return it->second->RefreshPage(instanceId, initData);;
}
}
void EagleBridge::UpdateComponentData(const char* instanceId, const char* cid, const char* json_data) {
const auto& it = pages_.find(instanceId);
if (it == pages_.end()){
weex_core_handler()->ReportException(
instanceId, "UpdateComponentData",
"There is no data_render_handler when UpdateComponentData invoked");
return;
} else {
return it->second->UpdateComponentData(instanceId, cid, json_data);;
}
}
bool EagleBridge::CallEagleTaskFromWeex(const char* instanceId,
const char* task,
const char* options) {
if (instanceId){
//a single instance task
const auto& it = pages_.find(instanceId);
if (it == pages_.end()){
return false;
} else {
return it->second->CallEagleTaskFromWeex(instanceId, task, options);
}
} else {
//a global task; call every plugins.
bool support = false;
for (const auto& it: plugins_){
support = support || it.second->CallEagleTaskFromWeex(nullptr, task ,options);
}
return support;
}
return false;
}
EagleRenderObject::EagleRenderObject() : render_object_impl_(nullptr) {}
EagleRenderObject::EagleRenderObject(RenderObject* render_object) : render_object_impl_(
render_object) {}
void EagleRenderObject::AddAttr(const std::string& key, const std::string& value) {
render_object_impl_->AddAttr(key, value);
}
void EagleRenderObject::AddStyle(const std::string& key, const std::string& value) {
if (render_object_impl_->is_richtext_child()) {
render_object_impl_->MapInsertOrAssign(render_object_impl_->styles(), key, value);
} else {
render_object_impl_->AddStyle(key, value, false);
}
}
void EagleRenderObject::UpdateAttr(const std::string& key, const std::string& value) {
render_object_impl_->UpdateAttr(key, value);
}
void EagleRenderObject::UpdateStyle(const std::string& key, const std::string& value) {
render_object_impl_->UpdateStyle(key, value);
}
void EagleRenderObject::AddEvent(const std::string& event) {
render_object_impl_->AddEvent(event);
}
void EagleRenderObject::RemoveEvent(const std::string& event) {
render_object_impl_->RemoveEvent(event);
}
std::set<std::string>* EagleRenderObject::events() {
return render_object_impl_->events();
}
void EagleRenderObject::set_page_id(const std::string& page_id) {
render_object_impl_->set_page_id(page_id);
}
void EagleRenderObject::ApplyDefaultAttr() {
render_object_impl_->ApplyDefaultAttr();
}
void EagleRenderObject::ApplyDefaultStyle() {
render_object_impl_->ApplyDefaultStyle(false);
}
int EagleRenderObject::AddRenderObject(int index, EagleRenderObject child) {
if (!render_object_impl_) {
return -1;
}
return render_object_impl_->AddRenderObject(index, child.render_object_impl_);
}
int EagleRenderObject::getChildCount() {
return static_cast<int>(render_object_impl_->getChildCount());
}
int EagleRenderObject::getChildIndex(EagleRenderObject child) {
return static_cast<int>(render_object_impl_->IndexOf(child.render_object_impl_));
}
EagleRenderObject EagleRenderObject::GetChild(int index) {
return render_object_impl_->GetChild(index);
}
void EagleRenderObject::set_is_richtext_child(const bool is_richtext_child) {
render_object_impl_->set_is_richtext_child(is_richtext_child);
}
EagleRenderObject EagleRenderObject::parent_render() {
return render_object_impl_->parent_render();
}
const std::string& EagleRenderObject::page_id() {
return render_object_impl_->page_id();
}
const std::string& EagleRenderObject::ref() {
return render_object_impl_->ref();
}
void EagleRenderObject::RemoveRenderObject(EagleRenderObject child) {
render_object_impl_->RemoveRenderObject(child.render_object_impl_);
}
EagleRenderObject EagleBridge::WeexCoreHandler::GetEagleRenderObject(const std::string& type,
const std::string& ref) {
return EagleRenderObject(
static_cast<WeexCore::RenderObject*>(WeexCore::RenderCreator::GetInstance()->CreateRender(
type, ref)));
}
bool EagleBridge::WeexCoreHandler::CreatePage(const std::string& page_id, EagleRenderObject root) {
return RenderManager::GetInstance()->CreatePage(page_id, root.render_object_impl_);
}
bool EagleBridge::WeexCoreHandler::HavePage(const std::string& page_id) {
return RenderManager::GetInstance()->GetPage(page_id) ? true : false;
}
bool EagleBridge::WeexCoreHandler::CreateFinish(const std::string& page_id) {
return RenderManager::GetInstance()->CreateFinish(page_id);
}
bool EagleBridge::WeexCoreHandler::ClosePage(const std::string& page_id) {
return RenderManager::GetInstance()->ClosePage(page_id);
}
void EagleBridge::WeexCoreHandler::ReportException(const char* page_id,
const char* func,
const char* exception_string) {
WeexCore::WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->ReportException(
page_id, func, exception_string);
}
void EagleBridge::WeexCoreHandler::Send(const char* instance_id,
const char* url,
std::function<void(const std::string&,
const std::string&)> callback) {
weex::core::network::HttpModule http_module;
http_module.Send(instance_id, url, callback);
}
void EagleBridge::WeexCoreHandler::GetBundleType(const char* instance_id,
const char* content,
std::function<void(const std::string&,
const std::string&)> callback) {
weex::core::network::HttpModule http_module;
http_module.GetBundleType(instance_id, content, callback);
}
//void EagleBridge::WeexCoreHandler::RequrieMoudle(const std::string& class_name) {
//}
//void EagleBridge::WeexCoreHandler::RequrieComponent(const std::string& class_name) {
//}
bool EagleBridge::WeexCoreHandler::RefreshFinish(const char* page_id,
const char* task,
const char* callback) {
WeexCore::WeexCoreManager::Instance()
->getPlatformBridge()
->core_side()->ForceLayout(page_id);
return static_cast<bool>(WeexCore::WeexCoreManager::Instance()
->getPlatformBridge()
->platform_side()
->RefreshFinish(page_id, task, callback));
}
//return empty for undefined
static std::string ParsePlatformResultToString(const std::unique_ptr<ValueWithType>& result) {
switch (result->type) {
case ParamsType::DOUBLE:
return json11::Json(result->value.doubleValue).dump();
case ParamsType::STRING: {
if (!result->value.string) {
return "";
} else {
std::string ret;
if (result->value.string->length > 0) {
const auto& basic_string = weex::base::to_utf8(result->value.string->content,
result->value.string->length);
ret = json11::Json(basic_string).dump();
} else {
ret = json11::Json("").dump();
}
free(result->value.string);
return ret;
}
}
case ParamsType::BYTEARRAYSTRING: {
if (!result->value.byteArray) {
return "";//null
} else {
std::string ret;
if (result->value.byteArray->length > 0) {
ret = json11::Json(result->value.byteArray->content).dump();
} else {
ret = json11::Json("").dump();
}
free(result->value.byteArray);
return ret;
}
}
case ParamsType::JSONSTRING: {
if (!result->value.string) {
return "";
} else {
std::string ret;
std::string err;
if (result->value.string->length > 0) {
const auto& raw_str = weex::base::to_utf8(result->value.string->content,
result->value.string->length);
const json11::Json& json = json11::Json::parse(raw_str, err);
if (err.empty()) {
//succ
ret = json.dump();
} else {
LOGE("VnodeManager CallNative return value to object err, %s", err.c_str());
}
}
free(result->value.string);
return ret;
}
}
case ParamsType::BYTEARRAYJSONSTRING: {
if (!result->value.byteArray) {
return "";
} else {
std::string ret;
std::string err;
if (result->value.string->length > 0) {
const json11::Json& json = json11::Json::parse(result->value.byteArray->content, err);
if (err.empty()) {
//succ
ret = json.dump();
} else {
LOGE("VnodeManager CallNative return value to object err, %s", err.c_str());
}
}
free(result->value.byteArray);
return ret;
}
}
case ParamsType::BYTEARRAY:
default:
return "";
}
}
std::string EagleBridge::WeexCoreHandler::CallNativeModule(const char* page_id,
const char* module,
const char* method,
const char* arguments,
int arguments_length,
const char* options,
int options_length) {
auto ptr = WeexCoreManager::Instance()
->getPlatformBridge()
->platform_side()
->CallNativeModule(page_id, module, method, arguments, arguments_length, options,
options_length);
return ParsePlatformResultToString(ptr);
}
#if OS_IOS
void EagleBridge::WeexCoreHandler::PostTaskOnComponentThread(const weex::base::Closure& closure) {
WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->PostTaskOnComponentThread(closure);
}
#endif
void EagleBridge::WeexCoreHandler::CallNativeComponent(const char* page_id,
const char* module,
const char* method,
const char* arguments,
int arguments_length,
const char* options,
int options_length) {
WeexCoreManager::Instance()
->getPlatformBridge()
->platform_side()
->CallNativeComponent(page_id, module, method, arguments, arguments_length, options,
options_length);
}
void EagleBridge::WeexCoreHandler::NativeLog(const char* str_array) {
WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->NativeLog(str_array);
}
bool EagleBridge::WeexCoreHandler::RemoveRenderObject(const std::string& page_id,
const std::string& ref) {
return RenderManager::GetInstance()->RemoveRenderObject(page_id, ref);
}
bool EagleBridge::WeexCoreHandler::AddRenderObject(const std::string& page_id,
const std::string& parent_ref,
int index,
EagleRenderObject root) {
return RenderManager::GetInstance()->AddRenderObject(page_id, parent_ref, index,
root.render_object_impl_);
}
bool EagleBridge::WeexCoreHandler::MoveRenderObject(const std::string& page_id,
const std::string& ref,
const std::string& parent_ref,
int index) {
return RenderManager::GetInstance()->MoveRenderObject(page_id, ref, parent_ref, index);
}
bool EagleBridge::WeexCoreHandler::RemoveEvent(const std::string& page_id, const std::string& ref,
const std::string& event) {
return RenderManager::GetInstance()->RemoveEvent(page_id, ref, event);
}
bool EagleBridge::WeexCoreHandler::AddEvent(const std::string& page_id, const std::string& ref,
const std::string& event) {
return RenderManager::GetInstance()->AddEvent(page_id, ref, event);
}
bool EagleBridge::WeexCoreHandler::UpdateAttr(const std::string& page_id, const std::string& ref,
const char* data) {
return RenderManager::GetInstance()->UpdateAttr(page_id, ref, data);
}
bool EagleBridge::WeexCoreHandler::UpdateAttr(const std::string& page_id, const std::string& ref,
std::vector<std::pair<std::string, std::string>>* attrPair) {
return RenderManager::GetInstance()->UpdateAttr(page_id, ref, attrPair);
}
bool EagleBridge::WeexCoreHandler::UpdateStyle(const std::string& page_id, const std::string& ref,
const char* data) {
return RenderManager::GetInstance()->UpdateStyle(page_id, ref, data);
}
bool EagleBridge::WeexCoreHandler::UpdateStyle(const std::string& page_id, const std::string& ref,
std::vector<std::pair<std::string, std::string>>* stylePair) {
return RenderManager::GetInstance()->UpdateStyle(page_id, ref, stylePair);
}
int EagleBridge::WeexCoreHandler::ExecJS(const char* instanceId, const char* nameSpace,
const char* func,
std::vector<ValueWithType*>& params) {
return WeexCore::WeexCoreManager::Instance()->script_bridge()->script_side()->ExecJS(
instanceId,
nameSpace,
func,
params
);
}
//FIXME Please don't call this method, which will cause downgrade of Weex.
void EagleBridge::WeexCoreHandler::PostTaskToMsgLoop(const weex::base::Closure& closure) {
WeexCore::WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->ReportException(
"", "PostTaskToMsgLoop",
"PostTaskToMsgLoop is not supported anymore, please update to the latest version of Weex.");
}
bool EagleBridge::WeexCoreHandler::CallWeexTaskFromEagle(const std::string& type,
const std::string& task,
const std::string& options) {
//No Extend Method now.
return false;
}
}