| /** |
| * 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 "core/bridge/platform/core_side_in_platform.h" |
| |
| #include "core/common/view_utils.h" |
| #include "base/string_util.h" |
| #include "base/log_defines.h" |
| #include "core/config/core_environment.h" |
| #include "core/manager/weex_core_manager.h" |
| #include "core/render/manager/render_manager.h" |
| #include "core/render/node/factory/render_creator.h" |
| #include "core/render/node/factory/render_type.h" |
| #include "core/render/node/render_list.h" |
| #include "core/render/node/render_object.h" |
| #include "core/render/page/render_page.h" |
| #include "core/json/JsonRenderManager.h" |
| #include "core/bridge/eagle_bridge.h" |
| #include "third_party/json11/json11.hpp" |
| #include "core/moniter/render_performance.h" |
| #include "core_side_in_platform.h" |
| |
| #ifdef OS_ANDROID |
| #include <android/utils/params_utils.h> |
| #include <wson/wson.h> |
| #endif |
| |
| namespace WeexCore { |
| |
| CoreSideInPlatform::CoreSideInPlatform() {} |
| CoreSideInPlatform::~CoreSideInPlatform() {} |
| void CoreSideInPlatform::SetDefaultHeightAndWidthIntoRootDom( |
| const std::string &instance_id, float default_width, float default_height, |
| bool is_width_wrap_content, bool is_height_wrap_content) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| page->SetDefaultHeightAndWidthIntoRootRender(default_width, default_height, |
| is_width_wrap_content, |
| is_height_wrap_content); |
| } |
| |
| void CoreSideInPlatform::OnInstanceClose(const std::string &instance_id) { |
| RenderManager::GetInstance()->ClosePage(instance_id); |
| } |
| |
| void CoreSideInPlatform::SetStyleWidth(const std::string &instance_id, |
| const std::string &render_ref, |
| float width) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_ref); |
| if (render == nullptr) return; |
| |
| render->setStyleWidthLevel(CSS_STYLE); |
| render->setStyleWidth(width, true); |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::SetStyleHeight(const std::string &instance_id, |
| const std::string &render_ref, |
| float height) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_ref); |
| if (render == nullptr) return; |
| |
| render->setStyleHeightLevel(CSS_STYLE); |
| render->setStyleHeight(height); |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::SetMargin(const std::string &instance_id, |
| const std::string &render_ref, int edge, |
| float value) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_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); |
| } |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::SetPadding(const std::string &instance_id, |
| const std::string &render_ref, int edge, |
| float value) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_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); |
| } |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::SetPosition(const std::string &instance_id, |
| const std::string &render_ref, int edge, |
| float value) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_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); |
| } |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::MarkDirty(const std::string &instance_id, |
| const std::string &render_ref) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| RenderObject *render = static_cast<RenderPage*>(page)->GetRenderObject(render_ref); |
| if (render == nullptr) return; |
| render->markDirty(); |
| } |
| |
| void CoreSideInPlatform::SetViewPortWidth(const std::string &instance_id, |
| float width) { |
| RenderManager::GetInstance()->set_viewport_width(instance_id, width); |
| } |
| |
| void CoreSideInPlatform::SetDeviceDisplayOfPage(const std::string &instance_id, float width, float height /* unused now */) { |
| RenderManager::GetInstance()->setDeviceWidth(instance_id, width); |
| } |
| |
| void CoreSideInPlatform::SetPageRenderType(const std::string &pageId, |
| const std::string &renderType) { |
| RenderManager::GetInstance()->setPageArgument(pageId, "renderType", renderType); |
| } |
| |
| void CoreSideInPlatform::RemovePageRenderType(const std::string &pageId) { |
| // void |
| } |
| |
| |
| void CoreSideInPlatform::SetPageArgument(const std::string &pageId, const std::string& key, const std::string& value){ |
| RenderManager::GetInstance()->setPageArgument(pageId, key, value); |
| } |
| |
| void CoreSideInPlatform::SetDeviceDisplay(const std::string &instance_id, float width, float height, float scale) { |
| RenderManager::GetInstance()->setDeviceWidth(instance_id, width); |
| |
| /** |
| * also update global device with height and options |
| * */ |
| WXCoreEnvironment::getInstance()->SetDeviceWidth(std::to_string(width)); |
| WXCoreEnvironment::getInstance()->SetDeviceHeight(std::to_string(height)); |
| WXCoreEnvironment::getInstance()->PutOption(SCALE, std::to_string(scale)); |
| } |
| |
| void CoreSideInPlatform::SetPageDirty(const std::string &instance_id) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(std::string(instance_id)); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| static_cast<RenderPage*>(page)->set_is_dirty(true); |
| } |
| |
| void CoreSideInPlatform::ForceLayout(const std::string &instance_id) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page != nullptr) { |
| if (!page->is_platform_page()) return; |
| static_cast<RenderPage*>(page)->LayoutImmediately(); |
| static_cast<RenderPage*>(page)->has_fore_layout_action_.store(false); |
| } |
| } |
| |
| bool CoreSideInPlatform::NotifyLayout(const std::string &instance_id) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page != nullptr) { |
| if (!page->is_platform_page()) return false; |
| |
| if (!static_cast<RenderPage*>(page)->need_layout_.load()) { |
| static_cast<RenderPage*>(page)->need_layout_.store(true); |
| } |
| |
| bool ret = !static_cast<RenderPage*>(page)->has_fore_layout_action_.load() && static_cast<RenderPage*>(page)->is_dirty(); |
| if (ret) { |
| static_cast<RenderPage*>(page)->has_fore_layout_action_.store(true); |
| } |
| return ret ? true : false; |
| } |
| return false; |
| } |
| |
| bool CoreSideInPlatform::RelayoutUsingRawCssStyles(const std::string& instance_id) { |
| return RenderManager::GetInstance()->ReloadPageLayout(instance_id); |
| } |
| |
| std::vector<int64_t> CoreSideInPlatform::GetFirstScreenRenderTime( |
| const std::string &instance_id) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) { |
| return std::vector<int64_t>(); |
| } else { |
| return page->PrintFirstScreenLog(); |
| } |
| } |
| |
| std::vector<int64_t> CoreSideInPlatform::GetRenderFinishTime( |
| const std::string &instance_id) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) { |
| return std::vector<int64_t>(); |
| } else { |
| return page->PrintRenderSuccessLog(); |
| } |
| } |
| |
| void CoreSideInPlatform::SetRenderContainerWrapContent( |
| const std::string &instance_id, bool wrap) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) return; |
| if (!page->is_platform_page()) return; |
| |
| static_cast<RenderPage*>(page)->set_is_render_container_width_wrap_content(wrap); |
| } |
| |
| void CoreSideInPlatform::BindMeasurementToRenderObject(long ptr) { |
| RenderObject *render = convert_long_to_render_object(ptr); |
| if (render && measure_function_adapter_exist_) { |
| render->BindMeasureFunc(); |
| } |
| } |
| |
| void CoreSideInPlatform::RegisterCoreEnv(const std::string &key, |
| const std::string &value) { |
| WXCoreEnvironment::getInstance()->AddOption(key, value); |
| } |
| |
| long CoreSideInPlatform::GetRenderObject(const std::string &instance_id, |
| const std::string &render_ref) { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instance_id); |
| if (page == nullptr) { |
| return 0; |
| } |
| return convert_render_object_to_long(page->GetRenderObject(render_ref)); |
| } |
| |
| void CoreSideInPlatform::UpdateRenderObjectStyle(long render_ptr, |
| const std::string &key, |
| const std::string &value) { |
| RenderObject *render = convert_long_to_render_object(render_ptr); |
| render->UpdateStyle(key, value); |
| } |
| |
| void CoreSideInPlatform::UpdateRenderObjectAttr(long render_ptr, |
| const std::string &key, |
| const std::string &value) { |
| RenderObject *render = convert_long_to_render_object(render_ptr); |
| render->UpdateAttr(key, value); |
| render->markDirty(true); |
| } |
| |
| long CoreSideInPlatform::CopyRenderObject(long render_ptr) { |
| RenderObject *render = convert_long_to_render_object(render_ptr); |
| RenderObject *copy = |
| static_cast<RenderObject *>(RenderCreator::GetInstance()->CreateRender( |
| render->type(), render->ref())); |
| copy->CopyFrom(render); |
| if (render->type() == WeexCore::kRenderCellSlot || |
| render->type() == WeexCore::kRenderCell) { |
| RenderList *renderList = static_cast<RenderList *>(render->getParent()); |
| if (renderList != nullptr) { |
| renderList->AddCellSlotCopyTrack(copy); |
| } else { |
| LOGE("CopyRenderObject: %s", "copy error parent null"); |
| } |
| } |
| return convert_render_object_to_long(copy); |
| } |
| |
| void CoreSideInPlatform::SetMeasureFunctionAdapter() { |
| measure_function_adapter_exist_ = true; |
| } |
| |
| void CoreSideInPlatform::SetPlatform(const std::string &platformName) { |
| WXCoreEnvironment::getInstance()->SetPlatform(platformName); |
| } |
| |
| void CoreSideInPlatform::SetDeviceWidthAndHeight(float width, float height) { |
| WXCoreEnvironment::getInstance()->set_device_width(width); |
| WXCoreEnvironment::getInstance()->set_device_height(height); |
| } |
| |
| void CoreSideInPlatform::AddOption(const std::string &key, |
| const std::string &value) { |
| WXCoreEnvironment::getInstance()->AddOption(key, value); |
| } |
| |
| int CoreSideInPlatform::RefreshInstance( |
| const char *instanceId, const char *nameSpace, const char *func, |
| std::vector<VALUE_WITH_TYPE *> ¶ms) { |
| #ifdef OS_ANDROID |
| if(params.size() < 2) |
| return false; |
| |
| if(params[1]->value.string->length <= 0) |
| return false; |
| |
| std::string init_data = weex::base::to_utf8(params[1]->value.string->content, |
| params[1]->value.string->length); |
| |
| EagleModeReturn mode = EagleBridge::GetInstance()->RefreshPage(instanceId, init_data.c_str()); |
| if (mode == EagleModeReturn::EAGLE_ONLY){ |
| return true; |
| } else { |
| //mode == EagleModeReturn::EAGLE_AND_SCRIPT || mode == EagleModeReturn::NOT_EAGLE |
| //continue; |
| } |
| return ExecJS(instanceId, nameSpace, func, params); |
| #else |
| return 0; |
| #endif |
| } |
| |
| int CoreSideInPlatform::InitFramework( |
| const char *script, std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->InitFramework(script, params); |
| } |
| |
| int CoreSideInPlatform::InitAppFramework( |
| const char *instanceId, const char *appFramework, |
| std::vector<INIT_FRAMEWORK_PARAMS *> ¶ms) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->InitAppFramework(instanceId, appFramework, params); |
| } |
| |
| int CoreSideInPlatform::CreateAppContext(const char *instanceId, |
| const char *jsBundle) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->CreateAppContext(instanceId, jsBundle); |
| } |
| |
| std::unique_ptr<WeexJSResult> CoreSideInPlatform::ExecJSOnAppWithResult(const char *instanceId, |
| const char *jsBundle) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecJSOnAppWithResult(instanceId, jsBundle); |
| } |
| |
| int CoreSideInPlatform::CallJSOnAppContext( |
| const char *instanceId, const char *func, |
| std::vector<VALUE_WITH_TYPE *> ¶ms) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->CallJSOnAppContext(instanceId, func, params); |
| } |
| |
| int CoreSideInPlatform::DestroyAppContext(const char *instanceId) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->DestroyAppContext(instanceId); |
| } |
| |
| int CoreSideInPlatform::ExecJsService(const char *source) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecJsService(source); |
| } |
| |
| int CoreSideInPlatform::ExecTimeCallback(const char *source) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecTimeCallback(source); |
| } |
| |
| int CoreSideInPlatform::ExecJS(const char *instanceId, const char *nameSpace, |
| const char *func, |
| std::vector<VALUE_WITH_TYPE *> ¶ms) { |
| return WeexCoreManager::Instance()->script_bridge()->script_side()->ExecJS( |
| instanceId, nameSpace, func, params); |
| } |
| |
| std::unique_ptr<WeexJSResult> CoreSideInPlatform::ExecJSWithResult( |
| const char *instanceId, const char *nameSpace, const char *func, |
| std::vector<VALUE_WITH_TYPE *> ¶ms) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecJSWithResult(instanceId, nameSpace, func, params); |
| } |
| |
| void CoreSideInPlatform::ExecJSWithCallback( |
| const char *instanceId, const char *nameSpace, const char *func, |
| std::vector<VALUE_WITH_TYPE *> ¶ms, long callback_id) { |
| WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecJSWithCallback(instanceId, nameSpace, func, params, callback_id); |
| } |
| |
| int CoreSideInPlatform::CreateInstance(const char *instanceId, const char *func, |
| const char *script, int script_length, |
| const char *opts, |
| const char *initData, |
| const char *extendsApi, std::vector<INIT_FRAMEWORK_PARAMS*>& params, |
| const char *render_strategy) { |
| if (render_strategy != nullptr) { |
| if(strcmp(render_strategy, "JSON_RENDER") == 0){ |
| JsonRenderManager::GetInstance()->CreatePage(script, instanceId, render_strategy); |
| return true; |
| } |
| |
| EagleBridge::GetInstance()->CreatePage(render_strategy, instanceId, func, script, script_length, opts, initData ,extendsApi, 0); |
| return true; |
| } |
| |
| |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->CreateInstance(instanceId, func, script, opts, initData, extendsApi, params); |
| } |
| |
| std::unique_ptr<WeexJSResult> CoreSideInPlatform::ExecJSOnInstance(const char *instanceId, |
| const char *script, int type) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->ExecJSOnInstance(instanceId, script,type); |
| } |
| |
| int CoreSideInPlatform::DestroyInstance(const char *instanceId) { |
| if (JsonRenderManager::GetInstance()->ClosePage(instanceId)) { |
| return true; |
| } |
| EagleModeReturn mode = EagleBridge::GetInstance()->DestroyPage(instanceId); |
| if (mode == EagleModeReturn::EAGLE_ONLY){ |
| return true; |
| } else { |
| //mode == EagleModeReturn::EAGLE_AND_SCRIPT || mode == EagleModeReturn::NOT_EAGLE |
| //continue; |
| } |
| auto script_side = WeexCoreManager::Instance()->script_bridge()->script_side(); |
| if (script_side) { |
| return script_side->DestroyInstance(instanceId); |
| } |
| return true; |
| } |
| |
| int CoreSideInPlatform::UpdateGlobalConfig(const char *config) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->UpdateGlobalConfig(config); |
| } |
| |
| |
| int CoreSideInPlatform::UpdateInitFrameworkParams(const std::string &key, const std::string &value, |
| const std::string &desc) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->UpdateInitFrameworkParams(key, value, desc); |
| } |
| |
| void CoreSideInPlatform::SetLogType(const int logType, const bool isPerf) { |
| WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->SetLogType(logType,isPerf); |
| } |
| |
| double CoreSideInPlatform::GetLayoutTime(const char* instanceId) const { |
| RenderPageBase *page = RenderManager::GetInstance()->GetPage(instanceId); |
| if (page == nullptr) return 0; |
| if (!page->is_platform_page()) return 0; |
| return page->getPerformance()->cssLayoutTime; |
| } |
| |
| int64_t CoreSideInPlatform::JsAction(long ctxContainer, int32_t jsActionType, const char *arg) { |
| return WeexCoreManager::Instance() |
| ->script_bridge() |
| ->script_side() |
| ->JsAction(ctxContainer, jsActionType, arg); |
| } |
| |
| } // namespace WeexCore |