mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
Signed-off-by: zhongjianfei <zhongjianfei@huawei.com> Change-Id: Id693aa3c4e59c491ca42006bd4ba19e5f335ee16
This commit is contained in:
parent
d32cd0ddfa
commit
cce980c0f8
7
BUILD.gn
7
BUILD.gn
@ -35,7 +35,8 @@ group("ace_packages") {
|
||||
deps += [
|
||||
"adapter/common/cpp:libace_engine_qjs",
|
||||
"adapter/common/cpp:libace_engine_qjs_debug",
|
||||
"adapter/common/cpp:libace_engine_declarative_qjs"
|
||||
"adapter/common/cpp:libace_engine_declarative_qjs",
|
||||
"adapter/common/cpp:libace_engine_pa_qjs"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -102,6 +103,10 @@ config("ace_config") {
|
||||
cflags += [ "-std=c++17" ]
|
||||
defines += [ "_USE_MATH_DEFINES" ]
|
||||
}
|
||||
|
||||
if (enable_ace_debug) {
|
||||
defines += [ "ACE_DEBUG" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("ace_test_config") {
|
||||
|
@ -14,6 +14,7 @@
|
||||
import("//third_party/flutter/flutter_ace_config.gni")
|
||||
|
||||
ace_root = "//foundation/ace/ace_engine"
|
||||
ace_flutter_engine_root = "//third_party/flutter"
|
||||
|
||||
ace_test_output_root = "ace_engine_standard"
|
||||
|
||||
@ -24,3 +25,4 @@ node_js_path = "//prebuilts/ace-toolkit/nodejs/node-v12.18.4-linux-x64/bin/"
|
||||
cjson_root = "//third_party/cJSON"
|
||||
|
||||
use_js_debug = false
|
||||
enable_ace_debug = false
|
||||
|
@ -23,8 +23,8 @@ template("ace_base_platform_source_set") {
|
||||
defines += invoker.defines
|
||||
configs = [
|
||||
"$ace_root:ace_config",
|
||||
"$flutter_root:flutter_config",
|
||||
"$flutter_root:icu_config_$platform",
|
||||
"$ace_flutter_engine_root:flutter_config",
|
||||
"$ace_flutter_engine_root:icu_config_$platform",
|
||||
]
|
||||
|
||||
include_dirs = [ "//utils/native/base/include" ]
|
||||
@ -34,8 +34,10 @@ template("ace_base_platform_source_set") {
|
||||
"ace_res_key_parser.cpp",
|
||||
"ace_trace.cpp",
|
||||
"file_asset_provider.cpp",
|
||||
"flutter_asset_manager.cpp",
|
||||
"flutter_task_executor.cpp",
|
||||
"localization.cpp",
|
||||
"string_utils.cpp",
|
||||
"thread_util.cpp",
|
||||
]
|
||||
if (is_standard_system) {
|
||||
@ -72,14 +74,13 @@ template("libace_shared_library") {
|
||||
"$ace_root/frameworks/core/accessibility:ace_accessibility_$platform",
|
||||
]
|
||||
|
||||
|
||||
if (link_qjs_engine) {
|
||||
if (use_js_debug) {
|
||||
deps += [ "$ace_root/frameworks/bridge:js_engine_debug_$platform" ]
|
||||
} else {
|
||||
deps += [
|
||||
"$ace_root/frameworks/bridge:js_engine_$platform",
|
||||
"$ace_root/frameworks/bridge:declarative_js_engine_qjs_$platform",
|
||||
]
|
||||
deps += [ "$ace_root/frameworks/bridge:js_engine_$platform",
|
||||
"$ace_root/frameworks/bridge:js_backend_engine_$platform" ]
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +138,8 @@ template("ace_platform_engine") {
|
||||
} else if (is_declarative) {
|
||||
deps += [ "$ace_root/frameworks/bridge:declarative_js_engine_qjs_$platform" ]
|
||||
} else {
|
||||
deps += [ "$ace_root/frameworks/bridge:js_engine_$platform"]
|
||||
deps += [ "$ace_root/frameworks/bridge:js_engine_$platform",
|
||||
"$ace_root/frameworks/bridge:js_backend_engine_$platform"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +171,15 @@ ace_platform_engine("libace_engine_declarative_qjs") {
|
||||
is_declarative = true
|
||||
}
|
||||
|
||||
ace_platform_engine("libace_engine_pa_qjs") {
|
||||
is_ohos_platform = true
|
||||
use_quickjs_engine = true
|
||||
if (is_standard_system) {
|
||||
platform = "ohos"
|
||||
}
|
||||
is_declarative = false
|
||||
}
|
||||
|
||||
ace_platform_engine("libace_engine_qjs_debug") {
|
||||
is_ohos_platform = true
|
||||
use_quickjs_engine = true
|
||||
|
@ -108,13 +108,18 @@ std::unique_ptr<fml::Mapping> FileAssetProvider::GetAsMapping(const std::string&
|
||||
|
||||
std::string FileAssetProvider::GetAssetPath(const std::string& assetName)
|
||||
{
|
||||
auto filePath = filePathMap_.find(assetName);
|
||||
if (filePath == filePathMap_.end()) {
|
||||
return "";
|
||||
for (const auto& basePath: assetBasePaths_) {
|
||||
std::string assetBasePath = packagePath_ + basePath;
|
||||
std::string fileName = assetBasePath + assetName;
|
||||
std::FILE* fp = std::fopen(fileName.c_str(), "r");
|
||||
if (fp == nullptr) {
|
||||
continue;
|
||||
}
|
||||
std::fclose(fp);
|
||||
return assetBasePath;
|
||||
}
|
||||
std::string assetPath;
|
||||
assetPath.append(packagePath_).append("!/").append(filePath->second);
|
||||
return assetPath;
|
||||
LOGE("Cannot find base path of %{public}s", assetName.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -13,22 +13,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components/box/box_base_element.h"
|
||||
|
||||
#include "core/components/box/box_base_component.h"
|
||||
#include "adapter/common/cpp/flutter_asset_manager.h"
|
||||
#include "adapter/common/cpp/file_asset_provider.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
void BoxBaseElement::PerformBuild()
|
||||
std::string FlutterAssetManager::GetAssetPath(const std::string& assetName)
|
||||
{
|
||||
RefPtr<BoxBaseComponent> box = AceType::DynamicCast<BoxBaseComponent>(component_);
|
||||
if (box) {
|
||||
RefPtr<Component> newComponent = box->GetChild();
|
||||
if (newComponent) {
|
||||
const auto& child = children_.empty() ? nullptr : children_.front();
|
||||
UpdateChild(child, newComponent);
|
||||
for (const auto& provider : providers_) {
|
||||
auto fileAssetProvider = static_cast<FileAssetProvider*>(provider.get());
|
||||
std::string path = fileAssetProvider->GetAssetPath(assetName);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
@ -47,7 +47,7 @@ private:
|
||||
std::unique_ptr<fml::Mapping> mapping_;
|
||||
};
|
||||
|
||||
class FlutterAssetManager final : public AssetManager {
|
||||
class ACE_EXPORT FlutterAssetManager final : public AssetManager {
|
||||
DECLARE_ACE_TYPE(FlutterAssetManager, AssetManager);
|
||||
|
||||
public:
|
||||
@ -86,6 +86,8 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string GetAssetPath(const std::string& assetName) override;
|
||||
|
||||
private:
|
||||
std::deque<std::unique_ptr<flutter::AssetResolver>> providers_;
|
||||
};
|
||||
|
@ -76,6 +76,10 @@ FlutterTaskExecutor::~FlutterTaskExecutor()
|
||||
void FlutterTaskExecutor::InitPlatformThread()
|
||||
{
|
||||
platformRunner_ = flutter::PlatformTaskRunnerAdapter::CurrentTaskRunner();
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
FillTaskTypeTable(TaskType::PLATFORM);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::InitJsThread(bool newThread)
|
||||
@ -86,6 +90,11 @@ void FlutterTaskExecutor::InitJsThread(bool newThread)
|
||||
} else {
|
||||
jsRunner_ = uiRunner_;
|
||||
}
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
PostTaskToTaskRunner(
|
||||
jsRunner_, [weak = AceType::WeakClaim(this)] { FillTaskTypeTable(weak, TaskType::JS); }, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::InitOtherThreads(const flutter::TaskRunners& taskRunners)
|
||||
@ -98,6 +107,15 @@ void FlutterTaskExecutor::InitOtherThreads(const flutter::TaskRunners& taskRunne
|
||||
uiRunner_, [] { SetThreadPriority(UI_THREAD_PRIORITY); }, 0);
|
||||
PostTaskToTaskRunner(
|
||||
gpuRunner_, [] { SetThreadPriority(GPU_THREAD_PRIORITY); }, 0);
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
PostTaskToTaskRunner(
|
||||
uiRunner_, [weak = AceType::WeakClaim(this)] { FillTaskTypeTable(weak, TaskType::UI); }, 0);
|
||||
PostTaskToTaskRunner(
|
||||
ioRunner_, [weak = AceType::WeakClaim(this)] { FillTaskTypeTable(weak, TaskType::IO); }, 0);
|
||||
PostTaskToTaskRunner(
|
||||
gpuRunner_, [weak = AceType::WeakClaim(this)] { FillTaskTypeTable(weak, TaskType::GPU); }, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FlutterTaskExecutor::OnPostTask(Task&& task, TaskType type, uint32_t delayTime) const
|
||||
@ -152,4 +170,100 @@ void FlutterTaskExecutor::RemoveTaskObserver()
|
||||
fml::MessageLoop::GetCurrent().RemoveTaskObserver(reinterpret_cast<intptr_t>(this));
|
||||
}
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
static const char* TaskTypeToString(TaskExecutor::TaskType type)
|
||||
{
|
||||
switch (type) {
|
||||
case TaskExecutor::TaskType::PLATFORM:
|
||||
return "PLATFORM";
|
||||
case TaskExecutor::TaskType::UI:
|
||||
return "UI";
|
||||
case TaskExecutor::TaskType::IO:
|
||||
return "IO";
|
||||
case TaskExecutor::TaskType::GPU:
|
||||
return "GPU";
|
||||
case TaskExecutor::TaskType::JS:
|
||||
return "JS";
|
||||
case TaskExecutor::TaskType::BACKGROUND:
|
||||
return "BACKGROUND";
|
||||
case TaskExecutor::TaskType::UNKNOWN:
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
thread_local TaskExecutor::TaskType FlutterTaskExecutor::localTaskType = TaskExecutor::TaskType::UNKNOWN;
|
||||
|
||||
bool FlutterTaskExecutor::OnPreSyncTask(TaskType type) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(tableMutex_);
|
||||
auto it = taskTypeTable_.find(type);
|
||||
// when task type not filled, just skip
|
||||
if (it == taskTypeTable_.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto itSync = syncTaskTable_.find(it->second.threadId);
|
||||
while (itSync != syncTaskTable_.end()) {
|
||||
if (itSync->second == std::this_thread::get_id()) {
|
||||
DumpDeadSyncTask(localTaskType, type);
|
||||
ACE_DCHECK(itSync->second != std::this_thread::get_id() && "DEAD LOCK HAPPENED !!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
itSync = syncTaskTable_.find(itSync->second);
|
||||
}
|
||||
|
||||
syncTaskTable_.emplace(std::this_thread::get_id(), it->second.threadId);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::OnPostSyncTask() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(tableMutex_);
|
||||
syncTaskTable_.erase(std::this_thread::get_id());
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::DumpDeadSyncTask(TaskType from, TaskType to) const
|
||||
{
|
||||
auto itFrom = taskTypeTable_.find(from);
|
||||
auto itTo = taskTypeTable_.find(to);
|
||||
|
||||
ACE_DCHECK(itFrom != taskTypeTable_.end());
|
||||
ACE_DCHECK(itTo != taskTypeTable_.end());
|
||||
|
||||
LOGE("DEAD LOCK HAPPEN: %{public}s(%{public}d, %{public}s) -> %{public}s(%{public}d, %{public}s)",
|
||||
TaskTypeToString(from), itFrom->second.tid, itFrom->second.threadName.c_str(),
|
||||
TaskTypeToString(to), itTo->second.tid, itTo->second.threadName.c_str());
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::FillTaskTypeTable(TaskType type)
|
||||
{
|
||||
constexpr size_t MAX_THREAD_NAME_SIZE = 32;
|
||||
char threadNameBuf[MAX_THREAD_NAME_SIZE] = {0};
|
||||
const char *threadName = threadNameBuf;
|
||||
if (pthread_getname_np(pthread_self(), threadNameBuf, sizeof(threadNameBuf)) != 0) {
|
||||
threadName = "unknown";
|
||||
}
|
||||
|
||||
localTaskType = type;
|
||||
ThreadInfo info = {
|
||||
.threadId = std::this_thread::get_id(),
|
||||
.tid = gettid(),
|
||||
.threadName = threadName,
|
||||
};
|
||||
|
||||
std::lock_guard<std::mutex> lock(tableMutex_);
|
||||
taskTypeTable_.emplace(type, info);
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::FillTaskTypeTable(const WeakPtr<FlutterTaskExecutor>& weak, TaskType type)
|
||||
{
|
||||
auto taskExecutor = weak.Upgrade();
|
||||
if (taskExecutor) {
|
||||
taskExecutor->FillTaskTypeTable(type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -16,6 +16,11 @@
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_CPP_FLUTTER_TASK_EXECUTOR_H
|
||||
#define FOUNDATION_ACE_ADAPTER_CPP_FLUTTER_TASK_EXECUTOR_H
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#include "flutter/common/task_runners.h"
|
||||
#include "flutter/fml/thread.h"
|
||||
|
||||
@ -41,6 +46,27 @@ public:
|
||||
private:
|
||||
bool OnPostTask(Task&& task, TaskType type, uint32_t delayTime) const final;
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
bool OnPreSyncTask(TaskType type) const final;
|
||||
void OnPostSyncTask() const final;
|
||||
|
||||
void DumpDeadSyncTask(TaskType from, TaskType to) const;
|
||||
|
||||
void FillTaskTypeTable(TaskType type);
|
||||
static void FillTaskTypeTable(const WeakPtr<FlutterTaskExecutor>& weak, TaskType type);
|
||||
|
||||
struct ThreadInfo {
|
||||
std::thread::id threadId;
|
||||
int32_t tid = 0;
|
||||
std::string threadName;
|
||||
};
|
||||
|
||||
mutable std::mutex tableMutex_;
|
||||
mutable std::unordered_map<std::thread::id, std::thread::id> syncTaskTable_;
|
||||
std::unordered_map<TaskType, ThreadInfo> taskTypeTable_;
|
||||
static thread_local TaskType localTaskType;
|
||||
#endif
|
||||
|
||||
std::unique_ptr<fml::Thread> jsThread_;
|
||||
|
||||
fml::RefPtr<fml::TaskRunner> platformRunner_;
|
||||
|
44
adapter/common/cpp/string_utils.cpp
Normal file
44
adapter/common/cpp/string_utils.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "base/utils/string_utils.h"
|
||||
|
||||
#ifndef WINDOWS_PLATFORM
|
||||
#include "securec.h"
|
||||
#endif
|
||||
|
||||
namespace OHOS::Ace::StringUtils {
|
||||
namespace {
|
||||
|
||||
const size_t MAX_STRING_SIZE = 256;
|
||||
|
||||
}
|
||||
|
||||
const std::string FormatString(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char name[MAX_STRING_SIZE] = { 0 };
|
||||
if (vsnprintf_s(name, sizeof(name), sizeof(name) - 1, fmt, args) < 0) {
|
||||
va_end(args);
|
||||
return "";
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::StringUtils
|
@ -24,8 +24,11 @@ template("ace_base_platform_source_set") {
|
||||
|
||||
sources = [
|
||||
"$ace_root/adapter/ohos/cpp/ace_ability.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/ace_service_ability.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/ace_data_ability.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/ace_application_info.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/ace_container.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/pa_container.cpp",
|
||||
"$ace_root/adapter/ohos/cpp/flutter_ace_view.cpp",
|
||||
]
|
||||
|
||||
@ -35,7 +38,12 @@ template("ace_base_platform_source_set") {
|
||||
"$flutter_root:icu_config_$platform",
|
||||
]
|
||||
|
||||
include_dirs = [ "//utils/native/base/include" ]
|
||||
include_dirs = [
|
||||
"//foundation/aafwk/standard/interfaces/kits/napi/aafwk/featureAbility",
|
||||
"//foundation/ace/napi/interfaces/kits",
|
||||
"//third_party/node/src",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$flutter_root:ace_skia_$platform",
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "adapter/ohos/cpp/ace_ability.h"
|
||||
|
||||
#include "ability_process.h"
|
||||
#include "adapter/ohos/cpp/ace_container.h"
|
||||
#include "adapter/ohos/cpp/flutter_ace_view.h"
|
||||
#include "base/log/log.h"
|
||||
@ -65,6 +66,12 @@ FrontendType GetFrontendTypeFromManifest(const std::string& packagePathStr)
|
||||
|
||||
std::string jsonString(jsonStream.get(), jsonStream.get() + size);
|
||||
auto rootJson = JsonUtil::ParseJsonString(jsonString);
|
||||
auto mode = rootJson->GetObject("mode");
|
||||
if (mode != nullptr) {
|
||||
if (mode->GetString("syntax") == "ets" || mode->GetString("type") == "pageAbility") {
|
||||
return FrontendType::DECLARATIVE_JS;
|
||||
}
|
||||
}
|
||||
std::string frontendType = rootJson->GetString("type");
|
||||
if (frontendType == "normal") {
|
||||
return FrontendType::JS;
|
||||
@ -201,9 +208,10 @@ void AceAbility::OnStart(const Want& want)
|
||||
parsedPageUrl = "";
|
||||
}
|
||||
|
||||
// set window id
|
||||
auto context = Platform::AceContainer::GetContainer(abilityId_)->GetPipelineContext();
|
||||
if (context != nullptr) {
|
||||
context->SetWindowId(window->GetWindowID());
|
||||
context->SetWindowId(window->GetWindowID());
|
||||
}
|
||||
|
||||
// run page.
|
||||
@ -295,5 +303,20 @@ void AceAbility::OnConfigurationUpdated(const Configuration& configuration)
|
||||
LOGI("AceAbility::OnConfigurationUpdated called End");
|
||||
}
|
||||
|
||||
void AceAbility::OnAbilityResult(int requestCode, int resultCode, const OHOS::AAFwk::Want& resultData)
|
||||
{
|
||||
LOGI("AceAbility::OnAbilityResult called ");
|
||||
AbilityProcess::GetInstance()->OnAbilityResult(this, requestCode, resultCode, resultData);
|
||||
LOGI("AceAbility::OnAbilityResult called End");
|
||||
}
|
||||
|
||||
void AceAbility::OnRequestPermissionsFromUserResult(
|
||||
int requestCode, const std::vector<std::string> &permissions, const std::vector<int> &grantResults)
|
||||
{
|
||||
LOGI("AceAbility::OnRequestPermissionsFromUserResult called ");
|
||||
AbilityProcess::GetInstance()->OnRequestPermissionsFromUserResult(this, requestCode, permissions, grantResults);
|
||||
LOGI("AceAbility::OnRequestPermissionsFromUserResult called End");
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -16,6 +16,8 @@
|
||||
#ifndef FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_ABILITY_H
|
||||
#define FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_ABILITY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ability.h"
|
||||
#include "ability_loader.h"
|
||||
#include "want.h"
|
||||
@ -42,6 +44,9 @@ public:
|
||||
void OnRestoreAbilityState(const OHOS::AppExecFwk::PacMap& inState) override;
|
||||
void OnSaveAbilityState(OHOS::AppExecFwk::PacMap& outState) override;
|
||||
void OnConfigurationUpdated(const OHOS::AppExecFwk::Configuration& configuration) override;
|
||||
void OnAbilityResult(int requestCode, int resultCode, const OHOS::AAFwk::Want& resultData) override;
|
||||
void OnRequestPermissionsFromUserResult(
|
||||
int requestCode, const std::vector<std::string> &permissions, const std::vector<int> &grantResults) override;
|
||||
|
||||
private:
|
||||
static int32_t instanceId_;
|
||||
|
0
adapter/ohos/cpp/ace_application_info.cpp
Executable file → Normal file
0
adapter/ohos/cpp/ace_application_info.cpp
Executable file → Normal file
26
adapter/ohos/cpp/ace_application_info.h
Executable file → Normal file
26
adapter/ohos/cpp/ace_application_info.h
Executable file → Normal file
@ -38,13 +38,33 @@ public:
|
||||
void ChangeLocale(const std::string& language, const std::string& countryOrRegion) override;
|
||||
std::vector<std::string> GetLocaleFallback(const std::vector<std::string>& localeList) const override;
|
||||
std::vector<std::string> GetResourceFallback(const std::vector<std::string>& resourceList) const override;
|
||||
double GetLifeTime() const override { return 0.0f; }
|
||||
std::string GetCurrentDeviceResTag() const override;
|
||||
std::vector<std::string> GetStyleResourceFallback(const std::vector<std::string>& resourceList) const override
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
std::vector<std::string> GetDeclarativeResourceFallback(const std::set<std::string>& resourceList) const override
|
||||
{
|
||||
std::vector<std::string> vector;
|
||||
return vector;
|
||||
}
|
||||
|
||||
bool GetFiles(const std::string& filePath, std::vector<std::string>& fileList) const override;
|
||||
|
||||
bool GetBundleInfo(const std::string& packageName, AceBundleInfo& bundleInfo) override;
|
||||
|
||||
double GetLifeTime() const override
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
std::string GetJsEngineParam(const std::string& key) const override;
|
||||
std::string GetCurrentDeviceResTag() const override;
|
||||
std::string GetCurrentDeviceDeclarativeResTag() const override
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
double GetTargetMediaScaleRatio(const std::string& targetResTag) const override
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void SetJsEngineParam(const std::string& key, const std::string& value);
|
||||
|
||||
|
@ -51,11 +51,30 @@ AceContainer::AceContainer(int32_t instanceId, FrontendType type, AceAbility* ac
|
||||
flutterTaskExecutor->InitPlatformThread();
|
||||
flutterTaskExecutor->InitJsThread();
|
||||
taskExecutor_ = flutterTaskExecutor;
|
||||
if (type_ != FrontendType::DECLARATIVE_JS) {
|
||||
InitializeFrontend();
|
||||
taskExecutor_->PostTask([id = instanceId_]() { Container::InitForThread(id); }, TaskExecutor::TaskType::JS);
|
||||
platformEventCallback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void AceContainer::Initialize()
|
||||
{
|
||||
InitializeFrontend();
|
||||
}
|
||||
|
||||
void AceContainer::Destroy()
|
||||
{
|
||||
if (pipelineContext_ && taskExecutor_) {
|
||||
if (taskExecutor_) {
|
||||
taskExecutor_->PostTask([context = pipelineContext_]() { context->Destroy(); }, TaskExecutor::TaskType::UI);
|
||||
}
|
||||
}
|
||||
if (frontend_) {
|
||||
frontend_->UpdateState(Frontend::State::ON_DESTROY);
|
||||
}
|
||||
|
||||
platformEventCallback_ = std::move(callback);
|
||||
resRegister_.Reset();
|
||||
assetManager_.Reset();
|
||||
frontend_.Reset();
|
||||
pipelineContext_.Reset();
|
||||
}
|
||||
|
||||
void AceContainer::InitializeFrontend()
|
||||
@ -67,10 +86,15 @@ void AceContainer::InitializeFrontend()
|
||||
jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
|
||||
jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
|
||||
jsFrontend->SetAbility(aceAbility_);
|
||||
} else if (type_ == FrontendType::JS_CARD) {
|
||||
AceApplicationInfo::GetInstance().SetCardType();
|
||||
frontend_ = AceType::MakeRefPtr<CardFrontend>();
|
||||
} else if (type_ == FrontendType::DECLARATIVE_JS) {
|
||||
frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
|
||||
auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
|
||||
declarativeFrontend->SetJsEngine(Framework::JsEngineLoader::GetDeclarative().CreateJsEngine(instanceId_));
|
||||
declarativeFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
|
||||
declarativeFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
|
||||
} else {
|
||||
LOGE("Frontend type not supported");
|
||||
EventReport::SendAppStartException(AppStartExcepType::FRONTEND_TYPE_ERR);
|
||||
@ -286,16 +310,6 @@ void AceContainer::InitializeCallback()
|
||||
[context, deadline]() { context->OnIdle(deadline); }, TaskExecutor::TaskType::UI);
|
||||
};
|
||||
aceView_->RegisterIdleCallback(idleCallback);
|
||||
|
||||
auto&& viewDestoryCallback = [context = pipelineContext_](AceView::ViewReleaseCallback&& callback) {
|
||||
context->GetTaskExecutor()->PostTask(
|
||||
[context, callback = std::move(callback)]() {
|
||||
context->GetTaskExecutor()->PostTask(
|
||||
[callback = std::move(callback)]() { callback(); }, TaskExecutor::TaskType::PLATFORM);
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
};
|
||||
aceView_->RegisterViewDestroyCallback(viewDestoryCallback);
|
||||
}
|
||||
|
||||
void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, AceAbility* aceAbility,
|
||||
@ -303,6 +317,7 @@ void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, AceAbi
|
||||
{
|
||||
auto aceContainer = AceType::MakeRefPtr<AceContainer>(instanceId, type, aceAbility, std::move(callback));
|
||||
AceEngine::Get().AddContainer(instanceId, aceContainer);
|
||||
aceContainer->Initialize();
|
||||
auto front = aceContainer->GetFrontend();
|
||||
if (front) {
|
||||
front->UpdateState(Frontend::State::ON_CREATE);
|
||||
@ -312,24 +327,18 @@ void AceContainer::CreateContainer(int32_t instanceId, FrontendType type, AceAbi
|
||||
|
||||
void AceContainer::DestroyContainer(int32_t instanceId)
|
||||
{
|
||||
LOGI("DestroyContainer with id %{private}d", instanceId);
|
||||
auto container = AceEngine::Get().GetContainer(instanceId);
|
||||
if (!container) {
|
||||
LOGE("no AceContainer with id %{private}d", instanceId);
|
||||
LOGE("no AceContainer with id %{private}d in AceEngine", instanceId);
|
||||
return;
|
||||
}
|
||||
auto context = container->GetPipelineContext();
|
||||
if (context) {
|
||||
auto taskExecutor = context->GetTaskExecutor();
|
||||
if (taskExecutor) {
|
||||
taskExecutor->PostTask([context]() { context->Destroy(); }, TaskExecutor::TaskType::UI);
|
||||
}
|
||||
container->Destroy();
|
||||
auto taskExecutor = container->GetTaskExecutor();
|
||||
if (taskExecutor) {
|
||||
taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI);
|
||||
taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS);
|
||||
}
|
||||
AceEngine::Get().RemoveContainer(instanceId);
|
||||
auto front = container->GetFrontend();
|
||||
if (front) {
|
||||
front->UpdateState(Frontend::State::ON_DESTROY);
|
||||
}
|
||||
}
|
||||
|
||||
void AceContainer::SetView(AceView* view, double density, int32_t width, int32_t height)
|
||||
@ -445,9 +454,7 @@ void AceContainer::AddAssetPath(
|
||||
} else {
|
||||
flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
|
||||
container->assetManager_ = flutterAssetManager;
|
||||
if (container->type_ != FrontendType::DECLARATIVE_JS) {
|
||||
container->frontend_->SetAssetManager(flutterAssetManager);
|
||||
}
|
||||
container->frontend_->SetAssetManager(flutterAssetManager);
|
||||
}
|
||||
if (flutterAssetManager && !packagePath.empty()) {
|
||||
auto assetProvider = std::make_unique<FileAssetProvider>();
|
||||
@ -467,19 +474,6 @@ void AceContainer::AttachView(
|
||||
ACE_DCHECK(state != nullptr);
|
||||
auto flutterTaskExecutor = AceType::DynamicCast<FlutterTaskExecutor>(taskExecutor_);
|
||||
flutterTaskExecutor->InitOtherThreads(state->GetTaskRunners());
|
||||
|
||||
if (type_ == FrontendType::DECLARATIVE_JS) {
|
||||
// For DECLARATIVE_JS or UJOINT_JS frontend display UI in JS thread temporarily.
|
||||
flutterTaskExecutor->InitJsThread(false);
|
||||
InitializeFrontend();
|
||||
auto front = GetFrontend();
|
||||
if (front) {
|
||||
front->UpdateState(Frontend::State::ON_CREATE);
|
||||
front->SetJsMessageDispatcher(AceType::Claim(this));
|
||||
front->SetAssetManager(assetManager_);
|
||||
}
|
||||
}
|
||||
|
||||
resRegister_ = aceView_->GetPlatformResRegister();
|
||||
pipelineContext_ = AceType::MakeRefPtr<PipelineContext>(std::move(window),
|
||||
taskExecutor_,
|
||||
|
@ -36,6 +36,10 @@ public:
|
||||
std::unique_ptr<PlatformEventCallback> callback);
|
||||
~AceContainer() override = default;
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
static bool Register();
|
||||
|
||||
int32_t GetInstanceId() const override
|
||||
@ -89,6 +93,10 @@ public:
|
||||
void Dispatch(
|
||||
const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const override;
|
||||
|
||||
void DispatchSync(
|
||||
const std::string& group, std::vector<uint8_t>&& data, uint8_t** resData, long& position) const override
|
||||
{}
|
||||
|
||||
void DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const override;
|
||||
|
||||
bool Dump(const std::vector<std::string>& params) override;
|
||||
|
105
adapter/ohos/cpp/ace_data_ability.cpp
Normal file
105
adapter/ohos/cpp/ace_data_ability.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "adapter/ohos/cpp/ace_data_ability.h"
|
||||
#include "adapter/ohos/cpp/pa_container.h"
|
||||
#include "adapter/ohos/cpp/platform_event_callback.h"
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "core/common/backend.h"
|
||||
#include "frameworks/bridge/pa_backend/pa_backend.h"
|
||||
|
||||
#include "res_config.h"
|
||||
#include "resource_manager.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
using namespace OHOS::AAFwk;
|
||||
using namespace OHOS::AppExecFwk;
|
||||
|
||||
using DataPlatformFinish = std::function<void()>;
|
||||
class DataPlatformEventCallback final : public Platform::PlatformEventCallback {
|
||||
public:
|
||||
explicit DataPlatformEventCallback(DataPlatformFinish onFinish) : onFinish_(onFinish) {}
|
||||
|
||||
~DataPlatformEventCallback() = default;
|
||||
|
||||
virtual void OnFinish() const
|
||||
{
|
||||
LOGI("DataPlatformEventCallback OnFinish");
|
||||
if (onFinish_) {
|
||||
onFinish_();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnStatusBarBgColorChanged(uint32_t color)
|
||||
{
|
||||
LOGI("DataPlatformEventCallback OnStatusBarBgColorChanged");
|
||||
}
|
||||
private:
|
||||
DataPlatformFinish onFinish_;
|
||||
};
|
||||
|
||||
int32_t AceDataAbility::instanceId_ = 0;
|
||||
const std::string AceDataAbility::START_PARAMS_KEY = "__startParams";
|
||||
const std::string AceDataAbility::URI = "url";
|
||||
|
||||
REGISTER_AA(AceDataAbility)
|
||||
void AceDataAbility::OnStart(const OHOS::AAFwk::Want &want)
|
||||
{
|
||||
Ability::OnStart(want);
|
||||
LOGI("AceDataAbility::OnStart called");
|
||||
|
||||
// get url
|
||||
std::string parsedUrl;
|
||||
if (want.HasParameter(URI)) {
|
||||
parsedUrl = want.GetStringParam(URI);
|
||||
} else {
|
||||
parsedUrl = "data.js";
|
||||
}
|
||||
|
||||
// init data ability
|
||||
BackendType backendType = BackendType::DATA;
|
||||
Platform::PaContainer::CreateContainer(
|
||||
abilityId_, backendType, this,
|
||||
std::make_unique<DataPlatformEventCallback>([this]() {
|
||||
TerminateAbility();
|
||||
}));
|
||||
|
||||
// get asset
|
||||
auto packagePathStr = GetBundleCodePath();
|
||||
auto moduleInfo = GetHapModuleInfo();
|
||||
if (moduleInfo != nullptr) {
|
||||
packagePathStr += "/" + moduleInfo->name + "/";
|
||||
}
|
||||
auto assetBasePathStr = {std::string("assets/js/default/"), std::string("assets/js/share/")};
|
||||
Platform::PaContainer::AddAssetPath(abilityId_, packagePathStr, assetBasePathStr);
|
||||
|
||||
// run data ability
|
||||
Platform::PaContainer::RunPa(
|
||||
abilityId_, parsedUrl, want.GetStringParam(START_PARAMS_KEY));
|
||||
|
||||
LOGI("AceDataAbility::OnStart called End");
|
||||
}
|
||||
|
||||
void AceDataAbility::OnStop()
|
||||
{
|
||||
LOGI("AceDataAbility::OnStop called ");
|
||||
Ability::OnStop();
|
||||
Platform::PaContainer::DestroyContainer(abilityId_);
|
||||
LOGI("AceDataAbility::OnStop called End");
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace
|
46
adapter/ohos/cpp/ace_data_ability.h
Normal file
46
adapter/ohos/cpp/ace_data_ability.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_DATA_ABILITY_H
|
||||
#define FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_DATA_ABILITY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ability.h"
|
||||
#include "ability_loader.h"
|
||||
#include "want.h"
|
||||
#include "iremote_object.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
class AceDataAbility final : public OHOS::AppExecFwk::Ability {
|
||||
public:
|
||||
AceDataAbility()
|
||||
{
|
||||
abilityId_ = instanceId_;
|
||||
instanceId_++;
|
||||
}
|
||||
virtual ~AceDataAbility() = default;
|
||||
|
||||
void OnStart(const OHOS::AAFwk::Want& want) override;
|
||||
void OnStop() override;
|
||||
private:
|
||||
int32_t abilityId_ = 0;
|
||||
|
||||
static int32_t instanceId_;
|
||||
static const std::string START_PARAMS_KEY;
|
||||
static const std::string URI;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
#endif // FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_DATA_ABILITY_H
|
117
adapter/ohos/cpp/ace_service_ability.cpp
Normal file
117
adapter/ohos/cpp/ace_service_ability.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "adapter/ohos/cpp/ace_service_ability.h"
|
||||
#include "adapter/ohos/cpp/pa_container.h"
|
||||
#include "adapter/ohos/cpp/platform_event_callback.h"
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "core/common/backend.h"
|
||||
#include "frameworks/bridge/pa_backend/pa_backend.h"
|
||||
|
||||
#include "res_config.h"
|
||||
#include "resource_manager.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
using namespace OHOS::AAFwk;
|
||||
using namespace OHOS::AppExecFwk;
|
||||
|
||||
using ServicePlatformFinish = std::function<void()>;
|
||||
class ServicePlatformEventCallback final : public Platform::PlatformEventCallback {
|
||||
public:
|
||||
explicit ServicePlatformEventCallback(ServicePlatformFinish onFinish) : onFinish_(onFinish) {}
|
||||
|
||||
~ServicePlatformEventCallback() = default;
|
||||
|
||||
virtual void OnFinish() const
|
||||
{
|
||||
LOGI("ServicePlatformEventCallback OnFinish");
|
||||
if (onFinish_) {
|
||||
onFinish_();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnStatusBarBgColorChanged(uint32_t color)
|
||||
{
|
||||
LOGI("ServicePlatformEventCallback OnStatusBarBgColorChanged");
|
||||
}
|
||||
|
||||
private:
|
||||
ServicePlatformFinish onFinish_;
|
||||
};
|
||||
|
||||
int32_t AceServiceAbility::instanceId_ = 0;
|
||||
const std::string AceServiceAbility::START_PARAMS_KEY = "__startParams";
|
||||
const std::string AceServiceAbility::URI = "url";
|
||||
|
||||
REGISTER_AA(AceServiceAbility)
|
||||
void AceServiceAbility::OnStart(const OHOS::AAFwk::Want &want)
|
||||
{
|
||||
Ability::OnStart(want);
|
||||
LOGI("AceServiceAbility::OnStart called");
|
||||
|
||||
// get url
|
||||
std::string parsedUrl;
|
||||
if (want.HasParameter(URI)) {
|
||||
parsedUrl = want.GetStringParam(URI);
|
||||
} else {
|
||||
parsedUrl = "service.js";
|
||||
}
|
||||
|
||||
// init service
|
||||
BackendType backendType = BackendType::SERVICE;
|
||||
Platform::PaContainer::CreateContainer(
|
||||
abilityId_, backendType, this,
|
||||
std::make_unique<ServicePlatformEventCallback>([this]() {
|
||||
TerminateAbility();
|
||||
}));
|
||||
|
||||
// get asset
|
||||
auto packagePathStr = GetBundleCodePath();
|
||||
auto moduleInfo = GetHapModuleInfo();
|
||||
if (moduleInfo != nullptr) {
|
||||
packagePathStr += "/" + moduleInfo->name + "/";
|
||||
}
|
||||
auto assetBasePathStr = {std::string("assets/js/default/"), std::string("assets/js/share/")};
|
||||
Platform::PaContainer::AddAssetPath(abilityId_, packagePathStr, assetBasePathStr);
|
||||
|
||||
// run service
|
||||
Platform::PaContainer::RunPa(
|
||||
abilityId_, parsedUrl, want.GetStringParam(START_PARAMS_KEY));
|
||||
|
||||
LOGI("AceServiceAbility::OnStart called End");
|
||||
}
|
||||
|
||||
void AceServiceAbility::OnStop()
|
||||
{
|
||||
LOGI("AceServiceAbility::OnStop called ");
|
||||
Ability::OnStop();
|
||||
Platform::PaContainer::DestroyContainer(abilityId_);
|
||||
LOGI("AceServiceAbility::OnStop called End");
|
||||
}
|
||||
|
||||
sptr<IRemoteObject> AceServiceAbility::OnConnet(const Want &want)
|
||||
{
|
||||
LOGI("AceServiceAbility::OnConnet");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AceServiceAbility::OnDisconnect(const Want &want)
|
||||
{
|
||||
LOGI("AceServiceAbility::OnDisconnect");
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace
|
49
adapter/ohos/cpp/ace_service_ability.h
Normal file
49
adapter/ohos/cpp/ace_service_ability.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_SERVICE_ABILITY_H
|
||||
#define FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_SERVICE_ABILITY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ability.h"
|
||||
#include "ability_loader.h"
|
||||
#include "want.h"
|
||||
#include "iremote_object.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
class AceServiceAbility final : public OHOS::AppExecFwk::Ability {
|
||||
public:
|
||||
AceServiceAbility()
|
||||
{
|
||||
abilityId_ = instanceId_;
|
||||
instanceId_++;
|
||||
}
|
||||
virtual ~AceServiceAbility() = default;
|
||||
|
||||
void OnStart(const OHOS::AAFwk::Want& want) override;
|
||||
void OnStop() override;
|
||||
sptr<IRemoteObject> OnConnet(const OHOS::AAFwk::Want &want);
|
||||
void OnDisconnect(const OHOS::AAFwk::Want &want) override;
|
||||
|
||||
private:
|
||||
int32_t abilityId_ = 0;
|
||||
|
||||
static int32_t instanceId_;
|
||||
static const std::string START_PARAMS_KEY;
|
||||
static const std::string URI;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
#endif // FOUNDATION_ACE_ACE_ENGINE_ADAPTER_OHOS_CPP_ACE_SERVICE_ABILITY_H
|
@ -177,7 +177,7 @@ void FlutterAceView::SurfaceChanged(FlutterAceView* view, int32_t width, int32_t
|
||||
|
||||
view->NotifySurfaceChanged(width, height);
|
||||
auto platformView = view->GetShellHolder()->GetPlatformView();
|
||||
LOGI("FlutterAceView::SurfaceChanged GetPlatformView");
|
||||
LOGI("FlutterAceView::SurfaceChanged, GetPlatformView");
|
||||
if (platformView) {
|
||||
LOGI("FlutterAceView::SurfaceChanged, call NotifyChanged");
|
||||
platformView->NotifyChanged(SkISize::Make(width, height));
|
||||
|
170
adapter/ohos/cpp/pa_container.cpp
Normal file
170
adapter/ohos/cpp/pa_container.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "adapter/common/cpp/file_asset_provider.h"
|
||||
#include "adapter/ohos/cpp/ace_application_info.h"
|
||||
#include "adapter/ohos/cpp/pa_container.h"
|
||||
#include "base/log/ace_trace.h"
|
||||
#include "base/log/event_report.h"
|
||||
#include "base/log/log.h"
|
||||
#include "base/utils/system_properties.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "base/watch_dog/watch_dog.h"
|
||||
#include "core/common/ace_engine.h"
|
||||
#include "core/common/platform_window.h"
|
||||
#include "core/common/text_field_manager.h"
|
||||
#include "core/common/window.h"
|
||||
|
||||
#include "frameworks/bridge/pa_backend/engine/common/js_backend_engine_loader.h"
|
||||
#include "frameworks/bridge/pa_backend/pa_backend.h"
|
||||
|
||||
#include "flutter/lib/ui/ui_dart_state.h"
|
||||
|
||||
#include "adapter/common/cpp/flutter_asset_manager.h"
|
||||
#include "adapter/common/cpp/flutter_task_executor.h"
|
||||
|
||||
namespace OHOS::Ace::Platform {
|
||||
PaContainer::PaContainer(int32_t instanceId, BackendType type, void* paAbility,
|
||||
std::unique_ptr<PlatformEventCallback> callback) : instanceId_(instanceId), type_(type),
|
||||
paAbility_(paAbility)
|
||||
{
|
||||
ACE_DCHECK(callback);
|
||||
auto flutterTaskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
|
||||
flutterTaskExecutor->InitPlatformThread();
|
||||
flutterTaskExecutor->InitJsThread();
|
||||
taskExecutor_ = flutterTaskExecutor;
|
||||
|
||||
InitializeBackend();
|
||||
|
||||
platformEventCallback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void PaContainer::InitializeBackend()
|
||||
{
|
||||
// create backend
|
||||
backend_ = Backend::Create();
|
||||
auto paBackend = AceType::DynamicCast<PaBackend>(backend_);
|
||||
|
||||
// set JS engine,init in JS thread
|
||||
paBackend->SetJsEngine(Framework::JsBackendEngineLoader::Get().CreateJsBackendEngine(instanceId_));
|
||||
paBackend->SetAbility(paAbility_);
|
||||
|
||||
ACE_DCHECK(backend_);
|
||||
backend_->Initialize(type_, taskExecutor_);
|
||||
}
|
||||
|
||||
RefPtr<PaContainer> PaContainer::GetContainer(int32_t instanceId)
|
||||
{
|
||||
auto container = AceEngine::Get().GetContainer(instanceId);
|
||||
if (container != nullptr) {
|
||||
auto aceContainer = AceType::DynamicCast<PaContainer>(container);
|
||||
return aceContainer;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PaContainer::CreateContainer(int32_t instanceId, BackendType type, void* paAbility,
|
||||
std::unique_ptr<PlatformEventCallback> callback)
|
||||
{
|
||||
auto aceContainer = AceType::MakeRefPtr<PaContainer>(instanceId, type, paAbility,
|
||||
std::move(callback));
|
||||
AceEngine::Get().AddContainer(instanceId, aceContainer);
|
||||
|
||||
auto back = aceContainer->GetBackend();
|
||||
if (back) {
|
||||
back->UpdateState(Backend::State::ON_CREATE);
|
||||
back->SetJsMessageDispatcher(aceContainer);
|
||||
}
|
||||
}
|
||||
|
||||
bool PaContainer::RunPa(int32_t instanceId, const std::string &content, const std::string ¶ms)
|
||||
{
|
||||
auto container = AceEngine::Get().GetContainer(instanceId);
|
||||
if (!container) {
|
||||
return false;
|
||||
}
|
||||
auto aceContainer = AceType::DynamicCast<PaContainer>(container);
|
||||
auto back = aceContainer->GetBackend();
|
||||
if (back) {
|
||||
auto paBackend = AceType::DynamicCast<PaBackend>(back);
|
||||
paBackend->RunPa(content, params);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PaContainer::DestroyContainer(int32_t instanceId)
|
||||
{
|
||||
LOGI("DestroyContainer with id %{private}d", instanceId);
|
||||
auto container = AceEngine::Get().GetContainer(instanceId);
|
||||
if (!container) {
|
||||
LOGE("no AceContainer with id %{private}d", instanceId);
|
||||
return;
|
||||
}
|
||||
auto aceContainer = AceType::DynamicCast<PaContainer>(container);
|
||||
auto back = aceContainer->GetBackend();
|
||||
if (back) {
|
||||
back->UpdateState(Backend::State::ON_DESTROY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void PaContainer::AddAssetPath(
|
||||
int32_t instanceId, const std::string &packagePath, const std::vector<std::string> &paths)
|
||||
{
|
||||
auto container = AceType::DynamicCast<PaContainer>(AceEngine::Get().GetContainer(instanceId));
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
AceEngine::Get().SetPackagePath(packagePath);
|
||||
for (auto path : paths) {
|
||||
AceEngine::Get().SetAssetBasePath(path);
|
||||
}
|
||||
|
||||
RefPtr<FlutterAssetManager> flutterAssetManager;
|
||||
if (container->assetManager_) {
|
||||
flutterAssetManager = AceType::DynamicCast<FlutterAssetManager>(container->assetManager_);
|
||||
} else {
|
||||
flutterAssetManager = Referenced::MakeRefPtr<FlutterAssetManager>();
|
||||
container->assetManager_ = flutterAssetManager;
|
||||
AceType::DynamicCast<PaBackend>(container->GetBackend())->SetAssetManager(flutterAssetManager);
|
||||
}
|
||||
if (flutterAssetManager && !packagePath.empty()) {
|
||||
auto assetProvider = std::make_unique<FileAssetProvider>();
|
||||
if (assetProvider->Initialize(packagePath, paths)) {
|
||||
LOGI("Push AssetProvider to queue.");
|
||||
flutterAssetManager->PushBack(std::move(assetProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PaContainer::Dispatch(
|
||||
const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void PaContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool PaContainer::Dump(const std::vector<std::string> ¶ms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // namespace OHOS::Ace::Platform
|
125
adapter/ohos/cpp/pa_container.h
Normal file
125
adapter/ohos/cpp/pa_container.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_OHOS_CPP_PA_CONTAINER_H
|
||||
#define FOUNDATION_ACE_ADAPTER_OHOS_CPP_PA_CONTAINER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "adapter/ohos/cpp/platform_event_callback.h"
|
||||
#include "base/resource/asset_manager.h"
|
||||
#include "base/thread/task_executor.h"
|
||||
#include "base/utils/noncopyable.h"
|
||||
#include "core/common/ace_view.h"
|
||||
#include "core/common/container.h"
|
||||
#include "core/common/js_message_dispatcher.h"
|
||||
#include "frameworks/core/common/backend.h"
|
||||
|
||||
namespace OHOS::Ace::Platform {
|
||||
class PaContainer : public Container, public JsMessageDispatcher {
|
||||
DECLARE_ACE_TYPE(PaContainer, Container, JsMessageDispatcher);
|
||||
|
||||
public:
|
||||
PaContainer(int32_t instanceId, BackendType type, void* paAbility,
|
||||
std::unique_ptr<PlatformEventCallback> callback);
|
||||
~PaContainer() override = default;
|
||||
|
||||
void Initialize() override {}
|
||||
|
||||
void Destroy() override {}
|
||||
|
||||
int32_t GetInstanceId() const override
|
||||
{
|
||||
return instanceId_;
|
||||
}
|
||||
|
||||
RefPtr<AssetManager> GetAssetManager() const override
|
||||
{
|
||||
return assetManager_;
|
||||
}
|
||||
|
||||
RefPtr<Frontend> GetFrontend() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PlatformResRegister> GetPlatformResRegister() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PipelineContext> GetPipelineContext() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Backend> GetBackend() const
|
||||
{
|
||||
return backend_;
|
||||
}
|
||||
|
||||
RefPtr<TaskExecutor> GetTaskExecutor() const override
|
||||
{
|
||||
return taskExecutor_;
|
||||
}
|
||||
|
||||
void Dispatch(
|
||||
const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const override;
|
||||
|
||||
void DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const override;
|
||||
|
||||
void DispatchSync(
|
||||
const std::string &group, std::vector<uint8_t> &&data, uint8_t **resData, long &position) const override
|
||||
{}
|
||||
|
||||
bool Dump(const std::vector<std::string>& params) override;
|
||||
|
||||
void OnFinish()
|
||||
{
|
||||
if (platformEventCallback_) {
|
||||
platformEventCallback_->OnFinish();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetHostClassName() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool Register();
|
||||
static void CreateContainer(int32_t instanceId, BackendType type, void* paAbility,
|
||||
std::unique_ptr<PlatformEventCallback> callback);
|
||||
static void DestroyContainer(int32_t instanceId);
|
||||
static RefPtr<PaContainer> GetContainer(int32_t instanceId);
|
||||
static bool RunPa(int32_t instanceId, const std::string &content, const std::string ¶ms);
|
||||
static void AddAssetPath(int32_t instanceId, const std::string &packagePath, const std::vector<std::string> &paths);
|
||||
|
||||
private:
|
||||
void InitializeBackend();
|
||||
void InitializeCallback();
|
||||
|
||||
RefPtr<TaskExecutor> taskExecutor_;
|
||||
RefPtr<AssetManager> assetManager_;
|
||||
RefPtr<Backend> backend_;
|
||||
|
||||
int32_t instanceId_ = 0;
|
||||
BackendType type_ = BackendType::SERVICE;
|
||||
std::unique_ptr<PlatformEventCallback> platformEventCallback_;
|
||||
void *paAbility_ = nullptr;
|
||||
|
||||
ACE_DISALLOW_COPY_AND_MOVE(PaContainer);
|
||||
};
|
||||
} // namespace OHOS::Ace::Platform
|
||||
#endif // FOUNDATION_ACE_ADAPTER_OHOS_CPP_PA_CONTAINER_H
|
@ -29,7 +29,7 @@ template("ace_osal_ohos_source_set") {
|
||||
configs = [
|
||||
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara_config",
|
||||
"$ace_root:ace_config",
|
||||
"$flutter_root:flutter_config",
|
||||
"$ace_flutter_engine_root:flutter_config",
|
||||
]
|
||||
}
|
||||
include_dirs = [ "//utils/native/base/include" ]
|
||||
|
@ -29,6 +29,7 @@ namespace {
|
||||
|
||||
constexpr char EVENT_KEY_ERROR_TYPE[] = "ERROR_TYPE";
|
||||
constexpr char EVENT_KEY_UID[] = "UID";
|
||||
constexpr char EVENT_KEY_SESSIONID[] = "SESSION_ID";
|
||||
constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME";
|
||||
constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME";
|
||||
constexpr char EVENT_KEY_MESSAGE[] = "MESSAGE";
|
||||
@ -37,13 +38,11 @@ constexpr char EVENT_KEY_TIME[] = "TIME";
|
||||
constexpr char EVENT_KEY_JS_ERR_RAW_CODE[] = "JS_ERR_RAW_CODE";
|
||||
constexpr char EVENT_KEY_REASON[] = "REASON";
|
||||
constexpr char EVENT_KEY_SUMMARY[] = "SUMMARY";
|
||||
constexpr char EVENT_NAME_JS_ERROR[] = "JS_ERROR";
|
||||
constexpr char STATISTIC_DURATION[] = "DURATION";
|
||||
|
||||
constexpr int32_t MAX_PACKAGE_NAME_LENGTH = 128;
|
||||
constexpr int32_t JS_CRASH_RAW_EVENT_ID = 5002;
|
||||
constexpr int32_t JS_ERR_RAW_CODE = 3;
|
||||
constexpr int32_t UIP_WARNING_EVENT_ID = 10257;
|
||||
constexpr int32_t UIP_FREEZE_EVENT_ID = 10258;
|
||||
constexpr int32_t UIP_RECOVER_EVENT_ID = 10280;
|
||||
|
||||
constexpr char DUMP_LOG_COMMAND[] = "B";
|
||||
|
||||
@ -62,12 +61,23 @@ void EventReport::SendEvent(const EventInfo& eventInfo)
|
||||
if (packageName.size() > MAX_PACKAGE_NAME_LENGTH) {
|
||||
StrTrim(packageName);
|
||||
}
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, std::to_string(eventInfo.eventType),
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, eventInfo.eventType,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
|
||||
EVENT_KEY_ERROR_TYPE, eventInfo.errorType,
|
||||
EVENT_KEY_PACKAGE_NAME, packageName);
|
||||
}
|
||||
|
||||
void EventReport::SendJsCardRenderTimeEvent(
|
||||
const std::string& sessionID,
|
||||
const std::string& timeType,
|
||||
uint64_t timeDelay)
|
||||
{
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, timeType,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
|
||||
EVENT_KEY_SESSIONID, sessionID,
|
||||
STATISTIC_DURATION, timeDelay);
|
||||
}
|
||||
|
||||
void EventReport::SendAppStartException(AppStartExcepType type)
|
||||
{
|
||||
EventInfo eventInfo = {
|
||||
@ -190,7 +200,7 @@ void EventReport::JsEventReport(int32_t eventType, const std::string& jsonStr)
|
||||
void EventReport::JsErrReport(
|
||||
int32_t uid, const std::string& packageName, const std::string& reason, const std::string& summary)
|
||||
{
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, std::to_string(JS_CRASH_RAW_EVENT_ID),
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, EVENT_NAME_JS_ERROR,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
|
||||
EVENT_KEY_TIME, std::to_string((int32_t)std::time(nullptr)),
|
||||
EVENT_KEY_UID, std::to_string(uid),
|
||||
@ -204,20 +214,19 @@ void EventReport::ANRRawReport(RawEventType type, int32_t uid, const std::string
|
||||
const std::string& processName, const std::string& msg)
|
||||
{
|
||||
int32_t pid = getpid();
|
||||
int32_t eventId = 0;
|
||||
std::string cmd = " ";
|
||||
std::string eventName = "";
|
||||
if (type == RawEventType::WARNING) {
|
||||
eventId = UIP_WARNING_EVENT_ID;
|
||||
eventName = "UI_BLOCK_3S";
|
||||
cmd = "p=" + std::to_string(pid);
|
||||
} else if (type == RawEventType::FREEZE) {
|
||||
eventId = UIP_FREEZE_EVENT_ID;
|
||||
eventName = "UI_BLOCK_6S";
|
||||
cmd = DUMP_LOG_COMMAND;
|
||||
} else {
|
||||
eventId = UIP_RECOVER_EVENT_ID;
|
||||
eventName = "UI_BLOCK_RECOVERED";
|
||||
}
|
||||
std::string eventIdStr = std::to_string(eventId);
|
||||
std::string uidStr = std::to_string(uid);
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, eventIdStr,
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, eventName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
|
||||
EVENT_KEY_UID, uidStr,
|
||||
EVENT_KEY_PACKAGE_NAME, packageName,
|
||||
@ -230,7 +239,7 @@ void EventReport::SendEventInner(const EventInfo& eventInfo)
|
||||
{
|
||||
auto packageName = AceEngine::Get().GetPackageName();
|
||||
StrTrim(packageName);
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, std::to_string(eventInfo.eventType),
|
||||
OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, eventInfo.eventType,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
|
||||
EVENT_KEY_ERROR_TYPE, eventInfo.errorType,
|
||||
EVENT_KEY_PACKAGE_NAME, packageName);
|
||||
|
@ -43,6 +43,11 @@ public:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string GetAssetPath(const std::string& assetName) override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -45,6 +45,11 @@ constexpr uint32_t LOG_DOMAINS[] = {
|
||||
0xD003B00,
|
||||
};
|
||||
|
||||
constexpr LogType LOG_TYPES[] = {
|
||||
LOG_CORE,
|
||||
LOG_APP,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// initial static member object
|
||||
@ -57,8 +62,8 @@ char LogWrapper::GetSeparatorCharacter()
|
||||
|
||||
void LogWrapper::PrintLog(LogDomain domain, LogLevel level, const char* fmt, va_list args)
|
||||
{
|
||||
HiLogPrintArgs(LOG_CORE, LOG_LEVELS[static_cast<uint32_t>(level)], LOG_DOMAINS[static_cast<uint32_t>(domain)],
|
||||
LOG_TAGS[static_cast<uint32_t>(domain)], fmt, args);
|
||||
HiLogPrintArgs(LOG_TYPES[static_cast<uint32_t>(domain)], LOG_LEVELS[static_cast<uint32_t>(level)],
|
||||
LOG_DOMAINS[static_cast<uint32_t>(domain)], LOG_TAGS[static_cast<uint32_t>(domain)], fmt, args);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -65,6 +65,8 @@ std::string SystemProperties::paramDeviceType_ = INVALID_PARAM;
|
||||
int32_t SystemProperties::mcc_ = MCC_UNDEFINED;
|
||||
int32_t SystemProperties::mnc_ = MNC_UNDEFINED;
|
||||
ColorMode SystemProperties::colorMode_ { ColorMode::LIGHT };
|
||||
ScreenShape SystemProperties::screenShape_ { ScreenShape::NOT_ROUND };
|
||||
LongScreenType SystemProperties::LongScreen_ { LongScreenType::NOT_LONG };
|
||||
|
||||
void SystemProperties::UpdateSurfaceStatus(int32_t width, int32_t height)
|
||||
{
|
||||
@ -101,7 +103,7 @@ void SystemProperties::InitDeviceTypeBySystemProperty()
|
||||
void SystemProperties::InitDeviceInfo(int32_t deviceWidth, int32_t deviceHeight, int32_t orientation,
|
||||
double resolution, bool isRound)
|
||||
{
|
||||
// SetDeviceOrientation should be eralier than deviceWidth/deviceHeight init.
|
||||
// SetDeviceOrientation should be earlier than deviceWidth/deviceHeight init.
|
||||
SetDeviceOrientation(orientation);
|
||||
|
||||
isRound_ = isRound;
|
||||
@ -116,6 +118,12 @@ void SystemProperties::InitDeviceInfo(int32_t deviceWidth, int32_t deviceHeight,
|
||||
releaseType_ = system::GetParameter("hw_sc.build.os.releasetype", INVALID_PARAM);
|
||||
paramDeviceType_ = system::GetParameter("hw_sc.build.os.devicetype", INVALID_PARAM);
|
||||
|
||||
if (isRound_) {
|
||||
screenShape_ = ScreenShape::ROUND;
|
||||
} else {
|
||||
screenShape_ = ScreenShape::NOT_ROUND;
|
||||
}
|
||||
|
||||
InitDeviceTypeBySystemProperty();
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,12 @@ template("libace_engine") {
|
||||
"$ace_root/adapter/common/cpp/ace_res_config.cpp",
|
||||
"$ace_root/adapter/common/cpp/ace_res_key_parser.cpp",
|
||||
"$ace_root/adapter/common/cpp/ace_trace.cpp",
|
||||
"$ace_root/adapter/common/cpp/flutter_asset_manager.cpp",
|
||||
"$ace_root/adapter/common/cpp/localization.cpp",
|
||||
"$ace_root/adapter/common/cpp/thread_util.cpp",
|
||||
"$ace_root/adapter/preview/osal/download_manager.cpp",
|
||||
"$ace_root/adapter/preview/osal/fetch_manager.cpp",
|
||||
"$ace_root/adapter/preview/osal/response_data.cpp",
|
||||
"ace_ability.cpp",
|
||||
"ace_application_info.cpp",
|
||||
"ace_container.cpp",
|
||||
@ -36,18 +39,20 @@ template("libace_engine") {
|
||||
|
||||
configs = [
|
||||
"$ace_root:ace_config",
|
||||
"$flutter_root:flutter_config",
|
||||
"$flutter_root:flutter_glfw_config",
|
||||
"$flutter_root:icu_config_$platform",
|
||||
"$ace_flutter_engine_root:flutter_config",
|
||||
"$ace_flutter_engine_root:flutter_glfw_config",
|
||||
"$ace_flutter_engine_root:icu_config_$platform",
|
||||
"//third_party/curl:curl_config",
|
||||
"//third_party/zlib:zlib_config",
|
||||
]
|
||||
|
||||
cflags = [ "-std=c++17" ]
|
||||
deps = [
|
||||
"$ace_flutter_engine_root:ace_skia_$platform",
|
||||
"$ace_root/frameworks/base:ace_base_$platform",
|
||||
"$ace_root/frameworks/bridge:declarative_js_engine_$platform",
|
||||
"$ace_root/frameworks/bridge:js_engine_$platform",
|
||||
"$ace_root/frameworks/core:ace_core_$platform",
|
||||
"$flutter_root:ace_skia_$platform",
|
||||
"//third_party/curl:curl",
|
||||
]
|
||||
if (platform == "windows") {
|
||||
|
@ -30,13 +30,9 @@ std::atomic<bool> AceAbility::loopRunning_ = true;
|
||||
namespace {
|
||||
|
||||
// JS frontend maintain the page ID self, so it's useless to pass page ID from platform
|
||||
// layer, neither OpenHarmony or Windows.
|
||||
// layer, neither OpenHarmony or Windows, we should delete here usage when Java delete it.
|
||||
constexpr int32_t UNUSED_PAGE_ID = 1;
|
||||
|
||||
// Different with mobile, we don't support multi-instances in Windows, because we only want
|
||||
// preivew UI effect, it doesn't make scense to create multi ability in one process.
|
||||
constexpr int32_t ACE_INSTANCE_ID = 0;
|
||||
|
||||
constexpr char ASSET_PATH_SHARE[] = "share";
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
constexpr char DELIMITER[] = "\\";
|
||||
@ -87,12 +83,10 @@ bool AceAbility::DispatchTouchEvent(const TouchPoint& event)
|
||||
|
||||
std::promise<bool> touchPromise;
|
||||
std::future<bool> touchFuture = touchPromise.get_future();
|
||||
container->GetTaskExecutor()->PostTask(
|
||||
[aceView, event, &touchPromise]() {
|
||||
bool isHandled = aceView->HandleTouchEvent(event);
|
||||
touchPromise.set_value(isHandled);
|
||||
},
|
||||
TaskExecutor::TaskType::PLATFORM);
|
||||
container->GetTaskExecutor()->PostTask([aceView, event, &touchPromise]() {
|
||||
bool isHandled = aceView->HandleTouchEvent(event);
|
||||
touchPromise.set_value(isHandled);
|
||||
}, TaskExecutor::TaskType::PLATFORM);
|
||||
return touchFuture.get();
|
||||
}
|
||||
|
||||
@ -111,33 +105,43 @@ bool AceAbility::DispatchBackPressedEvent()
|
||||
|
||||
std::promise<bool> backPromise;
|
||||
std::future<bool> backFuture = backPromise.get_future();
|
||||
container->GetTaskExecutor()->PostTask(
|
||||
[container, context, &backPromise]() {
|
||||
bool canBack = false;
|
||||
if (context->IsLastPage()) {
|
||||
LOGW("Can't back because this is the last page!");
|
||||
} else {
|
||||
canBack = context->CallRouterBackToPopPage();
|
||||
}
|
||||
backPromise.set_value(canBack);
|
||||
},
|
||||
TaskExecutor::TaskType::PLATFORM);
|
||||
auto weak = AceType::WeakClaim(AceType::RawPtr(context));
|
||||
container->GetTaskExecutor()->PostTask([weak, &backPromise]() {
|
||||
auto context = weak.Upgrade();
|
||||
if (context == nullptr) {
|
||||
LOGW("context is nullptr.");
|
||||
return;
|
||||
}
|
||||
bool canBack = false;
|
||||
if (context->IsLastPage()) {
|
||||
LOGW("Can't back because this is the last page!");
|
||||
} else {
|
||||
canBack = context->CallRouterBackToPopPage();
|
||||
}
|
||||
backPromise.set_value(canBack);
|
||||
}, TaskExecutor::TaskType::PLATFORM);
|
||||
return backFuture.get();
|
||||
}
|
||||
|
||||
AceAbility::AceAbility(const AceRunArgs& runArgs) : runArgs_(runArgs)
|
||||
{
|
||||
SystemProperties::InitDeviceInfo(runArgs_.deviceWidth, runArgs_.deviceHeight,
|
||||
runArgs_.orientation == DeviceOrientation::PORTRAIT ? 0 : 1, runArgs_.resolution, runArgs_.isRound);
|
||||
SystemProperties::InitDeviceType(runArgs_.deviceType);
|
||||
SystemProperties::SetColorMode(runArgs_.colorMode == OHOS::Ace::Platform::ColorMode::DARK ?
|
||||
runArgs_.deviceConfig.orientation == DeviceOrientation::PORTRAIT ? 0 : 1,
|
||||
runArgs_.deviceConfig.density, runArgs_.isRound);
|
||||
SystemProperties::InitDeviceType(runArgs_.deviceConfig.deviceType);
|
||||
SystemProperties::SetColorMode(runArgs_.deviceConfig.colorMode == OHOS::Ace::Platform::ColorMode::DARK ?
|
||||
OHOS::Ace::ColorMode::DARK : OHOS::Ace::ColorMode::LIGHT);
|
||||
if (runArgs_.formsEnabled) {
|
||||
LOGI("CreateContainer with JS_CARD frontend");
|
||||
AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::JS_CARD);
|
||||
} else {
|
||||
} else if (runArgs_.aceVersion == AceVersion::ACE_1_0) {
|
||||
LOGI("CreateContainer with JS frontend");
|
||||
AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::JS);
|
||||
} else if (runArgs_.aceVersion == AceVersion::ACE_2_0) {
|
||||
LOGI("CreateContainer with JSDECLARATIVE frontend");
|
||||
AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::DECLARATIVE_JS);
|
||||
} else {
|
||||
LOGE("UnKnown frontend type");
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,16 +173,32 @@ void AceAbility::InitEnv()
|
||||
ACE_INSTANCE_ID, "", { runArgs_.assetPath, GetCustomAssetPath(runArgs_.assetPath).append(ASSET_PATH_SHARE) });
|
||||
|
||||
AceContainer::SetResourcesPathAndThemeStyle(ACE_INSTANCE_ID, runArgs_.resourcesPath,
|
||||
runArgs_.themeId, runArgs_.colorMode);
|
||||
runArgs_.themeId, runArgs_.deviceConfig.colorMode);
|
||||
|
||||
auto view = new FlutterAceView(ACE_INSTANCE_ID);
|
||||
AceContainer::SetView(view, runArgs_.resolution, runArgs_.deviceWidth, runArgs_.deviceHeight);
|
||||
AceContainer::SetView(view, runArgs_.deviceConfig.density, runArgs_.deviceWidth, runArgs_.deviceHeight);
|
||||
AceContainer::AddRouterChangeCallback(ACE_INSTANCE_ID, runArgs_.onRouterChange);
|
||||
IdleCallback idleNoticeCallback = [view](int64_t deadline) { view->ProcessIdleEvent(deadline); };
|
||||
FlutterDesktopSetIdleCallback(controller_, idleNoticeCallback);
|
||||
|
||||
// Should make it possible to update surface changes by using viewWidth and viewHeight.
|
||||
view->NotifySurfaceChanged(runArgs_.deviceWidth, runArgs_.deviceHeight);
|
||||
view->NotifyDensityChanged(runArgs_.resolution);
|
||||
view->NotifyDensityChanged(runArgs_.deviceConfig.density);
|
||||
}
|
||||
|
||||
void AceAbility::OnConfigurationChanged(const DeviceConfig& newConfig)
|
||||
{
|
||||
auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
|
||||
if (!container) {
|
||||
LOGE("container is null, change configuration failed.");
|
||||
return;
|
||||
}
|
||||
if (newConfig.colorMode == runArgs_.deviceConfig.colorMode) {
|
||||
LOGI("newConfig's colorMode is same as before, return.");
|
||||
return;
|
||||
}
|
||||
container->UpdateColorMode(newConfig.colorMode);
|
||||
runArgs_.deviceConfig.colorMode = newConfig.colorMode;
|
||||
}
|
||||
|
||||
void AceAbility::Start()
|
||||
@ -200,14 +220,14 @@ void AceAbility::Stop()
|
||||
#ifdef USE_GLFW_WINDOW
|
||||
void AdaptDeviceType(AceRunArgs& runArgs)
|
||||
{
|
||||
if (runArgs.deviceType == DeviceType::PHONE) {
|
||||
runArgs.resolution = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_PHONE;
|
||||
} else if (runArgs.deviceType == DeviceType::WATCH) {
|
||||
runArgs.resolution = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_WATCH;
|
||||
} else if (runArgs.deviceType == DeviceType::TABLET) {
|
||||
runArgs.resolution = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_TABLE;
|
||||
} else if (runArgs.deviceType == DeviceType::TV) {
|
||||
runArgs.resolution = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_TV;
|
||||
if (runArgs.deviceConfig.deviceType == DeviceType::PHONE) {
|
||||
runArgs.deviceConfig.density = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_PHONE;
|
||||
} else if (runArgs.deviceConfig.deviceType == DeviceType::WATCH) {
|
||||
runArgs.deviceConfig.density = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_WATCH;
|
||||
} else if (runArgs.deviceConfig.deviceType == DeviceType::TABLET) {
|
||||
runArgs.deviceConfig.density = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_TABLE;
|
||||
} else if (runArgs.deviceConfig.deviceType == DeviceType::TV) {
|
||||
runArgs.deviceConfig.density = runArgs.deviceWidth / SCREEN_DENSITY_COEFFICIENT_TV;
|
||||
} else {
|
||||
LOGE("DeviceType not supported");
|
||||
}
|
||||
@ -222,10 +242,10 @@ void AceAbility::RunEventLoop()
|
||||
auto window = FlutterDesktopGetWindow(controller_);
|
||||
int width;
|
||||
int height;
|
||||
FlutterDesktopGetFramebufferSize(window, &width, &height);
|
||||
FlutterDesktopGetWindowSize(window, &width, &height);
|
||||
if (width != runArgs_.deviceWidth || height != runArgs_.deviceHeight) {
|
||||
AdaptDeviceType(runArgs_);
|
||||
SurfaceChanged(runArgs_.orientation, width, height, runArgs_.resolution);
|
||||
SurfaceChanged(runArgs_.deviceConfig.orientation, runArgs_.deviceConfig.density, width, height);
|
||||
}
|
||||
#endif
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
@ -254,10 +274,8 @@ void AceAbility::RunEventLoop()
|
||||
}
|
||||
|
||||
void AceAbility::SurfaceChanged(
|
||||
const DeviceOrientation& orientation, const int32_t& width, const int32_t& height, const double& resolution)
|
||||
const DeviceOrientation& orientation, const double& resolution, int32_t& width, int32_t& height)
|
||||
{
|
||||
SystemProperties::InitDeviceInfo(
|
||||
width, height, orientation == DeviceOrientation::PORTRAIT ? 0 : 1, resolution, runArgs_.isRound);
|
||||
auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
|
||||
if (!container) {
|
||||
LOGE("container is null, SurfaceChanged failed.");
|
||||
@ -269,12 +287,25 @@ void AceAbility::SurfaceChanged(
|
||||
LOGE("aceView is null, SurfaceChanged failed.");
|
||||
return;
|
||||
}
|
||||
auto window = FlutterDesktopGetWindow(controller_);
|
||||
// Need to change the window resolution and then change the rendering resolution. Otherwise, the image may not adapt
|
||||
// to the new window after the window is modified.
|
||||
auto context = container->GetPipelineContext();
|
||||
if (context == nullptr) {
|
||||
LOGE("context is null, SurfaceChanged failed.");
|
||||
return;
|
||||
}
|
||||
context->GetTaskExecutor()->PostSyncTask(
|
||||
[window, &width, &height]() { FlutterDesktopSetWindowSize(window, width, height); },
|
||||
TaskExecutor::TaskType::PLATFORM);
|
||||
SystemProperties::InitDeviceInfo(
|
||||
width, height, orientation == DeviceOrientation::PORTRAIT ? 0 : 1, resolution, runArgs_.isRound);
|
||||
viewPtr->NotifySurfaceChanged(width, height);
|
||||
viewPtr->NotifyDensityChanged(resolution);
|
||||
runArgs_.orientation = orientation;
|
||||
runArgs_.deviceConfig.orientation = orientation;
|
||||
runArgs_.deviceWidth = width;
|
||||
runArgs_.deviceHeight = height;
|
||||
runArgs_.resolution = resolution;
|
||||
runArgs_.deviceConfig.density = resolution;
|
||||
}
|
||||
|
||||
std::string AceAbility::GetJSONTree()
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
static void Stop();
|
||||
static bool DispatchTouchEvent(const TouchPoint& event);
|
||||
static bool DispatchBackPressedEvent();
|
||||
void OnConfigurationChanged(const DeviceConfig& newConfig);
|
||||
|
||||
explicit AceAbility(const AceRunArgs& runArgs);
|
||||
~AceAbility();
|
||||
@ -49,7 +50,7 @@ public:
|
||||
void InitEnv();
|
||||
void Start();
|
||||
void SurfaceChanged(
|
||||
const DeviceOrientation& orientation, const int32_t& width, const int32_t& height, const double& resolution);
|
||||
const DeviceOrientation& orientation, const double& resolution, int32_t& width, int32_t& height);
|
||||
std::string GetJSONTree();
|
||||
std::string GetDefaultJSONTree();
|
||||
|
||||
|
@ -50,13 +50,74 @@ std::vector<std::string> AceApplicationInfoImpl::GetResourceFallback(const std::
|
||||
return fileList;
|
||||
}
|
||||
|
||||
std::vector<std::string> AceApplicationInfoImpl::GetStyleResourceFallback(
|
||||
const std::vector<std::string>& resourceList) const
|
||||
{
|
||||
std::vector<std::string> fileList;
|
||||
std::string deviceConfigTag = GetCurrentDeviceResTag();
|
||||
AceResConfig::MatchAndSortStyleResConfigs(resourceList, deviceConfigTag, fileList);
|
||||
return fileList;
|
||||
}
|
||||
|
||||
std::vector<std::string> AceApplicationInfoImpl::GetDeclarativeResourceFallback(
|
||||
const std::set<std::string>& resourceFolderList) const
|
||||
{
|
||||
std::string deviceConfigTag = GetCurrentDeviceDeclarativeResTag();
|
||||
std::vector<std::string> folderList;
|
||||
AceResConfig::MatchAndSortDeclarativeResConfigs(resourceFolderList, deviceConfigTag, folderList);
|
||||
return folderList;
|
||||
}
|
||||
|
||||
std::string AceApplicationInfoImpl::GetCurrentDeviceResTag() const
|
||||
{
|
||||
ResolutionType resolutionType = AceResConfig::GetResolutionType(SystemProperties::GetResolution());
|
||||
AceResConfig deviceResConfig = AceResConfig(SystemProperties::GetMcc(), SystemProperties::GetMnc(),
|
||||
SystemProperties::GetDevcieOrientation(), SystemProperties::GetColorMode(), SystemProperties::GetDeviceType(),
|
||||
SystemProperties::GetDevcieOrientation(), SystemProperties::GetColorMode(),
|
||||
SystemProperties::GetParamDeviceType() == "tablet" ? DeviceType::TABLET : SystemProperties::GetDeviceType(),
|
||||
resolutionType);
|
||||
return AceResConfig::ConvertResConfigToTag(deviceResConfig);
|
||||
return AceResConfig::ConvertResConfigToTag(deviceResConfig, false);
|
||||
}
|
||||
|
||||
std::string AceApplicationInfoImpl::GetCurrentDeviceDeclarativeResTag() const
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
icu::Locale locale = icu::Locale::forLanguageTag(icu::StringPiece(localeTag_), status);
|
||||
ResolutionType resolutionType = AceResConfig::GetResolutionType(SystemProperties::GetResolution());
|
||||
LongScreenType longScreenType = AceResConfig::GetLongScreenType(SystemProperties::GetResolution());
|
||||
AceResConfig deviceResConfig;
|
||||
if (status != U_ZERO_ERROR) {
|
||||
LOGE("This localeTag is not valid.");
|
||||
deviceResConfig = AceResConfig("", "", "", longScreenType, SystemProperties::GetScreenShape(),
|
||||
SystemProperties::GetDevcieOrientation(), SystemProperties::GetColorMode(),
|
||||
SystemProperties::GetParamDeviceType() == "tablet" ? DeviceType::TABLET : SystemProperties::GetDeviceType(),
|
||||
resolutionType);
|
||||
} else {
|
||||
deviceResConfig = AceResConfig(locale.getLanguage(), locale.getScript(), locale.getCountry(),
|
||||
longScreenType, SystemProperties::GetScreenShape(), SystemProperties::GetDevcieOrientation(),
|
||||
SystemProperties::GetColorMode(), SystemProperties::GetParamDeviceType() == "tablet" ? DeviceType::TABLET :
|
||||
SystemProperties::GetDeviceType(), resolutionType);
|
||||
}
|
||||
|
||||
return AceResConfig::ConvertDeclarativeResConfigToTag(deviceResConfig);
|
||||
}
|
||||
|
||||
double AceApplicationInfoImpl::GetTargetMediaScaleRatio(const std::string& targetResTag) const
|
||||
{
|
||||
std::string deviceConfigTag = GetCurrentDeviceDeclarativeResTag();
|
||||
auto deviceConfig = AceResConfig::ConvertDeclarativeResTagToConfig(deviceConfigTag);
|
||||
ResolutionType deviceResolution = (deviceConfig.resolution_ != ResolutionType::RESOLUTION_NONE) ?
|
||||
deviceConfig.resolution_ : ResolutionType::RESOLUTION_MDPI;
|
||||
|
||||
ResolutionType targetResolution;
|
||||
if (targetResTag == "default") {
|
||||
targetResolution = ResolutionType::RESOLUTION_MDPI;
|
||||
} else {
|
||||
AceResConfig targetConfig = AceResConfig::ConvertDeclarativeResTagToConfig(targetResTag);
|
||||
targetResolution = (targetConfig.resolution_ != ResolutionType::RESOLUTION_NONE) ?
|
||||
targetConfig.resolution_ : ResolutionType::RESOLUTION_MDPI;
|
||||
}
|
||||
|
||||
return static_cast<double>(deviceResolution) / static_cast<double>(targetResolution);
|
||||
}
|
||||
|
||||
void AceApplicationInfoImpl::SetLocale(const std::string& language, const std::string& countryOrRegion,
|
||||
@ -127,6 +188,12 @@ bool AceApplicationInfoImpl::GetFiles(const std::string& filePath, std::vector<s
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AceApplicationInfoImpl::GetFiles(
|
||||
int32_t instanceId, const std::string& filePath, std::vector<std::string>& fileList) const
|
||||
{
|
||||
return GetFiles(filePath, fileList);
|
||||
}
|
||||
|
||||
bool AceApplicationInfoImpl::GetBundleInfo(const std::string& packageName, AceBundleInfo& bundleInfo)
|
||||
{
|
||||
return false;
|
||||
|
@ -29,7 +29,11 @@ public:
|
||||
void ChangeLocale(const std::string& language, const std::string& countryOrRegion) override;
|
||||
std::vector<std::string> GetLocaleFallback(const std::vector<std::string>& localeList) const override;
|
||||
std::vector<std::string> GetResourceFallback(const std::vector<std::string>& resourceList) const override;
|
||||
std::vector<std::string> GetStyleResourceFallback(const std::vector<std::string>& resourceList) const override;
|
||||
std::vector<std::string> GetDeclarativeResourceFallback(
|
||||
const std::set<std::string>& resourceList) const override;
|
||||
bool GetFiles(const std::string& filePath, std::vector<std::string>& fileList) const override;
|
||||
bool GetFiles(int32_t instanceId, const std::string& filePath, std::vector<std::string>& fileList) const override;
|
||||
|
||||
bool GetBundleInfo(const std::string& packageName, AceBundleInfo& bundleInfo) override;
|
||||
double GetLifeTime() const override;
|
||||
@ -37,6 +41,10 @@ public:
|
||||
std::string GetJsEngineParam(const std::string& key) const override;
|
||||
|
||||
std::string GetCurrentDeviceResTag() const override;
|
||||
|
||||
std::string GetCurrentDeviceDeclarativeResTag() const override;
|
||||
|
||||
double GetTargetMediaScaleRatio(const std::string& targetResTag) const override;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::Platform
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "core/pipeline/base/element.h"
|
||||
#include "core/pipeline/pipeline_context.h"
|
||||
#include "frameworks/bridge/card_frontend/card_frontend.h"
|
||||
#include "frameworks/bridge/declarative_frontend/declarative_frontend.h"
|
||||
#include "frameworks/bridge/js_frontend/engine/common/js_engine_loader.h"
|
||||
#include "frameworks/bridge/js_frontend/js_frontend.h"
|
||||
|
||||
@ -50,16 +51,43 @@ namespace OHOS::Ace::Platform {
|
||||
|
||||
std::once_flag AceContainer::onceFlag_;
|
||||
|
||||
AceContainer::AceContainer(int32_t instanceId, FrontendType type) : instanceId_(instanceId), type_(type)
|
||||
AceContainer::AceContainer(int32_t instanceId, FrontendType type)
|
||||
: instanceId_(instanceId), messageBridge_(AceType::MakeRefPtr<PlatformBridge>()), type_(type)
|
||||
{
|
||||
ThemeConstants::InitDeviceType();
|
||||
|
||||
auto state = flutter::UIDartState::Current()->GetStateById(instanceId);
|
||||
taskExecutor_ = Referenced::MakeRefPtr<FlutterTaskExecutor>(state->GetTaskRunners());
|
||||
taskExecutor_->PostTask([instanceId]() { Container::InitForThread(instanceId); }, TaskExecutor::TaskType::JS);
|
||||
}
|
||||
|
||||
void AceContainer::Initialize()
|
||||
{
|
||||
InitializeFrontend();
|
||||
}
|
||||
|
||||
void AceContainer::Destroy()
|
||||
{
|
||||
if (pipelineContext_ && taskExecutor_) {
|
||||
taskExecutor_->PostTask([context = pipelineContext_]() { context->Destroy(); }, TaskExecutor::TaskType::UI);
|
||||
}
|
||||
|
||||
if (frontend_ && taskExecutor_) {
|
||||
taskExecutor_->PostTask(
|
||||
[front = frontend_]() { front->UpdateState(Frontend::State::ON_DESTROY); }, TaskExecutor::TaskType::JS);
|
||||
}
|
||||
|
||||
if (aceView_) {
|
||||
aceView_->DecRefCount();
|
||||
}
|
||||
|
||||
resRegister_.Reset();
|
||||
assetManager_.Reset();
|
||||
messageBridge_.Reset();
|
||||
frontend_.Reset();
|
||||
pipelineContext_.Reset();
|
||||
}
|
||||
|
||||
void AceContainer::InitializeFrontend()
|
||||
{
|
||||
if (type_ == FrontendType::JS) {
|
||||
@ -68,6 +96,10 @@ void AceContainer::InitializeFrontend()
|
||||
jsFrontend->SetJsEngine(Framework::JsEngineLoader::Get().CreateJsEngine(GetInstanceId()));
|
||||
jsFrontend->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
|
||||
jsFrontend->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
|
||||
} else if (type_ == FrontendType::DECLARATIVE_JS) {
|
||||
frontend_ = AceType::MakeRefPtr<DeclarativeFrontend>();
|
||||
auto declarativeFrontend = AceType::DynamicCast<DeclarativeFrontend>(frontend_);
|
||||
declarativeFrontend->SetJsEngine(Framework::JsEngineLoader::GetDeclarative().CreateJsEngine(instanceId_));
|
||||
} else if (type_ == FrontendType::JS_CARD) {
|
||||
AceApplicationInfo::GetInstance().SetCardType();
|
||||
frontend_ = AceType::MakeRefPtr<CardFrontend>();
|
||||
@ -159,16 +191,6 @@ void AceContainer::InitializeCallback()
|
||||
[context, deadline]() { context->OnIdle(deadline); }, TaskExecutor::TaskType::UI);
|
||||
};
|
||||
aceView_->RegisterIdleCallback(idleCallback);
|
||||
|
||||
auto&& viewDestoryCallback = [context = pipelineContext_](AceView::ViewReleaseCallback&& callback) {
|
||||
context->GetTaskExecutor()->PostTask(
|
||||
[context, callback = std::move(callback)]() {
|
||||
context->GetTaskExecutor()->PostTask(
|
||||
[callback = std::move(callback)]() { callback(); }, TaskExecutor::TaskType::PLATFORM);
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
};
|
||||
aceView_->RegisterViewDestroyCallback(viewDestoryCallback);
|
||||
}
|
||||
|
||||
void AceContainer::CreateContainer(int32_t instanceId, FrontendType type)
|
||||
@ -186,6 +208,7 @@ void AceContainer::CreateContainer(int32_t instanceId, FrontendType type)
|
||||
#endif
|
||||
auto aceContainer = AceType::MakeRefPtr<AceContainer>(instanceId, type);
|
||||
AceEngine::Get().AddContainer(aceContainer->GetInstanceId(), aceContainer);
|
||||
aceContainer->Initialize();
|
||||
auto front = aceContainer->GetFrontend();
|
||||
if (front) {
|
||||
front->UpdateState(Frontend::State::ON_CREATE);
|
||||
@ -200,26 +223,13 @@ void AceContainer::DestroyContainer(int32_t instanceId)
|
||||
LOGE("no AceContainer with id %{private}d in AceEngine", instanceId);
|
||||
return;
|
||||
}
|
||||
auto context = container->GetPipelineContext();
|
||||
if (context) {
|
||||
context->Destroy();
|
||||
container->Destroy();
|
||||
auto taskExecutor = container->GetTaskExecutor();
|
||||
if (taskExecutor) {
|
||||
taskExecutor->PostSyncTask([] { LOGI("Wait UI thread..."); }, TaskExecutor::TaskType::UI);
|
||||
taskExecutor->PostSyncTask([] { LOGI("Wait JS thread..."); }, TaskExecutor::TaskType::JS);
|
||||
}
|
||||
AceEngine::Get().RemoveContainer(instanceId);
|
||||
auto front = container->GetFrontend();
|
||||
if (front) {
|
||||
front->UpdateState(Frontend::State::ON_DESTROY);
|
||||
}
|
||||
|
||||
auto taskExecutor = AceType::DynamicCast<FlutterTaskExecutor>(container->GetTaskExecutor());
|
||||
if (taskExecutor) {
|
||||
taskExecutor->DestroyJsThread();
|
||||
}
|
||||
|
||||
auto aceView = AceType::DynamicCast<AceContainer>(container)->GetAceView();
|
||||
if (aceView) {
|
||||
LOGI("NotifyViewDestroyed");
|
||||
aceView->NotifyViewDestroyed([aceView]() { aceView->DecRefCount(); });
|
||||
}
|
||||
}
|
||||
|
||||
bool AceContainer::RunPage(int32_t instanceId, int32_t pageId, const std::string& url, const std::string& params)
|
||||
@ -233,7 +243,7 @@ bool AceContainer::RunPage(int32_t instanceId, int32_t pageId, const std::string
|
||||
auto front = container->GetFrontend();
|
||||
if (front) {
|
||||
auto type = front->GetType();
|
||||
if ((type == FrontendType::JS) || (type == FrontendType::JS_CARD)) {
|
||||
if ((type == FrontendType::JS) || (type == FrontendType::DECLARATIVE_JS) || (type == FrontendType::JS_CARD)) {
|
||||
front->RunPage(pageId, url, params);
|
||||
return true;
|
||||
} else {
|
||||
@ -249,7 +259,59 @@ void AceContainer::Dispatch(
|
||||
const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const
|
||||
{}
|
||||
|
||||
void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const {}
|
||||
void AceContainer::FetchResponse(const ResponseData responseData, const int32_t callbackId) const
|
||||
{
|
||||
auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(0));
|
||||
if (!container) {
|
||||
LOGE("FetchResponse container is null!");
|
||||
return;
|
||||
}
|
||||
auto front = container->GetFrontend();
|
||||
auto type = container->GetType();
|
||||
// todo Adapting to cards and 2.0
|
||||
if (type == FrontendType::JS) {
|
||||
auto jsFrontend = AceType::DynamicCast<JsFrontend>(front);
|
||||
if (jsFrontend) {
|
||||
// todo deal with code success is 0;
|
||||
jsFrontend->TransferJsResponseDataPreview(callbackId, ACTION_SUCCESS, responseData);
|
||||
}
|
||||
} else {
|
||||
LOGE("Frontend type not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AceContainer::CallCurlFunction(const RequestData requestData, const int32_t callbackId) const
|
||||
{
|
||||
auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(ACE_INSTANCE_ID));
|
||||
if (!container) {
|
||||
LOGE("CallCurlFunction container is null!");
|
||||
return;
|
||||
}
|
||||
taskExecutor_->PostTask(
|
||||
[container, requestData, callbackId]() mutable {
|
||||
ResponseData responseData;
|
||||
if (FetchManager::GetInstance().Fetch(requestData, callbackId, responseData)) {
|
||||
container->FetchResponse(responseData, callbackId);
|
||||
}
|
||||
},
|
||||
TaskExecutor::TaskType::BACKGROUND);
|
||||
}
|
||||
|
||||
void AceContainer::DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
|
||||
{
|
||||
auto front = GetFrontend();
|
||||
if (!front) {
|
||||
LOGE("the front is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
taskExecutor_->PostTask(
|
||||
[front, callbackId, errorCode, errorMessage = std::move(errorMessage)]() mutable {
|
||||
front->TransferJsPluginGetError(callbackId, errorCode, std::move(errorMessage));
|
||||
},
|
||||
TaskExecutor::TaskType::BACKGROUND);
|
||||
}
|
||||
|
||||
bool AceContainer::Dump(const std::vector<std::string>& params)
|
||||
{
|
||||
@ -264,6 +326,19 @@ bool AceContainer::Dump(const std::vector<std::string>& params)
|
||||
return false;
|
||||
}
|
||||
|
||||
void AceContainer::AddRouterChangeCallback(int32_t instanceId, const OnRouterChangeCallback& onRouterChangeCallback)
|
||||
{
|
||||
auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
if (!container->pipelineContext_) {
|
||||
LOGE("container pipelineContext not init");
|
||||
return;
|
||||
}
|
||||
container->pipelineContext_->AddRouterChangeCallback(onRouterChangeCallback);
|
||||
}
|
||||
|
||||
void AceContainer::AddAssetPath(
|
||||
int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths)
|
||||
{
|
||||
@ -294,15 +369,56 @@ void AceContainer::AddAssetPath(
|
||||
}
|
||||
|
||||
void AceContainer::SetResourcesPathAndThemeStyle(int32_t instanceId, const std::string& resourcesPath,
|
||||
const ThemeId& themeId, const ColorMode& colorMode)
|
||||
const int32_t& themeId, const ColorMode& colorMode)
|
||||
{
|
||||
auto container = AceType::DynamicCast<AceContainer>(AceEngine::Get().GetContainer(instanceId));
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
container->deviceResourceInfo_.deviceConfig.colorMode = static_cast<OHOS::Ace::ColorMode>(colorMode);
|
||||
container->deviceResourceInfo_.packagePath = resourcesPath;
|
||||
container->deviceResourceInfo_.themeId = static_cast<int32_t>(themeId);
|
||||
container->resourceInfo_.deviceConfig.colorMode = static_cast<OHOS::Ace::ColorMode>(colorMode);
|
||||
container->resourceInfo_.packagePath = resourcesPath;
|
||||
container->resourceInfo_.themeId = themeId;
|
||||
}
|
||||
|
||||
void AceContainer::UpdateColorMode(ColorMode newColorMode)
|
||||
{
|
||||
auto& deviceConfig = resourceInfo_.deviceConfig;
|
||||
|
||||
OHOS::Ace::ColorMode colorMode = static_cast<OHOS::Ace::ColorMode>(newColorMode);
|
||||
SystemProperties::SetColorMode(colorMode);
|
||||
if (deviceConfig.colorMode == colorMode) {
|
||||
return;
|
||||
} else {
|
||||
deviceConfig.colorMode = colorMode;
|
||||
if (frontend_) {
|
||||
frontend_->SetColorMode(colorMode);
|
||||
}
|
||||
}
|
||||
if (!pipelineContext_) {
|
||||
return;
|
||||
}
|
||||
auto themeManager = pipelineContext_->GetThemeManager();
|
||||
if (!themeManager) {
|
||||
return;
|
||||
}
|
||||
themeManager->UpdateConfig(deviceConfig);
|
||||
taskExecutor_->PostTask(
|
||||
[weakThemeManager = WeakPtr<ThemeManager>(themeManager), colorScheme = colorScheme_,
|
||||
weakContext = WeakPtr<PipelineContext>(pipelineContext_)]() {
|
||||
auto themeManager = weakThemeManager.Upgrade();
|
||||
auto context = weakContext.Upgrade();
|
||||
if (!themeManager || !context) {
|
||||
return;
|
||||
}
|
||||
themeManager->ReloadThemes();
|
||||
themeManager->ParseSystemTheme();
|
||||
themeManager->SetColorScheme(colorScheme);
|
||||
context->RefreshRootBgColor();
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
if (frontend_) {
|
||||
frontend_->RebuildAllPages();
|
||||
}
|
||||
}
|
||||
|
||||
void AceContainer::SetView(FlutterAceView* view, double density, int32_t width, int32_t height)
|
||||
@ -337,6 +453,7 @@ void AceContainer::AttachView(
|
||||
pipelineContext_->SetRootSize(density, width, height);
|
||||
pipelineContext_->SetTextFieldManager(AceType::MakeRefPtr<TextFieldManager>());
|
||||
pipelineContext_->SetIsRightToLeft(AceApplicationInfo::GetInstance().IsRightToLeft());
|
||||
pipelineContext_->SetMessageBridge(messageBridge_);
|
||||
pipelineContext_->SetWindowModal(windowModal_);
|
||||
pipelineContext_->SetDrawDelegate(aceView_->GetDrawDelegate());
|
||||
pipelineContext_->SetIsJsCard(type_ == FrontendType::JS_CARD);
|
||||
@ -346,16 +463,16 @@ void AceContainer::AttachView(
|
||||
auto themeManager = pipelineContext_->GetThemeManager();
|
||||
if (themeManager) {
|
||||
// Init resource, load theme map.
|
||||
themeManager->InitResource(deviceResourceInfo_);
|
||||
themeManager->LoadSystemTheme(deviceResourceInfo_.themeId);
|
||||
// get background color from theme
|
||||
aceView_->SetBackgroundColor(themeManager->GetBackgroundColor());
|
||||
themeManager->InitResource(resourceInfo_);
|
||||
themeManager->LoadSystemTheme(resourceInfo_.themeId);
|
||||
|
||||
taskExecutor_->PostTask(
|
||||
[themeManager, assetManager = assetManager_, colorScheme = colorScheme_]() {
|
||||
[themeManager, assetManager = assetManager_, colorScheme = colorScheme_, aceView = aceView_]() {
|
||||
themeManager->ParseSystemTheme();
|
||||
themeManager->SetColorScheme(colorScheme);
|
||||
themeManager->LoadCustomTheme(assetManager);
|
||||
// get background color from theme
|
||||
aceView->SetBackgroundColor(themeManager->GetBackgroundColor());
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "adapter/preview/entrance/ace_run_args.h"
|
||||
#include "adapter/preview/entrance/flutter_ace_view.h"
|
||||
#include "adapter/preview/osal/fetch_manager.h"
|
||||
#include "base/resource/asset_manager.h"
|
||||
#include "base/thread/task_executor.h"
|
||||
#include "base/utils/noncopyable.h"
|
||||
@ -33,6 +34,14 @@
|
||||
|
||||
namespace OHOS::Ace::Platform {
|
||||
|
||||
namespace {
|
||||
// Different with mobile, we don't support multi-instances in Windows, because we only want
|
||||
// preivew UI effect, it doesn't make scense to create multi ability in one process.
|
||||
constexpr int32_t ACE_INSTANCE_ID = 0;
|
||||
}
|
||||
|
||||
using OnRouterChangeCallback = bool (*)(const std::string currentRouterPath);
|
||||
|
||||
// AceContainer is the instance have its own pipeline and thread models, it can contains multiple pages.
|
||||
class AceContainer : public Container, public JsMessageDispatcher {
|
||||
DECLARE_ACE_TYPE(AceContainer, Container, JsMessageDispatcher);
|
||||
@ -43,14 +52,19 @@ public:
|
||||
|
||||
static void AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths);
|
||||
static void SetResourcesPathAndThemeStyle(int32_t instanceId, const std::string& resourcesPath,
|
||||
const ThemeId& themeId, const ColorMode& colorMode);
|
||||
const int32_t& themeId, const ColorMode& colorMode);
|
||||
static void SetView(FlutterAceView* view, double density, int32_t width, int32_t height);
|
||||
static bool RunPage(int32_t instanceId, int32_t pageId, const std::string& url, const std::string& params);
|
||||
static RefPtr<AceContainer> GetContainerInstance(int32_t instanceId);
|
||||
static void AddRouterChangeCallback(int32_t instanceId, const OnRouterChangeCallback& onRouterChangeCallback);
|
||||
|
||||
AceContainer(int32_t instanceId, FrontendType type);
|
||||
~AceContainer() override = default;
|
||||
|
||||
void Initialize() override;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
int32_t GetInstanceId() const override
|
||||
{
|
||||
return instanceId_;
|
||||
@ -66,6 +80,11 @@ public:
|
||||
return frontend_;
|
||||
}
|
||||
|
||||
RefPtr<PlatformBridge> GetMessageBridge() const
|
||||
{
|
||||
return messageBridge_;
|
||||
}
|
||||
|
||||
RefPtr<TaskExecutor> GetTaskExecutor() const override
|
||||
{
|
||||
return taskExecutor_;
|
||||
@ -101,13 +120,28 @@ public:
|
||||
colorScheme_ = colorScheme;
|
||||
}
|
||||
|
||||
FrontendType GetType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
void FetchResponse(const ResponseData responseData, const int32_t callbackId) const;
|
||||
|
||||
void CallCurlFunction(const RequestData requestData, const int32_t callbackId) const override;
|
||||
|
||||
void Dispatch(
|
||||
const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const override;
|
||||
|
||||
void DispatchSync(
|
||||
const std::string& group, std::vector<uint8_t>&& data, uint8_t** resData, long& position) const override
|
||||
{}
|
||||
|
||||
void DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const override;
|
||||
|
||||
bool Dump(const std::vector<std::string>& params) override;
|
||||
|
||||
void UpdateColorMode(ColorMode newColorMode);
|
||||
|
||||
private:
|
||||
void InitializeFrontend();
|
||||
void InitializeCallback();
|
||||
@ -122,10 +156,11 @@ private:
|
||||
RefPtr<PlatformResRegister> resRegister_;
|
||||
RefPtr<PipelineContext> pipelineContext_;
|
||||
RefPtr<Frontend> frontend_;
|
||||
RefPtr<PlatformBridge> messageBridge_;
|
||||
FrontendType type_ { FrontendType::JSON };
|
||||
WindowModal windowModal_ { WindowModal::NORMAL };
|
||||
ColorScheme colorScheme_ { ColorScheme::SCHEME_LIGHT };
|
||||
DeviceResourceInfo deviceResourceInfo_;
|
||||
DeviceResourceInfo resourceInfo_;
|
||||
static std::once_flag onceFlag_;
|
||||
|
||||
ACE_DISALLOW_COPY_AND_MOVE(AceContainer);
|
||||
|
@ -32,6 +32,10 @@
|
||||
namespace OHOS::Ace::Platform {
|
||||
|
||||
using SendRenderDataCallback = bool (*)(const void*, size_t);
|
||||
using SendCurrentRouterCallback = bool (*)(const std::string currentRouterPath);
|
||||
|
||||
constexpr uint32_t THEME_ID_LIGHT = 117440515;
|
||||
constexpr uint32_t THEME_ID_DARK = 117440516;
|
||||
|
||||
// Keep the same with definition in base/utils/system_properties.h
|
||||
enum class DeviceOrientation : int32_t {
|
||||
@ -39,9 +43,9 @@ enum class DeviceOrientation : int32_t {
|
||||
LANDSCAPE,
|
||||
};
|
||||
|
||||
enum class ThemeId : int32_t {
|
||||
THEME_ID_LIGHT,
|
||||
THEME_ID_DARK,
|
||||
enum class AceVersion {
|
||||
ACE_1_0,
|
||||
ACE_2_0,
|
||||
};
|
||||
|
||||
// Keep the same with definition in base/utils/system_properties.h
|
||||
@ -50,17 +54,33 @@ enum class ColorMode : int32_t {
|
||||
DARK,
|
||||
};
|
||||
|
||||
// keep same with definition in base/utils/device_config.h
|
||||
struct DeviceConfig {
|
||||
DeviceOrientation orientation { DeviceOrientation::PORTRAIT };
|
||||
// resolution.
|
||||
double density { 1.0 };
|
||||
DeviceType deviceType { DeviceType::PHONE };
|
||||
// Current user perference for scaling fator for fonts, relative to the base density.
|
||||
// Set through by java interface, not support in previewer yet.
|
||||
double fontRatio { 1.0 };
|
||||
ColorMode colorMode { ColorMode::LIGHT };
|
||||
};
|
||||
|
||||
struct ACE_PREVIEW_EXPORT AceRunArgs {
|
||||
// The absolute path end of "default".
|
||||
std::string assetPath;
|
||||
// The absolute path of system resources.
|
||||
std::string resourcesPath;
|
||||
|
||||
// Indecate light or dark theme. 0 is theme_light, 1 is theme_dark.
|
||||
ThemeId themeId = ThemeId::THEME_ID_LIGHT;
|
||||
// Indecate light or dark theme.
|
||||
uint32_t themeId = THEME_ID_LIGHT;
|
||||
|
||||
// Light Theme contains light mode and dark mode. The dafault is light mode of light theme.
|
||||
ColorMode colorMode = ColorMode::LIGHT;
|
||||
DeviceConfig deviceConfig = {
|
||||
.orientation = DeviceOrientation::PORTRAIT,
|
||||
.density = 1.0,
|
||||
.deviceType = DeviceType::PHONE,
|
||||
.colorMode = ColorMode::LIGHT,
|
||||
};
|
||||
|
||||
// Set page path to launch directly, or launch the main page in default.
|
||||
std::string url;
|
||||
@ -72,19 +92,18 @@ struct ACE_PREVIEW_EXPORT AceRunArgs {
|
||||
int32_t viewHeight = 0;
|
||||
int32_t deviceWidth = 0;
|
||||
int32_t deviceHeight = 0;
|
||||
double resolution = 1.0;
|
||||
|
||||
// Locale
|
||||
std::string language = "zh";
|
||||
std::string region = "CN";
|
||||
std::string script = "";
|
||||
|
||||
DeviceOrientation orientation = DeviceOrientation::PORTRAIT;
|
||||
DeviceType deviceType = DeviceType::PHONE;
|
||||
AceVersion aceVersion = AceVersion::ACE_1_0;
|
||||
|
||||
bool formsEnabled = false;
|
||||
|
||||
SendRenderDataCallback onRender;
|
||||
SendRenderDataCallback onRender = nullptr;
|
||||
SendCurrentRouterCallback onRouterChange = nullptr;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::Platform
|
||||
|
@ -96,9 +96,12 @@ bool FlutterTaskExecutor::WillRunOnCurrentThread(TaskType type) const
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::DestroyJsThread()
|
||||
void FlutterTaskExecutor::AddTaskObserver(Task&& callback)
|
||||
{
|
||||
}
|
||||
|
||||
void FlutterTaskExecutor::RemoveTaskObserver()
|
||||
{
|
||||
jsThread_.reset();
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -31,7 +31,8 @@ public:
|
||||
explicit FlutterTaskExecutor(const flutter::TaskRunners& taskRunners);
|
||||
~FlutterTaskExecutor() override = default;
|
||||
|
||||
void DestroyJsThread();
|
||||
void AddTaskObserver(Task&& callback) override;
|
||||
void RemoveTaskObserver() override;
|
||||
bool WillRunOnCurrentThread(TaskType type) const final;
|
||||
|
||||
private:
|
||||
|
@ -39,6 +39,8 @@ template("ace_test") {
|
||||
sources = [ "ace_tablet_test.cpp" ]
|
||||
} else if (device == "card") {
|
||||
sources = [ "ace_card_test.cpp" ]
|
||||
} else if (device == "car") {
|
||||
sources = [ "ace_car_test.cpp" ]
|
||||
}
|
||||
|
||||
configs = [ ":ace_pc_preview_config" ]
|
||||
@ -79,6 +81,12 @@ ace_test("ace_test_windows_card") {
|
||||
device = "card"
|
||||
}
|
||||
|
||||
ace_test("ace_test_windows_car") {
|
||||
defines = ace_windows_defines
|
||||
platform = "windows"
|
||||
device = "car"
|
||||
}
|
||||
|
||||
ace_test("ace_test_mac_phone") {
|
||||
defines = ace_mac_defines
|
||||
platform = "mac"
|
||||
@ -108,3 +116,9 @@ ace_test("ace_test_mac_card") {
|
||||
platform = "mac"
|
||||
device = "card"
|
||||
}
|
||||
|
||||
ace_test("ace_test_mac_car") {
|
||||
defines = ace_mac_defines
|
||||
platform = "mac"
|
||||
device = "car"
|
||||
}
|
||||
|
88
adapter/preview/entrance/samples/ace_car_test.cpp
Normal file
88
adapter/preview/entrance/samples/ace_car_test.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "adapter/preview/entrance/ace_ability.h"
|
||||
#include "adapter/preview/entrance/ace_run_args.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int32_t GET_INSPECTOR_TREE_TIMES = 12;
|
||||
constexpr int32_t GET_INSPECTOR_TREE_INTERVAL = 5000;
|
||||
constexpr char FILE_NAME[] = "InspectorTree.txt";
|
||||
constexpr char ACE_VERSION_2[] = "2.0";
|
||||
constexpr char MAX_ARGS_COUNT = 2;
|
||||
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool { return true; };
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default";
|
||||
std::string assetPath2 = "/Volumes/SSD2T/daily-test/preview/js/default_2.0";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string assetPath2 = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
#endif
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.resourcesPath = resourcesPath,
|
||||
.deviceConfig.orientation = OHOS::Ace::Platform::DeviceOrientation::LANDSCAPE,
|
||||
.deviceConfig.density = 1,
|
||||
.deviceConfig.deviceType = OHOS::Ace::DeviceType::CAR,
|
||||
.windowTitle = "ACE Car",
|
||||
.deviceWidth = 1280,
|
||||
.deviceHeight = 800,
|
||||
.onRender = std::move(renderCallback),
|
||||
};
|
||||
|
||||
if (argc == MAX_ARGS_COUNT && !std::strcmp(argv[1], ACE_VERSION_2)) {
|
||||
args.assetPath = assetPath2;
|
||||
args.aceVersion = OHOS::Ace::Platform::AceVersion::ACE_2_0;
|
||||
}
|
||||
|
||||
auto ability = OHOS::Ace::Platform::AceAbility::CreateInstance(args);
|
||||
if (!ability) {
|
||||
std::cerr << "Could not create AceAbility!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::thread timer([&ability]() {
|
||||
int32_t getJSONTreeTimes = GET_INSPECTOR_TREE_TIMES;
|
||||
while (getJSONTreeTimes--) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(GET_INSPECTOR_TREE_INTERVAL));
|
||||
std::string jsonTreeStr = ability->GetJSONTree();
|
||||
// clear all information
|
||||
std::ofstream fileCleaner(FILE_NAME, std::ios_base::out);
|
||||
std::ofstream fileWriter(FILE_NAME, std::ofstream::app);
|
||||
fileWriter << jsonTreeStr;
|
||||
fileWriter << std::endl;
|
||||
fileWriter.close();
|
||||
}
|
||||
});
|
||||
ability->InitEnv();
|
||||
std::cout << "Ace initialize done. run loop now" << std::endl;
|
||||
ability->Start();
|
||||
|
||||
return 0;
|
||||
}
|
@ -43,20 +43,21 @@ int main()
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default_card";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
constexpr double resolution = 2;
|
||||
constexpr double density = 2;
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default_card";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
constexpr double resolution = 1;
|
||||
constexpr double density = 1;
|
||||
#endif
|
||||
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.resourcesPath = resourcesPath,
|
||||
.deviceConfig.density = density,
|
||||
.deviceConfig.colorMode = OHOS::Ace::Platform::ColorMode::DARK,
|
||||
.windowTitle = "ACE card",
|
||||
.deviceWidth = CARD_DEFAULT_WIDTH,
|
||||
.deviceHeight = CARD_DEFAULT_HEIGHT,
|
||||
.windowTitle = "ACE card",
|
||||
.resolution = resolution,
|
||||
.formsEnabled = true,
|
||||
.onRender = std::move(renderCallback),
|
||||
};
|
||||
|
@ -26,35 +26,47 @@ namespace {
|
||||
constexpr int32_t GET_INSPECTOR_TREE_TIMES = 12;
|
||||
constexpr int32_t GET_INSPECTOR_TREE_INTERVAL = 5000;
|
||||
constexpr char FILE_NAME[] = "InspectorTree.txt";
|
||||
constexpr char ACE_VERSION_2[] = "2.0";
|
||||
constexpr char MAX_ARGS_COUNT = 2;
|
||||
|
||||
}
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool { return true; };
|
||||
|
||||
int main()
|
||||
auto&& pageCallback = [](const std::string currentPagePath) -> bool {
|
||||
printf("callback currentPage:%s", currentPagePath.c_str());
|
||||
return true;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool {
|
||||
return true;
|
||||
};
|
||||
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default";
|
||||
std::string assetPath2 = "/Volumes/SSD2T/daily-test/preview/js/default_2.0";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
constexpr double resolution = 2;
|
||||
constexpr double density = 2;
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default";
|
||||
std::string assetPath2 = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
constexpr double resolution = 1;
|
||||
constexpr double density = 1;
|
||||
#endif
|
||||
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.resourcesPath = resourcesPath,
|
||||
.deviceConfig.density = density,
|
||||
.windowTitle = "ACE phone",
|
||||
.deviceWidth = 360,
|
||||
.deviceHeight = 750,
|
||||
.windowTitle = "ACE phone",
|
||||
.resolution = resolution,
|
||||
.onRender = std::move(renderCallback),
|
||||
.onRouterChange = std::move(pageCallback),
|
||||
};
|
||||
|
||||
if (argc == MAX_ARGS_COUNT && !std::strcmp(argv[1], ACE_VERSION_2)) {
|
||||
args.assetPath = assetPath2;
|
||||
args.aceVersion = OHOS::Ace::Platform::AceVersion::ACE_2_0;
|
||||
}
|
||||
|
||||
auto ability = OHOS::Ace::Platform::AceAbility::CreateInstance(args);
|
||||
if (!ability) {
|
||||
std::cerr << "Could not create AceAbility!" << std::endl;
|
||||
|
@ -26,35 +26,41 @@ namespace {
|
||||
constexpr int32_t GET_INSPECTOR_TREE_TIMES = 12;
|
||||
constexpr int32_t GET_INSPECTOR_TREE_INTERVAL = 5000;
|
||||
constexpr char FILE_NAME[] = "InspectorTree.txt";
|
||||
constexpr char ACE_VERSION_2[] = "2.0";
|
||||
constexpr char MAX_ARGS_COUNT = 2;
|
||||
|
||||
}
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool { return true; };
|
||||
|
||||
int main()
|
||||
} // namespace
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool {
|
||||
return true;
|
||||
};
|
||||
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default";
|
||||
std::string assetPath2 = "/Volumes/SSD2T/daily-test/preview/js/default_2.0";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default";
|
||||
std::string assetPath2 = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
#endif
|
||||
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.resourcesPath = resourcesPath,
|
||||
.orientation = OHOS::Ace::Platform::DeviceOrientation::LANDSCAPE,
|
||||
.deviceConfig.orientation = OHOS::Ace::Platform::DeviceOrientation::LANDSCAPE,
|
||||
.deviceConfig.density = 1,
|
||||
.deviceConfig.deviceType = OHOS::Ace::DeviceType::TABLET,
|
||||
.windowTitle = "ACE Table",
|
||||
.deviceWidth = 1280,
|
||||
.deviceHeight = 800,
|
||||
.windowTitle = "ACE Table",
|
||||
.resolution = 1,
|
||||
.deviceType = OHOS::Ace::DeviceType::TABLET,
|
||||
.onRender = std::move(renderCallback),
|
||||
};
|
||||
|
||||
if (argc == MAX_ARGS_COUNT && !std::strcmp(argv[1], ACE_VERSION_2)) {
|
||||
args.assetPath = assetPath2;
|
||||
args.aceVersion = OHOS::Ace::Platform::AceVersion::ACE_2_0;
|
||||
}
|
||||
|
||||
auto ability = OHOS::Ace::Platform::AceAbility::CreateInstance(args);
|
||||
if (!ability) {
|
||||
std::cerr << "Could not create AceAbility!" << std::endl;
|
||||
|
@ -26,34 +26,40 @@ namespace {
|
||||
constexpr int32_t GET_INSPECTOR_TREE_TIMES = 12;
|
||||
constexpr int32_t GET_INSPECTOR_TREE_INTERVAL = 5000;
|
||||
constexpr char FILE_NAME[] = "InspectorTree.txt";
|
||||
constexpr char ACE_VERSION_2[] = "2.0";
|
||||
constexpr char MAX_ARGS_COUNT = 2;
|
||||
|
||||
}
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool { return true; };
|
||||
|
||||
int main()
|
||||
} // namespace
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool {
|
||||
return true;
|
||||
};
|
||||
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default";
|
||||
std::string assetPath2 = "/Volumes/SSD2T/daily-test/preview/js/default_2.0";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default";
|
||||
std::string assetPath2 = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
#endif
|
||||
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.orientation = OHOS::Ace::Platform::DeviceOrientation::LANDSCAPE,
|
||||
.deviceConfig.orientation = OHOS::Ace::Platform::DeviceOrientation::LANDSCAPE,
|
||||
.deviceConfig.density = 1,
|
||||
.deviceConfig.deviceType = OHOS::Ace::DeviceType::TV,
|
||||
.windowTitle = "ACE TV",
|
||||
.deviceWidth = 960,
|
||||
.deviceHeight = 540,
|
||||
.windowTitle = "ACE TV",
|
||||
.resolution = 1,
|
||||
.deviceType = OHOS::Ace::DeviceType::TV,
|
||||
.onRender = std::move(renderCallback),
|
||||
};
|
||||
|
||||
if (argc == MAX_ARGS_COUNT && !std::strcmp(argv[1], ACE_VERSION_2)) {
|
||||
args.assetPath = assetPath2;
|
||||
args.aceVersion = OHOS::Ace::Platform::AceVersion::ACE_2_0;
|
||||
}
|
||||
|
||||
auto ability = OHOS::Ace::Platform::AceAbility::CreateInstance(args);
|
||||
if (!ability) {
|
||||
std::cerr << "Could not create AceAbility!" << std::endl;
|
||||
|
@ -26,34 +26,40 @@ namespace {
|
||||
constexpr int32_t GET_INSPECTOR_TREE_TIMES = 12;
|
||||
constexpr int32_t GET_INSPECTOR_TREE_INTERVAL = 5000;
|
||||
constexpr char FILE_NAME[] = "InspectorTree.txt";
|
||||
constexpr char ACE_VERSION_2[] = "2.0";
|
||||
constexpr char MAX_ARGS_COUNT = 2;
|
||||
|
||||
}
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool { return true; };
|
||||
|
||||
int main()
|
||||
} // namespace
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
auto&& renderCallback = [](const void*, size_t bufferSize) -> bool {
|
||||
return true;
|
||||
};
|
||||
|
||||
#ifdef MAC_PLATFORM
|
||||
std::string assetPath = "/Volumes/SSD2T/daily-test/preview/js/default";
|
||||
std::string assetPath2 = "/Volumes/SSD2T/daily-test/preview/js/default_2.0";
|
||||
std::string resourcesPath = "/Volumes/SSD2T/daily-test/preview/js/resources";
|
||||
#else
|
||||
std::string assetPath = "D:\\Workspace\\preview\\js\\default";
|
||||
std::string assetPath2 = "D:\\Workspace\\preview\\js\\default_2.0";
|
||||
std::string resourcesPath = "D:\\Workspace\\preview\\js\\resources";
|
||||
#endif
|
||||
|
||||
OHOS::Ace::Platform::AceRunArgs args = {
|
||||
.assetPath = assetPath,
|
||||
.deviceConfig.density = 2.0,
|
||||
.deviceConfig.deviceType = OHOS::Ace::DeviceType::WATCH,
|
||||
.windowTitle = "ACE wearable",
|
||||
.isRound = true,
|
||||
.deviceWidth = 466,
|
||||
.deviceHeight = 466,
|
||||
.windowTitle = "ACE wearable",
|
||||
.resolution = 2.0,
|
||||
.isRound = true,
|
||||
.deviceType = OHOS::Ace::DeviceType::WATCH,
|
||||
.onRender = std::move(renderCallback),
|
||||
};
|
||||
|
||||
if (argc == MAX_ARGS_COUNT && !std::strcmp(argv[1], ACE_VERSION_2)) {
|
||||
args.assetPath = assetPath2;
|
||||
args.aceVersion = OHOS::Ace::Platform::AceVersion::ACE_2_0;
|
||||
}
|
||||
|
||||
auto ability = OHOS::Ace::Platform::AceAbility::CreateInstance(args);
|
||||
if (!ability) {
|
||||
std::cerr << "Could not create AceAbility!" << std::endl;
|
||||
|
@ -14,6 +14,36 @@
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/ace/ace_engine/ace_config.gni")
|
||||
|
||||
template("utilsecurec_source") {
|
||||
# get is_ohos_platform
|
||||
forward_variables_from(invoker, "*")
|
||||
ohos_source_set(target_name) {
|
||||
defines += invoker.defines
|
||||
sources = [ "//utils/native/base/src/securec/vsnprintf_s_p.c" ]
|
||||
if (platform == "windows") {
|
||||
sources += [
|
||||
"//utils/native/base/src/securec/memset_s.c",
|
||||
"//utils/native/base/src/securec/securecutil.c",
|
||||
"//utils/native/base/src/securec/secureinput_w.c",
|
||||
"//utils/native/base/src/securec/secureprintoutput_a.c",
|
||||
"//utils/native/base/src/securec/secureprintoutput_w.c",
|
||||
]
|
||||
cflags = [ "-Wno-inconsistent-dllimport" ]
|
||||
}
|
||||
configs = [ "//utils/native/base:utils_config" ]
|
||||
}
|
||||
}
|
||||
|
||||
utilsecurec_source("utilsecurec_source_windows") {
|
||||
defines = ace_windows_defines
|
||||
platform = "windows"
|
||||
}
|
||||
|
||||
utilsecurec_source("utilsecurec_source_mac") {
|
||||
defines = ace_windows_defines
|
||||
platform = "mac"
|
||||
}
|
||||
|
||||
# build static
|
||||
template("ace_osal_preview_source_set") {
|
||||
# get is_ohos_platform
|
||||
@ -39,10 +69,13 @@ template("ace_osal_preview_source_set") {
|
||||
|
||||
configs = [
|
||||
"$ace_root:ace_config",
|
||||
"$flutter_root:flutter_config",
|
||||
"$ace_flutter_engine_root:flutter_config",
|
||||
]
|
||||
|
||||
deps = [ "//third_party/zlib:libz" ]
|
||||
deps = [
|
||||
":utilsecurec_source_$platform",
|
||||
"//third_party/zlib:libz",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
200
adapter/preview/osal/fetch_manager.cpp
Normal file
200
adapter/preview/osal/fetch_manager.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "adapter/preview/osal/fetch_manager.h"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "curl/curl.h"
|
||||
|
||||
#include "adapter/preview/osal/http_constant.h"
|
||||
#include "base/log/log.h"
|
||||
#include "base/utils/singleton.h"
|
||||
|
||||
#define ACE_CURL_EASY_SET_OPTION(handle, opt, data) \
|
||||
do { \
|
||||
CURLcode result = curl_easy_setopt(handle, opt, data); \
|
||||
if (result != CURLE_OK) { \
|
||||
LOGE("Failed to set option: %{public}s, %{public}s", #opt, curl_easy_strerror(result)); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
class FetchManagerImpl final : public FetchManager, public Singleton<FetchManagerImpl> {
|
||||
DECLARE_SINGLETON(FetchManagerImpl);
|
||||
ACE_DISALLOW_MOVE(FetchManagerImpl);
|
||||
|
||||
public:
|
||||
bool Fetch(const RequestData requestData, const int32_t callbackId, ResponseData& responseData) override
|
||||
{
|
||||
if (!Initialize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> handle(curl_easy_init(), &curl_easy_cleanup);
|
||||
if (!handle) {
|
||||
LOGE("Failed to create fetch task");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct curl_slist* header = nullptr;
|
||||
if (!requestData.GetHeader().empty()) {
|
||||
for (auto&& [key, value] : requestData.GetHeader()) {
|
||||
header = curl_slist_append(header, (key + ":" + value).c_str());
|
||||
}
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_HTTPHEADER, header);
|
||||
}
|
||||
|
||||
std::string responseBody;
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_WRITEFUNCTION, OnWritingMemoryBody);
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_WRITEDATA, &responseBody);
|
||||
|
||||
std::string responseHeader;
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_HEADERFUNCTION, OnWritingMemoryHeader);
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_HEADERDATA, &responseHeader);
|
||||
|
||||
// Some servers don't like requests that are made without a user-agent field, so we provide one
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
ACE_CURL_EASY_SET_OPTION(handle.get(), CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
#endif
|
||||
|
||||
std::string method = requestData.GetMethod();
|
||||
if (method == HttpConstant::HTTP_METHOD_HEAD || method == HttpConstant::HTTP_METHOD_OPTIONS ||
|
||||
method == HttpConstant::HTTP_METHOD_DELETE || method == HttpConstant::HTTP_METHOD_TRACE ||
|
||||
method == HttpConstant::HTTP_METHOD_GET) {
|
||||
SetOptionForGet(requestData, handle.get());
|
||||
} else if (method == HttpConstant::HTTP_METHOD_POST || method == HttpConstant::HTTP_METHOD_PUT) {
|
||||
SetOptionForPost(requestData, handle.get());
|
||||
} else {
|
||||
LOGE("no method match!");
|
||||
responseData.SetCode(HttpConstant::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
CURLcode result = curl_easy_perform(handle.get());
|
||||
if (result != CURLE_OK) {
|
||||
LOGE("Failed to fetch, url: %{private}s, %{public}s", requestData.GetUrl().c_str(),
|
||||
curl_easy_strerror(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
char* ct = nullptr;
|
||||
CURLcode res = curl_easy_getinfo(handle.get(), CURLINFO_CONTENT_TYPE, &ct);
|
||||
if ((CURLE_OK == res) && ct) {
|
||||
LOGD("fetch-preview content_type: %{public}s", ct);
|
||||
}
|
||||
|
||||
int32_t responseCode;
|
||||
curl_easy_getinfo(handle.get(), CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
responseData.SetCode(responseCode);
|
||||
responseData.SetData(responseBody);
|
||||
responseData.SetHeaders(responseHeader);
|
||||
|
||||
curl_slist_free_all(header);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetOptionForGet(const RequestData requestData, CURL* curl) const
|
||||
{
|
||||
// refer to function buildConnectionWithParam() in HttpFetchImpl.java
|
||||
LOGD("begin to set option for get and encode final url");
|
||||
std::string url = requestData.GetUrl();
|
||||
if (requestData.GetData() != "") {
|
||||
std::size_t index = url.find(HttpConstant::URL_PARAM_SEPARATOR);
|
||||
if (index != std::string::npos) {
|
||||
std::string param = url.substr(index + 1);
|
||||
|
||||
std::string encodeIn = param + HttpConstant::URL_PARAM_DELIMITER + requestData.GetData();
|
||||
char* encodeOut = curl_easy_escape(curl, encodeIn.c_str(), 0);
|
||||
if (encodeOut != nullptr) {
|
||||
url = url.substr(0, index + 1) + encodeOut;
|
||||
curl_free(encodeOut);
|
||||
}
|
||||
} else {
|
||||
char* encodeOut = curl_easy_escape(curl, requestData.GetData().c_str(), 0);
|
||||
if (encodeOut != nullptr) {
|
||||
url = url + HttpConstant::URL_PARAM_SEPARATOR + encodeOut;
|
||||
curl_free(encodeOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGD("final url : %{public}s", url.c_str());
|
||||
ACE_CURL_EASY_SET_OPTION(curl, CURLOPT_URL, url.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetOptionForPost(const RequestData requestData, CURL* curl) const
|
||||
{
|
||||
ACE_CURL_EASY_SET_OPTION(curl, CURLOPT_URL, requestData.GetUrl().c_str());
|
||||
ACE_CURL_EASY_SET_OPTION(curl, CURLOPT_POST, 1L);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t OnWritingMemoryBody(const void* data, size_t size, size_t memBytes, void* userData)
|
||||
{
|
||||
((std::string*)userData)->append((char*)data, 0, size * memBytes);
|
||||
return size * memBytes;
|
||||
}
|
||||
static size_t OnWritingMemoryHeader(const void* data, size_t size, size_t memBytes, void* userData)
|
||||
{
|
||||
((std::string*)userData)->append((char*)data, 0, size * memBytes);
|
||||
return size * memBytes;
|
||||
}
|
||||
|
||||
bool Initialize()
|
||||
{
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
LOGE("Failed to initialize 'curl'");
|
||||
return false;
|
||||
}
|
||||
initialized_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::mutex mutex_;
|
||||
bool initialized_ = false;
|
||||
};
|
||||
|
||||
FetchManagerImpl::FetchManagerImpl() = default;
|
||||
|
||||
FetchManagerImpl::~FetchManagerImpl()
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FetchManager& FetchManager::GetInstance()
|
||||
{
|
||||
return Singleton<FetchManagerImpl>::GetInstance();
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
37
adapter/preview/osal/fetch_manager.h
Normal file
37
adapter/preview/osal/fetch_manager.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_FETCH_MANAGER_H
|
||||
#define FOUNDATION_ACE_ADAPTER_PREVIEW_FETCH_MANAGER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "adapter/preview/osal/request_data.h"
|
||||
#include "adapter/preview/osal/response_data.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class FetchManager {
|
||||
public:
|
||||
static FetchManager& GetInstance();
|
||||
|
||||
virtual ~FetchManager() = default;
|
||||
virtual bool Fetch(const RequestData requestData, const int32_t callbackId, ResponseData& responseData) = 0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // #ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_FETCH_MANAGER_H
|
38
adapter/preview/osal/http_constant.h
Normal file
38
adapter/preview/osal/http_constant.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_HTTPCONSTANT_H
|
||||
#define FOUNDATION_ACE_ADAPTER_PREVIEW_HTTPCONSTANT_H
|
||||
|
||||
namespace OHOS::Ace {
|
||||
class HttpConstant {
|
||||
public:
|
||||
static const int ERROR = -1;
|
||||
static const int TIME_OUT = 30000;
|
||||
static const int BUFFER_SIZE = 8192;
|
||||
inline static const std::string URL_PARAM_SEPARATOR = "?";
|
||||
inline static const std::string URL_PARAM_DELIMITER = "&";
|
||||
inline static const std::string HTTP_METHOD_GET = "GET";
|
||||
inline static const std::string HTTP_METHOD_HEAD = "HEAD";
|
||||
inline static const std::string HTTP_METHOD_OPTIONS = "OPTIONS";
|
||||
inline static const std::string HTTP_METHOD_TRACE = "TRACE";
|
||||
inline static const std::string HTTP_METHOD_DELETE = "DELETE";
|
||||
inline static const std::string HTTP_METHOD_CONNECT = "CONNECT";
|
||||
inline static const std::string HTTP_METHOD_POST = "POST";
|
||||
inline static const std::string HTTP_METHOD_PUT = "PUT";
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // #ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_HTTPCONSTANT_H
|
@ -20,12 +20,14 @@
|
||||
#else
|
||||
#include "securec.h"
|
||||
#endif
|
||||
#include <securec_p.h>
|
||||
#include <thread>
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
constexpr uint32_t MAX_BUFFER_SIZE = 512;
|
||||
// MAX_BUFFER_SIZE same with hilog
|
||||
constexpr uint32_t MAX_BUFFER_SIZE = 4000;
|
||||
constexpr uint32_t MAX_TIME_SIZE = 32;
|
||||
const char* const LOGLEVELNAME[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
|
||||
|
||||
@ -68,28 +70,28 @@ std::string GetTimeStamp()
|
||||
void LogWrapper::PrintLog(LogDomain domain, LogLevel level, const char* fmt, va_list args)
|
||||
{
|
||||
std::string newFmt(fmt);
|
||||
StripFormatString("{public}", newFmt);
|
||||
StripFormatString("{private}", newFmt);
|
||||
|
||||
char buf[MAX_BUFFER_SIZE];
|
||||
if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, newFmt.c_str(), args) < 0) {
|
||||
if (vsnprintfp_s(buf, sizeof(buf), sizeof(buf) - 1, true, newFmt.c_str(), args) < 0 && errno == EINVAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string newTimeFmt("%s %-6d [%-7s %7s]");
|
||||
std::string newTimeFmt("[%-7s %7s] %s %-6d");
|
||||
char timeBuf[MAX_BUFFER_SIZE];
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
if (_snprintf_s(timeBuf, sizeof(timeBuf), sizeof(timeBuf) - 1, newTimeFmt.c_str(), GetTimeStamp().c_str(),
|
||||
std::this_thread::get_id(), LOG_TAGS[static_cast<uint32_t>(domain)], GetNameForLogLevel(level)) < 0) {
|
||||
if (_snprintf_s(timeBuf, sizeof(timeBuf), sizeof(timeBuf) - 1, newTimeFmt.c_str(),
|
||||
LOG_TAGS[static_cast<uint32_t>(domain)], GetNameForLogLevel(level), GetTimeStamp().c_str(),
|
||||
std::this_thread::get_id()) < 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (snprintf_s(timeBuf, sizeof(timeBuf), sizeof(timeBuf) - 1, newTimeFmt.c_str(), GetTimeStamp().c_str(),
|
||||
std::this_thread::get_id(), LOG_TAGS[static_cast<uint32_t>(domain)], GetNameForLogLevel(level)) < 0) {
|
||||
if (snprintf_s(timeBuf, sizeof(timeBuf), sizeof(timeBuf) - 1, newTimeFmt.c_str(),
|
||||
LOG_TAGS[static_cast<uint32_t>(domain)], GetNameForLogLevel(level), GetTimeStamp().c_str(),
|
||||
std::this_thread::get_id()) < 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
printf("%s %s\r\n", timeBuf, buf);
|
||||
printf("%s %s\r\n", timeBuf, buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
83
adapter/preview/osal/request_data.h
Normal file
83
adapter/preview/osal/request_data.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_REQUESTDATA_H
|
||||
#define FOUNDATION_ACE_ADAPTER_PREVIEW_REQUESTDATA_H
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace OHOS::Ace {
|
||||
class RequestData {
|
||||
public:
|
||||
const std::string GetUrl() const
|
||||
{
|
||||
return url_;
|
||||
}
|
||||
|
||||
void SetUrl(const std::string url)
|
||||
{
|
||||
url_ = url;
|
||||
}
|
||||
|
||||
const std::string GetData() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
void SetData(const std::string data)
|
||||
{
|
||||
data_ = data;
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string> GetHeader() const
|
||||
{
|
||||
return header_;
|
||||
}
|
||||
|
||||
void SetHeader(const std::map<std::string, std::string> header)
|
||||
{
|
||||
header_ = header;
|
||||
}
|
||||
|
||||
const std::string GetMethod() const
|
||||
{
|
||||
return method_;
|
||||
}
|
||||
|
||||
void SetMethod(const std::string method)
|
||||
{
|
||||
method_ = method;
|
||||
}
|
||||
|
||||
const std::string GetEesponseType() const
|
||||
{
|
||||
return responseType_;
|
||||
}
|
||||
|
||||
void SetResponseType(const std::string responseType)
|
||||
{
|
||||
responseType_ = responseType;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string url_;
|
||||
std::string data_;
|
||||
std::map<std::string, std::string> header_;
|
||||
std::string method_;
|
||||
std::string responseType_;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // #ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_REQUESTDATA_H
|
70
adapter/preview/osal/response_data.cpp
Normal file
70
adapter/preview/osal/response_data.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "adapter/preview/osal/response_data.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
std::unique_ptr<JsonValue> ResponseData::GetResultString() const
|
||||
{
|
||||
auto resultJson = JsonUtil::Create(true);
|
||||
if (code_ == HTTP_OK) {
|
||||
resultJson->Put(std::string("code").c_str(), ACTION_SUCCESS);
|
||||
resultJson->Put(std::string("data").c_str(), GetStringValue());
|
||||
} else {
|
||||
resultJson->Put(std::string("code").c_str(), COMMON_ERROR_CODE);
|
||||
resultJson->Put(std::string("data").c_str(), "invalid response data");
|
||||
}
|
||||
|
||||
return resultJson;
|
||||
}
|
||||
|
||||
std::unique_ptr<JsonValue> ResponseData::GetStringValue() const
|
||||
{
|
||||
auto responseJson = JsonUtil::Create(true);
|
||||
responseJson->Put(std::string("code").c_str(), code_);
|
||||
responseJson->Put(std::string("data").c_str(), data_.c_str());
|
||||
|
||||
if (code_ == HTTP_OK) {
|
||||
std::string headersStr = "{";
|
||||
for (auto&& [key, value] : headers_) {
|
||||
headersStr += key + ":" + value + ",";
|
||||
}
|
||||
headersStr[headersStr.size() - 1] = '}';
|
||||
responseJson->Put(std::string("headers").c_str(), headersStr.c_str());
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
void ResponseData::SetHeaders(std::string headersStr)
|
||||
{
|
||||
const char separator = '\n';
|
||||
size_t posSeparator = headersStr.find(separator);
|
||||
while (std::string::npos != posSeparator) {
|
||||
std::string header = headersStr.substr(0, posSeparator - 1);
|
||||
if (header == "") {
|
||||
break;
|
||||
}
|
||||
size_t posColon = header.find(':');
|
||||
if (std::string::npos == posColon) {
|
||||
headers_["null"] = "[\"" + header + "\"]";
|
||||
} else {
|
||||
headers_["\"" + header.substr(0, posColon) + "\""] = "[\"" + header.substr(posColon + 2) + "\"]";
|
||||
}
|
||||
headersStr = headersStr.substr(posSeparator + 1);
|
||||
posSeparator = headersStr.find(separator);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace
|
72
adapter/preview/osal/response_data.h
Normal file
72
adapter/preview/osal/response_data.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_RESPONSEDATA_H
|
||||
#define FOUNDATION_ACE_ADAPTER_PREVIEW_RESPONSEDATA_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
#include "base/json/json_util.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
namespace {
|
||||
// error code
|
||||
constexpr int32_t ACTION_SUCCESS = 0;
|
||||
constexpr int32_t COMMON_ERROR_CODE = 200;
|
||||
// httpcode
|
||||
constexpr int32_t HTTP_OK = 200;
|
||||
} // namespace
|
||||
|
||||
class ResponseData {
|
||||
public:
|
||||
int32_t GetCode() const
|
||||
{
|
||||
return code_;
|
||||
}
|
||||
|
||||
void SetCode(const int32_t code)
|
||||
{
|
||||
code_ = code;
|
||||
}
|
||||
|
||||
std::string GetData() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
void SetData(const std::string data)
|
||||
{
|
||||
data_ = data;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> GetHeaders() const
|
||||
{
|
||||
return headers_;
|
||||
}
|
||||
|
||||
void SetHeaders(std::string headersStr);
|
||||
std::unique_ptr<JsonValue> GetResultString() const;
|
||||
private:
|
||||
int32_t code_ = COMMON_ERROR_CODE;
|
||||
std::string data_;
|
||||
std::unordered_map<std::string, std::string> headers_;
|
||||
|
||||
std::unique_ptr<JsonValue> GetStringValue() const;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // #ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_RESPONSEDATA_H
|
15
adapter/preview/osal/system_properties.cpp
Executable file → Normal file
15
adapter/preview/osal/system_properties.cpp
Executable file → Normal file
@ -79,6 +79,8 @@ std::string SystemProperties::paramDeviceType_ = UNDEFINED_PARAM;
|
||||
int32_t SystemProperties::mcc_ = MCC_UNDEFINED;
|
||||
int32_t SystemProperties::mnc_ = MNC_UNDEFINED;
|
||||
ColorMode SystemProperties::colorMode_ = ColorMode::LIGHT;
|
||||
ScreenShape SystemProperties::screenShape_ { ScreenShape::NOT_ROUND };
|
||||
LongScreenType SystemProperties::LongScreen_ { LongScreenType::NOT_LONG };
|
||||
|
||||
void SystemProperties::UpdateSurfaceStatus(int32_t width, int32_t height)
|
||||
{
|
||||
@ -100,7 +102,13 @@ void SystemProperties::InitDeviceInfo(int32_t deviceWidth, int32_t deviceHeight,
|
||||
double resolution, bool isRound)
|
||||
{
|
||||
// SetDeviceOrientation should be eralier than deviceWidth/deviceHeight init.
|
||||
SetDeviceOrientation(orientation);
|
||||
if (orientation == ORIENTATION_PORTRAIT && orientation_ != DeviceOrientation::PORTRAIT) {
|
||||
orientation_ = DeviceOrientation::PORTRAIT;
|
||||
} else if (orientation == ORIENTATION_LANDSCAPE && orientation_ != DeviceOrientation::LANDSCAPE) {
|
||||
orientation_ = DeviceOrientation::LANDSCAPE;
|
||||
} else {
|
||||
LOGW("SetDeviceOrientation, undefined orientation");
|
||||
}
|
||||
|
||||
isRound_ = isRound;
|
||||
resolution_ = resolution;
|
||||
@ -109,6 +117,11 @@ void SystemProperties::InitDeviceInfo(int32_t deviceWidth, int32_t deviceHeight,
|
||||
// To avoid the deviceinfor api failure due to surface width and height equal 0 in previewer.
|
||||
width_ = deviceWidth_;
|
||||
height_ = deviceHeight_;
|
||||
if (isRound_) {
|
||||
screenShape_ = ScreenShape::ROUND;
|
||||
} else {
|
||||
screenShape_ = ScreenShape::NOT_ROUND;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemProperties::SetDeviceOrientation(int32_t orientation)
|
||||
|
@ -44,7 +44,11 @@ template("ace_base_source_set") {
|
||||
|
||||
# add base source file here
|
||||
sources = [
|
||||
"geometry/animatable_dimension.cpp",
|
||||
"geometry/animatable_matrix4.cpp",
|
||||
"geometry/matrix4.cpp",
|
||||
"geometry/quaternion.cpp",
|
||||
"geometry/transform_util.cpp",
|
||||
"json/json_util.cpp",
|
||||
"log/ace_trace.cpp",
|
||||
"log/dump_log.cpp",
|
||||
@ -56,7 +60,7 @@ template("ace_base_source_set") {
|
||||
"utils/time_util.cpp",
|
||||
]
|
||||
|
||||
if (is_standard_system) {
|
||||
if (is_standard_system && !use_mingw_win && !use_mac) {
|
||||
configs += [ "//third_party/curl:curl_config" ]
|
||||
deps += [ "//third_party/curl:curl" ]
|
||||
sources += [ "network/download_manager.cpp" ]
|
||||
|
131
frameworks/base/geometry/animatable_dimension.cpp
Normal file
131
frameworks/base/geometry/animatable_dimension.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "base/geometry/animatable_dimension.h"
|
||||
|
||||
#include "core/event/ace_event_helper.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
AnimatableDimension& AnimatableDimension::operator=(const Dimension& newDimension)
|
||||
{
|
||||
ResetAnimatableDimension();
|
||||
Dimension& dimension = *this;
|
||||
dimension = newDimension;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AnimatableDimension& AnimatableDimension::operator=(const AnimatableDimension& newDimension)
|
||||
{
|
||||
SetUnit(newDimension.Unit());
|
||||
SetAnimationOption(newDimension.GetAnimationOption());
|
||||
auto pipelineContext = context_.Upgrade();
|
||||
if (!animationCallback_ || !pipelineContext) {
|
||||
LOGD("Animatable assign without animation due to null callback or context");
|
||||
SetValue(newDimension.Value());
|
||||
return *this;
|
||||
}
|
||||
AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
|
||||
if (explicitAnim.IsValid()) {
|
||||
LOGD("Animatable assign with explicit animation, duration: %{public}d", explicitAnim.GetDuration());
|
||||
SetAnimationOption(explicitAnim);
|
||||
AnimateTo(newDimension.Value());
|
||||
} else if (animationOption_.IsValid()) {
|
||||
LOGD("Animatable assign with implicit animation, duration: %{public}d", explicitAnim.GetDuration());
|
||||
AnimateTo(newDimension.Value());
|
||||
} else {
|
||||
LOGD("Animatable assign without animation.");
|
||||
ResetController();
|
||||
SetValue(newDimension.Value());
|
||||
}
|
||||
isFirstAssign_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AnimatableDimension::AnimateTo(double endValue)
|
||||
{
|
||||
if (isFirstAssign_) {
|
||||
LOGD("AnimateTo with first assign. endValue: %{public}.2f", endValue);
|
||||
isFirstAssign_ = false;
|
||||
SetValue(endValue);
|
||||
return;
|
||||
}
|
||||
if (NearEqual(Value(), endValue) && !evaluator_) {
|
||||
LOGD("AnimateTo with same value. endValue: %{public}.2f", endValue);
|
||||
return;
|
||||
}
|
||||
ResetController();
|
||||
if (!animationController_) {
|
||||
animationController_ = AceType::MakeRefPtr<Animator>(context_);
|
||||
}
|
||||
RefPtr<CurveAnimation<double>> animation =
|
||||
AceType::MakeRefPtr<CurveAnimation<double>>(Value(), endValue, animationOption_.GetCurve());
|
||||
if (evaluator_) {
|
||||
animation->SetEvaluator(evaluator_);
|
||||
}
|
||||
animation->AddListener(std::bind(&AnimatableDimension::OnAnimationCallback, this, std::placeholders::_1));
|
||||
|
||||
animationController_->AddInterpolator(animation);
|
||||
auto onFinishEvent = animationOption_.GetOnFinishEvent();
|
||||
if (!onFinishEvent.IsEmpty()) {
|
||||
animationController_->AddStopListener(
|
||||
[onFinishEvent, weakContext = context_] { AceAsyncEvent<void()>::Create(onFinishEvent, weakContext)(); });
|
||||
}
|
||||
if (stopCallback_) {
|
||||
animationController_->AddStopListener(stopCallback_);
|
||||
}
|
||||
animationController_->SetDuration(animationOption_.GetDuration());
|
||||
animationController_->SetStartDelay(animationOption_.GetDelay());
|
||||
animationController_->SetIteration(animationOption_.GetIteration());
|
||||
animationController_->SetTempo(animationOption_.GetTempo());
|
||||
animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
|
||||
animationController_->SetFillMode(FillMode::FORWARDS);
|
||||
animationController_->Play();
|
||||
}
|
||||
|
||||
void AnimatableDimension::ResetController()
|
||||
{
|
||||
if (animationController_) {
|
||||
if (!animationController_->IsStopped()) {
|
||||
animationController_->Stop();
|
||||
}
|
||||
animationController_->ClearInterpolators();
|
||||
animationController_->ClearAllListeners();
|
||||
animationController_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatableDimension::OnAnimationCallback(double value)
|
||||
{
|
||||
SetValue(value);
|
||||
if (animationCallback_) {
|
||||
animationCallback_();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatableDimension::MoveTo(double target)
|
||||
{
|
||||
SetValue(target);
|
||||
isFirstAssign_ = false;
|
||||
}
|
||||
|
||||
void AnimatableDimension::ResetAnimatableDimension()
|
||||
{
|
||||
isFirstAssign_ = true;
|
||||
animationOption_ = AnimationOption();
|
||||
animationController_ = nullptr;
|
||||
context_ = nullptr;
|
||||
animationCallback_ = nullptr;
|
||||
}
|
||||
}
|
102
frameworks/base/geometry/animatable_dimension.h
Normal file
102
frameworks/base/geometry/animatable_dimension.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_DIMENSION_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_DIMENSION_H
|
||||
|
||||
#include "base/geometry/dimension.h"
|
||||
#include "core/animation/animator.h"
|
||||
#include "core/animation/curve_animation.h"
|
||||
#include "core/components/common/properties/animation_option.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
using RenderNodeAnimationCallback = std::function<void()>;
|
||||
|
||||
/*
|
||||
* AnimatableDimension is a Dimension with AnimationOption and Animator.
|
||||
*/
|
||||
class ACE_EXPORT AnimatableDimension : public Dimension {
|
||||
public:
|
||||
AnimatableDimension() = default;
|
||||
~AnimatableDimension() = default;
|
||||
|
||||
explicit AnimatableDimension(
|
||||
double value, DimensionUnit unit = DimensionUnit::PX, const AnimationOption& option = AnimationOption())
|
||||
: Dimension(value, unit), animationOption_(option)
|
||||
{}
|
||||
explicit AnimatableDimension(const Dimension& dimension, const AnimationOption& option = AnimationOption())
|
||||
: Dimension(dimension), animationOption_(option)
|
||||
{}
|
||||
|
||||
void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
|
||||
{
|
||||
context_ = context;
|
||||
animationCallback_ = callback;
|
||||
}
|
||||
|
||||
const AnimationOption& GetAnimationOption() const
|
||||
{
|
||||
return animationOption_;
|
||||
}
|
||||
|
||||
void SetAnimationOption(const AnimationOption& option)
|
||||
{
|
||||
animationOption_ = option;
|
||||
}
|
||||
|
||||
void SetAnimationStopCallback(const RenderNodeAnimationCallback& callback)
|
||||
{
|
||||
stopCallback_ = callback;
|
||||
}
|
||||
|
||||
Animator::Status GetAnimationStatus() const
|
||||
{
|
||||
if (!animationController_) {
|
||||
return Animator::Status::IDLE;
|
||||
}
|
||||
return animationController_->GetStatus();
|
||||
}
|
||||
|
||||
void SetEvaluator(const RefPtr<Evaluator<double>>& evaluator)
|
||||
{
|
||||
evaluator_ = evaluator;
|
||||
}
|
||||
|
||||
AnimatableDimension& operator=(const Dimension& newDimension);
|
||||
|
||||
AnimatableDimension& operator=(const AnimatableDimension& newDimension);
|
||||
|
||||
void MoveTo(double target);
|
||||
|
||||
private:
|
||||
void AnimateTo(double endValue);
|
||||
void ResetController();
|
||||
void OnAnimationCallback(double value);
|
||||
void ResetAnimatableDimension();
|
||||
|
||||
private:
|
||||
bool isFirstAssign_ = true;
|
||||
AnimationOption animationOption_;
|
||||
RefPtr<Animator> animationController_;
|
||||
WeakPtr<PipelineContext> context_;
|
||||
RenderNodeAnimationCallback animationCallback_;
|
||||
RenderNodeAnimationCallback stopCallback_;
|
||||
RefPtr<Evaluator<double>> evaluator_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_DIMENSION_H
|
144
frameworks/base/geometry/animatable_matrix4.cpp
Normal file
144
frameworks/base/geometry/animatable_matrix4.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "base/geometry/animatable_matrix4.h"
|
||||
|
||||
#include "core/event/ace_event_helper.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
AnimatableMatrix4& AnimatableMatrix4::operator=(const Matrix4& newMatrix4)
|
||||
{
|
||||
ResetAnimatableMatrix();
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = newMatrix4;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AnimatableMatrix4& AnimatableMatrix4::operator=(const AnimatableMatrix4& newMatrix4)
|
||||
{
|
||||
SetAnimationOption(newMatrix4.GetAnimationOption());
|
||||
auto pipelineContext = context_.Upgrade();
|
||||
if (!animationCallback_ || !pipelineContext) {
|
||||
LOGD("Animatable assign without animation due to null callback or context");
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = newMatrix4;
|
||||
return *this;
|
||||
}
|
||||
AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
|
||||
if (explicitAnim.IsValid()) {
|
||||
LOGD("Animatable assign with explicit animation, duration: %{public}d", explicitAnim.GetDuration());
|
||||
SetAnimationOption(explicitAnim);
|
||||
AnimateTo(newMatrix4);
|
||||
} else if (animationOption_.IsValid()) {
|
||||
LOGD("Animatable assign with implicit animation, duration: %{public}d", animationOption_.GetDuration());
|
||||
AnimateTo(newMatrix4);
|
||||
} else {
|
||||
LOGD("Animatable assign without animation.");
|
||||
ResetController();
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = newMatrix4;
|
||||
}
|
||||
isFirstAssign_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AnimatableMatrix4::MoveTo(const Matrix4& target)
|
||||
{
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = target;
|
||||
isFirstAssign_ = false;
|
||||
}
|
||||
|
||||
void AnimatableMatrix4::AnimateTo(const Matrix4& endValue)
|
||||
{
|
||||
if (isFirstAssign_) {
|
||||
LOGD("AnimateTo with first assign. endValue: %{public}s", endValue.ToString().c_str());
|
||||
isFirstAssign_ = false;
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = endValue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*this == endValue && !evaluator_) {
|
||||
LOGD("AnimateTo with same value. endValue: %{public}s", endValue.ToString().c_str());
|
||||
return;
|
||||
}
|
||||
ResetController();
|
||||
if (!animationController_) {
|
||||
animationController_ = AceType::MakeRefPtr<Animator>(context_);
|
||||
}
|
||||
|
||||
TransformOperation operationInit;
|
||||
TransformOperation operationEnd;
|
||||
operationInit.type_ = TransformOperationType::MATRIX;
|
||||
operationEnd.type_ = TransformOperationType::MATRIX;
|
||||
operationInit.matrix4_ = static_cast<Matrix4>(*this);
|
||||
operationEnd.matrix4_ = endValue;
|
||||
RefPtr<CurveAnimation<TransformOperation>> animation = AceType::MakeRefPtr<CurveAnimation<TransformOperation>>(
|
||||
operationInit, operationEnd, animationOption_.GetCurve());
|
||||
if (evaluator_) {
|
||||
animation->SetEvaluator(evaluator_);
|
||||
}
|
||||
animation->AddListener(std::bind(&AnimatableMatrix4::OnAnimationCallback, this, std::placeholders::_1));
|
||||
animationController_->AddInterpolator(animation);
|
||||
auto onFinishEvent = animationOption_.GetOnFinishEvent();
|
||||
if (!onFinishEvent.IsEmpty()) {
|
||||
animationController_->AddStopListener(
|
||||
[onFinishEvent, weakContext = context_] { AceAsyncEvent<void()>::Create(onFinishEvent, weakContext)(); });
|
||||
}
|
||||
if (stopCallback_) {
|
||||
animationController_->AddStopListener(stopCallback_);
|
||||
}
|
||||
animationController_->SetDuration(animationOption_.GetDuration());
|
||||
animationController_->SetStartDelay(animationOption_.GetDelay());
|
||||
animationController_->SetIteration(animationOption_.GetIteration());
|
||||
animationController_->SetTempo(animationOption_.GetTempo());
|
||||
animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
|
||||
animationController_->SetFillMode(FillMode::FORWARDS);
|
||||
animationController_->Play();
|
||||
}
|
||||
|
||||
void AnimatableMatrix4::ResetController()
|
||||
{
|
||||
if (animationController_) {
|
||||
if (!animationController_->IsStopped()) {
|
||||
animationController_->Stop();
|
||||
}
|
||||
animationController_->ClearInterpolators();
|
||||
animationController_->ClearAllListeners();
|
||||
animationController_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatableMatrix4::OnAnimationCallback(const TransformOperation& value)
|
||||
{
|
||||
Matrix4& matrix4 = *this;
|
||||
matrix4 = value.matrix4_;
|
||||
if (animationCallback_) {
|
||||
animationCallback_();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatableMatrix4::ResetAnimatableMatrix()
|
||||
{
|
||||
isFirstAssign_ = true;
|
||||
animationOption_ = AnimationOption();
|
||||
animationController_ = nullptr;
|
||||
context_ = nullptr;
|
||||
animationCallback_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
96
frameworks/base/geometry/animatable_matrix4.h
Normal file
96
frameworks/base/geometry/animatable_matrix4.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_MATRIX4_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_MATRIX4_H
|
||||
|
||||
#include "base/geometry/matrix4.h"
|
||||
#include "core/animation/animator.h"
|
||||
#include "core/animation/curve_animation.h"
|
||||
#include "core/components/common/properties/animation_option.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
using RenderNodeAnimationCallback = std::function<void()>;
|
||||
|
||||
class ACE_EXPORT AnimatableMatrix4 : public Matrix4 {
|
||||
public:
|
||||
AnimatableMatrix4() = default;
|
||||
~AnimatableMatrix4() = default;
|
||||
|
||||
explicit AnimatableMatrix4(Matrix4 matrix4, const AnimationOption& option = AnimationOption())
|
||||
: Matrix4(matrix4), animationOption_(option)
|
||||
{}
|
||||
|
||||
void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
|
||||
{
|
||||
context_ = context;
|
||||
animationCallback_ = callback;
|
||||
}
|
||||
|
||||
const AnimationOption& GetAnimationOption() const
|
||||
{
|
||||
return animationOption_;
|
||||
}
|
||||
|
||||
void SetAnimationOption(const AnimationOption& option)
|
||||
{
|
||||
animationOption_ = option;
|
||||
}
|
||||
|
||||
void SetAnimationStopCallback(const RenderNodeAnimationCallback& callback)
|
||||
{
|
||||
stopCallback_ = callback;
|
||||
}
|
||||
|
||||
Animator::Status GetAnimationStatus() const
|
||||
{
|
||||
if (!animationController_) {
|
||||
return Animator::Status::IDLE;
|
||||
}
|
||||
return animationController_->GetStatus();
|
||||
}
|
||||
|
||||
AnimatableMatrix4& operator=(const Matrix4& matrix4);
|
||||
|
||||
AnimatableMatrix4& operator=(const AnimatableMatrix4& newMatrix4);
|
||||
|
||||
void MoveTo(const Matrix4& target);
|
||||
|
||||
void SetEvaluator(const RefPtr<Evaluator<TransformOperation>>& evaluator)
|
||||
{
|
||||
evaluator_ = evaluator;
|
||||
}
|
||||
|
||||
private:
|
||||
void AnimateTo(const Matrix4& endValue);
|
||||
void ResetController();
|
||||
void OnAnimationCallback(const TransformOperation& value);
|
||||
void ResetAnimatableMatrix();
|
||||
|
||||
private:
|
||||
bool isFirstAssign_ = true;
|
||||
AnimationOption animationOption_;
|
||||
RefPtr<Animator> animationController_;
|
||||
WeakPtr<PipelineContext> context_;
|
||||
RenderNodeAnimationCallback animationCallback_;
|
||||
RenderNodeAnimationCallback stopCallback_;
|
||||
|
||||
RefPtr<Evaluator<TransformOperation>> evaluator_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_MATRIX4_H
|
@ -22,6 +22,7 @@ enum class Axis {
|
||||
VERTICAL = 0,
|
||||
HORIZONTAL,
|
||||
FREE,
|
||||
NONE,
|
||||
};
|
||||
|
||||
enum class RotateAxis {
|
||||
|
@ -16,14 +16,18 @@
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_DIMENSION_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_DIMENSION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/utils/macros.h"
|
||||
#include "base/utils/utils.h"
|
||||
|
||||
#define NEAR_ZERO(value) ((value > 0.0) ? ((value - 0.0) <= 0.000001f) : ((0.0 - value) <= 0.000001f))
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
enum class DimensionUnit {
|
||||
/*
|
||||
* Logical pixel used in Ace. It's based on frontend design width.
|
||||
* Logical pixel used in Ace1.0. It's based on frontend design width.
|
||||
* For example, when a frontend with 750px design width running on a
|
||||
* device with 1080 pixels width, 1px represents 1.44 pixels.
|
||||
*/
|
||||
@ -33,7 +37,7 @@ enum class DimensionUnit {
|
||||
*/
|
||||
VP,
|
||||
/*
|
||||
* scale independent pixels, this is like VP but will be scaled by
|
||||
* Scale independent pixels. This is like VP but will be scaled by
|
||||
* user's font size preference.
|
||||
*/
|
||||
FP,
|
||||
@ -42,6 +46,10 @@ enum class DimensionUnit {
|
||||
* another property of the element itself.
|
||||
*/
|
||||
PERCENT,
|
||||
/*
|
||||
* logic pixels used in ACE2.0 instead of PX, and PX is the physical pixels in ACE2.0
|
||||
*/
|
||||
LPX,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -54,7 +62,7 @@ public:
|
||||
~Dimension() = default;
|
||||
constexpr explicit Dimension(double value, DimensionUnit unit = DimensionUnit::PX) : value_(value), unit_(unit) {}
|
||||
|
||||
double Value() const
|
||||
constexpr double Value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
@ -64,11 +72,16 @@ public:
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
DimensionUnit Unit() const
|
||||
constexpr DimensionUnit Unit() const
|
||||
{
|
||||
return unit_;
|
||||
}
|
||||
|
||||
void SetUnit(DimensionUnit unit)
|
||||
{
|
||||
unit_ = unit;
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return (value_ > 0.0) && (!NearZero(value_));
|
||||
@ -91,7 +104,7 @@ public:
|
||||
constexpr Dimension operator/(double value) const
|
||||
{
|
||||
// NearZero cannot be used in a constant expression
|
||||
if (value > 0.0 ? value - 0.0 <= 0.000001f : 0.0 - value <= 0.000001f) {
|
||||
if (NEAR_ZERO(value)) {
|
||||
return Dimension();
|
||||
}
|
||||
return Dimension(value_ / value, unit_);
|
||||
@ -112,6 +125,9 @@ public:
|
||||
*/
|
||||
constexpr Dimension operator+(const Dimension& dimension) const
|
||||
{
|
||||
if (NEAR_ZERO(dimension.Value())) {
|
||||
return *this;
|
||||
}
|
||||
ACE_DCHECK(unit_ == dimension.unit_);
|
||||
return Dimension(value_ + dimension.value_, unit_);
|
||||
}
|
||||
@ -131,6 +147,9 @@ public:
|
||||
*/
|
||||
constexpr Dimension operator-(const Dimension& dimension) const
|
||||
{
|
||||
if (NEAR_ZERO(dimension.Value())) {
|
||||
return *this;
|
||||
}
|
||||
ACE_DCHECK(unit_ == dimension.unit_);
|
||||
return Dimension(value_ - dimension.value_, unit_);
|
||||
}
|
||||
@ -165,6 +184,12 @@ public:
|
||||
return (value_ < dimension.value_);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
static std::string units[5] = {"px", "vp", "fp", "%", "lpx"};
|
||||
return std::to_string(value_).append(units[static_cast<int>(unit_)]);
|
||||
}
|
||||
|
||||
private:
|
||||
double value_ = 0.0;
|
||||
DimensionUnit unit_ = DimensionUnit::PX;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "base/geometry/matrix4.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "base/utils/utils.h"
|
||||
|
||||
@ -23,6 +24,7 @@ namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MATRIX_LENGTH = Matrix4::DIMENSION * Matrix4::DIMENSION;
|
||||
constexpr float ANGLE_UNIT = 0.017453f; // PI / 180
|
||||
|
||||
inline bool IsEqual(const float& left, const float& right)
|
||||
{
|
||||
@ -80,6 +82,33 @@ Matrix4 Matrix4::CreateRotate(float angle, float dx, float dy, float dz)
|
||||
cosValue + (z * z * (1.0f - cosValue)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateMatrix2D(float m00, float m10, float m01, float m11, float m03, float m13)
|
||||
{
|
||||
return Matrix4(
|
||||
m00, m01, 0.0f, m03,
|
||||
m10, m11, 0.0f, m13,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreateSkew(float x, float y)
|
||||
{
|
||||
return Matrix4(
|
||||
1.0f, std::tan(x * ANGLE_UNIT), 0.0f, 0.0f,
|
||||
std::tan(y * ANGLE_UNIT), 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::CreatePerspective(float distance)
|
||||
{
|
||||
auto result = CreateIdentity();
|
||||
if (GreatNotEqual(distance, 0.0f)) {
|
||||
result.matrix4x4_[2][3] = -1.0f / distance;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::Invert(const Matrix4& matrix)
|
||||
{
|
||||
Matrix4 inverted = CreateInvert(matrix);
|
||||
@ -305,4 +334,85 @@ float Matrix4::operator()(int32_t row, int32_t col) const
|
||||
return matrix4x4_[row][col];
|
||||
}
|
||||
|
||||
double Matrix4::Determinant() const
|
||||
{
|
||||
if (this->IsIdentityMatrix()) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double m00 = matrix4x4_[0][0];
|
||||
double m01 = matrix4x4_[0][1];
|
||||
double m02 = matrix4x4_[0][2];
|
||||
double m03 = matrix4x4_[0][3];
|
||||
double m10 = matrix4x4_[1][0];
|
||||
double m11 = matrix4x4_[1][1];
|
||||
double m12 = matrix4x4_[1][2];
|
||||
double m13 = matrix4x4_[1][3];
|
||||
double m20 = matrix4x4_[2][0];
|
||||
double m21 = matrix4x4_[2][1];
|
||||
double m22 = matrix4x4_[2][2];
|
||||
double m23 = matrix4x4_[2][3];
|
||||
double m30 = matrix4x4_[3][0];
|
||||
double m31 = matrix4x4_[3][1];
|
||||
double m32 = matrix4x4_[3][2];
|
||||
double m33 = matrix4x4_[3][3];
|
||||
|
||||
double b00 = m00 * m11 - m01 * m10;
|
||||
double b01 = m00 * m12 - m02 * m10;
|
||||
double b02 = m00 * m13 - m03 * m10;
|
||||
double b03 = m01 * m12 - m02 * m11;
|
||||
double b04 = m01 * m13 - m03 * m11;
|
||||
double b05 = m02 * m13 - m03 * m12;
|
||||
double b06 = m20 * m31 - m21 * m30;
|
||||
double b07 = m20 * m32 - m22 * m30;
|
||||
double b08 = m20 * m33 - m23 * m30;
|
||||
double b09 = m21 * m32 - m22 * m31;
|
||||
double b10 = m21 * m33 - m23 * m31;
|
||||
double b11 = m22 * m33 - m23 * m32;
|
||||
|
||||
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
||||
}
|
||||
|
||||
void Matrix4::Transpose()
|
||||
{
|
||||
std::swap(matrix4x4_[0][1], matrix4x4_[1][0]);
|
||||
std::swap(matrix4x4_[0][2], matrix4x4_[2][0]);
|
||||
std::swap(matrix4x4_[0][3], matrix4x4_[3][0]);
|
||||
std::swap(matrix4x4_[1][2], matrix4x4_[2][1]);
|
||||
std::swap(matrix4x4_[1][3], matrix4x4_[3][1]);
|
||||
std::swap(matrix4x4_[2][3], matrix4x4_[3][2]);
|
||||
}
|
||||
|
||||
void Matrix4::MapScalars(const float src[DIMENSION], float dst[DIMENSION]) const
|
||||
{
|
||||
float storage[DIMENSION];
|
||||
|
||||
float* result = (src == dst) ? storage : dst;
|
||||
|
||||
for (int i = 0; i < DIMENSION; i++) {
|
||||
float value = 0;
|
||||
for (int j = 0; j < DIMENSION; j++) {
|
||||
value += matrix4x4_[j][i] * src[j];
|
||||
}
|
||||
result[i] = value;
|
||||
}
|
||||
|
||||
if (storage == result) {
|
||||
std::copy_n(result, DIMENSION, dst);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Matrix4::ToString() const
|
||||
{
|
||||
std::string out;
|
||||
for (auto& i : matrix4x4_) {
|
||||
for (float j : i) {
|
||||
out += std::to_string(j);
|
||||
out += ",";
|
||||
}
|
||||
out += "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
@ -20,11 +20,11 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class ACE_EXPORT Matrix4 final {
|
||||
class ACE_EXPORT Matrix4 {
|
||||
public:
|
||||
// Matrix dimension is 4X4.
|
||||
static constexpr int32_t DIMENSION = 4;
|
||||
// Crate an identity matrix.
|
||||
// Create an identity matrix.
|
||||
static Matrix4 CreateIdentity();
|
||||
// Multiplies this matrix by another that translates coordinates by the vector (x, y, z).
|
||||
static Matrix4 CreateTranslate(float x, float y, float z);
|
||||
@ -32,6 +32,13 @@ public:
|
||||
static Matrix4 CreateScale(float x, float y, float z);
|
||||
// Multiplies this matrix by another that rotates coordinates through angle degrees about the vector (dx, dy, dz).
|
||||
static Matrix4 CreateRotate(float angle, float dx, float dy, float dz);
|
||||
|
||||
static Matrix4 CreateMatrix2D(float m00, float m10, float m01, float m11, float m03, float m13);
|
||||
// Multiplies this matrix by another that skew through angle degrees.
|
||||
static Matrix4 CreateSkew(float x, float y);
|
||||
// Create an perspective matrix, the distance value represents the distance between the user and the z=0 plane. not
|
||||
// support percent
|
||||
static Matrix4 CreatePerspective(float distance);
|
||||
// Returns the inverse of this matrix. Returns the identity if this matrix cannot be inverted;
|
||||
static Matrix4 Invert(const Matrix4& matrix);
|
||||
|
||||
@ -58,6 +65,28 @@ public:
|
||||
Point operator*(const Point& point);
|
||||
Matrix4& operator=(const Matrix4& matrix);
|
||||
float operator[](int32_t index) const;
|
||||
inline float Get(int32_t row, int32_t col) const
|
||||
{
|
||||
ACE_DCHECK((unsigned)row < DIMENSION);
|
||||
ACE_DCHECK((unsigned)col < DIMENSION);
|
||||
return matrix4x4_[col][row];
|
||||
}
|
||||
inline void Set(int32_t row, int32_t col, float value)
|
||||
{
|
||||
ACE_DCHECK((unsigned)row < DIMENSION);
|
||||
ACE_DCHECK((unsigned)col < DIMENSION);
|
||||
matrix4x4_[col][row] = value;
|
||||
}
|
||||
double Determinant() const;
|
||||
void Transpose();
|
||||
void MapScalars(const float src[DIMENSION], float dst[DIMENSION]) const;
|
||||
inline void MapScalars(float vec[DIMENSION], int length = DIMENSION) const
|
||||
{
|
||||
if (length == DIMENSION) {
|
||||
this->MapScalars(vec, vec);
|
||||
}
|
||||
}
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
static Matrix4 CreateInvert(const Matrix4& matrix);
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "base/geometry/size.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components/common/properties/animation_option.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
@ -34,6 +35,8 @@ public:
|
||||
{
|
||||
deltaX_ = 0.0;
|
||||
deltaY_ = 0.0;
|
||||
deltaXAnimationOption_ = AnimationOption();
|
||||
deltaYAnimationOption_ = AnimationOption();
|
||||
}
|
||||
|
||||
static Offset Zero()
|
||||
@ -66,14 +69,26 @@ public:
|
||||
return deltaY_;
|
||||
}
|
||||
|
||||
void SetX(double x)
|
||||
void SetX(double x, const AnimationOption& option = AnimationOption())
|
||||
{
|
||||
deltaX_ = x;
|
||||
deltaXAnimationOption_ = option;
|
||||
}
|
||||
|
||||
void SetY(double y)
|
||||
void SetY(double y, const AnimationOption& option = AnimationOption())
|
||||
{
|
||||
deltaY_ = y;
|
||||
deltaYAnimationOption_ = option;
|
||||
}
|
||||
|
||||
AnimationOption GetXAnimationOption() const
|
||||
{
|
||||
return deltaXAnimationOption_;
|
||||
}
|
||||
|
||||
AnimationOption GetYAnimationOption() const
|
||||
{
|
||||
return deltaYAnimationOption_;
|
||||
}
|
||||
|
||||
double GetDistance() const
|
||||
@ -143,6 +158,8 @@ public:
|
||||
private:
|
||||
double deltaX_ = 0.0;
|
||||
double deltaY_ = 0.0;
|
||||
AnimationOption deltaXAnimationOption_;
|
||||
AnimationOption deltaYAnimationOption_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
67
frameworks/base/geometry/quaternion.cpp
Normal file
67
frameworks/base/geometry/quaternion.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "base/geometry/quaternion.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
constexpr double KEPSILON = 1e-5;
|
||||
|
||||
} // namespace
|
||||
|
||||
Quaternion Quaternion::Slerp(const Quaternion& to, double t) const
|
||||
{
|
||||
if (t < 0.0 || t > 1.0) {
|
||||
// https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/index.htm
|
||||
// a scalar between 0.0 (at from) and 1.0 (at to)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quaternion from = *this;
|
||||
|
||||
double cosHalfAngle = from.x_ * to.x_ + from.y_ * to.y_ + from.z_ * to.z_ + from.w_ * to.w_;
|
||||
if (cosHalfAngle < 0.0) {
|
||||
// Since the half angle is > 90 degrees, the full rotation angle would
|
||||
// exceed 180 degrees. The quaternions (x, y, z, w) and (-x, -y, -z, -w)
|
||||
// represent the same rotation. Flipping the orientation of either
|
||||
// quaternion ensures that the half angle is less than 90 and that we are
|
||||
// taking the shortest path.
|
||||
from = from.flip();
|
||||
cosHalfAngle = -cosHalfAngle;
|
||||
}
|
||||
|
||||
// Ensure that acos is well behaved at the boundary.
|
||||
if (cosHalfAngle > 1.0) {
|
||||
cosHalfAngle = 1.0;
|
||||
}
|
||||
|
||||
double sinHalfAngle = std::sqrt(1.0 - cosHalfAngle * cosHalfAngle);
|
||||
if (sinHalfAngle < KEPSILON) {
|
||||
// Quaternions share common axis and angle.
|
||||
return *this;
|
||||
}
|
||||
|
||||
double half_angle = std::acos(cosHalfAngle);
|
||||
|
||||
double scaleA = std::sin((1.0 - t) * half_angle) / sinHalfAngle;
|
||||
double scaleB = std::sin(t * half_angle) / sinHalfAngle;
|
||||
|
||||
return (scaleA * from) + (scaleB * to);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
114
frameworks/base/geometry/quaternion.h
Normal file
114
frameworks/base/geometry/quaternion.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class Quaternion {
|
||||
public:
|
||||
Quaternion() = default;
|
||||
Quaternion(double x, double y, double z, double w) : x_(x), y_(y), z_(z), w_(w) {}
|
||||
~Quaternion() = default;
|
||||
|
||||
double GetX() const
|
||||
{
|
||||
return x_;
|
||||
}
|
||||
double GetY() const
|
||||
{
|
||||
return y_;
|
||||
}
|
||||
double GetZ() const
|
||||
{
|
||||
return z_;
|
||||
}
|
||||
double GetW() const
|
||||
{
|
||||
return w_;
|
||||
}
|
||||
void SetX(double x)
|
||||
{
|
||||
x_ = x;
|
||||
}
|
||||
void SetY(double y)
|
||||
{
|
||||
y_ = y;
|
||||
}
|
||||
void SetZ(double z)
|
||||
{
|
||||
z_ = z;
|
||||
}
|
||||
void SetW(double w)
|
||||
{
|
||||
w_ = w;
|
||||
}
|
||||
|
||||
Quaternion operator+(const Quaternion& q) const
|
||||
{
|
||||
auto x = this->x_ + q.x_;
|
||||
auto y = this->y_ + q.y_;
|
||||
auto z = this->z_ + q.z_;
|
||||
auto w = this->w_ + q.w_;
|
||||
return Quaternion(x, y, z, w);
|
||||
}
|
||||
|
||||
Quaternion operator*(const Quaternion& q) const
|
||||
{
|
||||
auto x = w_ * q.x_ + x_ * q.w_ + y_ * q.z_ - z_ * q.y_;
|
||||
auto y = w_ * q.y_ - x_ * q.z_ + y_ * q.w_ + z_ * q.x_;
|
||||
auto z = w_ * q.z_ + x_ * q.y_ - y_ * q.x_ + z_ * q.w_;
|
||||
auto w = w_ * q.w_ - x_ * q.x_ - y_ * q.y_ - z_ * q.z_;
|
||||
return Quaternion(x, y, z, w);
|
||||
}
|
||||
|
||||
Quaternion inverse() const
|
||||
{
|
||||
return { -x_, -y_, -z_, w_ };
|
||||
}
|
||||
|
||||
Quaternion flip() const
|
||||
{
|
||||
return { -x_, -y_, -z_, -w_ };
|
||||
}
|
||||
|
||||
// Blends with the given quaternion, |q|, via spherical linear interpolation.
|
||||
// Values of |t| in the range [0, 1] will interpolate between |this| and |q|,
|
||||
// and values outside that range will extrapolate beyond in either direction.
|
||||
Quaternion Slerp(const Quaternion& q, double t) const;
|
||||
|
||||
private:
|
||||
double x_ = 0.0;
|
||||
double y_ = 0.0;
|
||||
double z_ = 0.0;
|
||||
double w_ = 0.0;
|
||||
};
|
||||
|
||||
// |s| is an arbitrary, real constant.
|
||||
inline Quaternion operator*(const Quaternion& q, double s)
|
||||
{
|
||||
return Quaternion(q.GetX() * s, q.GetY() * s, q.GetZ() * s, q.GetW() * s);
|
||||
}
|
||||
|
||||
// |s| is an arbitrary, real constant.
|
||||
inline Quaternion operator*(double s, const Quaternion& q)
|
||||
{
|
||||
return Quaternion(q.GetX() * s, q.GetY() * s, q.GetZ() * s, q.GetW() * s);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_QUATERNION_H
|
@ -134,21 +134,12 @@ public:
|
||||
return rect_.Height();
|
||||
}
|
||||
|
||||
bool NearEqual(const RRect& rrect) const
|
||||
{
|
||||
return rrect.GetCorner().bottomLeftRadius == corner_.bottomLeftRadius &&
|
||||
rrect.GetCorner().bottomRightRadius == corner_.bottomRightRadius &&
|
||||
rrect.GetCorner().topLeftRadius == corner_.topLeftRadius &&
|
||||
rrect.GetCorner().topRightRadius == corner_.topRightRadius && rrect.GetRect() == rect_;
|
||||
}
|
||||
|
||||
bool operator==(const RRect& rrect) const
|
||||
{
|
||||
return rrect.GetCorner().bottomLeftRadius == corner_.bottomLeftRadius &&
|
||||
rrect.GetCorner().bottomRightRadius == corner_.bottomRightRadius &&
|
||||
rrect.GetCorner().topLeftRadius == corner_.topLeftRadius &&
|
||||
rrect.GetCorner().topRightRadius == corner_.topRightRadius && rrect.Height() == rect_.Height() &&
|
||||
rrect.Width() == rect_.Width();
|
||||
rrect.GetCorner().topRightRadius == corner_.topRightRadius && rrect.GetRect() == rect_;
|
||||
}
|
||||
|
||||
RRect& operator+=(const Offset& offset)
|
||||
|
654
frameworks/base/geometry/transform_util.cpp
Normal file
654
frameworks/base/geometry/transform_util.cpp
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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 "base/geometry/transform_util.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
float Length3(const float v[3])
|
||||
{
|
||||
double vd[3] = { v[0], v[1], v[2] };
|
||||
return static_cast<float>(std::sqrt(vd[0] * vd[0] + vd[1] * vd[1] + vd[2] * vd[2]));
|
||||
}
|
||||
|
||||
template<int n>
|
||||
float Dot(const float* a, const float* b)
|
||||
{
|
||||
double total = 0.0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
total += a[i] * b[i];
|
||||
}
|
||||
return static_cast<float>(total);
|
||||
}
|
||||
|
||||
template<int n>
|
||||
void Combine(float* out, const float* a, const float* b, double scaleA, double scaleB)
|
||||
{
|
||||
for (int i = 0; i < n; ++i) {
|
||||
out[i] = static_cast<float>(a[i] * scaleA + b[i] * scaleB);
|
||||
}
|
||||
}
|
||||
|
||||
void Cross3(float out[3], const float a[3], const float b[3])
|
||||
{
|
||||
float x = a[1] * b[2] - a[2] * b[1];
|
||||
float y = a[2] * b[0] - a[0] * b[2];
|
||||
float z = a[0] * b[1] - a[1] * b[0];
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
out[2] = z;
|
||||
}
|
||||
|
||||
// Returns false if the matrix cannot be normalized.
|
||||
bool Normalize(Matrix4& m)
|
||||
{
|
||||
if (NearZero(m.Get(3, 3))) {
|
||||
return false;
|
||||
}
|
||||
float scale = 1.0f / m.Get(3, 3);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
auto value = m.Get(i, j) * scale;
|
||||
m.Set(i, j, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix4 BuildPerspectiveMatrix(const DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 matrix = Matrix4::CreateIdentity();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
matrix.Set(3, i, decomp.perspective[i]);
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Matrix4 BuildTranslationMatrix(const DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 matrix = Matrix4::CreateIdentity();
|
||||
float dx = decomp.translate[0];
|
||||
float dy = decomp.translate[1];
|
||||
float dz = decomp.translate[2];
|
||||
if (NearZero(dx) && NearZero(dy) && NearZero(dz)) {
|
||||
return matrix;
|
||||
}
|
||||
|
||||
matrix.Set(0, 3, dx);
|
||||
matrix.Set(1, 3, dy);
|
||||
matrix.Set(2, 3, dz);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Matrix4 BuildRotationMatrix(const DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 matrix4;
|
||||
double x = decomp.quaternion.GetX();
|
||||
double y = decomp.quaternion.GetY();
|
||||
double z = decomp.quaternion.GetZ();
|
||||
double w = decomp.quaternion.GetW();
|
||||
|
||||
matrix4.Set(0, 0, static_cast<float>(1.0 - 2.0 * (y * y + z * z)));
|
||||
matrix4.Set(1, 0, static_cast<float>(2.0 * (x * y + z * w)));
|
||||
matrix4.Set(2, 0, static_cast<float>(2.0 * (x * z - y * w)));
|
||||
matrix4.Set(3, 0, 0);
|
||||
|
||||
matrix4.Set(0, 1, static_cast<float>(2.0 * (x * y - z * w)));
|
||||
matrix4.Set(1, 1, static_cast<float>(1.0 - 2.0 * (x * x + z * z)));
|
||||
matrix4.Set(2, 1, static_cast<float>(2.0 * (y * z + x * w)));
|
||||
matrix4.Set(3, 1, 0);
|
||||
|
||||
matrix4.Set(0, 2, static_cast<float>(2.0 * (x * z + y * w)));
|
||||
matrix4.Set(1, 2, static_cast<float>(2.0 * (y * z - x * w)));
|
||||
matrix4.Set(2, 2, static_cast<float>(1.0 - 2.0 * (x * x + y * y)));
|
||||
matrix4.Set(3, 2, 0);
|
||||
|
||||
matrix4.Set(0, 3, 0);
|
||||
matrix4.Set(1, 3, 0);
|
||||
matrix4.Set(2, 3, 0);
|
||||
matrix4.Set(3, 3, 1);
|
||||
|
||||
return matrix4;
|
||||
}
|
||||
|
||||
Matrix4 BuildSkewMatrix(const DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 matrix = Matrix4::CreateIdentity();
|
||||
|
||||
Matrix4 temp = Matrix4::CreateIdentity();
|
||||
if (decomp.skew[2]) {
|
||||
temp.Set(1, 2, decomp.skew[2]);
|
||||
matrix = matrix * temp;
|
||||
}
|
||||
|
||||
if (decomp.skew[1]) {
|
||||
temp.Set(1, 2, 0);
|
||||
temp.Set(0, 2, decomp.skew[1]);
|
||||
matrix = matrix * temp;
|
||||
}
|
||||
|
||||
if (decomp.skew[0]) {
|
||||
temp.Set(0, 2, 0);
|
||||
temp.Set(0, 1, decomp.skew[0]);
|
||||
matrix = matrix * temp;
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Matrix4 BuildScaleMatrix(const DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 matrix = Matrix4::CreateIdentity();
|
||||
matrix.SetScale(decomp.scale[0], decomp.scale[1], decomp.scale[2]);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Matrix4 ComposeTransform(const Matrix4& perspective, const Matrix4& translation, const Matrix4& rotation,
|
||||
const Matrix4& skew, const Matrix4& scale)
|
||||
{
|
||||
Matrix4 matrix = Matrix4::CreateIdentity();
|
||||
matrix = matrix * perspective;
|
||||
matrix = matrix * translation;
|
||||
matrix = matrix * rotation;
|
||||
matrix = matrix * skew;
|
||||
matrix = matrix * scale;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TranslateOperation TranslateOperation::Blend(
|
||||
const TranslateOperation& to, const TranslateOperation& from, float progress)
|
||||
{
|
||||
TranslateOperation ret;
|
||||
float scaleA = progress;
|
||||
float scaleB = 1 - progress;
|
||||
ret.dx = to.dx * scaleA + from.dx * scaleB;
|
||||
ret.dy = to.dy * scaleA + from.dy * scaleB;
|
||||
ret.dz = to.dz * scaleA + from.dz * scaleB;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ScaleOperation ScaleOperation::Blend(const ScaleOperation& to, const ScaleOperation& from, float progress)
|
||||
{
|
||||
ScaleOperation ret;
|
||||
float scaleA = progress;
|
||||
float scaleB = 1 - progress;
|
||||
ret.scaleX = to.scaleX * scaleA + from.scaleX * scaleB;
|
||||
ret.scaleY = to.scaleY * scaleA + from.scaleY * scaleB;
|
||||
ret.scaleZ = to.scaleZ * scaleA + from.scaleZ * scaleB;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SkewOperation SkewOperation::Blend(const SkewOperation& to, const SkewOperation& from, float progress)
|
||||
{
|
||||
SkewOperation ret;
|
||||
float scaleA = progress;
|
||||
float scaleB = 1 - progress;
|
||||
ret.skewX = to.skewX * scaleA + from.skewX * scaleB;
|
||||
ret.skewY = to.skewY * scaleA + from.skewY * scaleB;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RotateOperation RotateOperation::Blend(const RotateOperation& to, const RotateOperation& from, float progress)
|
||||
{
|
||||
RotateOperation ret;
|
||||
float scaleA = progress;
|
||||
float scaleB = 1 - progress;
|
||||
ret.angle = to.angle * scaleA + from.angle * scaleB;
|
||||
ret.dx = to.dx;
|
||||
ret.dy = to.dy;
|
||||
ret.dz = to.dz;
|
||||
// rotate vector is (0,0,0) is error
|
||||
if (NearZero(ret.dx) && NearZero(ret.dy) && NearZero(ret.dz)) {
|
||||
ret.dx = from.dx;
|
||||
ret.dy = from.dy;
|
||||
ret.dz = from.dz;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PerspectiveOperation PerspectiveOperation::Blend(
|
||||
const PerspectiveOperation& to, const PerspectiveOperation& from, float progress)
|
||||
{
|
||||
PerspectiveOperation ret;
|
||||
ret.distance = from.distance + (to.distance - from.distance) * progress;
|
||||
return ret;
|
||||
}
|
||||
|
||||
TransformOperation TransformOperation::Blend(
|
||||
const TransformOperation& to, const TransformOperation& from, float progress)
|
||||
{
|
||||
TransformOperation ret;
|
||||
if (to.type_ == from.type_ && to.type_ == TransformOperationType::UNDEFINED) {
|
||||
return ret;
|
||||
} else if (to.type_ == TransformOperationType::UNDEFINED) {
|
||||
ret.type_ = from.type_;
|
||||
BlendInner(Create(ret.type_), from, progress, ret);
|
||||
} else if (from.type_ == TransformOperationType::UNDEFINED) {
|
||||
ret.type_ = to.type_;
|
||||
BlendInner(to, Create(ret.type_), progress, ret);
|
||||
} else if (to.type_ == from.type_) {
|
||||
ret.type_ = to.type_;
|
||||
BlendInner(to, from, progress, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
TransformOperation TransformOperation::Create(TransformOperationType type)
|
||||
{
|
||||
TransformOperation ret;
|
||||
ret.type_ = type;
|
||||
switch (ret.type_) {
|
||||
case TransformOperationType::TRANSLATE:
|
||||
ret.translateOperation_ = TranslateOperation();
|
||||
break;
|
||||
case TransformOperationType::SCALE:
|
||||
ret.scaleOperation_ = ScaleOperation();
|
||||
break;
|
||||
case TransformOperationType::SKEW:
|
||||
ret.skewOperation_ = SkewOperation();
|
||||
break;
|
||||
case TransformOperationType::ROTATE:
|
||||
ret.rotateOperation_ = RotateOperation();
|
||||
break;
|
||||
case TransformOperationType::MATRIX:
|
||||
ret.matrix4_ = Matrix4::CreateIdentity();
|
||||
break;
|
||||
case TransformOperationType::PERSPECTIVE:
|
||||
ret.perspectiveOperation_ = PerspectiveOperation();
|
||||
break;
|
||||
case TransformOperationType::UNDEFINED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TransformOperation::BlendInner(
|
||||
const TransformOperation& to, const TransformOperation& from, float progress, TransformOperation& ret)
|
||||
{
|
||||
switch (ret.type_) {
|
||||
case TransformOperationType::TRANSLATE:
|
||||
ret.translateOperation_ =
|
||||
TranslateOperation::Blend(to.translateOperation_, from.translateOperation_, progress);
|
||||
break;
|
||||
case TransformOperationType::SCALE:
|
||||
ret.scaleOperation_ = ScaleOperation::Blend(to.scaleOperation_, from.scaleOperation_, progress);
|
||||
break;
|
||||
case TransformOperationType::SKEW:
|
||||
ret.skewOperation_ = SkewOperation::Blend(to.skewOperation_, from.skewOperation_, progress);
|
||||
break;
|
||||
case TransformOperationType::ROTATE:
|
||||
ret.rotateOperation_ = RotateOperation::Blend(to.rotateOperation_, from.rotateOperation_, progress);
|
||||
break;
|
||||
case TransformOperationType::MATRIX: {
|
||||
DecomposedTransform toTransform;
|
||||
DecomposedTransform fromTransform;
|
||||
if (TransformUtil::DecomposeTransform(toTransform, to.matrix4_) &&
|
||||
TransformUtil::DecomposeTransform(fromTransform, from.matrix4_)) {
|
||||
auto result = TransformUtil::BlendDecomposedTransforms(toTransform, fromTransform, progress);
|
||||
ret.matrix4_ = TransformUtil::ComposeTransform(result);
|
||||
} else {
|
||||
LOGE("DecomposeTransform failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::PERSPECTIVE:
|
||||
ret.perspectiveOperation_ =
|
||||
PerspectiveOperation::Blend(to.perspectiveOperation_, from.perspectiveOperation_, progress);
|
||||
break;
|
||||
case TransformOperationType::UNDEFINED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string DecomposedTransform::ToString() const
|
||||
{
|
||||
std::string out;
|
||||
out.append("translate: ")
|
||||
.append(std::to_string(translate[0]))
|
||||
.append(" ")
|
||||
.append(std::to_string(translate[1]))
|
||||
.append(" ")
|
||||
.append(std::to_string(translate[2]))
|
||||
.append("\n")
|
||||
.append("scale: ")
|
||||
.append(std::to_string(scale[0]))
|
||||
.append(" ")
|
||||
.append(std::to_string(scale[1]))
|
||||
.append(" ")
|
||||
.append(std::to_string(scale[2]))
|
||||
.append("\n")
|
||||
.append("skew: ")
|
||||
.append(std::to_string(skew[0]))
|
||||
.append(" ")
|
||||
.append(std::to_string(skew[1]))
|
||||
.append(" ")
|
||||
.append(std::to_string(skew[2]))
|
||||
.append("\n")
|
||||
.append("perspective: ")
|
||||
.append(std::to_string(perspective[0]))
|
||||
.append(" ")
|
||||
.append(std::to_string(perspective[1]))
|
||||
.append(" ")
|
||||
.append(std::to_string(perspective[2]))
|
||||
.append(" ")
|
||||
.append(std::to_string(perspective[3]))
|
||||
.append("\n")
|
||||
.append("quaternion: ")
|
||||
.append(std::to_string(quaternion.GetX()))
|
||||
.append(" ")
|
||||
.append(std::to_string(quaternion.GetY()))
|
||||
.append(" ")
|
||||
.append(std::to_string(quaternion.GetZ()))
|
||||
.append(" ")
|
||||
.append(std::to_string(quaternion.GetW()))
|
||||
.append("\n");
|
||||
return out;
|
||||
}
|
||||
|
||||
TransformOperations TransformOperations::Blend(
|
||||
const TransformOperations& to, const TransformOperations& from, float progress)
|
||||
{
|
||||
TransformOperations result;
|
||||
to.BlendInner(from, progress, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::size_t TransformOperations::MatchingLength(const TransformOperations& to, const TransformOperations& from) const
|
||||
{
|
||||
auto numOperations = std::min(to.operations_.size(), from.operations_.size());
|
||||
|
||||
for (std::size_t i = 0; i < numOperations; i++) {
|
||||
auto& first = to.operations_[i];
|
||||
auto& second = from.operations_[i];
|
||||
|
||||
if (first.type_ != TransformOperationType::UNDEFINED || second.type_ != TransformOperationType::UNDEFINED) {
|
||||
if (first.type_ != second.type_) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::max(to.operations_.size(), from.operations_.size());
|
||||
}
|
||||
|
||||
void TransformOperations::ParseOperationsToMatrix(std::vector<TransformOperation>& operations)
|
||||
{
|
||||
for (auto& operation : operations) {
|
||||
ParseOperationToMatrix(operation);
|
||||
}
|
||||
}
|
||||
|
||||
void TransformOperations::ParseOperationToMatrix(TransformOperation& operation)
|
||||
{
|
||||
switch (operation.type_) {
|
||||
case TransformOperationType::TRANSLATE: {
|
||||
auto& translate = operation.translateOperation_;
|
||||
float dx = translate.dx.Value();
|
||||
float dy = translate.dy.Value();
|
||||
float dz = translate.dz.Value();
|
||||
operation.matrix4_ = Matrix4::CreateTranslate(dx, dy, dz);
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::SCALE: {
|
||||
auto& scale = operation.scaleOperation_;
|
||||
operation.matrix4_ = Matrix4::CreateScale(scale.scaleX, scale.scaleY, scale.scaleZ);
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::SKEW: {
|
||||
auto& skew = operation.skewOperation_;
|
||||
operation.matrix4_ = Matrix4::CreateSkew(skew.skewX, skew.skewY);
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::ROTATE: {
|
||||
auto& rotate = operation.rotateOperation_;
|
||||
operation.matrix4_ = Matrix4::CreateRotate(rotate.angle, rotate.dx, rotate.dy, rotate.dz);
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::PERSPECTIVE: {
|
||||
auto& perspective = operation.perspectiveOperation_;
|
||||
double distance = perspective.distance.Value();
|
||||
operation.matrix4_ = Matrix4::CreatePerspective(distance);
|
||||
break;
|
||||
}
|
||||
case TransformOperationType::MATRIX:
|
||||
case TransformOperationType::UNDEFINED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TransformOperations::BlendInner(const TransformOperations& from, float progress, TransformOperations& out) const
|
||||
{
|
||||
auto matchPrefix = MatchingLength(*this, from);
|
||||
auto fromSize = from.operations_.size();
|
||||
auto toSize = operations_.size();
|
||||
|
||||
// find most match type transform
|
||||
for (std::size_t i = 0; i < matchPrefix; i++) {
|
||||
const auto& fromTransformOperation = i >= fromSize ? TransformOperation() : from.operations_[i];
|
||||
const auto& toTransformOperation = i >= toSize ? TransformOperation() : operations_[i];
|
||||
out.operations_.push_back(TransformOperation::Blend(toTransformOperation, fromTransformOperation, progress));
|
||||
}
|
||||
// type not match
|
||||
if (matchPrefix < std::max(fromSize, toSize)) {
|
||||
TransformOperation fromTransformOperation;
|
||||
fromTransformOperation.type_ = TransformOperationType::MATRIX;
|
||||
fromTransformOperation.matrix4_ = from.ComputerRemaining(matchPrefix);
|
||||
TransformOperation toTransformOperation;
|
||||
toTransformOperation.type_ = TransformOperationType::MATRIX;
|
||||
toTransformOperation.matrix4_ = ComputerRemaining(matchPrefix);
|
||||
out.operations_.push_back(TransformOperation::Blend(toTransformOperation, fromTransformOperation, progress));
|
||||
}
|
||||
}
|
||||
|
||||
Matrix4 TransformOperations::ComputerRemaining(std::size_t startOffset) const
|
||||
{
|
||||
Matrix4 result = Matrix4::CreateIdentity();
|
||||
for (auto i = startOffset; i < operations_.size(); i++) {
|
||||
result = result * operations_[i].matrix4_;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DecomposedTransform TransformUtil::BlendDecomposedTransforms(
|
||||
const DecomposedTransform& to, const DecomposedTransform& from, double progress)
|
||||
{
|
||||
DecomposedTransform ret;
|
||||
Combine<3>(ret.translate, to.translate, from.translate, progress, 1.0 - progress);
|
||||
Combine<3>(ret.scale, to.scale, from.scale, progress, 1.0 - progress);
|
||||
Combine<3>(ret.skew, to.skew, from.skew, progress, 1.0 - progress);
|
||||
Combine<4>(ret.perspective, to.perspective, from.perspective, progress, 1.0 - progress);
|
||||
ret.quaternion = from.quaternion.Slerp(to.quaternion, progress);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TransformUtil::DecomposeTransform(DecomposedTransform& out, const Matrix4& transform)
|
||||
{
|
||||
Matrix4 matrix = transform;
|
||||
|
||||
if (!Normalize(matrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Matrix4 perspectiveMatrix = matrix;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
perspectiveMatrix.Set(3, i, 0.0);
|
||||
}
|
||||
perspectiveMatrix.Set(3, 3, 1.0);
|
||||
|
||||
if (NearZero(std::abs(perspectiveMatrix.Determinant()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NearZero(matrix.Get(3, 0)) || !NearZero(matrix.Get(3, 1)) || !NearZero(matrix.Get(3, 2))) {
|
||||
float rhs[4] = { matrix.Get(3, 0), matrix.Get(3, 1), matrix.Get(3, 2), matrix.Get(3, 3) };
|
||||
|
||||
Matrix4 inversePerspectiveMatrix = Matrix4::Invert(perspectiveMatrix);
|
||||
Matrix4 transposedInversePerspectiveMatrix = inversePerspectiveMatrix;
|
||||
|
||||
transposedInversePerspectiveMatrix.Transpose();
|
||||
transposedInversePerspectiveMatrix.MapScalars(rhs, 4);
|
||||
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
out.perspective[i] = rhs[i];
|
||||
}
|
||||
} else {
|
||||
// No perspective.
|
||||
for (int i = 0; i < 3; ++i)
|
||||
out.perspective[i] = 0.0;
|
||||
out.perspective[3] = 1.0;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < 3; i++) {
|
||||
out.translate[i] = matrix.Get(i, 3);
|
||||
}
|
||||
|
||||
// Copy of matrix is stored in column major order to facilitate column-level
|
||||
// operations.
|
||||
float column[3][3];
|
||||
for (int32_t i = 0; i < 3; i++) {
|
||||
for (int32_t j = 0; j < 3; j++) {
|
||||
column[i][j] = matrix.Get(j, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute X scale factor and normalize first column.
|
||||
out.scale[0] = Length3(column[0]);
|
||||
if (out.scale[0] != 0.0) {
|
||||
column[0][0] /= out.scale[0];
|
||||
column[0][1] /= out.scale[0];
|
||||
column[0][2] /= out.scale[0];
|
||||
}
|
||||
|
||||
// Compute XY shear factor and make 2nd column orthogonal to 1st.
|
||||
out.skew[0] = Dot<3>(column[0], column[1]);
|
||||
Combine<3>(column[1], column[1], column[0], 1.0, -out.skew[0]);
|
||||
|
||||
// Now, compute Y scale and normalize 2nd column.
|
||||
out.scale[1] = Length3(column[1]);
|
||||
if (out.scale[1] != 0.0) {
|
||||
column[1][0] /= out.scale[1];
|
||||
column[1][1] /= out.scale[1];
|
||||
column[1][2] /= out.scale[1];
|
||||
}
|
||||
|
||||
out.skew[0] /= out.scale[1];
|
||||
|
||||
// Compute XZ and YZ shears, orthogonalize the 3rd column.
|
||||
out.skew[1] = Dot<3>(column[0], column[2]);
|
||||
Combine<3>(column[2], column[2], column[0], 1.0, -out.skew[1]);
|
||||
out.skew[2] = Dot<3>(column[1], column[2]);
|
||||
Combine<3>(column[2], column[2], column[1], 1.0, -out.skew[2]);
|
||||
|
||||
// Next, get Z scale and normalize the 3rd column.
|
||||
out.scale[2] = Length3(column[2]);
|
||||
if (out.scale[2] != 0.0) {
|
||||
column[2][0] /= out.scale[2];
|
||||
column[2][1] /= out.scale[2];
|
||||
column[2][2] /= out.scale[2];
|
||||
}
|
||||
|
||||
out.skew[1] /= out.scale[2];
|
||||
out.skew[2] /= out.scale[2];
|
||||
|
||||
// At this point, the matrix is orthonormal.
|
||||
// Check for a coordinate system flip. If the determinant
|
||||
// is -1, then negate the matrix and the scaling factors.
|
||||
// only 1 axis is flipped when the determinant is negative. Verify if it is
|
||||
// correct to flip all of the scales and matrix elements, as this introduces
|
||||
// rotation for the simple case of a single axis scale inversion.
|
||||
float pdum3[3];
|
||||
Cross3(pdum3, column[1], column[2]);
|
||||
if (Dot<3>(column[0], pdum3) < 0) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
out.scale[i] *= -1.0;
|
||||
for (int j = 0; j < 3; ++j)
|
||||
column[i][j] *= -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// See https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion.
|
||||
// Note: deviating from spec (http://www.w3.org/TR/css3-transforms/)
|
||||
// which has a degenerate case of zero off-diagonal elements in the
|
||||
// orthonormal matrix, which leads to errors in determining the sign
|
||||
// of the quaternions.
|
||||
double q_xx = column[0][0];
|
||||
double q_xy = column[1][0];
|
||||
double q_xz = column[2][0];
|
||||
double q_yx = column[0][1];
|
||||
double q_yy = column[1][1];
|
||||
double q_yz = column[2][1];
|
||||
double q_zx = column[0][2];
|
||||
double q_zy = column[1][2];
|
||||
double q_zz = column[2][2];
|
||||
|
||||
double r, s, t, x, y, z, w;
|
||||
t = q_xx + q_yy + q_zz;
|
||||
if (t > 0) {
|
||||
r = std::sqrt(1.0 + t);
|
||||
s = 0.5 / r;
|
||||
w = 0.5 * r;
|
||||
x = (q_zy - q_yz) * s;
|
||||
y = (q_xz - q_zx) * s;
|
||||
z = (q_yx - q_xy) * s;
|
||||
} else if (q_xx > q_yy && q_xx > q_zz) {
|
||||
r = std::sqrt(1.0 + q_xx - q_yy - q_zz);
|
||||
s = 0.5 / r;
|
||||
x = 0.5 * r;
|
||||
y = (q_xy + q_yx) * s;
|
||||
z = (q_xz + q_zx) * s;
|
||||
w = (q_zy - q_yz) * s;
|
||||
} else if (q_yy > q_zz) {
|
||||
r = std::sqrt(1.0 - q_xx + q_yy - q_zz);
|
||||
s = 0.5 / r;
|
||||
x = (q_xy + q_yx) * s;
|
||||
y = 0.5 * r;
|
||||
z = (q_yz + q_zy) * s;
|
||||
w = (q_xz - q_zx) * s;
|
||||
} else {
|
||||
r = std::sqrt(1.0 - q_xx - q_yy + q_zz);
|
||||
s = 0.5 / r;
|
||||
x = (q_xz + q_zx) * s;
|
||||
y = (q_yz + q_zy) * s;
|
||||
z = 0.5 * r;
|
||||
w = (q_yx - q_xy) * s;
|
||||
}
|
||||
|
||||
out.quaternion.SetX(static_cast<float>(x));
|
||||
out.quaternion.SetY(static_cast<float>(y));
|
||||
out.quaternion.SetZ(static_cast<float>(z));
|
||||
out.quaternion.SetW(static_cast<float>(w));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Matrix4 TransformUtil::ComposeTransform(const struct DecomposedTransform& decomp)
|
||||
{
|
||||
Matrix4 perspective = BuildPerspectiveMatrix(decomp);
|
||||
Matrix4 translation = BuildTranslationMatrix(decomp);
|
||||
Matrix4 rotation = BuildRotationMatrix(decomp);
|
||||
Matrix4 skew = BuildSkewMatrix(decomp);
|
||||
Matrix4 scale = BuildScaleMatrix(decomp);
|
||||
|
||||
return OHOS::Ace::ComposeTransform(perspective, translation, rotation, skew, scale);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
159
frameworks/base/geometry/transform_util.h
Normal file
159
frameworks/base/geometry/transform_util.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/dimension.h"
|
||||
#include "base/geometry/matrix4.h"
|
||||
#include "base/geometry/quaternion.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
struct ACE_EXPORT TranslateOperation {
|
||||
TranslateOperation() = default;
|
||||
TranslateOperation(Dimension dx, Dimension dy, Dimension dz = Dimension {}) : dx(dx), dy(dy), dz(dz) {}
|
||||
Dimension dx;
|
||||
Dimension dy;
|
||||
Dimension dz;
|
||||
|
||||
static TranslateOperation Blend(const TranslateOperation& to, const TranslateOperation& from, float progress);
|
||||
};
|
||||
|
||||
struct ACE_EXPORT ScaleOperation {
|
||||
ScaleOperation() = default;
|
||||
ScaleOperation(float x, float y, float z) : scaleX(x), scaleY(y), scaleZ(z) {}
|
||||
float scaleX = 1.0f;
|
||||
float scaleY = 1.0f;
|
||||
float scaleZ = 1.0f;
|
||||
|
||||
static ScaleOperation Blend(const ScaleOperation& to, const ScaleOperation& from, float progress);
|
||||
};
|
||||
|
||||
struct ACE_EXPORT SkewOperation {
|
||||
SkewOperation() = default;
|
||||
SkewOperation(float x, float y) : skewX(x), skewY(y) {};
|
||||
float skewX = 0.0f;
|
||||
float skewY = 0.0f;
|
||||
|
||||
static SkewOperation Blend(const SkewOperation& to, const SkewOperation& from, float progress);
|
||||
};
|
||||
|
||||
struct ACE_EXPORT RotateOperation {
|
||||
RotateOperation() = default;
|
||||
RotateOperation(float x, float y, float z, float angle) : dx(x), dy(y), dz(z), angle(angle) {};
|
||||
float dx = 0.0f;
|
||||
float dy = 0.0f;
|
||||
float dz = 0.0f;
|
||||
float angle = 0.0f;
|
||||
|
||||
static RotateOperation Blend(const RotateOperation& to, const RotateOperation& from, float progress);
|
||||
};
|
||||
|
||||
struct ACE_EXPORT PerspectiveOperation {
|
||||
PerspectiveOperation() = default;
|
||||
PerspectiveOperation(const Dimension& dis) : distance(dis) {};
|
||||
Dimension distance;
|
||||
|
||||
static PerspectiveOperation Blend(const PerspectiveOperation& to, const PerspectiveOperation& from, float progress);
|
||||
};
|
||||
|
||||
struct ACE_EXPORT DecomposedTransform {
|
||||
float translate[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float scale[3] = { 1.0f, 1.0f, 1.0f };
|
||||
float skew[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float perspective[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
Quaternion quaternion;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
enum class TransformOperationType {
|
||||
TRANSLATE,
|
||||
SCALE,
|
||||
SKEW,
|
||||
ROTATE,
|
||||
MATRIX,
|
||||
PERSPECTIVE,
|
||||
UNDEFINED,
|
||||
};
|
||||
|
||||
struct ACE_EXPORT TransformOperation {
|
||||
TransformOperation() : type_(TransformOperationType::UNDEFINED) {};
|
||||
|
||||
TransformOperationType type_ = TransformOperationType::UNDEFINED;
|
||||
Matrix4 matrix4_ = Matrix4::CreateIdentity();
|
||||
union {
|
||||
TranslateOperation translateOperation_;
|
||||
ScaleOperation scaleOperation_;
|
||||
SkewOperation skewOperation_;
|
||||
RotateOperation rotateOperation_;
|
||||
PerspectiveOperation perspectiveOperation_;
|
||||
};
|
||||
|
||||
static TransformOperation Blend(const TransformOperation& to, const TransformOperation& from, float progress);
|
||||
static TransformOperation Create(TransformOperationType type);
|
||||
|
||||
private:
|
||||
static void BlendInner(
|
||||
const TransformOperation& to, const TransformOperation& from, float progress, TransformOperation& out);
|
||||
};
|
||||
|
||||
class ACE_EXPORT TransformOperations {
|
||||
public:
|
||||
static void ParseOperationsToMatrix(std::vector<TransformOperation>& operations);
|
||||
|
||||
static void ParseOperationToMatrix(TransformOperation& operations);
|
||||
|
||||
static TransformOperations Blend(const TransformOperations& to, const TransformOperations& from, float progress);
|
||||
|
||||
explicit TransformOperations(std::vector<TransformOperation> operation = std::vector<TransformOperation>())
|
||||
: operations_(std::move(operation))
|
||||
{}
|
||||
|
||||
std::vector<TransformOperation>& GetOperations()
|
||||
{
|
||||
return operations_;
|
||||
}
|
||||
|
||||
const std::vector<TransformOperation>& GetOperations() const
|
||||
{
|
||||
return operations_;
|
||||
}
|
||||
|
||||
Matrix4 ComputerRemaining(std::size_t startOffset) const;
|
||||
|
||||
protected:
|
||||
std::vector<TransformOperation> operations_;
|
||||
|
||||
private:
|
||||
std::size_t MatchingLength(const TransformOperations& to, const TransformOperations& from) const;
|
||||
void BlendInner(const TransformOperations& from, float progress, TransformOperations& out) const;
|
||||
};
|
||||
|
||||
class ACE_EXPORT TransformUtil final {
|
||||
public:
|
||||
static bool DecomposeTransform(DecomposedTransform& out, const Matrix4& transform);
|
||||
static DecomposedTransform BlendDecomposedTransforms(
|
||||
const DecomposedTransform& to, const DecomposedTransform& from, double progress);
|
||||
static Matrix4 ComposeTransform(const DecomposedTransform& decomp);
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H
|
@ -25,14 +25,14 @@ template("ace_base_i18n") {
|
||||
source_set(target_name) {
|
||||
defines += invoker.defines
|
||||
deps = [
|
||||
"$ace_flutter_engine_root:ace_libicu_$platform",
|
||||
"$ace_root/frameworks/base/resource:ace_resource",
|
||||
"$flutter_root:ace_libicu_$platform",
|
||||
]
|
||||
|
||||
configs += [
|
||||
":ace_base_i18n_config",
|
||||
"$ace_root:ace_config",
|
||||
"$flutter_root:icu_config_$platform",
|
||||
"$ace_flutter_engine_root:icu_config_$platform",
|
||||
]
|
||||
|
||||
# add base source file here
|
||||
|
@ -57,15 +57,15 @@ namespace {
|
||||
|
||||
#define CHECK_RETURN(status, ret) \
|
||||
do { \
|
||||
if (status > U_ZERO_ERROR) { \
|
||||
if ((status) > U_ZERO_ERROR) { \
|
||||
LOGE("status = %{public}d", static_cast<int32_t>(status)); \
|
||||
return ret; \
|
||||
return (ret); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_NO_RETURN(status) \
|
||||
do { \
|
||||
if (status > U_ZERO_ERROR) { \
|
||||
if ((status) > U_ZERO_ERROR) { \
|
||||
LOGE("status = %{public}d", static_cast<int32_t>(status)); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -74,6 +74,7 @@ const char JSON_PATH_CARVE = '.';
|
||||
const char DEFAULT_LANGUAGE[] = "en-US";
|
||||
constexpr uint32_t SEXAGENARY_CYCLE_SIZE = 60;
|
||||
constexpr uint32_t GUIHAI_YEAR_RECENT = 3;
|
||||
constexpr uint32_t SECONDS_IN_HOUR = 3600;
|
||||
|
||||
const char CHINESE_LEAP[] = u8"\u95f0";
|
||||
const char CHINESE_FIRST[] = u8"\u521d";
|
||||
@ -209,7 +210,7 @@ void Localization::SetLocaleImpl(const std::string& language, const std::string&
|
||||
}
|
||||
languageTag_.append("-").append(countryOrRegion);
|
||||
fontLocale_ = languageTag_;
|
||||
// Smiple chinese
|
||||
// Simple chinese
|
||||
if (languageTag_ == "zh-Hans-CN") {
|
||||
languageTag_ = "zh-CN";
|
||||
fontLocale_ = "";
|
||||
@ -257,7 +258,7 @@ const std::string Localization::FormatDuration(uint32_t duration, bool needShowH
|
||||
WaitingForInit();
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// duration greater than 1 hour, use hh:mm:ss;
|
||||
if (!needShowHour && duration > 3600) {
|
||||
if (!needShowHour && duration > SECONDS_IN_HOUR) {
|
||||
needShowHour = true;
|
||||
}
|
||||
const char* engTimeFormat = needShowHour ? "hh:mm:ss" : "mm:ss";
|
||||
@ -771,7 +772,7 @@ std::string Localization::GetErrorDescription(const std::string& errorIndex)
|
||||
return "";
|
||||
}
|
||||
|
||||
if (localJsonError && localJsonError->Contains(errorIndex)) {
|
||||
if (localJsonError->Contains(errorIndex)) {
|
||||
localJsonError = localJsonError->GetValue(errorIndex);
|
||||
} else {
|
||||
LOGE("read error json failed. error path: %{private}s.", errorIndex.c_str());
|
||||
|
@ -311,6 +311,15 @@ bool JsonValue::Replace(const char* key, const std::unique_ptr<JsonValue>& value
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonValue::Delete(const char* key)
|
||||
{
|
||||
if (key == nullptr) {
|
||||
return false;
|
||||
}
|
||||
cJSON_DeleteItemFromObject(object_, key);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string JsonValue::ToString()
|
||||
{
|
||||
std::string result;
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
|
||||
// get functions
|
||||
bool GetBool() const;
|
||||
bool GetBool(const std::string& key, bool defaultValue) const;
|
||||
bool GetBool(const std::string& key, bool defaultValue = false) const;
|
||||
int32_t GetInt() const;
|
||||
int32_t GetInt(const std::string& key, int32_t defaultVal = 0) const;
|
||||
uint32_t GetUInt() const;
|
||||
@ -79,6 +79,9 @@ public:
|
||||
bool Replace(const char* key, int32_t value);
|
||||
bool Replace(const char* key, const std::unique_ptr<JsonValue>& value);
|
||||
|
||||
// delete functions
|
||||
bool Delete(const char* key);
|
||||
|
||||
// serialize
|
||||
std::string ToString();
|
||||
|
||||
|
@ -22,20 +22,17 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
// eventType use int32_t type, no need enum class.
|
||||
enum {
|
||||
EXCEPTION_FRAMEWORK_APP_START = 951004000,
|
||||
EXCEPTION_FRAMEWORK_PAGE_ROUTER = 951004001,
|
||||
EXCEPTION_COMPONENT = 951004002,
|
||||
EXCEPTION_API_CHANNEL = 951004003,
|
||||
EXCEPTION_RENDER = 951004004,
|
||||
EXCEPTION_JS = 951004005,
|
||||
EXCEPTION_ANIMATION = 951004006,
|
||||
EXCEPTION_EVENT = 951004007,
|
||||
EXCEPTION_INTERNATIONALIZATION = 951004009,
|
||||
EXCEPTION_ACCESSIBILITY = 951004010,
|
||||
EXCEPTION_FORM = 951004011,
|
||||
};
|
||||
const std::string EXCEPTION_FRAMEWORK_APP_START = "FrameworkAppStartException";
|
||||
const std::string EXCEPTION_FRAMEWORK_PAGE_ROUTER = "FrameworkPageRouterException";
|
||||
const std::string EXCEPTION_COMPONENT = "ComponentException";
|
||||
const std::string EXCEPTION_API_CHANNEL = "ApiChannelException";
|
||||
const std::string EXCEPTION_RENDER = "RenderException";
|
||||
const std::string EXCEPTION_JS = "JsException";
|
||||
const std::string EXCEPTION_ANIMATION = "AnimationException";
|
||||
const std::string EXCEPTION_EVENT = "EventException";
|
||||
const std::string EXCEPTION_INTERNATIONALIZATION = "InternationalizationException";
|
||||
const std::string EXCEPTION_ACCESSIBILITY = "AccessibilityException";
|
||||
const std::string EXCEPTION_FORM = "FormException";
|
||||
|
||||
// EXCEPTION_FRAMEWORK_APP_START
|
||||
enum class AppStartExcepType {
|
||||
@ -141,7 +138,7 @@ enum class FormExcepType {
|
||||
enum class RawEventType { WARNING, FREEZE, RECOVER };
|
||||
|
||||
struct EventInfo {
|
||||
int32_t eventType = 0;
|
||||
std::string eventType;
|
||||
int32_t errorType = 0;
|
||||
std::string pageUrl;
|
||||
};
|
||||
@ -149,6 +146,10 @@ struct EventInfo {
|
||||
class ACE_EXPORT EventReport {
|
||||
public:
|
||||
static void SendEvent(const EventInfo& eventInfo);
|
||||
static void SendJsCardRenderTimeEvent(
|
||||
const std::string& sessionID,
|
||||
const std::string& timeType,
|
||||
uint64_t timeDelay);
|
||||
|
||||
static void SendAppStartException(AppStartExcepType type);
|
||||
static void SendPageRouterException(PageRouterExcepType type, const std::string& pageUrl = "");
|
||||
|
@ -42,6 +42,8 @@
|
||||
#define LOGE(fmt, ...) PRINT_LOG(ERROR, fmt, ##__VA_ARGS__)
|
||||
#define LOGF(fmt, ...) PRINT_LOG(FATAL, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_DESTROY() LOGI("destroyed")
|
||||
|
||||
#define PRINT_APP_LOG(level, fmt, ...) \
|
||||
OHOS::Ace::LogWrapper::PrintLog(OHOS::Ace::LogDomain::JS_APP, OHOS::Ace::LogLevel::level, fmt, ##__VA_ARGS__)
|
||||
|
||||
|
@ -18,13 +18,25 @@
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "base/log/dump_log.h"
|
||||
#include "base/log/log.h"
|
||||
|
||||
#ifdef ACE_MEMORY_MONITOR
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
void PurgeMallocCache()
|
||||
{
|
||||
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
|
||||
#if defined(__BIONIC__)
|
||||
mallopt(M_PURGE, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ACE_MEMORY_MONITOR
|
||||
class MemoryMonitorImpl : public MemoryMonitor {
|
||||
public:
|
||||
void Add(void* ptr) final
|
||||
@ -114,7 +126,6 @@ MemoryMonitor& MemoryMonitor::GetInstance()
|
||||
static MemoryMonitorImpl instance;
|
||||
return instance;
|
||||
}
|
||||
#endif // ACE_MEMORY_MONITOR
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // ACE_MEMORY_MONITOR
|
||||
|
@ -22,10 +22,11 @@
|
||||
#include "base/memory/type_info_base.h"
|
||||
#include "base/utils/macros.h"
|
||||
|
||||
#ifdef ACE_MEMORY_MONITOR
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
void PurgeMallocCache();
|
||||
|
||||
#ifdef ACE_MEMORY_MONITOR
|
||||
class ACE_EXPORT MemoryMonitor {
|
||||
public:
|
||||
static MemoryMonitor& GetInstance();
|
||||
@ -75,9 +76,8 @@ private:
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif // ACE_MEMORY_MONITOR
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // ACE_MEMORY_MONITOR
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_MEMORY_MEMORY_MONITOR_H
|
||||
|
@ -22,40 +22,40 @@
|
||||
|
||||
// Generate 'TypeInfo' for each classes.
|
||||
// And using hash code of its name for 'TypeId'.
|
||||
#define DECLARE_CLASS_TYPE_INFO(classname) \
|
||||
public: \
|
||||
static const char* TypeName() \
|
||||
{ \
|
||||
return #classname; \
|
||||
} \
|
||||
static IdType TypeId() \
|
||||
{ \
|
||||
static IdType myTypeId = std::hash<std::string> {}(TypeName()); \
|
||||
return myTypeId; \
|
||||
} \
|
||||
#define DECLARE_CLASS_TYPE_INFO(classname) \
|
||||
public: \
|
||||
static const char* TypeName() \
|
||||
{ \
|
||||
return #classname; \
|
||||
} \
|
||||
static TypeInfoBase::IdType TypeId() \
|
||||
{ \
|
||||
static TypeInfoBase::IdType myTypeId = std::hash<std::string> {}(TypeName()); \
|
||||
return myTypeId; \
|
||||
} \
|
||||
DECLARE_CLASS_TYPE_SIZE(classname)
|
||||
|
||||
// Integrate it into class declaration to support 'DynamicCast'.
|
||||
#define DECLARE_RELATIONSHIP_OF_CLASSES(classname, ...) DECLARE_CLASS_TYPE_INFO(classname) \
|
||||
protected: \
|
||||
template<class __T, class __O, class... __V> \
|
||||
uintptr_t TrySafeCastById(IdType id) const \
|
||||
uintptr_t TrySafeCastById(TypeInfoBase::IdType id) const \
|
||||
{ \
|
||||
VERIFY_DECLARED_CLASS(__T); \
|
||||
uintptr_t ptr = __T::SafeCastById(id); \
|
||||
return ptr != 0 ? ptr : TrySafeCastById<__O, __V...>(id); \
|
||||
} \
|
||||
template<class __T> \
|
||||
uintptr_t TrySafeCastById(IdType id) const \
|
||||
uintptr_t TrySafeCastById(TypeInfoBase::IdType id) const \
|
||||
{ \
|
||||
VERIFY_DECLARED_CLASS(__T); \
|
||||
return __T::SafeCastById(id); \
|
||||
} \
|
||||
uintptr_t SafeCastById(IdType id) const override \
|
||||
uintptr_t SafeCastById(TypeInfoBase::IdType id) const override \
|
||||
{ \
|
||||
return id == TypeId() ? reinterpret_cast<uintptr_t>(this) : TrySafeCastById<__VA_ARGS__>(id); \
|
||||
} \
|
||||
IdType GetTypeId() const override \
|
||||
TypeInfoBase::IdType GetTypeId() const override \
|
||||
{ \
|
||||
return TypeId(); \
|
||||
} \
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
~AssetManager() override = default;
|
||||
|
||||
virtual RefPtr<Asset> GetAsset(const std::string& assetName) = 0;
|
||||
|
||||
virtual std::string GetAssetPath(const std::string& assetName) = 0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
63
frameworks/base/resource/data_provider_manager.h
Normal file
63
frameworks/base/resource/data_provider_manager.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_ACE_ENGINE_FRAMEWORKS_BASE_RESOURCE_DATA_PROVIDER_MANAGER_H
|
||||
#define FOUNDATION_ACE_ACE_ENGINE_FRAMEWORKS_BASE_RESOURCE_DATA_PROVIDER_MANAGER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/ace_type.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class DataProviderRes {
|
||||
public:
|
||||
DataProviderRes(uint8_t* dataRes, int64_t size) : data_(dataRes, dataRes + size) {}
|
||||
~DataProviderRes() = default;
|
||||
|
||||
const std::vector<uint8_t>& GetData()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> data_;
|
||||
};
|
||||
|
||||
using DataProviderImpl = std::function<std::unique_ptr<DataProviderRes>(const std::string& uriStr)>;
|
||||
|
||||
class DataProviderManager : public AceType {
|
||||
DECLARE_ACE_TYPE(DataProviderManager, AceType)
|
||||
public:
|
||||
explicit DataProviderManager(const DataProviderImpl& dataProvider) : platformImpl_(dataProvider) {}
|
||||
~DataProviderManager() = default;
|
||||
|
||||
std::unique_ptr<DataProviderRes> GetDataProviderResFromUri(const std::string& uriStr)
|
||||
{
|
||||
if (platformImpl_) {
|
||||
return platformImpl_(uriStr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
DataProviderImpl platformImpl_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_ACE_ENGINE_FRAMEWORKS_BASE_RESOURCE_DATA_PROVIDER_MANAGER_H
|
@ -30,7 +30,6 @@ std::function<void()> SharedImageManager::GenerateClearImageDataCallback(const s
|
||||
auto clearImageDataCallback = [wp = AceType::WeakClaim(this), picName = name]() {
|
||||
auto sharedImageManager = wp.Upgrade();
|
||||
if (!sharedImageManager) {
|
||||
LOGW("sharedImageManager upgrade fail, picName: %{private}s", picName.c_str());
|
||||
return;
|
||||
}
|
||||
{
|
||||
@ -41,6 +40,7 @@ std::function<void()> SharedImageManager::GenerateClearImageDataCallback(const s
|
||||
std::lock_guard<std::mutex> lockCancelableCallbackMap_(sharedImageManager->cancelableCallbackMapMutex_);
|
||||
sharedImageManager->cancelableCallbackMap_.erase(picName);
|
||||
}
|
||||
LOGI("Done clean image data for %{private}s", picName.c_str());
|
||||
};
|
||||
return clearImageDataCallback;
|
||||
}
|
||||
|
@ -64,8 +64,6 @@ void JsonUtilsTest::TearDown()
|
||||
* @tc.name: JsonUtilsTest001
|
||||
* @tc.desc: Check json util function for bool type value
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest001, TestSize.Level1)
|
||||
{
|
||||
@ -90,8 +88,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest001, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest002
|
||||
* @tc.desc: Check json util function for bool type value
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest002, TestSize.Level1)
|
||||
{
|
||||
@ -116,8 +112,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest002, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest003
|
||||
* @tc.desc: Check json util function for signed integer
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest003, TestSize.Level1)
|
||||
{
|
||||
@ -147,8 +141,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest003, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest004
|
||||
* @tc.desc: Check json util function for unsigned integer
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest004, TestSize.Level1)
|
||||
{
|
||||
@ -178,8 +170,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest004, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest005
|
||||
* @tc.desc: Check json util function for decimal number
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest005, TestSize.Level1)
|
||||
{
|
||||
@ -209,8 +199,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest005, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest006
|
||||
* @tc.desc: Check json util function for string
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest006, TestSize.Level1)
|
||||
{
|
||||
@ -235,8 +223,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest006, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest007
|
||||
* @tc.desc: Check json util function for empty string
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest007, TestSize.Level1)
|
||||
{
|
||||
@ -261,8 +247,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest007, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest008
|
||||
* @tc.desc: Check json util function for JsonObject
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest008, TestSize.Level1)
|
||||
{
|
||||
@ -290,8 +274,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest008, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest009
|
||||
* @tc.desc: Check json util function for incorrect JsonObject
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest009, TestSize.Level1)
|
||||
{
|
||||
@ -317,8 +299,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest009, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest010
|
||||
* @tc.desc: Check json util function for array
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest010, TestSize.Level1)
|
||||
{
|
||||
@ -347,8 +327,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest010, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest011
|
||||
* @tc.desc: Check json util function for empty array
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest011, TestSize.Level1)
|
||||
{
|
||||
@ -373,8 +351,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest011, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest012
|
||||
* @tc.desc: Check json util function for empty test string
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest012, TestSize.Level1)
|
||||
{
|
||||
@ -397,8 +373,6 @@ HWTEST_F(JsonUtilsTest, JsonUtilsTest012, TestSize.Level1)
|
||||
* @tc.name: JsonUtilsTest013
|
||||
* @tc.desc: Check json util function for illegal type value
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000DAQVN
|
||||
* @tc.author: luoying
|
||||
*/
|
||||
HWTEST_F(JsonUtilsTest, JsonUtilsTest013, TestSize.Level1)
|
||||
{
|
||||
|
@ -25,13 +25,13 @@ ohos_unittest("TaskExecutorsTest") {
|
||||
|
||||
configs = [
|
||||
"$ace_root:ace_test_config",
|
||||
"$flutter_root:flutter_config",
|
||||
"$ace_flutter_engine_root:flutter_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$ace_flutter_engine_root:ace_libicu_ohos",
|
||||
"$ace_flutter_engine_root:third_party_flutter_engine_ohos",
|
||||
"$ace_root/frameworks/base:ace_base_ohos",
|
||||
"$flutter_root:ace_libicu_ohos",
|
||||
"$flutter_root:third_party_flutter_engine_ohos",
|
||||
"//third_party/googletest:gtest_main",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
@ -18,12 +18,14 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "base/memory/memory_monitor.h"
|
||||
#include "base/thread/thread_util.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
const size_t MAX_BACKGROUND_THREADS = 8;
|
||||
constexpr size_t MAX_BACKGROUND_THREADS = 8;
|
||||
constexpr uint32_t PURGE_FLAG_MASK = (1 << MAX_BACKGROUND_THREADS) - 1;
|
||||
|
||||
void SetThreadName(uint32_t threadNo)
|
||||
{
|
||||
@ -141,10 +143,20 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo)
|
||||
SetThreadName(threadNo);
|
||||
|
||||
Task task;
|
||||
const uint32_t purgeFlag = (1 << (threadNo - 1));
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
while (running_) {
|
||||
if (tasks_.empty()) {
|
||||
condition_.wait(lock);
|
||||
if ((purgeFlags_ & purgeFlag) != purgeFlag) {
|
||||
condition_.wait(lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
LOGD("Purge malloc cache for background thread %{public}u", threadNo);
|
||||
PurgeMallocCache();
|
||||
lock.lock();
|
||||
purgeFlags_ &= ~purgeFlag;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -161,4 +173,11 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo)
|
||||
LOGD("Background thread is stopped");
|
||||
}
|
||||
|
||||
void BackgroundTaskExecutor::TriggerGarbageCollection()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
purgeFlags_ = PURGE_FLAG_MASK;
|
||||
condition_.notify_all();
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
bool PostTask(Task&& task);
|
||||
bool PostTask(const Task& task);
|
||||
|
||||
void TriggerGarbageCollection();
|
||||
|
||||
private:
|
||||
BackgroundTaskExecutor();
|
||||
~BackgroundTaskExecutor();
|
||||
@ -48,6 +50,7 @@ private:
|
||||
size_t currentThreadNum_ { 0 };
|
||||
size_t maxThreadNum_ { 0 };
|
||||
bool running_ { true };
|
||||
uint32_t purgeFlags_ { 0 };
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
GPU,
|
||||
JS,
|
||||
BACKGROUND,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
~TaskExecutor() override = default;
|
||||
@ -172,10 +173,27 @@ protected:
|
||||
|
||||
virtual bool OnPostTask(Task&& task, TaskType type, uint32_t delayTime) const = 0;
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
virtual bool OnPreSyncTask(TaskType type) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual void OnPostSyncTask() const {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool PostTaskAndWait(CancelableTask&& task, TaskType type) const
|
||||
{
|
||||
#ifdef ACE_DEBUG
|
||||
bool result = false;
|
||||
if (OnPreSyncTask(type)) {
|
||||
result = OnPostTask(Task(task), type, 0) && task.WaitUntilComplete();
|
||||
OnPostSyncTask();
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return OnPostTask(Task(task), type, 0) && task.WaitUntilComplete();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -32,6 +32,8 @@ namespace OHOS::Ace::StringUtils {
|
||||
ACE_EXPORT extern const char DEFAULT_STRING[];
|
||||
ACE_EXPORT extern const std::wstring DEFAULT_WSTRING;
|
||||
ACE_EXPORT extern const std::u16string DEFAULT_USTRING;
|
||||
constexpr int32_t TEXT_CASE_LOWERCASR = 1;
|
||||
constexpr int32_t TEXT_CASE_UPPERCASR = 2;
|
||||
|
||||
inline std::u16string Str8ToStr16(const std::string& str)
|
||||
{
|
||||
@ -106,6 +108,22 @@ inline int32_t StringToInt(const std::string& value)
|
||||
}
|
||||
}
|
||||
|
||||
inline int64_t StringToLongInt(const std::string& value)
|
||||
{
|
||||
errno = 0;
|
||||
char* pEnd = nullptr;
|
||||
int64_t result = std::strtoll(value.c_str(), &pEnd, 10);
|
||||
if (pEnd == value.c_str() || errno == ERANGE) {
|
||||
return 0;
|
||||
} else if (result < INT64_MIN) {
|
||||
return INT64_MIN;
|
||||
} else if (result > INT64_MAX) {
|
||||
return INT64_MAX;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t StringToUint(const std::string& value, uint32_t defaultErr = 0)
|
||||
{
|
||||
errno = 0;
|
||||
@ -120,7 +138,7 @@ inline uint32_t StringToUint(const std::string& value, uint32_t defaultErr = 0)
|
||||
|
||||
inline double StringToDouble(const std::string& value)
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
char* pEnd = nullptr;
|
||||
double result = std::strtod(value.c_str(), &pEnd);
|
||||
if (pEnd == value.c_str() || errno == ERANGE) {
|
||||
return 0.0;
|
||||
@ -129,26 +147,44 @@ inline double StringToDouble(const std::string& value)
|
||||
}
|
||||
}
|
||||
|
||||
inline Dimension StringToDimension(const std::string& value, bool useVp = false)
|
||||
inline float StringToFloat(const std::string& value)
|
||||
{
|
||||
char* pEnd = nullptr;
|
||||
float result = std::strtof(value.c_str(), &pEnd);
|
||||
if (pEnd == value.c_str() || errno == ERANGE) {
|
||||
return 0.0f;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
inline Dimension StringToDimensionWithUnit(const std::string& value, DimensionUnit defaultUnit = DimensionUnit::PX)
|
||||
{
|
||||
errno = 0;
|
||||
char* pEnd = nullptr;
|
||||
double result = std::strtod(value.c_str(), &pEnd);
|
||||
if (pEnd == value.c_str() || errno == ERANGE) {
|
||||
return Dimension(0.0, DimensionUnit::PX);
|
||||
} else {
|
||||
if ((pEnd) && (std::strcmp(pEnd, "%") == 0)) {
|
||||
return Dimension(0.0, defaultUnit);
|
||||
} else if (pEnd != nullptr) {
|
||||
if (std::strcmp(pEnd, "%") == 0) {
|
||||
// Parse percent, transfer from [0, 100] to [0, 1]
|
||||
return Dimension(result / 100.0, DimensionUnit::PERCENT);
|
||||
} else if ((pEnd) && (std::strcmp(pEnd, "px") == 0)) {
|
||||
} else if (std::strcmp(pEnd, "px") == 0) {
|
||||
return Dimension(result, DimensionUnit::PX);
|
||||
} else if ((pEnd) && (std::strcmp(pEnd, "vp") == 0)) {
|
||||
} else if (std::strcmp(pEnd, "vp") == 0) {
|
||||
return Dimension(result, DimensionUnit::VP);
|
||||
} else if ((pEnd) && (std::strcmp(pEnd, "fp") == 0)) {
|
||||
} else if (std::strcmp(pEnd, "fp") == 0) {
|
||||
return Dimension(result, DimensionUnit::FP);
|
||||
} else if ((pEnd) && (std::strcmp(pEnd, "lpx") == 0)) {
|
||||
return Dimension(result, DimensionUnit::LPX);
|
||||
}
|
||||
return Dimension(result, useVp ? DimensionUnit::VP : DimensionUnit::PX);
|
||||
}
|
||||
return Dimension(result, defaultUnit);
|
||||
}
|
||||
|
||||
inline Dimension StringToDimension(const std::string& value, bool useVp = false)
|
||||
{
|
||||
return StringToDimensionWithUnit(value, useVp ? DimensionUnit::VP : DimensionUnit::PX);
|
||||
}
|
||||
|
||||
inline double StringToDegree(const std::string& value)
|
||||
@ -217,6 +253,13 @@ inline void StringSpliter(const std::string& source, char delimiter, std::vector
|
||||
StringSpliter(source, delimiter, func, out);
|
||||
}
|
||||
|
||||
inline void StringSpliter(const std::string& source, char delimiter, std::vector<float>& out)
|
||||
{
|
||||
using Func = float (*)(const std::string&);
|
||||
Func func = [](const std::string& value) { return StringToFloat(value); };
|
||||
StringSpliter(source, delimiter, func, out);
|
||||
}
|
||||
|
||||
inline void StringSpliter(const std::string& source, char delimiter, std::vector<int>& out)
|
||||
{
|
||||
using Func = int32_t (*)(const std::string&);
|
||||
@ -224,6 +267,13 @@ inline void StringSpliter(const std::string& source, char delimiter, std::vector
|
||||
StringSpliter(source, delimiter, func, out);
|
||||
}
|
||||
|
||||
inline void StringSpliter(const std::string& source, char delimiter, std::vector<Dimension>& out)
|
||||
{
|
||||
using Func = Dimension (*)(const std::string&);
|
||||
Func func = [](const std::string& value) { return StringToDimension(value); };
|
||||
StringSpliter(source, delimiter, func, out);
|
||||
}
|
||||
|
||||
inline std::string DoubleToString(double value, int32_t precision = 2)
|
||||
{
|
||||
std::ostringstream result;
|
||||
@ -247,6 +297,22 @@ inline std::string TrimStr(const std::string& str, char cTrim = ' ')
|
||||
return str.substr(firstPos, endPos - firstPos + 1);
|
||||
}
|
||||
|
||||
inline void TrimStrLeadingAndTrailing(std::string& str, char cTrim = ' ')
|
||||
{
|
||||
auto firstIndexNotOfSpace = str.find_first_not_of(" ");
|
||||
if (firstIndexNotOfSpace == std::string::npos) {
|
||||
str = "";
|
||||
return;
|
||||
}
|
||||
str.erase(0, firstIndexNotOfSpace);
|
||||
auto lastIndexNotOfSpace = str.find_last_not_of(" ");
|
||||
if (lastIndexNotOfSpace == std::string::npos) {
|
||||
str = "";
|
||||
return;
|
||||
}
|
||||
str.erase(lastIndexNotOfSpace + 1);
|
||||
}
|
||||
|
||||
inline void SplitStr(
|
||||
const std::string& str, const std::string& sep, std::vector<std::string>& out, bool needTrim = true)
|
||||
{
|
||||
@ -274,6 +340,35 @@ inline void SplitStr(
|
||||
}
|
||||
}
|
||||
|
||||
inline void SplitStr(const std::string& str, const std::string& sep, std::vector<Dimension>& out, bool needTrim = true)
|
||||
{
|
||||
out.erase(out.begin(), out.end());
|
||||
if (str.empty() || sep.empty()) {
|
||||
return;
|
||||
}
|
||||
std::string strPart;
|
||||
std::string::size_type startPos = 0;
|
||||
std::string::size_type pos = str.find_first_of(sep, startPos);
|
||||
while (pos != std::string::npos) {
|
||||
if (pos > startPos) {
|
||||
strPart = needTrim ? TrimStr(str.substr(startPos, pos - startPos)) : str.substr(startPos, pos - startPos);
|
||||
if (!strPart.empty()) {
|
||||
out.emplace_back(StringToDimension(std::move(strPart)));
|
||||
}
|
||||
}
|
||||
startPos = pos + sep.size();
|
||||
pos = str.find_first_of(sep, startPos);
|
||||
}
|
||||
if (startPos < str.size()) {
|
||||
strPart = needTrim ? TrimStr(str.substr(startPos)) : str.substr(startPos);
|
||||
if (!strPart.empty()) {
|
||||
out.emplace_back(StringToDimension(std::move(strPart)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string ACE_EXPORT FormatString(const char* fmt, ...);
|
||||
|
||||
inline bool StartWith(const std::string& dst, const std::string& prefix)
|
||||
{
|
||||
return dst.compare(0, prefix.size(), prefix) == 0;
|
||||
@ -284,6 +379,24 @@ inline bool EndWith(const std::string& dst, const std::string& suffix)
|
||||
return (dst.size() >= suffix.size()) && dst.compare(dst.size() - suffix.size(), suffix.size(), suffix) == 0;
|
||||
}
|
||||
|
||||
inline void TransfromStrCase(std::string& str, int32_t textCase)
|
||||
{
|
||||
if (str.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (textCase) {
|
||||
case TEXT_CASE_LOWERCASR:
|
||||
transform(str.begin(), str.end(), str.begin(), ::tolower);
|
||||
break;
|
||||
case TEXT_CASE_UPPERCASR:
|
||||
transform(str.begin(), str.end(), str.begin(), ::toupper);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::StringUtils
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_STRING_UTILS_H
|
||||
|
@ -49,6 +49,18 @@ enum class ResolutionType : int32_t {
|
||||
constexpr int32_t MCC_UNDEFINED = 0;
|
||||
constexpr int32_t MNC_UNDEFINED = 0;
|
||||
|
||||
enum class LongScreenType : int32_t {
|
||||
LONG = 0,
|
||||
NOT_LONG,
|
||||
LONG_SCREEN_UNDEFINED,
|
||||
};
|
||||
|
||||
enum class ScreenShape : int32_t {
|
||||
ROUND = 0,
|
||||
NOT_ROUND,
|
||||
SCREEN_SHAPE_UNDEFINED,
|
||||
};
|
||||
|
||||
class ACE_EXPORT SystemProperties final {
|
||||
public:
|
||||
/*
|
||||
@ -194,7 +206,9 @@ public:
|
||||
|
||||
static void SetColorMode(ColorMode colorMode)
|
||||
{
|
||||
colorMode_ = colorMode;
|
||||
if (colorMode_ != colorMode) {
|
||||
colorMode_ = colorMode;
|
||||
}
|
||||
}
|
||||
|
||||
static ColorMode GetColorMode()
|
||||
@ -204,6 +218,11 @@ public:
|
||||
|
||||
static void InitMccMnc(int32_t mcc, int32_t mnc);
|
||||
|
||||
static ScreenShape GetScreenShape()
|
||||
{
|
||||
return screenShape_;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool traceEnabled_;
|
||||
static bool isRound_;
|
||||
@ -224,6 +243,8 @@ private:
|
||||
static int32_t mcc_;
|
||||
static int32_t mnc_;
|
||||
static ColorMode colorMode_;
|
||||
static ScreenShape screenShape_;
|
||||
static LongScreenType LongScreen_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -27,7 +27,7 @@ class ValueChangeObserver : public virtual AceType {
|
||||
DECLARE_ACE_TYPE(ValueChangeObserver, AceType);
|
||||
|
||||
public:
|
||||
virtual void OnValueChanged(bool needFireChangeEvent = true) = 0;
|
||||
virtual void OnValueChanged(bool needFireChangeEvent = true, bool needFireSelectChangeEvent = true) = 0;
|
||||
|
||||
protected:
|
||||
ValueChangeObserver() = default;
|
||||
@ -65,6 +65,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
preValue_ = value_;
|
||||
value_ = std::move(newValue);
|
||||
Notify(needFireChangeEvent);
|
||||
}
|
||||
@ -75,6 +76,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
preValue_ = value_;
|
||||
value_ = newValue;
|
||||
Notify(needFireChangeEvent);
|
||||
}
|
||||
@ -84,6 +86,11 @@ public:
|
||||
return value_;
|
||||
}
|
||||
|
||||
const U& GetPreValue() const
|
||||
{
|
||||
return preValue_;
|
||||
}
|
||||
|
||||
private:
|
||||
void Notify(bool needFireChangeEvent = true)
|
||||
{
|
||||
@ -102,6 +109,7 @@ private:
|
||||
std::list<WeakPtr<ValueChangeObserver>> observers_;
|
||||
|
||||
U value_;
|
||||
U preValue_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
252
frameworks/bridge/BUILD.gn
Executable file → Normal file
252
frameworks/bridge/BUILD.gn
Executable file → Normal file
@ -27,9 +27,11 @@ template("js_framework") {
|
||||
defines += invoker.defines
|
||||
|
||||
deps = [
|
||||
"$ace_flutter_engine_root:ace_skia_$platform",
|
||||
"$ace_root/frameworks/base:ace_base_$platform",
|
||||
"$ace_root/frameworks/core:ace_core_$platform",
|
||||
"$ace_root/frameworks/core/accessibility:ace_accessibility_$platform",
|
||||
"$ace_root/frameworks/core/components/theme:build_theme_code",
|
||||
]
|
||||
|
||||
# add common source file needed by all product platform here
|
||||
@ -49,6 +51,7 @@ template("js_framework") {
|
||||
"common/dom/dom_div.cpp",
|
||||
"common/dom/dom_divider.cpp",
|
||||
"common/dom/dom_document.cpp",
|
||||
"common/dom/dom_form.cpp",
|
||||
"common/dom/dom_grid_column.cpp",
|
||||
"common/dom/dom_grid_container.cpp",
|
||||
"common/dom/dom_grid_row.cpp",
|
||||
@ -80,6 +83,7 @@ template("js_framework") {
|
||||
"common/dom/dom_svg_circle.cpp",
|
||||
"common/dom/dom_svg_ellipse.cpp",
|
||||
"common/dom/dom_svg_line.cpp",
|
||||
"common/dom/dom_svg_mask.cpp",
|
||||
"common/dom/dom_svg_path.cpp",
|
||||
"common/dom/dom_svg_polygon.cpp",
|
||||
"common/dom/dom_svg_polyline.cpp",
|
||||
@ -108,6 +112,7 @@ template("js_framework") {
|
||||
"js_frontend/engine/common/base_animation_bridge.cpp",
|
||||
"js_frontend/engine/common/js_api_perf.cpp",
|
||||
"js_frontend/engine/common/js_constants.cpp",
|
||||
"js_frontend/frontend_delegate.cpp",
|
||||
"js_frontend/frontend_delegate_impl.cpp",
|
||||
"js_frontend/js_ace_page.cpp",
|
||||
"js_frontend/js_command.cpp",
|
||||
@ -125,11 +130,16 @@ template("js_framework") {
|
||||
|
||||
# utils
|
||||
"common/utils/source_map.cpp",
|
||||
"common/utils/transform_convertor.cpp",
|
||||
"common/utils/utils.cpp",
|
||||
|
||||
# declarative js
|
||||
"declarative_frontend/declarative_frontend.cpp",
|
||||
"declarative_frontend/frontend_delegate_declarative.cpp",
|
||||
|
||||
# pa backend
|
||||
"pa_backend/pa_backend.cpp",
|
||||
"pa_backend/backend_delegate_impl.cpp",
|
||||
]
|
||||
if (!use_mingw_win && !use_mac) {
|
||||
sources += [ "common/dom/dom_qrcode.cpp" ]
|
||||
@ -161,12 +171,17 @@ template("js_framework") {
|
||||
|
||||
# add sources needed by phone and TV. wearable like watch do not need them
|
||||
if (!is_wearable_product && !use_mingw_win && !use_mac) {
|
||||
sources += [ "common/dom/dom_web.cpp" ]
|
||||
sources += [
|
||||
"common/dom/dom_rich_text.cpp",
|
||||
"common/dom/dom_web.cpp",
|
||||
"common/dom/dom_xcomponent.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_wearable_product && !use_mingw_win &&
|
||||
!use_mac) {
|
||||
sources += [ "js_frontend/engine/common/js_engine_loader.cpp" ]
|
||||
sources += [ "js_frontend/engine/common/js_engine_loader.cpp",
|
||||
"pa_backend/engine/common/js_backend_engine_loader.cpp" ]
|
||||
}
|
||||
|
||||
configs = [
|
||||
@ -194,12 +209,17 @@ template("js_framework") {
|
||||
} else if (use_mingw_win) {
|
||||
sources += [
|
||||
"common/accessibility/accessibility_node_manager.cpp",
|
||||
"common/inspector/inspect_badge.cpp",
|
||||
"common/inspector/inspect_button.cpp",
|
||||
"common/inspector/inspect_canvas.cpp",
|
||||
"common/inspector/inspect_chart.cpp",
|
||||
"common/inspector/inspect_dialog.cpp",
|
||||
"common/inspector/inspect_div.cpp",
|
||||
"common/inspector/inspect_divider.cpp",
|
||||
"common/inspector/inspect_form.cpp",
|
||||
"common/inspector/inspect_grid_column.cpp",
|
||||
"common/inspector/inspect_grid_container.cpp",
|
||||
"common/inspector/inspect_grid_row.cpp",
|
||||
"common/inspector/inspect_image.cpp",
|
||||
"common/inspector/inspect_image_animator.cpp",
|
||||
"common/inspector/inspect_input.cpp",
|
||||
@ -211,10 +231,13 @@ template("js_framework") {
|
||||
"common/inspector/inspect_menu.cpp",
|
||||
"common/inspector/inspect_node.cpp",
|
||||
"common/inspector/inspect_option.cpp",
|
||||
"common/inspector/inspect_panel.cpp",
|
||||
"common/inspector/inspect_picker.cpp",
|
||||
"common/inspector/inspect_picker_view.cpp",
|
||||
"common/inspector/inspect_piece.cpp",
|
||||
"common/inspector/inspect_popup.cpp",
|
||||
"common/inspector/inspect_progress.cpp",
|
||||
"common/inspector/inspect_qrcode.cpp",
|
||||
"common/inspector/inspect_rating.cpp",
|
||||
"common/inspector/inspect_refresh.cpp",
|
||||
"common/inspector/inspect_search.cpp",
|
||||
@ -222,6 +245,8 @@ template("js_framework") {
|
||||
"common/inspector/inspect_slider.cpp",
|
||||
"common/inspector/inspect_span.cpp",
|
||||
"common/inspector/inspect_stack.cpp",
|
||||
"common/inspector/inspect_stepper.cpp",
|
||||
"common/inspector/inspect_stepper_item.cpp",
|
||||
"common/inspector/inspect_swiper.cpp",
|
||||
"common/inspector/inspect_switch.cpp",
|
||||
"common/inspector/inspect_tab_bar.cpp",
|
||||
@ -229,6 +254,9 @@ template("js_framework") {
|
||||
"common/inspector/inspect_tabs.cpp",
|
||||
"common/inspector/inspect_text.cpp",
|
||||
"common/inspector/inspect_textarea.cpp",
|
||||
"common/inspector/inspect_toggle.cpp",
|
||||
"common/inspector/inspect_toolbar.cpp",
|
||||
"common/inspector/inspect_toolbar_item.cpp",
|
||||
"common/inspector/inspect_video.cpp",
|
||||
"common/inspector/inspector_client.cpp",
|
||||
"common/inspector/js_inspector_manager.cpp",
|
||||
@ -340,6 +368,7 @@ template("js_engine") {
|
||||
sources += [
|
||||
#runtime
|
||||
"js_frontend/engine/quickjs/animation_bridge.cpp",
|
||||
"js_frontend/engine/quickjs/animator_bridge.cpp",
|
||||
"js_frontend/engine/quickjs/badge_bridge.cpp",
|
||||
"js_frontend/engine/quickjs/canvas_bridge.cpp",
|
||||
"js_frontend/engine/quickjs/chart_bridge.cpp",
|
||||
@ -355,9 +384,46 @@ template("js_engine") {
|
||||
# utils
|
||||
"js_frontend/engine/quickjs/qjs_utils.cpp",
|
||||
]
|
||||
include_dirs = [
|
||||
"//foundation/ace/napi",
|
||||
"//foundation/ace/napi/native_engine/impl/quickjs",
|
||||
"//third_party/libuv/include",
|
||||
"//third_party/quickjs",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
deps += [ "//foundation/ace/napi:ace_napi_quickjs" ]
|
||||
}
|
||||
|
||||
# add ark engine support
|
||||
use_ark_engine = false
|
||||
if (use_ark_engine && !is_standard_system && !build_public_version) {
|
||||
if (target_cpu == "arm64") {
|
||||
defines += [ "APP_USE_ARM64" ]
|
||||
} else if (target_cpu == "arm") {
|
||||
defines += [ "APP_USE_ARM" ]
|
||||
}
|
||||
|
||||
deps += [ "//third_party/jsframework:ark_build" ]
|
||||
|
||||
sources += [
|
||||
"js_frontend/engine/jsi/jsi_animation_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_animator_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_badge_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_canvas_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_chart_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_clock_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_component_api_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_engine.cpp",
|
||||
"js_frontend/engine/jsi/jsi_engine_loader.cpp",
|
||||
"js_frontend/engine/jsi/jsi_group_js_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_image_animator_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_input_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_list_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_stepper_bridge.cpp",
|
||||
"js_frontend/engine/jsi/jsi_utils.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
configs += [ "$ace_root:ace_config" ]
|
||||
|
||||
print("platform: ${platform}")
|
||||
@ -427,7 +493,7 @@ template("gen_obj") {
|
||||
script = "$flutter_root/engine/flutter/sky/tools/objcopy_pc_mac.py"
|
||||
} else if (use_mac) {
|
||||
objcopy_tool = objcopy_clang
|
||||
script = "$flutter_root/engine/flutter/sky/tools/objcopy_pc_mac.py"
|
||||
script = "declarative_frontend/engine/tools/build_resource_to_bytecode.py"
|
||||
} else if (target_cpu == "x86_64") {
|
||||
objcopy_tool = objcopy_x86_64
|
||||
script = "$flutter_root/engine/flutter/sky/tools/objcopy.py"
|
||||
@ -462,9 +528,13 @@ template("gen_obj") {
|
||||
|
||||
base_output_path = get_label_info(":js_proxyclass", "target_out_dir")
|
||||
jsproxyclass_obj_path = base_output_path + "/js_proxy_class.o"
|
||||
base_output_path = get_label_info(":js_enumstyle", "target_out_dir")
|
||||
jsenumstyle_obj_path = base_output_path + "/js_enum_style.o"
|
||||
base_output_path = get_label_info(":js_mocksystemplugin", "target_out_dir")
|
||||
jsmocksystemplugin_obj_path = base_output_path + "/js_mock_system_plugin.o"
|
||||
|
||||
gen_obj("js_proxyclass") {
|
||||
input = "declarative_frontend/engine/jsproxyClass.js"
|
||||
input = "declarative_frontend/engine/stateMgmt.js"
|
||||
if (use_mac) {
|
||||
jsproxyclass_obj_path = base_output_path + "/js_proxy_class.c"
|
||||
}
|
||||
@ -472,6 +542,24 @@ gen_obj("js_proxyclass") {
|
||||
snapshot_dep = []
|
||||
}
|
||||
|
||||
gen_obj("js_enum_style") {
|
||||
input = "declarative_frontend/engine/jsEnumStyle.js"
|
||||
if (use_mac) {
|
||||
jsenumstyle_obj_path = base_output_path + "/js_enum_style.c"
|
||||
}
|
||||
output = jsenumstyle_obj_path
|
||||
snapshot_dep = []
|
||||
}
|
||||
|
||||
gen_obj("js_mock_system_plugin") {
|
||||
input = "declarative_frontend/engine/quickjs/jsMockSystemPlugin.js"
|
||||
if (use_mac) {
|
||||
jsmocksystemplugin_obj_path = base_output_path + "/js_mock_system_plugin.c"
|
||||
}
|
||||
output = jsmocksystemplugin_obj_path
|
||||
snapshot_dep = []
|
||||
}
|
||||
|
||||
# build declarative javascript engine library
|
||||
template("declarative_js_engine") {
|
||||
# get is_ohos_platform, use_quickjs_engine flag.
|
||||
@ -482,33 +570,82 @@ template("declarative_js_engine") {
|
||||
deps = []
|
||||
configs = []
|
||||
is_separated_so = is_ohos_platform && !is_wearable_product
|
||||
|
||||
sources = [
|
||||
"declarative_frontend/engine/declarative_engine_loader.cpp",
|
||||
"declarative_frontend/engine/js_view_listeners.cpp",
|
||||
"declarative_frontend/jsview/js_animation.cpp",
|
||||
"declarative_frontend/engine/functions/js_animator_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_click_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_foreach_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_gesture_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_key_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_page_transition_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_pan_function.cpp",
|
||||
"declarative_frontend/engine/functions/js_touch_function.cpp",
|
||||
"declarative_frontend/engine/js_types.cpp",
|
||||
"declarative_frontend/jsview/js_alert_dialog.cpp",
|
||||
"declarative_frontend/jsview/js_animator.cpp",
|
||||
"declarative_frontend/jsview/js_blank.cpp",
|
||||
"declarative_frontend/jsview/js_button.cpp",
|
||||
"declarative_frontend/jsview/js_calendar.cpp",
|
||||
"declarative_frontend/jsview/js_calendar_controller.cpp",
|
||||
"declarative_frontend/jsview/js_circle.cpp",
|
||||
"declarative_frontend/jsview/js_column.cpp",
|
||||
"declarative_frontend/jsview/js_column_split.cpp",
|
||||
"declarative_frontend/jsview/js_container_base.cpp",
|
||||
"declarative_frontend/jsview/js_customview_base.cpp",
|
||||
"declarative_frontend/jsview/js_counter.cpp",
|
||||
"declarative_frontend/jsview/js_divider.cpp",
|
||||
"declarative_frontend/jsview/js_ellipse.cpp",
|
||||
"declarative_frontend/jsview/js_environment.cpp",
|
||||
"declarative_frontend/jsview/js_flex.cpp",
|
||||
"declarative_frontend/jsview/js_flex_impl.cpp",
|
||||
"declarative_frontend/jsview/js_foreach.cpp",
|
||||
"declarative_frontend/jsview/js_gesture.cpp",
|
||||
"declarative_frontend/jsview/js_grid.cpp",
|
||||
"declarative_frontend/jsview/js_grid_container.cpp",
|
||||
"declarative_frontend/jsview/js_grid_item.cpp",
|
||||
"declarative_frontend/jsview/js_if_else.cpp",
|
||||
"declarative_frontend/jsview/js_image.cpp",
|
||||
"declarative_frontend/jsview/js_image_animator.cpp",
|
||||
"declarative_frontend/jsview/js_interactable_view.cpp",
|
||||
"declarative_frontend/jsview/js_lazy_foreach.cpp",
|
||||
"declarative_frontend/jsview/js_list.cpp",
|
||||
"declarative_frontend/jsview/js_list_item.cpp",
|
||||
"declarative_frontend/jsview/js_navigation_view.cpp",
|
||||
"declarative_frontend/jsview/js_navigator.cpp",
|
||||
"declarative_frontend/jsview/js_page_transition.cpp",
|
||||
"declarative_frontend/jsview/js_path.cpp",
|
||||
"declarative_frontend/jsview/js_persistent.cpp",
|
||||
"declarative_frontend/jsview/js_qrcode.cpp",
|
||||
"declarative_frontend/jsview/js_rect.cpp",
|
||||
"declarative_frontend/jsview/js_row.cpp",
|
||||
"declarative_frontend/jsview/js_row_split.cpp",
|
||||
"declarative_frontend/jsview/js_scroll.cpp",
|
||||
"declarative_frontend/jsview/js_scroller.cpp",
|
||||
"declarative_frontend/jsview/js_shape.cpp",
|
||||
"declarative_frontend/jsview/js_shape_abstract.cpp",
|
||||
"declarative_frontend/jsview/js_sliding_panel.cpp",
|
||||
"declarative_frontend/jsview/js_span.cpp",
|
||||
"declarative_frontend/jsview/js_stack.cpp",
|
||||
"declarative_frontend/jsview/js_swiper.cpp",
|
||||
"declarative_frontend/jsview/js_tab_content.cpp",
|
||||
"declarative_frontend/jsview/js_tabs.cpp",
|
||||
"declarative_frontend/jsview/js_text.cpp",
|
||||
"declarative_frontend/jsview/js_toggle.cpp",
|
||||
"declarative_frontend/jsview/js_touch_handler.cpp",
|
||||
"declarative_frontend/jsview/js_view.cpp",
|
||||
"declarative_frontend/jsview/js_view_abstract.cpp",
|
||||
"declarative_frontend/jsview/js_view_context.cpp",
|
||||
"declarative_frontend/view_stack_processor.cpp",
|
||||
]
|
||||
|
||||
if (!is_wearable_product) {
|
||||
sources += [
|
||||
"declarative_frontend/jsview/js_camera.cpp",
|
||||
"declarative_frontend/jsview/js_video.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
#add quickjs engine support
|
||||
if (use_quickjs_engine) {
|
||||
defines += [ "USE_QUICKJS_ENGINE" ]
|
||||
@ -520,17 +657,17 @@ template("declarative_js_engine") {
|
||||
}
|
||||
|
||||
sources += [
|
||||
"declarative_frontend/engine/quickjs/functions/qjs_click_function.cpp",
|
||||
"declarative_frontend/engine/quickjs/functions/qjs_foreach_function.cpp",
|
||||
"declarative_frontend/engine/quickjs/functions/qjs_function.cpp",
|
||||
"declarative_frontend/engine/quickjs/functions/qjs_touch_function.cpp",
|
||||
"declarative_frontend/engine/quickjs/functions/qjs_view_function.cpp",
|
||||
"declarative_frontend/engine/quickjs/modules/qjs_curves_module.cpp",
|
||||
"declarative_frontend/engine/quickjs/modules/qjs_module_manager.cpp",
|
||||
"declarative_frontend/engine/quickjs/modules/qjs_router_module.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_bindings.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_declarative_engine.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_declarative_engine_instance.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_function_list_entries_container.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_helpers.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_object_template.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_types.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_unwrap_any.cpp",
|
||||
"declarative_frontend/engine/quickjs/qjs_view_register.cpp",
|
||||
]
|
||||
|
||||
@ -560,10 +697,16 @@ template("declarative_js_engine") {
|
||||
]
|
||||
}
|
||||
|
||||
deps += [
|
||||
":gen_obj_src_js_enum_style",
|
||||
":gen_obj_src_js_mock_system_plugin",
|
||||
":gen_obj_src_js_proxyclass",
|
||||
]
|
||||
|
||||
if (use_mingw_win || use_mac) {
|
||||
deps += [
|
||||
":gen_obj_src_js_proxyclass",
|
||||
":intl_qjs_preview",
|
||||
":js_framework_$platform",
|
||||
]
|
||||
|
||||
defines += [ "_USE_MATH_DEFINES" ]
|
||||
@ -573,9 +716,92 @@ template("declarative_js_engine") {
|
||||
}
|
||||
}
|
||||
|
||||
declarative_js_engine("declarative_js_engine_windows") {
|
||||
defines = ace_windows_defines
|
||||
is_ohos_platform = false
|
||||
use_quickjs_engine = true
|
||||
platform = "windows"
|
||||
}
|
||||
|
||||
declarative_js_engine("declarative_js_engine_mac") {
|
||||
defines = ace_mac_defines
|
||||
is_ohos_platform = false
|
||||
use_quickjs_engine = true
|
||||
platform = "mac"
|
||||
}
|
||||
|
||||
declarative_js_engine("declarative_js_engine_qjs_ohos") {
|
||||
defines = ace_ohos_defines
|
||||
is_ohos_platform = true
|
||||
use_quickjs_engine = true
|
||||
platform = "ohos"
|
||||
}
|
||||
|
||||
# build servie backend javascript engine library
|
||||
template("js_backend_engine") {
|
||||
# get is_ohos_platform, use_quickjs_engine flag.
|
||||
forward_variables_from(invoker, "*")
|
||||
|
||||
ohos_source_set(target_name) {
|
||||
defines += invoker.defines
|
||||
deps = []
|
||||
configs = []
|
||||
sources = []
|
||||
|
||||
#add quickjs engine support
|
||||
if (use_quickjs_engine) {
|
||||
deps += [ "//third_party/jsframework:jsf" ]
|
||||
|
||||
if (use_js_debug) {
|
||||
deps += [ "//third_party/quickjs:qjs_debugger" ]
|
||||
defines += [ "ENABLE_JS_DEBUG" ]
|
||||
configs += [ "//third_party/quickjs:qjs_debug_config" ]
|
||||
} else {
|
||||
deps += [ "//third_party/quickjs:qjs" ]
|
||||
}
|
||||
|
||||
sources += [
|
||||
#runtime
|
||||
"pa_backend/engine/quickjs/qjs_pa_engine_loader.cpp",
|
||||
"pa_backend/engine/quickjs/qjs_pa_engine.cpp",
|
||||
|
||||
]
|
||||
deps += [ "//foundation/ace/napi:ace_napi_quickjs" ]
|
||||
}
|
||||
|
||||
configs += [ "$ace_root:ace_config" ]
|
||||
|
||||
print("platform: ${platform}")
|
||||
|
||||
if (is_ohos_platform) {
|
||||
if (!is_wearable_product) {
|
||||
deps += [ "$ace_root/adapter/common/cpp:libace" ]
|
||||
} else {
|
||||
deps += [ ":js_framework_$platform" ]
|
||||
defines += [ "BUILT_IN_JS_ENGINE" ]
|
||||
}
|
||||
deps += [ ":intl_qjs" ]
|
||||
if (is_standard_system) {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (use_mingw_win || use_mac) {
|
||||
deps += [
|
||||
":intl_qjs_preview",
|
||||
":js_framework_$platform",
|
||||
]
|
||||
|
||||
defines += [ "_USE_MATH_DEFINES" ]
|
||||
defines += [ "BUILT_IN_JS_ENGINE" ]
|
||||
cflags = [ "-std=c++17" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
js_backend_engine("js_backend_engine_ohos") {
|
||||
defines = ace_ohos_defines
|
||||
is_ohos_platform = true
|
||||
use_quickjs_engine = true
|
||||
platform = "ohos"
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/log/event_report.h"
|
||||
#include "core/common/thread_checker.h"
|
||||
#include "frameworks/bridge/common/utils/utils.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
@ -29,7 +30,10 @@ const char FILE_TYPE_JSON[] = ".json";
|
||||
|
||||
} // namespace
|
||||
|
||||
CardFrontend::~CardFrontend() = default;
|
||||
CardFrontend::~CardFrontend()
|
||||
{
|
||||
LOG_DESTROY();
|
||||
}
|
||||
|
||||
bool CardFrontend::Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor)
|
||||
{
|
||||
@ -40,8 +44,21 @@ bool CardFrontend::Initialize(FrontendType type, const RefPtr<TaskExecutor>& tas
|
||||
return true;
|
||||
}
|
||||
|
||||
void CardFrontend::Destroy()
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
LOGI("CardFrontend Destroy begin.");
|
||||
parseJsCard_.Reset();
|
||||
delegate_.Reset();
|
||||
eventHandler_.Reset();
|
||||
LOGI("CardFrontend Destroy end.");
|
||||
}
|
||||
|
||||
void CardFrontend::AttachPipelineContext(const RefPtr<PipelineContext>& context)
|
||||
{
|
||||
if (!delegate_) {
|
||||
return;
|
||||
}
|
||||
eventHandler_ = AceType::MakeRefPtr<CardEventHandler>(delegate_);
|
||||
context->RegisterEventHandler(eventHandler_);
|
||||
holder_.Attach(context);
|
||||
@ -108,6 +125,10 @@ const WindowConfig& CardFrontend::GetWindowConfig() const
|
||||
|
||||
void CardFrontend::LoadPage(const std::string& urlPath, const std::string& params)
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
if (!delegate_) {
|
||||
return;
|
||||
}
|
||||
auto page = delegate_->CreatePage(0, urlPath);
|
||||
page->SetPageParams(params);
|
||||
page->SetFlushCallback([weak = WeakClaim(this)](const RefPtr<Framework::JsAcePage>& page) {
|
||||
@ -129,6 +150,7 @@ void CardFrontend::LoadPage(const std::string& urlPath, const std::string& param
|
||||
void CardFrontend::ParsePage(const RefPtr<PipelineContext>& context, const std::string& pageContent,
|
||||
const std::string& params, const RefPtr<Framework::JsAcePage>& page)
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
auto rootBody = Framework::ParseFileData(pageContent);
|
||||
if (!rootBody) {
|
||||
LOGE("parse index json error");
|
||||
@ -154,6 +176,7 @@ void CardFrontend::ParsePage(const RefPtr<PipelineContext>& context, const std::
|
||||
|
||||
void CardFrontend::OnPageLoaded(const RefPtr<Framework::JsAcePage>& page)
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
// Pop all JS command and execute them in UI thread.
|
||||
auto jsCommands = std::make_shared<std::vector<RefPtr<Framework::JsCommand>>>();
|
||||
page->PopAllCommands(*jsCommands);
|
||||
@ -210,7 +233,9 @@ void CardFrontend::OnPageLoaded(const RefPtr<Framework::JsAcePage>& page)
|
||||
if (pipelineContext->CanPushPage()) {
|
||||
pipelineContext->PushPage(page->BuildPage(page->GetUrl()));
|
||||
frontend->pageLoaded_ = true;
|
||||
frontend->delegate_->GetJsAccessibilityManager()->SetRunningPage(page);
|
||||
if (frontend->delegate_) {
|
||||
frontend->delegate_->GetJsAccessibilityManager()->SetRunningPage(page);
|
||||
}
|
||||
}
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
@ -230,6 +255,7 @@ void CardFrontend::UpdateData(const std::string& dataList)
|
||||
|
||||
void CardFrontend::UpdatePageData(const std::string& dataList)
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
if (!delegate_ || !parseJsCard_) {
|
||||
LOGE("the delegate or parseJsCard is null");
|
||||
EventReport::SendFormException(FormExcepType::UPDATE_PAGE_ERR);
|
||||
@ -240,13 +266,22 @@ void CardFrontend::UpdatePageData(const std::string& dataList)
|
||||
|
||||
void CardFrontend::SetColorMode(ColorMode colorMode)
|
||||
{
|
||||
colorMode_ = colorMode;
|
||||
if (!delegate_ || !parseJsCard_) {
|
||||
LOGI("the delegate is null");
|
||||
return;
|
||||
}
|
||||
parseJsCard_->SetColorMode(colorMode);
|
||||
OnMediaFeatureUpdate();
|
||||
taskExecutor_->PostTask(
|
||||
[weak = AceType::WeakClaim(this), colorMode]() {
|
||||
auto frontend = weak.Upgrade();
|
||||
if (frontend) {
|
||||
frontend->colorMode_ = colorMode;
|
||||
if (!frontend->delegate_ || !frontend->parseJsCard_) {
|
||||
LOGI("the delegate is null");
|
||||
return;
|
||||
}
|
||||
frontend->parseJsCard_->SetColorMode(frontend->colorMode_);
|
||||
frontend->OnMediaFeatureUpdate();
|
||||
} else {
|
||||
LOGE("card frontend is nullptr");
|
||||
}
|
||||
},
|
||||
TaskExecutor::TaskType::JS);
|
||||
}
|
||||
|
||||
void CardFrontend::RebuildAllPages()
|
||||
@ -289,6 +324,7 @@ void CardFrontend::OnSurfaceChanged(int32_t width, int32_t height)
|
||||
|
||||
void CardFrontend::HandleSurfaceChanged(int32_t width, int32_t height)
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
if (!parseJsCard_) {
|
||||
LOGE("the parser is null");
|
||||
return;
|
||||
@ -299,6 +335,7 @@ void CardFrontend::HandleSurfaceChanged(int32_t width, int32_t height)
|
||||
|
||||
void CardFrontend::OnMediaFeatureUpdate()
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
if (!delegate_ || !parseJsCard_) {
|
||||
LOGE("the delegate or parser is null");
|
||||
return;
|
||||
|
@ -38,6 +38,9 @@ public:
|
||||
~CardFrontend() override;
|
||||
|
||||
bool Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor) override;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
void AttachPipelineContext(const RefPtr<PipelineContext>& context) override;
|
||||
void SetAssetManager(const RefPtr<AssetManager>& assetManager) override;
|
||||
|
||||
@ -56,6 +59,7 @@ public:
|
||||
void TransferJsPluginGetError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const override {}
|
||||
|
||||
void LoadPluginJsCode(std::string&& jsCode) const override {}
|
||||
void LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) const override {}
|
||||
|
||||
// application lifecycle.
|
||||
void UpdateState(Frontend::State state) override {}
|
||||
@ -74,7 +78,6 @@ public:
|
||||
foregroundFrontend_ = false;
|
||||
}
|
||||
|
||||
// TODO(maxuchu): these life cycle function needs to be completed.
|
||||
void OnActive() override {}
|
||||
void OnInactive() override {}
|
||||
bool OnStartContinuation() override
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/log/event_report.h"
|
||||
#include "core/common/thread_checker.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
|
||||
@ -30,6 +31,12 @@ CardFrontendDelegate::CardFrontendDelegate()
|
||||
#endif
|
||||
}
|
||||
|
||||
CardFrontendDelegate::~CardFrontendDelegate()
|
||||
{
|
||||
CHECK_RUN_ON(JS);
|
||||
LOG_DESTROY();
|
||||
}
|
||||
|
||||
void CardFrontendDelegate::FireCardEvent(const EventMarker& eventMarker, const std::string& params)
|
||||
{
|
||||
if (!page_) {
|
||||
|
@ -32,7 +32,7 @@ class CardFrontendDelegate : public AceType {
|
||||
|
||||
public:
|
||||
CardFrontendDelegate();
|
||||
~CardFrontendDelegate() override = default;
|
||||
~CardFrontendDelegate() override;
|
||||
void FireCardEvent(const EventMarker& eventMarker, const std::string& params = "");
|
||||
RefPtr<JsAcePage>& CreatePage(int32_t pageId, const std::string& url);
|
||||
RefPtr<JsAcePage>& GetPage();
|
||||
|
@ -36,6 +36,39 @@ const std::string REPEAT_ITEM = "$item";
|
||||
const std::string TRUE_STR = "true";
|
||||
const std::string FALSE_STR = "false";
|
||||
|
||||
class VersionData {
|
||||
public:
|
||||
void AddRecord(const std::string& key, const std::string& value)
|
||||
{
|
||||
records_.emplace_back(StringUtils::StringToInt(key), value);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetVersionPatch()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
int32_t sysApiVersion = StringUtils::StringToInt(SystemProperties::GetApiVersion());
|
||||
if (sysApiVersion <= 0) {
|
||||
LOGE("get system api version failed!");
|
||||
return result;
|
||||
}
|
||||
std::sort(records_.begin(), records_.end(),
|
||||
[](const std::pair<uint32_t, std::string>& recordA, const std::pair<uint32_t, std::string>& recordB) {
|
||||
return recordA.first > recordB.first;
|
||||
});
|
||||
for (const auto& record : records_) {
|
||||
if (record.first <= sysApiVersion) {
|
||||
result.emplace_back(record.second);
|
||||
}
|
||||
}
|
||||
// prepare patches in order of api version from smallest to largest.
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<int32_t, std::string>> records_;
|
||||
};
|
||||
|
||||
std::unique_ptr<JsonValue> GetJsonValue(
|
||||
const std::vector<std::string>& keys, const std::unique_ptr<JsonValue>& fileData)
|
||||
{
|
||||
@ -92,7 +125,7 @@ void GetAttrOptionsSeriesPoint(const std::unique_ptr<JsonValue>& jsonPoint, Poin
|
||||
{ "fillColor",
|
||||
[](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
|
||||
const auto& valStr = child->GetString();
|
||||
pointInfo.SetFillColor(Color::FromString(valStr));
|
||||
pointInfo.SetFillColorString(valStr);
|
||||
} },
|
||||
{ "shape",
|
||||
[](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
|
||||
@ -110,7 +143,7 @@ void GetAttrOptionsSeriesPoint(const std::unique_ptr<JsonValue>& jsonPoint, Poin
|
||||
{ "strokeColor",
|
||||
[](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
|
||||
auto valStr = child->GetString();
|
||||
pointInfo.SetStrokeColor(Color::FromString(valStr));
|
||||
pointInfo.SetStrokeColorString(valStr);
|
||||
} },
|
||||
{ "strokeWidth",
|
||||
[](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
|
||||
@ -277,7 +310,7 @@ void GetAttrOptions(const std::unique_ptr<JsonValue>& jsonOption, ChartOptions&
|
||||
}
|
||||
}
|
||||
|
||||
void ParseLineDash(const std::string val, SegmentInfo& segmentInfo)
|
||||
void ParseLineDash(const std::string& val, SegmentInfo& segmentInfo)
|
||||
{
|
||||
std::vector<std::string> dash;
|
||||
StringUtils::StringSpliter(val, ',', dash);
|
||||
@ -292,7 +325,7 @@ void ParseLineDash(const std::string val, SegmentInfo& segmentInfo)
|
||||
}
|
||||
}
|
||||
|
||||
void ParseTextPlacement(const std::string val, TextInfo& textInfo)
|
||||
void ParseTextPlacement(const std::string& val, TextInfo& textInfo)
|
||||
{
|
||||
if (val == "top") {
|
||||
textInfo.SetPlacement(Placement::TOP);
|
||||
@ -328,9 +361,9 @@ void GetAttrDataSetData(const std::unique_ptr<JsonValue>& jsonData, MainChart& d
|
||||
} else if (key == "lineDash") {
|
||||
ParseLineDash(val, segmentInfo);
|
||||
} else if (key == "lineColor") {
|
||||
segmentInfo.SetSegmentColor(Color::FromString(val));
|
||||
segmentInfo.SetColorString(val);
|
||||
} else if (key == "textColor") {
|
||||
textInfo.SetColor(Color::FromString(val));
|
||||
textInfo.SetColorString(val);
|
||||
} else if (key == "value" && data->IsNumber()) {
|
||||
pointInfo.SetX(static_cast<double>(i));
|
||||
pointInfo.SetY(data->GetDouble());
|
||||
@ -509,6 +542,53 @@ bool IsVariable(const std::string& value)
|
||||
return StartWith(value, "{{") && EndWith(value, "}}");
|
||||
}
|
||||
|
||||
bool IsJsonObject(const std::string& value)
|
||||
{
|
||||
if (!StartWith(value, "{") || !EndWith(value, "}")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsVariable(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsJsonArray(const std::string& value)
|
||||
{
|
||||
return StartWith(value, "[") && EndWith(value, "]");
|
||||
}
|
||||
|
||||
std::vector<std::string> GetVecFromArrStr(const std::string& value)
|
||||
{
|
||||
if (value.empty() || value.length() < 2) {
|
||||
return {};
|
||||
}
|
||||
std::string tmp = value.substr(1, value.length() - 2);
|
||||
tmp.erase(std::remove(tmp.begin(), tmp.end(), '"'), tmp.end());
|
||||
tmp.erase(std::remove(tmp.begin(), tmp.end(), ' '), tmp.end());
|
||||
std::regex strDivider(",");
|
||||
std::vector<std::string> strVec(std::sregex_token_iterator(tmp.begin(), tmp.end(), strDivider, -1),
|
||||
std::sregex_token_iterator());
|
||||
return strVec;
|
||||
}
|
||||
|
||||
std::string GetArrStrFromVec(const std::vector<std::string>& vec)
|
||||
{
|
||||
std::string res = "[";
|
||||
for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
|
||||
res += "\"";
|
||||
res += *iter;
|
||||
res += "\",";
|
||||
}
|
||||
if (res.length() > 1) {
|
||||
res = res.substr(0, res.length() - 1);
|
||||
}
|
||||
res += "]";
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IsMultiVariable(const std::string& value)
|
||||
{
|
||||
return StartWith(value, "$f(") && EndWith(value, ")");
|
||||
@ -516,8 +596,28 @@ bool IsMultiVariable(const std::string& value)
|
||||
|
||||
} // namespace
|
||||
|
||||
void JsCardParser::UpdateProps(const std::string& key, std::string value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
if (!propsJson) {
|
||||
return;
|
||||
}
|
||||
auto propsObject = propsJson->GetValue(key);
|
||||
if (!propsObject || !propsObject->IsValid()) {
|
||||
return;
|
||||
}
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value);
|
||||
}
|
||||
if (!propsObject->Contains("value")) {
|
||||
propsObject->Put("value", propsObject->GetValue("default")->ToString().c_str());
|
||||
} else {
|
||||
propsObject->Replace("value", value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseAttributes(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command)
|
||||
std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command,
|
||||
const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
auto attrList = rootJson->GetValue("attr");
|
||||
if (!attrList || !attrList->IsValid()) {
|
||||
@ -570,31 +670,31 @@ void JsCardParser::ParseAttributes(const std::unique_ptr<JsonValue>& rootJson, i
|
||||
continue;
|
||||
}
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value);
|
||||
ParseVariable(value, dataJson, propsJson);
|
||||
} else if (IsMultiVariable(value)) {
|
||||
ParseMultiVariable(value);
|
||||
ParseMultiVariable(value, dataJson, propsJson);
|
||||
}
|
||||
attrs.emplace_back(std::make_pair(key, value));
|
||||
attr = attr->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
bool JsCardParser::GetShownValue(std::string& value)
|
||||
bool JsCardParser::GetShownValue(
|
||||
std::string& value, const std::unique_ptr<JsonValue>& datajson, const std::unique_ptr<JsonValue>& propsjson)
|
||||
{
|
||||
std::vector<std::string> splitResult;
|
||||
StringUtils::SplitStr(value, "&&", splitResult);
|
||||
bool showValue = true;
|
||||
std::vector<std::pair<std::string, bool>> shownVariable;
|
||||
for (const auto& splitStr : splitResult) {
|
||||
if (IsVariable(splitStr)) {
|
||||
auto key = splitStr;
|
||||
ParseVariable(key);
|
||||
showValue &= StringToBool(key);
|
||||
ParseVariable(key, datajson, propsjson);
|
||||
showValue = showValue && StringToBool(key);
|
||||
} else if (StartWith(splitStr, "!{{") && EndWith(splitStr, "}}")) {
|
||||
// !{{value}} --> {{value}}
|
||||
auto key = splitStr.substr(1, splitStr.size() - 1);
|
||||
ParseVariable(key);
|
||||
showValue &= !StringToBool(key);
|
||||
ParseVariable(key, datajson, propsjson);
|
||||
showValue = showValue && !StringToBool(key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -670,6 +770,11 @@ void JsCardParser::ResetRepeatIndexItem()
|
||||
|
||||
void JsCardParser::LoadResImageUrl(const std::string& jsonFile, const std::string& splitStr, std::string& value)
|
||||
{
|
||||
if (!resourceJson_->Contains(jsonFile)) {
|
||||
return;
|
||||
}
|
||||
// Path only print relative path
|
||||
LOGI("load res image file is %{public}s", jsonFile.c_str());
|
||||
auto content = resourceJson_->GetValue(jsonFile);
|
||||
if (!content || !content->IsValid()) {
|
||||
LOGE("LoadResImageUrl failed, content is invalid.");
|
||||
@ -694,7 +799,6 @@ void JsCardParser::GetResImageUrl(std::string& value)
|
||||
value = iter->second;
|
||||
return;
|
||||
}
|
||||
auto assetManager = assetManager_.Upgrade();
|
||||
std::string imagePath;
|
||||
auto jsonFile = std::string(RESOURCES_FOLDER) + "res-" + themeArray[mode] + (themeArray[mode].empty() ? "" : "-") +
|
||||
GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
|
||||
@ -706,6 +810,12 @@ void JsCardParser::GetResImageUrl(std::string& value)
|
||||
LoadResImageUrl(jsonFile, splitStr, imagePath);
|
||||
}
|
||||
|
||||
if (!themeArray[mode].empty() && imagePath.empty()) {
|
||||
jsonFile =
|
||||
std::string(RESOURCES_FOLDER) + "res-" + themeArray[mode] + std::string(FILE_TYPE_JSON);
|
||||
LoadResImageUrl(jsonFile, splitStr, imagePath);
|
||||
}
|
||||
|
||||
if (imagePath.empty()) {
|
||||
jsonFile = std::string(RESOURCES_FOLDER) + std::string(DEFAULTS_RESOURCES_JSON_FILE);
|
||||
LoadResImageUrl(jsonFile, splitStr, imagePath);
|
||||
@ -775,7 +885,7 @@ void JsCardParser::GetPlurals(std::string& value)
|
||||
}
|
||||
|
||||
void JsCardParser::ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& styles)
|
||||
std::vector<std::pair<std::string, std::string>>& styles, const std::unique_ptr<JsonValue>& styleJson)
|
||||
{
|
||||
// parse class style
|
||||
auto classList = rootJson->GetValue("classList");
|
||||
@ -787,7 +897,7 @@ void JsCardParser::ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32
|
||||
ParseVariable(value);
|
||||
}
|
||||
std::string styleClass("." + value);
|
||||
SelectStyle(styleClass, styleJson_, styles);
|
||||
SelectStyle(styleClass, styleJson, styles);
|
||||
SelectMediaQueryStyle(styleClass, styles);
|
||||
styleList = styleList->GetNext();
|
||||
}
|
||||
@ -800,7 +910,7 @@ void JsCardParser::ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32
|
||||
ParseVariable(value);
|
||||
}
|
||||
std::string idStyle("#" + value);
|
||||
SelectStyle(idStyle, styleJson_, styles);
|
||||
SelectStyle(idStyle, styleJson, styles);
|
||||
SelectMediaQueryStyle(idStyle, styles);
|
||||
}
|
||||
|
||||
@ -830,12 +940,12 @@ void JsCardParser::ParseInlineStyles(
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
|
||||
bool JsCardParser::SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
|
||||
std::vector<std::pair<std::string, std::string>>& styles)
|
||||
{
|
||||
auto styleDetail = styleClass->GetValue(className);
|
||||
if (!styleDetail || !styleDetail->IsValid()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
auto style = styleDetail->GetChild();
|
||||
while (style && style->IsValid()) {
|
||||
@ -847,6 +957,7 @@ void JsCardParser::SelectStyle(const std::string& className, const std::unique_p
|
||||
styles.emplace_back(std::make_pair(key, styleValue));
|
||||
style = style->GetNext();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void JsCardParser::SelectMediaQueryStyle(
|
||||
@ -857,7 +968,11 @@ void JsCardParser::SelectMediaQueryStyle(
|
||||
if (mediaQueryer_.MatchCondition(iter.first, mediaFeature)) {
|
||||
auto mediaIter = mediaQueryStyles_.find(iter.first);
|
||||
if (mediaIter != mediaQueryStyles_.end()) {
|
||||
SelectStyle(styleClass, mediaIter->second, styles);
|
||||
if (!SelectStyle(styleClass, mediaIter->second, styles)) {
|
||||
continue;
|
||||
}
|
||||
LOGI("current condition is %{public}s, style class is %{public}s", mediaIter->first.c_str(),
|
||||
styleClass.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -887,21 +1002,47 @@ void JsCardParser::RegisterFont(const std::string& fontFamily)
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseEvents(const std::unique_ptr<JsonValue>& rootJson, std::vector<std::string>& events,
|
||||
const RefPtr<Framework::JsAcePage>& page, int32_t nodeId)
|
||||
void JsCardParser::PreUpdateMethodToAction(const std::unique_ptr<JsonValue>& rootJson)
|
||||
{
|
||||
auto eventList = rootJson->GetValue("events");
|
||||
if (!eventList || !eventList->IsValid()) {
|
||||
return;
|
||||
}
|
||||
auto event = eventList->GetChild();
|
||||
while (event && event->IsValid()) {
|
||||
auto key = event->GetKey();
|
||||
auto value = event->GetString();
|
||||
auto actionJson = eventJson_->GetValue(value);
|
||||
auto eventAction = actionJson->ToString();
|
||||
methodToAction_[key] = eventAction;
|
||||
event = event->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseEvents(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& eventJson,
|
||||
std::vector<std::string>& events, const RefPtr<Framework::JsAcePage>& page, int32_t nodeId)
|
||||
{
|
||||
LOGD("ParseEvents json:%{public}s", eventJson->ToString().c_str());
|
||||
auto eventList = rootJson->GetValue("events");
|
||||
if (!eventList || !eventList->IsValid()) {
|
||||
LOGI("ParseEvents eventList is empty or eventList->IsValid()");
|
||||
return;
|
||||
}
|
||||
auto event = eventList->GetChild();
|
||||
while (event && event->IsValid()) {
|
||||
auto key = event->GetKey();
|
||||
auto value = event->GetString();
|
||||
events.emplace_back(key);
|
||||
auto action = eventJson_->GetValue(value)->ToString();
|
||||
auto eventAction = GetEventAction(action, key, nodeId);
|
||||
page->AddNodeEvent(nodeId, key, eventAction);
|
||||
auto actionJson = eventJson->GetValue(value);
|
||||
auto eventAction = GetEventAction(actionJson->ToString(), key, nodeId);
|
||||
if (actionJson->Contains("action") && actionJson->GetString("action") == "proxy") {
|
||||
auto linkedEventKey = actionJson->GetString("method");
|
||||
eventAction = methodToAction_[linkedEventKey];
|
||||
eventJson_->Put(value.c_str(), JsonUtil::ParseJsonString(eventAction));
|
||||
}
|
||||
if (!key.empty() && !eventAction.empty()) {
|
||||
page->AddNodeEvent(nodeId, key, eventAction);
|
||||
}
|
||||
event = event->GetNext();
|
||||
}
|
||||
}
|
||||
@ -913,36 +1054,36 @@ std::string JsCardParser::GetEventAction(const std::string& action, const std::s
|
||||
LOGE("GetEventAction: action detail is invalid");
|
||||
return "";
|
||||
}
|
||||
auto child = actionDetail->GetChild();
|
||||
ReplaceParam(actionDetail);
|
||||
return actionDetail->ToString();
|
||||
}
|
||||
|
||||
void JsCardParser::ReplaceParam(const std::unique_ptr<JsonValue>& node)
|
||||
{
|
||||
auto child = node->GetChild();
|
||||
while (child && child->IsValid()) {
|
||||
auto key = child->GetKey();
|
||||
auto value = child->IsString() ? child->GetString() : child->ToString();
|
||||
child = child->GetNext();
|
||||
if (key != "params") {
|
||||
auto originValue = value;
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value);
|
||||
actionDetail->Replace(key.c_str(), value.c_str());
|
||||
}
|
||||
} else {
|
||||
auto jsonParamDetail = actionDetail->GetValue("params");
|
||||
if (jsonParamDetail->IsValid()) {
|
||||
auto pChild = jsonParamDetail->GetChild();
|
||||
while (pChild->IsValid()) {
|
||||
auto paramKey = pChild->GetKey();
|
||||
auto paramValue = pChild->IsString() ? pChild->GetString() : child->ToString();
|
||||
pChild = pChild->GetNext();
|
||||
auto originParamValue = paramValue;
|
||||
if (IsVariable(paramValue)) {
|
||||
ParseVariable(paramValue);
|
||||
jsonParamDetail->Replace(paramKey.c_str(), paramValue.c_str());
|
||||
}
|
||||
auto oldChild = std::move(child);
|
||||
child = oldChild->GetNext();
|
||||
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value);
|
||||
node->Replace(key.c_str(), value.c_str());
|
||||
} else if (IsJsonArray(value)) {
|
||||
auto strVec = GetVecFromArrStr(value);
|
||||
for (auto iter = strVec.begin(); iter != strVec.end(); ++iter) {
|
||||
if (IsVariable(*iter)) {
|
||||
ParseVariable(*iter);
|
||||
}
|
||||
}
|
||||
actionDetail->Replace("params", jsonParamDetail);
|
||||
value = GetArrStrFromVec(strVec);
|
||||
node->Replace(key.c_str(), value.c_str());
|
||||
} else if (IsJsonObject(value)) {
|
||||
ReplaceParam(oldChild);
|
||||
node->Replace(key.c_str(), oldChild);
|
||||
}
|
||||
}
|
||||
return actionDetail->ToString();
|
||||
}
|
||||
|
||||
void JsCardParser::LoadMediaQueryStyle()
|
||||
@ -951,19 +1092,29 @@ void JsCardParser::LoadMediaQueryStyle()
|
||||
if (!media || !media->IsValid()) {
|
||||
return;
|
||||
}
|
||||
static const std::string CONDITION_KEY = "condition";
|
||||
auto mediaChild = media->GetChild();
|
||||
while (mediaChild && mediaChild->IsValid()) {
|
||||
auto condition = mediaChild->GetString("condition", "");
|
||||
auto condition = mediaChild->GetString(CONDITION_KEY, "");
|
||||
if (condition.empty()) {
|
||||
mediaChild = mediaChild->GetNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
// record media query style
|
||||
auto mediaQueryStyle = JsonUtil::Create(true);
|
||||
std::unique_ptr<JsonValue> mediaQueryStyle;
|
||||
auto iter = mediaQueryStyles_.find(condition);
|
||||
if (iter != mediaQueryStyles_.end()) {
|
||||
// already exist same media condition
|
||||
mediaQueryStyle = std::move(iter->second);
|
||||
} else {
|
||||
mediaQueryStyle = JsonUtil::Create(true);
|
||||
}
|
||||
auto child = mediaChild->GetChild();
|
||||
while (child && child->IsValid()) {
|
||||
mediaQueryStyle->Put(child->GetKey().c_str(), child);
|
||||
if (child->GetKey() != CONDITION_KEY) {
|
||||
mediaQueryStyle->Put(child->GetKey().c_str(), child);
|
||||
}
|
||||
child = child->GetNext();
|
||||
}
|
||||
|
||||
@ -1033,14 +1184,14 @@ void JsCardParser::UpdateStyle(const RefPtr<JsAcePage>& page)
|
||||
SetUpdateStatus(page);
|
||||
}
|
||||
|
||||
bool JsCardParser::ParseComplexExpression(std::string& value)
|
||||
bool JsCardParser::ParseComplexExpression(std::string& value, const std::unique_ptr<JsonValue>& json)
|
||||
{
|
||||
if (value.find('[') == std::string::npos && value.find('.') == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
std::stack<std::string> keyStack;
|
||||
auto key = value;
|
||||
if (!ParseArrayExpression(key, keyStack) || keyStack.size() != 1) {
|
||||
if (!ParseArrayExpression(key, keyStack, json) || keyStack.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
auto result = keyStack.top();
|
||||
@ -1049,9 +1200,10 @@ bool JsCardParser::ParseComplexExpression(std::string& value)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsCardParser::ParseArrayExpression(const std::string& expression, std::stack<std::string>& keyStack)
|
||||
bool JsCardParser::ParseArrayExpression(
|
||||
const std::string& expression, std::stack<std::string>& keyStack, const std::unique_ptr<JsonValue>& json)
|
||||
{
|
||||
auto dataJson = isRepeat_ ? repeatJson_->ToString() : dataJson_->ToString();
|
||||
auto dataJson = isRepeat_ ? repeatJson_->ToString() : json->ToString();
|
||||
auto dataValue = JsonUtil::ParseJsonString(dataJson);
|
||||
std::string tmpKey;
|
||||
for (char i : expression) {
|
||||
@ -1110,10 +1262,12 @@ bool JsCardParser::ParseArrayExpression(const std::string& expression, std::stac
|
||||
}
|
||||
|
||||
void JsCardParser::UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, const std::vector<int>& idArray)
|
||||
int32_t parentId, const std::vector<int>& idArray, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
LOGD("UpdateDomNode root json: %{public}s", rootJson->ToString().c_str());
|
||||
if (!page || !rootJson->IsValid()) {
|
||||
LOGE("fail to CreateDomNode due to page or root is invalid");
|
||||
LOGE("fail to UpdateDomNode due to page or root is invalid");
|
||||
return;
|
||||
}
|
||||
if (rootJson->Contains("repeat") && !isRepeat_) {
|
||||
@ -1137,23 +1291,45 @@ void JsCardParser::UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const
|
||||
}
|
||||
bool shouldShow = true;
|
||||
bool hasShownAttr = false;
|
||||
GetShownAttr(rootJson, shouldShow, hasShownAttr);
|
||||
|
||||
GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
|
||||
type = rootJson->GetValue("type")->GetString();
|
||||
if (rootBody_->Contains(type)) {
|
||||
// if rootBody contains this type, it must be a customer component.
|
||||
auto customJson = rootBody_->GetValue(type);
|
||||
auto customJsonTemplate = customJson->GetValue("template");
|
||||
auto customJsonData = customJson->GetValue("data");
|
||||
auto customJsonProps = customJson->GetValue("props");
|
||||
auto customJsonStyle = customJson->GetValue("styles");
|
||||
auto attrList = rootJson->GetValue("attr");
|
||||
if (!attrList || !attrList->IsValid()) {
|
||||
return;
|
||||
}
|
||||
auto attr = attrList->GetChild();
|
||||
while (attr && attr->IsValid()) {
|
||||
auto key = attr->GetKey();
|
||||
auto value = attr->IsString() ? attr->GetString() : attr->ToString();
|
||||
UpdateProps(key, value, customJsonProps);
|
||||
attr = attr->GetNext();
|
||||
}
|
||||
ParseStyles(rootJson, selfId, customStyles_, styleJson);
|
||||
UpdateDomNode(page, customJsonTemplate, parentId, idArray, customJsonData, customJsonStyle, customJsonProps);
|
||||
return;
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> attrs;
|
||||
std::vector<std::pair<std::string, std::string>> styles;
|
||||
std::vector<std::pair<std::string, std::string>> styles(customStyles_);
|
||||
customStyles_.clear();
|
||||
std::vector<std::string> events;
|
||||
|
||||
auto styleCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementStyles>(selfId);
|
||||
auto attrCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementAttrs>(selfId);
|
||||
auto ptr = Referenced::RawPtr(attrCommand);
|
||||
if (shouldShow && hasShownAttr) {
|
||||
attrs.emplace_back(std::make_pair("show", TRUE_STR));
|
||||
}
|
||||
ParseAttributes(rootJson, selfId, attrs, (JsCommandDomElementOperator*)ptr);
|
||||
ParseAttributes(rootJson, selfId, attrs, (JsCommandDomElementOperator*)ptr, dataJson, propsJson);
|
||||
if (!shouldShow && hasShownAttr) {
|
||||
attrs.emplace_back(std::make_pair("show", FALSE_STR));
|
||||
}
|
||||
ParseStyles(rootJson, selfId, styles);
|
||||
ParseStyles(rootJson, selfId, styles, styleJson);
|
||||
ParseEvents(rootJson, events, page, selfId);
|
||||
attrCommand->SetAttributes(std::move(attrs));
|
||||
styleCommand->SetStyles(std::move(styles));
|
||||
@ -1164,42 +1340,59 @@ void JsCardParser::UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const
|
||||
if (childList && childList->IsValid()) {
|
||||
auto child = childList->GetChild();
|
||||
while (child && child->IsValid()) {
|
||||
UpdateDomNode(page, child, selfId, idArray);
|
||||
UpdateDomNode(page, child, selfId, idArray, dataJson, styleJson, propsJson);
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseVariable(std::string& value)
|
||||
void JsCardParser::ParseVariable(
|
||||
std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
// {{value}} --> value
|
||||
auto variable = value.substr(2, value.size() - 4);
|
||||
if (ParseComplexExpression(variable) || GetVariable(variable) || ParseSpecialVariable(variable) ||
|
||||
ParseTernaryExpression(variable) || ParseLogicalExpression(variable)) {
|
||||
if (GetAndParseProps(variable, propsJson) || ParseComplexExpression(variable, dataJson) ||
|
||||
GetVariable(variable, dataJson) || ParseSpecialVariable(variable) ||
|
||||
ParseTernaryExpression(variable, propsJson) || ParseLogicalExpression(variable, propsJson)) {
|
||||
value = variable;
|
||||
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value, dataJson, propsJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseMultiVariable(std::string& value)
|
||||
void JsCardParser::ParseMultiVariable(
|
||||
std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
if (value.size() < 4) {
|
||||
return;
|
||||
}
|
||||
// $f({{key1}} {{key2}}) --> {{key1}} {{key2}}
|
||||
auto variable = value.substr(3, value.size() - 4);
|
||||
std::vector<std::string> splitStr;
|
||||
StringUtils::SplitStr(variable, ".", splitStr);
|
||||
std::string resultStr;
|
||||
for (auto& split : splitStr) {
|
||||
if (IsVariable(split)) {
|
||||
ParseVariable(split);
|
||||
|
||||
value = "";
|
||||
// Splicing Between Variables and constants,like variable = "my name is {{name}}, and i am from {{city}}."
|
||||
while (variable.find("{{") != std::string::npos && variable.find("}}") != std::string::npos) {
|
||||
int32_t startPos = variable.find("{{");
|
||||
int32_t endPos = variable.find("}}");
|
||||
if (endPos < startPos) {
|
||||
break;
|
||||
}
|
||||
resultStr += (split + '.');
|
||||
// var = {{name}}, after parsing, var = "tom".
|
||||
std::string var = variable.substr(startPos, endPos - startPos + 2);
|
||||
ParseVariable(var, dataJson, propsJson);
|
||||
|
||||
// after parsing, value = "my name is tom".
|
||||
value += variable.substr(0, startPos) + var;
|
||||
|
||||
// variable = ", and i am from {{city}}."
|
||||
variable = variable.substr(endPos + 2, variable.size() - endPos - 2);
|
||||
}
|
||||
value = resultStr.substr(0, resultStr.size() - 1);
|
||||
value += variable;
|
||||
}
|
||||
|
||||
bool JsCardParser::ParseTernaryExpression(std::string& value)
|
||||
bool JsCardParser::ParseTernaryExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
if (value.find('?') == std::string::npos || value.find(':') == std::string::npos) {
|
||||
return false;
|
||||
@ -1210,14 +1403,25 @@ bool JsCardParser::ParseTernaryExpression(std::string& value)
|
||||
if (flagStr.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
GetVariable(flagStr[0]);
|
||||
auto flag = flagStr[0] == TRUE_STR;
|
||||
bool flag = false;
|
||||
if (GetAndParseProps(flagStr[0], propsJson) || GetVariable(flagStr[0])) {
|
||||
flag = flagStr[0] == TRUE_STR;
|
||||
}
|
||||
|
||||
std::vector<std::string> keyStr;
|
||||
StringUtils::SplitStr(flagStr[1], ":", keyStr);
|
||||
if (keyStr.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
for (auto& key : keyStr) {
|
||||
if (StartWith(key, "\'") && EndWith(key, "\'")) {
|
||||
key = key.substr(1, key.size() - 2);
|
||||
}
|
||||
if (StartWith(key, "\"") && EndWith(key, "\"")) {
|
||||
key = key.substr(1, key.size() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// parse key1 and key2.
|
||||
GetVariable(keyStr[0]);
|
||||
GetVariable(keyStr[1]);
|
||||
@ -1225,7 +1429,7 @@ bool JsCardParser::ParseTernaryExpression(std::string& value)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsCardParser::ParseLogicalExpression(std::string& value)
|
||||
bool JsCardParser::ParseLogicalExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
std::vector<std::string> splitStr;
|
||||
if (value.find("&&") != std::string::npos) {
|
||||
@ -1234,28 +1438,103 @@ bool JsCardParser::ParseLogicalExpression(std::string& value)
|
||||
if (splitStr.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
GetVariable(splitStr[0]);
|
||||
GetVariable(splitStr[1]);
|
||||
value = (splitStr[0] == TRUE_STR && splitStr[1] == TRUE_STR) ? TRUE_STR : FALSE_STR;
|
||||
return true;
|
||||
if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
|
||||
(GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
|
||||
value = (splitStr[0] == TRUE_STR && splitStr[1] == TRUE_STR) ? TRUE_STR : FALSE_STR;
|
||||
return true;
|
||||
}
|
||||
} else if (value.find("||") != std::string::npos) {
|
||||
// for {{flag1 || flag2}}.
|
||||
StringUtils::SplitStr(value, "||", splitStr);
|
||||
if (splitStr.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
GetVariable(splitStr[0]);
|
||||
GetVariable(splitStr[1]);
|
||||
value = (splitStr[0] == TRUE_STR || splitStr[1] == TRUE_STR) ? TRUE_STR : FALSE_STR;
|
||||
return true;
|
||||
if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
|
||||
(GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
|
||||
value = (splitStr[0] == TRUE_STR || splitStr[1] == TRUE_STR) ? TRUE_STR : FALSE_STR;
|
||||
return true;
|
||||
}
|
||||
} else if (value.find('!') != std::string::npos) {
|
||||
// for {{!flag1}}.
|
||||
StringUtils::SplitStr(value, "!", splitStr);
|
||||
if (splitStr.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
GetVariable(splitStr[0]);
|
||||
value = splitStr[0] == TRUE_STR ? FALSE_STR : TRUE_STR;
|
||||
if (GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) {
|
||||
value = splitStr[0] == TRUE_STR ? FALSE_STR : TRUE_STR;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsCardParser::GetAndParseProps(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
if (!propsJson) {
|
||||
return false;
|
||||
}
|
||||
if (ParsePropsArray(value, propsJson) || ParsePropsVariable(value, propsJson)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsCardParser::ParsePropsVariable(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
auto propsObject = propsJson->GetValue(value);
|
||||
if (!propsObject || !propsObject->IsValid()) {
|
||||
LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
|
||||
return false;
|
||||
}
|
||||
auto propValueJson = propsObject->GetValue("value");
|
||||
auto defaultJson = propsObject->GetValue("default");
|
||||
if (propValueJson && propValueJson->IsValid()) {
|
||||
value = propValueJson->IsString() ? propValueJson->GetString() : propValueJson->ToString();
|
||||
} else {
|
||||
// no need to check valid, the json will recover from error state
|
||||
value = defaultJson->IsString() ? defaultJson->GetString() : defaultJson->ToString();
|
||||
}
|
||||
// after user use current value in json, need to reset back to default
|
||||
|
||||
propsObject->Replace(
|
||||
"value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetArrayItemSubstring(const std::string& s)
|
||||
{
|
||||
std::string result;
|
||||
auto endIndex = s.find("[");
|
||||
if (endIndex != std::string::npos) {
|
||||
result = s.substr(0, endIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JsCardParser::ParsePropsArray(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
|
||||
{
|
||||
const auto arrayParam = GetArrayItemSubstring(value);
|
||||
if (arrayParam.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto propsObject = propsJson->GetValue(arrayParam);
|
||||
if (!propsObject || !propsObject->IsValid()) {
|
||||
LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
|
||||
return false;
|
||||
}
|
||||
auto propValueJson = propsObject->GetValue("value");
|
||||
auto defaultJson = propsObject->GetValue("default");
|
||||
auto arrayPropJson = JsonUtil::Create(true);
|
||||
if (propValueJson && propValueJson->IsValid()) {
|
||||
arrayPropJson->Put(arrayParam.c_str(), propValueJson);
|
||||
} else {
|
||||
arrayPropJson->Put(arrayParam.c_str(), defaultJson);
|
||||
}
|
||||
|
||||
if (ParseComplexExpression(value, arrayPropJson)) {
|
||||
// after user use current value in json, need to reset back to default
|
||||
propsObject->Replace(
|
||||
"value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1277,13 +1556,18 @@ bool JsCardParser::ParseSpecialVariable(std::string& value)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsCardParser::GetVariable(std::string& value)
|
||||
bool JsCardParser::GetVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson)
|
||||
{
|
||||
LOGD("GetVariable value :%{private}s dataJson:%{private}s", value.c_str(), dataJson->ToString().c_str());
|
||||
auto key = value;
|
||||
if (!repeatJson_->Contains(key)) {
|
||||
if (!repeatJson_->Contains(key) && isRepeat_) {
|
||||
return false;
|
||||
}
|
||||
auto dataValue = dataJson_->GetValue(key);
|
||||
|
||||
if (!dataJson) {
|
||||
return false;
|
||||
}
|
||||
auto dataValue = dataJson->GetValue(key);
|
||||
if (isRepeat_) {
|
||||
dataValue = repeatJson_->GetValue(key);
|
||||
}
|
||||
@ -1292,8 +1576,9 @@ bool JsCardParser::GetVariable(std::string& value)
|
||||
}
|
||||
value = dataValue->IsString() ? dataValue->GetString() : dataValue->ToString();
|
||||
if (IsVariable(value)) {
|
||||
ParseVariable(value);
|
||||
ParseVariable(value, dataJson);
|
||||
}
|
||||
LOGD("return value :%{private}s", value.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1351,7 +1636,8 @@ bool JsCardParser::ParsePointOperator(
|
||||
}
|
||||
|
||||
void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, bool isNewNode)
|
||||
int32_t parentId, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& actionJson,
|
||||
const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson, bool isNewNode)
|
||||
{
|
||||
if (!page || !rootJson->IsValid()) {
|
||||
LOGE("fail to CreateDomNode due to page or root is invalid");
|
||||
@ -1379,12 +1665,37 @@ void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const
|
||||
}
|
||||
bool shouldShow = true;
|
||||
bool hasShownAttr = false;
|
||||
GetShownAttr(rootJson, shouldShow, hasShownAttr);
|
||||
|
||||
GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
|
||||
type = rootJson->GetValue("type")->GetString();
|
||||
if (rootBody_->Contains(type)) {
|
||||
// if rootBody contains this type, it must be a customer component.
|
||||
auto customJson = rootBody_->GetValue(type);
|
||||
auto customJsonTemplate = customJson->GetValue("template");
|
||||
auto customJsonData = customJson->GetValue("data");
|
||||
auto customJsonProps = customJson->GetValue("props");
|
||||
auto customJsonActions = customJson->GetValue("actions");
|
||||
auto customJsonStyle = customJson->GetValue("styles");
|
||||
auto attrList = rootJson->GetValue("attr");
|
||||
if (!attrList || !attrList->IsValid()) {
|
||||
return;
|
||||
}
|
||||
auto attr = attrList->GetChild();
|
||||
while (attr && attr->IsValid()) {
|
||||
auto key = attr->GetKey();
|
||||
auto value = attr->IsString() ? attr->GetString() : attr->ToString();
|
||||
UpdateProps(key, value, customJsonProps);
|
||||
attr = attr->GetNext();
|
||||
}
|
||||
ParseStyles(rootJson, nodeId, customStyles_, styleJson);
|
||||
PreUpdateMethodToAction(rootJson);
|
||||
CreateDomNode(page, customJsonTemplate, parentId, customJsonData, customJsonActions, customJsonStyle,
|
||||
customJsonProps, isNewNode);
|
||||
return;
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> attrs;
|
||||
std::vector<std::pair<std::string, std::string>> styles;
|
||||
std::vector<std::pair<std::string, std::string>> styles(customStyles_);
|
||||
customStyles_.clear();
|
||||
std::vector<std::string> events;
|
||||
|
||||
RefPtr<Framework::JsCommandDomElementCreator> command;
|
||||
if (parentId < 0) {
|
||||
command = Referenced::MakeRefPtr<Framework::JsCommandCreateDomBody>(type, nodeId);
|
||||
@ -1396,13 +1707,12 @@ void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const
|
||||
if (shouldShow && hasShownAttr) {
|
||||
attrs.emplace_back(std::make_pair("show", TRUE_STR));
|
||||
}
|
||||
ParseAttributes(rootJson, nodeId, attrs, (Framework::JsCommandDomElementOperator*)ptr);
|
||||
ParseAttributes(rootJson, nodeId, attrs, (Framework::JsCommandDomElementOperator*)ptr, dataJson, propsJson);
|
||||
if (!shouldShow && hasShownAttr) {
|
||||
attrs.emplace_back(std::make_pair("show", FALSE_STR));
|
||||
}
|
||||
LOGD("card nodeId: %d, parentId: %d, type: %s", nodeId, parentId, type.c_str());
|
||||
ParseStyles(rootJson, nodeId, styles);
|
||||
ParseEvents(rootJson, events, page, nodeId);
|
||||
ParseStyles(rootJson, nodeId, styles, styleJson);
|
||||
ParseEvents(rootJson, actionJson, events, page, nodeId);
|
||||
command->SetAttributes(std::move(attrs));
|
||||
command->SetStyles(std::move(styles));
|
||||
command->AddEvents(std::move(events));
|
||||
@ -1412,7 +1722,7 @@ void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const
|
||||
if (childList && childList->IsValid()) {
|
||||
auto child = childList->GetChild();
|
||||
while (child && child->IsValid()) {
|
||||
CreateDomNode(page, child, nodeId, isNewNode);
|
||||
CreateDomNode(page, child, nodeId, dataJson, actionJson, styleJson, propsJson, isNewNode);
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
@ -1466,11 +1776,13 @@ void JsCardParser::GetClockConfig(const std::unique_ptr<JsonValue>& jsonDataSets
|
||||
auto key = data->GetKey();
|
||||
auto valStr = data->IsString() ? data->GetString() : data->ToString();
|
||||
static const LinearMapNode<void (*)(std::string&, ClockConfig&, JsCardParser&)> clockConfigOperators[] = {
|
||||
{ DOM_DIGIT_COLOR, [](std::string& valStr, ClockConfig& clockConfig,
|
||||
JsCardParser& jsCardParser) { clockConfig.digitColor_ = Color::FromString(valStr); } },
|
||||
{ DOM_DIGIT_COLOR,
|
||||
[](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
|
||||
clockConfig.digitColor_ = valStr;
|
||||
} },
|
||||
{ DOM_DIGIT_COLOR_NIGHT,
|
||||
[](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
|
||||
clockConfig.digitColorNight_ = Color::FromString(valStr);
|
||||
clockConfig.digitColorNight_ = valStr;
|
||||
} },
|
||||
{ DOM_DIGIT_RADIUS_RATIO,
|
||||
[](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
|
||||
@ -1614,18 +1926,56 @@ void JsCardParser::SetUpdateStatus(const RefPtr<Framework::JsAcePage>& page)
|
||||
page->FlushCommands();
|
||||
}
|
||||
|
||||
void JsCardParser::GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, bool& shouldShow, bool& hasShownAttr)
|
||||
void JsCardParser::GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson, bool& shouldShow, bool& hasShownAttr)
|
||||
{
|
||||
GetBoolValue(rootJson, "shown", shouldShow, hasShownAttr);
|
||||
GetBoolValue(rootJson, dataJson, propsJson, "shown", shouldShow, hasShownAttr);
|
||||
bool blockValue = false;
|
||||
bool hasBlock = false;
|
||||
GetBoolValue(rootJson, BLOCK_VALUE, blockValue, hasBlock);
|
||||
if (hasBlock) {
|
||||
shouldShow &= blockValue;
|
||||
shouldShow = shouldShow && blockValue;
|
||||
hasShownAttr = true;
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::ParseVersionAndUpdateData()
|
||||
{
|
||||
LOGI("parse version info and update data field");
|
||||
auto versionJson = rootBody_->GetValue("apiVersion");
|
||||
if (!versionJson || !versionJson->IsValid()) {
|
||||
return;
|
||||
}
|
||||
auto child = versionJson->GetChild();
|
||||
VersionData versionData;
|
||||
while (child && child->IsValid()) {
|
||||
if (child->IsObject()) {
|
||||
auto key = child->GetKey();
|
||||
auto value = child->IsString() ? child->GetString() : child->ToString();
|
||||
versionData.AddRecord(key, value);
|
||||
}
|
||||
child = child->GetNext();
|
||||
}
|
||||
auto versionPatch = versionData.GetVersionPatch();
|
||||
for (const auto& patchInfo : versionPatch) {
|
||||
auto patchJson = JsonUtil::ParseJsonString(patchInfo);
|
||||
if (!patchJson || !patchJson->IsValid()) {
|
||||
LOGW("parse version patch failed, patchInfo = %{public}s", patchInfo.c_str());
|
||||
continue;
|
||||
}
|
||||
auto patchItem = patchJson->GetChild();
|
||||
while (patchItem && patchItem->IsValid()) {
|
||||
auto key = patchItem->GetKey();
|
||||
if (dataJson_->Contains(key)) {
|
||||
dataJson_->Replace(key.c_str(), patchItem);
|
||||
} else {
|
||||
dataJson_->Put(key.c_str(), patchItem);
|
||||
}
|
||||
patchItem = patchItem->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JsCardParser::Initialize()
|
||||
{
|
||||
rootJson_ = rootBody_->GetValue("template");
|
||||
@ -1641,6 +1991,8 @@ bool JsCardParser::Initialize()
|
||||
LOGE("the json template is error");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParseVersionAndUpdateData();
|
||||
// repeatJson contains dataJson.
|
||||
repeatJson_ = JsonUtil::ParseJsonString(dataJson_->ToString());
|
||||
LoadMediaQueryStyle();
|
||||
@ -1659,13 +2011,14 @@ void JsCardParser::CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework:
|
||||
bool shouldShow = true;
|
||||
bool hasShownAttr = false;
|
||||
GetBoolValue(rootJson, "shown", shouldShow, hasShownAttr);
|
||||
const char* value = shouldShow ? "true" : "false";
|
||||
if (blockChild && blockChild->IsValid()) {
|
||||
auto child = blockChild->GetChild();
|
||||
while (child && child->IsValid()) {
|
||||
if (child->Contains(BLOCK_VALUE)) {
|
||||
shouldShow ? child->Replace(BLOCK_VALUE, "true") : child->Replace(BLOCK_VALUE, "false");
|
||||
child->Replace(BLOCK_VALUE, value);
|
||||
} else {
|
||||
shouldShow ? child->Put(BLOCK_VALUE, "true") : child->Put(BLOCK_VALUE, "false");
|
||||
child->Put(BLOCK_VALUE, value);
|
||||
}
|
||||
parsingStatus_ == ParsingStatus::UPDATE ? UpdateDomNode(page, child, parentId)
|
||||
: CreateDomNode(page, child, parentId);
|
||||
@ -1674,21 +2027,31 @@ void JsCardParser::CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework:
|
||||
}
|
||||
}
|
||||
|
||||
void JsCardParser::GetBoolValue(
|
||||
const std::unique_ptr<JsonValue>& rootJson, const std::string& key, bool& shouldShow, bool& hasShownAttr)
|
||||
void JsCardParser::GetBoolValue(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson, const std::string& key, bool& value, bool& hasAttr)
|
||||
{
|
||||
auto shown = rootJson->GetValue(key);
|
||||
if (shown && shown->IsValid()) {
|
||||
if (shown->IsString()) {
|
||||
auto shownValue = shown->GetString();
|
||||
GetShownValue(shownValue);
|
||||
shouldShow = shownValue == "true";
|
||||
hasShownAttr = true;
|
||||
} else if (shown->IsBool()) {
|
||||
shouldShow = shown->GetBool();
|
||||
hasShownAttr = true;
|
||||
auto result = rootJson->GetValue(key);
|
||||
if (result && result->IsValid()) {
|
||||
if (result->IsString()) {
|
||||
auto strValue = result->GetString();
|
||||
GetShownValue(strValue, dataJson, propsJson);
|
||||
value = strValue == "true";
|
||||
hasAttr = true;
|
||||
return;
|
||||
} else if (result->IsBool()) {
|
||||
value = result->GetBool();
|
||||
hasAttr = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
hasAttr = false;
|
||||
}
|
||||
|
||||
void JsCardParser::SetColorMode(ColorMode colorMode)
|
||||
{
|
||||
LOGI("current color mode is %{public}d", colorMode);
|
||||
colorMode_ = colorMode;
|
||||
mediaQueryer_.SetColorMode(colorMode);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
|
@ -36,38 +36,65 @@ public:
|
||||
{}
|
||||
~JsCardParser() override = default;
|
||||
|
||||
void CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, bool isNewNode = false)
|
||||
{
|
||||
CreateDomNode(page, rootJson, parentId, dataJson_, eventJson_, styleJson_, nullptr, isNewNode);
|
||||
}
|
||||
void ParseAttributes(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command);
|
||||
bool GetShownValue(std::string& value);
|
||||
std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command)
|
||||
{
|
||||
ParseAttributes(rootJson, nodeId, attrs, command, dataJson_, nullptr);
|
||||
}
|
||||
void ParseEvents(const std::unique_ptr<JsonValue>& rootJson, std::vector<std::string>& events,
|
||||
const RefPtr<JsAcePage>& page, int32_t nodeId)
|
||||
{
|
||||
ParseEvents(rootJson, eventJson_, events, page, nodeId);
|
||||
}
|
||||
void UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, const std::vector<int>& idArray = std::vector<int>())
|
||||
{
|
||||
UpdateDomNode(page, rootJson, parentId, idArray, dataJson_, styleJson_, nullptr);
|
||||
}
|
||||
void ParseVariable(std::string& value)
|
||||
{
|
||||
ParseVariable(value, dataJson_, nullptr);
|
||||
}
|
||||
void ParseMultiVariable(std::string& value)
|
||||
{
|
||||
ParseMultiVariable(value, dataJson_);
|
||||
}
|
||||
void ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& styles)
|
||||
{
|
||||
ParseStyles(rootJson, nodeId, styles, styleJson_);
|
||||
}
|
||||
|
||||
bool GetVariable(std::string& value)
|
||||
{
|
||||
return GetVariable(value, dataJson_);
|
||||
}
|
||||
bool GetShownValue(std::string& value)
|
||||
{
|
||||
return GetShownValue(value, dataJson_, nullptr);
|
||||
}
|
||||
bool GetShownValue(
|
||||
std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson);
|
||||
bool GetRepeatData(std::unique_ptr<JsonValue>& repeatValue, std::string& key);
|
||||
|
||||
void ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& styles);
|
||||
void ParseEvents(const std::unique_ptr<JsonValue>& rootJson, std::vector<std::string>& events,
|
||||
const RefPtr<JsAcePage>& page, int32_t nodeId);
|
||||
void UpdatePageData(const std::string& dataList, const RefPtr<JsAcePage>& page);
|
||||
void LoadImageInfo();
|
||||
void UpdateStyle(const RefPtr<JsAcePage>& page);
|
||||
void CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, bool isNewNode = false);
|
||||
void ParseVariable(std::string& value);
|
||||
void ParseMultiVariable(std::string& value);
|
||||
|
||||
void ParseRepeatIndexItem(const std::unique_ptr<JsonValue>& repeatValue);
|
||||
void SetRepeatItemValue(uint32_t index, const std::unique_ptr<JsonValue>& repeatValue, bool hasKeyValue);
|
||||
bool Initialize();
|
||||
void SetColorMode(ColorMode colorMode);
|
||||
|
||||
const WeakPtr<PipelineContext>& GetPipelineContext() const
|
||||
{
|
||||
return context_;
|
||||
}
|
||||
|
||||
void SetColorMode(ColorMode colorMode)
|
||||
{
|
||||
colorMode_ = colorMode;
|
||||
mediaQueryer_.SetColorMode(colorMode);
|
||||
}
|
||||
|
||||
void SetDensity(double density)
|
||||
{
|
||||
density_ = density;
|
||||
@ -99,21 +126,43 @@ private:
|
||||
void GetPlurals(std::string& value);
|
||||
void ParseInlineStyles(
|
||||
const std::unique_ptr<JsonValue>& rootJson, std::vector<std::pair<std::string, std::string>>& styles);
|
||||
void SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
|
||||
bool SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
|
||||
std::vector<std::pair<std::string, std::string>>& styles);
|
||||
void SelectMediaQueryStyle(const std::string& styleClass, std::vector<std::pair<std::string, std::string>>& styles);
|
||||
void LoadMediaQueryStyle();
|
||||
void LoadResImageUrl(const std::string& jsonFile, const std::string& splitStr, std::string& value);
|
||||
void RegisterFont(const std::string& fontFamily);
|
||||
std::string GetEventAction(const std::string& action, const std::string& actionType, int32_t nodeId);
|
||||
bool ParseComplexExpression(std::string& value);
|
||||
bool ParseTernaryExpression(std::string& value);
|
||||
bool ParseLogicalExpression(std::string& value);
|
||||
bool ParseArrayExpression(const std::string& expression, std::stack<std::string>& keyStack);
|
||||
void UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, const std::vector<int>& idArray = std::vector<int>());
|
||||
std::string GetEventAction(const std::string& action, const std::string& actionType, int32_t nodeId = 0);
|
||||
bool ParsePropsVariable(std::string& value, const std::unique_ptr<JsonValue>& propsJson);
|
||||
bool ParsePropsArray(std::string& value, const std::unique_ptr<JsonValue>& propsJson);
|
||||
bool ParseComplexExpression(std::string& value, const std::unique_ptr<JsonValue>& json);
|
||||
bool ParseTernaryExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson = nullptr);
|
||||
bool ParseLogicalExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson = nullptr);
|
||||
bool ParseArrayExpression(
|
||||
const std::string& expression, std::stack<std::string>& keyStack, const std::unique_ptr<JsonValue>& json);
|
||||
bool ParseSpecialVariable(std::string& value);
|
||||
bool GetVariable(std::string& value);
|
||||
void CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& actionJson,
|
||||
const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson = nullptr,
|
||||
bool isNewNode = false);
|
||||
void PreUpdateMethodToAction(const std::unique_ptr<JsonValue>& rootJson);
|
||||
void ParseAttributes(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command,
|
||||
const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson);
|
||||
void ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
|
||||
std::vector<std::pair<std::string, std::string>>& styles, const std::unique_ptr<JsonValue>& styleJson);
|
||||
void ParseVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson = nullptr);
|
||||
void ParseMultiVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson = nullptr);
|
||||
void UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
int32_t parentId, const std::vector<int>& idArray, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson);
|
||||
void ParseEvents(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& eventJson,
|
||||
std::vector<std::string>& events, const RefPtr<Framework::JsAcePage>& page, int32_t nodeId);
|
||||
void UpdateProps(const std::string& key, std::string value, const std::unique_ptr<JsonValue>& propsJson);
|
||||
bool GetAndParseProps(std::string& value, const std::unique_ptr<JsonValue>& propsJson);
|
||||
bool GetVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson);
|
||||
template<typename T>
|
||||
void ParseSpecialAttr(const std::function<void(const std::unique_ptr<JsonValue>&, std::vector<T>&)>& function,
|
||||
std::string& value, std::vector<T>& vector);
|
||||
@ -126,15 +175,21 @@ private:
|
||||
const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson, int32_t parentId);
|
||||
void GetResourceValue(const std::string& path);
|
||||
void GetClockConfig(const std::unique_ptr<JsonValue>& jsonDataSets, ClockConfig& clockConfig);
|
||||
void ProcessRepeatNode(const RefPtr<Framework::JsAcePage>& page,
|
||||
const std::unique_ptr<JsonValue>& rootJson, const std::string& key, int32_t parentId, bool hasKeyValue,
|
||||
std::unique_ptr<JsonValue>& repeatValue);
|
||||
void ProcessRepeatNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
|
||||
const std::string& key, int32_t parentId, bool hasKeyValue, std::unique_ptr<JsonValue>& repeatValue);
|
||||
void SetUpdateStatus(const RefPtr<Framework::JsAcePage>& page);
|
||||
void GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, bool& shouldShow, bool& hasShownAttr);
|
||||
void GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson, bool& shouldShow, bool& hasShownAttr);
|
||||
void CreateBlockNode(
|
||||
const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson, int32_t parentId);
|
||||
void GetBoolValue(
|
||||
const std::unique_ptr<JsonValue>& rootJson, const std::string& key, bool& shouldShow, bool& hasShownAttr);
|
||||
void GetBoolValue(const std::unique_ptr<JsonValue>& rootJson, const std::string& key, bool& value, bool& hasAttr)
|
||||
{
|
||||
GetBoolValue(rootJson, dataJson_, nullptr, key, value, hasAttr);
|
||||
}
|
||||
void GetBoolValue(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
|
||||
const std::unique_ptr<JsonValue>& propsJson, const std::string& key, bool& value, bool& hasAttr);
|
||||
void ParseVersionAndUpdateData();
|
||||
void ReplaceParam(const std::unique_ptr<JsonValue>& node);
|
||||
|
||||
double density_ = 1.0;
|
||||
int32_t nodeId_ = 0;
|
||||
@ -154,9 +209,11 @@ private:
|
||||
std::unique_ptr<JsonValue> repeatJson_;
|
||||
std::unique_ptr<JsonValue> resourceJson_;
|
||||
std::unordered_map<std::string, std::string> imageUrlMap_;
|
||||
std::unordered_map<std::string, std::string> methodToAction_;
|
||||
std::unordered_map<int32_t, std::pair<std::vector<int32_t>, int32_t>> listIdMap_;
|
||||
std::unordered_map<std::string, int32_t> singleLoopMap_;
|
||||
std::unordered_map<std::string, std::unique_ptr<JsonValue>> mediaQueryStyles_;
|
||||
std::vector<std::pair<std::string, std::string>> customStyles_;
|
||||
MediaQueryer mediaQueryer_;
|
||||
|
||||
// for repeat attr
|
||||
@ -167,4 +224,4 @@ private:
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CARD_FRONTEND_JS_CARD_PARSER_H
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CARD_FRONTEND_JS_CARD_PARSER_H
|
@ -210,6 +210,15 @@ const MediaQueryerRule DEVICE_TYPE_RULE(
|
||||
},
|
||||
2);
|
||||
|
||||
const MediaQueryerRule DEVICE_BRAND_RULE(
|
||||
std::regex("\\(device-brand:([A-Z]+)\\)"),
|
||||
[](const std::smatch& matchResults, const MediaFeature& mediaFeature, MediaError& failReason) {
|
||||
static constexpr int32_t CONDITION_VALUE = 1;
|
||||
auto value = matchResults[CONDITION_VALUE] == mediaFeature->GetString("device-brand", "");
|
||||
return value;
|
||||
},
|
||||
2);
|
||||
|
||||
const MediaQueryerRule DARK_MODE_RULE(
|
||||
std::regex("\\(dark-mode:([a-z]+)\\)"),
|
||||
[](const std::smatch& matchResults, const MediaFeature& mediaFeature, MediaError& failReason) {
|
||||
@ -225,6 +234,7 @@ const std::list<MediaQueryerRule> SINGLE_CONDITION_RULES = {
|
||||
CSS_LEVEL3_RULE,
|
||||
ORIENTATION_RULE,
|
||||
DEVICE_TYPE_RULE,
|
||||
DEVICE_BRAND_RULE,
|
||||
SCREEN_SHAPE_RULE,
|
||||
DARK_MODE_RULE,
|
||||
|
||||
@ -232,7 +242,6 @@ const std::list<MediaQueryerRule> SINGLE_CONDITION_RULES = {
|
||||
|
||||
bool ParseSingleCondition(const std::string& condition, const MediaFeature& mediaFeature, MediaError& failReason)
|
||||
{
|
||||
std::smatch result;
|
||||
for (const auto& rule : SINGLE_CONDITION_RULES) {
|
||||
std::smatch matchResults;
|
||||
if (rule.Match(condition, matchResults)) {
|
||||
@ -350,11 +359,13 @@ std::unique_ptr<JsonValue> MediaQueryer::GetMediaFeature() const
|
||||
json->Put("aspect-ratio", aspectRatio);
|
||||
json->Put("round-screen", SystemProperties::GetIsScreenRound());
|
||||
json->Put("device-width", SystemProperties::GetDeviceWidth());
|
||||
json->Put("device-brand", SystemProperties::GetBrand().c_str());
|
||||
json->Put("device-height", SystemProperties::GetDeviceHeight());
|
||||
json->Put("resolution", SystemProperties::GetResolution());
|
||||
json->Put("orientation", mediaQueryInfo.GetOrientation().c_str());
|
||||
json->Put("device-type", mediaQueryInfo.GetDeviceType().c_str());
|
||||
json->Put("dark-mode", colorMode_ == ColorMode::DARK ? true : false);
|
||||
json->Put("dark-mode", colorMode_ == ColorMode::DARK);
|
||||
LOGD("current media info %{public}s", json->ToString().c_str());
|
||||
return json;
|
||||
}
|
||||
|
||||
|
@ -208,6 +208,14 @@ void UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode>& node, Accessib
|
||||
nodeInfo.height = node->GetHeight();
|
||||
}
|
||||
|
||||
auto scaleX = manager->GetScaleX();
|
||||
auto scaleY = manager->GetScaleY();
|
||||
|
||||
nodeInfo.top *= scaleY;
|
||||
nodeInfo.left *= scaleX;
|
||||
nodeInfo.width *= scaleX;
|
||||
nodeInfo.height *= scaleY;
|
||||
|
||||
nodeInfo.isChecked = node->GetCheckedState();
|
||||
nodeInfo.isEnabled = node->GetEnabledState();
|
||||
nodeInfo.isFocused = node->GetFocusedState();
|
||||
@ -271,6 +279,7 @@ void UpdateAccessibilityNodeInfo(const RefPtr<AccessibilityNode>& node, Accessib
|
||||
}
|
||||
|
||||
nodeInfo.supportAction = std::move(actions);
|
||||
|
||||
#ifdef ACE_DEBUG
|
||||
std::string actionForLog;
|
||||
for (const auto& action : supportAceActions) {
|
||||
@ -416,11 +425,27 @@ void JsAccessibilityManager::InitializeCallback()
|
||||
LOGW("AccessibilityNodeInfo can't attach component by Id = %{public}d", nodeInfo.ID);
|
||||
return false;
|
||||
}
|
||||
jsAccessibilityManager->UpdateNodeChildIds(node);
|
||||
UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager);
|
||||
|
||||
if (nodeInfo.ID == 0) {
|
||||
jsAccessibilityManager->UpdateViewScale();
|
||||
}
|
||||
auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
|
||||
if (!context) {
|
||||
return false;
|
||||
}
|
||||
context->GetTaskExecutor()->PostSyncTask(
|
||||
[&jsAccessibilityManager, &node, &nodeInfo]() {
|
||||
jsAccessibilityManager->UpdateNodeChildIds(node);
|
||||
UpdateAccessibilityNodeInfo(node, nodeInfo, jsAccessibilityManager);
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
return true;
|
||||
};
|
||||
AccessibilityAbilityClient::GetInstance().RegisterFetchNodeInfoCallback(fetchNodeInfoCallback);
|
||||
if (callbackKey_.empty()) {
|
||||
AccessibilityAbilityClient::GetInstance().RegisterFetchNodeInfoCallback(fetchNodeInfoCallback);
|
||||
} else {
|
||||
AccessibilityAbilityClient::GetInstance().RegisterFetchNodeInfoCallback(fetchNodeInfoCallback, callbackKey_);
|
||||
}
|
||||
|
||||
auto eventHandleCallback = [weak = WeakClaim(this)](AccessibilityActionInfo& actionInfo) {
|
||||
LOGD("AccessibilityActionInfo nodeId= %{public}d, action=%{public}d", actionInfo.ID, actionInfo.action);
|
||||
@ -451,7 +476,11 @@ void JsAccessibilityManager::InitializeCallback()
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
AccessibilityAbilityClient::GetInstance().RegisterEventHandleCallback(eventHandleCallback);
|
||||
if (callbackKey_.empty()) {
|
||||
AccessibilityAbilityClient::GetInstance().RegisterEventHandleCallback(eventHandleCallback);
|
||||
} else {
|
||||
AccessibilityAbilityClient::GetInstance().RegisterEventHandleCallback(eventHandleCallback, callbackKey_);
|
||||
}
|
||||
}
|
||||
|
||||
void JsAccessibilityManager::SendAccessibilitySyncEvent(const AccessibilityEvent& accessibilityEvent)
|
||||
@ -566,9 +595,10 @@ void JsAccessibilityManager::DumpHandleEvent(const std::vector<std::string>& par
|
||||
}
|
||||
auto context = GetPipelineContext().Upgrade();
|
||||
if (context) {
|
||||
context->GetTaskExecutor()->PostTask(
|
||||
[actionInfo, node, context]() { AccessibilityActionEvent(actionInfo, node, context); },
|
||||
TaskExecutor::TaskType::UI);
|
||||
auto weakContext = AceType::WeakClaim(AceType::RawPtr(context));
|
||||
context->GetTaskExecutor()->PostTask([actionInfo, node, weakContext]() {
|
||||
AccessibilityActionEvent(actionInfo, node, weakContext.Upgrade());
|
||||
}, TaskExecutor::TaskType::UI);
|
||||
}
|
||||
}
|
||||
|
||||
@ -687,4 +717,18 @@ void JsAccessibilityManager::SetCardViewParams(const std::string& key, bool focu
|
||||
}
|
||||
}
|
||||
|
||||
void JsAccessibilityManager::UpdateViewScale()
|
||||
{
|
||||
auto context = GetPipelineContext().Upgrade();
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
float scaleX = 1.0;
|
||||
float scaleY = 1.0;
|
||||
if (context->GetViewScale(scaleX, scaleY)) {
|
||||
scaleX_ = scaleX;
|
||||
scaleY_ = scaleY;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
|
@ -41,11 +41,25 @@ public:
|
||||
void DumpTree(int32_t depth, NodeId nodeID) override;
|
||||
void SetCardViewParams(const std::string& key, bool focus) override;
|
||||
|
||||
void UpdateViewScale();
|
||||
|
||||
float GetScaleX() const
|
||||
{
|
||||
return scaleX_;
|
||||
}
|
||||
|
||||
float GetScaleY() const
|
||||
{
|
||||
return scaleY_;
|
||||
}
|
||||
|
||||
private:
|
||||
void UpdateNodeChildIds(const RefPtr<AccessibilityNode>& node);
|
||||
void SendAccessibilitySyncEvent(const AccessibilityEvent& accessibilityEvent);
|
||||
|
||||
std::string callbackKey_;
|
||||
float scaleX_ = 1.0f;
|
||||
float scaleY_ = 1.0f;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "frameworks/bridge/common/dom/dom_badge.h"
|
||||
|
||||
#include "base/log/event_report.h"
|
||||
#include "core/components/declaration/badge/badge_declaration.h"
|
||||
#include "frameworks/bridge/common/utils/utils.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
@ -23,89 +24,29 @@ namespace OHOS::Ace::Framework {
|
||||
DOMBadge::DOMBadge(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
|
||||
{
|
||||
badgeChild_ = AceType::MakeRefPtr<BadgeComponent>();
|
||||
if (IsRightToLeft()) {
|
||||
badgeChild_->SetTextDirection(TextDirection::RTL);
|
||||
}
|
||||
}
|
||||
|
||||
void DOMBadge::ResetInitializedStyle()
|
||||
{
|
||||
InitializeStyle();
|
||||
}
|
||||
|
||||
bool DOMBadge::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
|
||||
{
|
||||
static const LinearMapNode<void (*)(DOMBadge&, const std::string&)> badgeAttrOperators[] = {
|
||||
{ DOM_BADGE_COUNT,
|
||||
[](DOMBadge& badge, const std::string& value) { badge.badgeChild_->SetMessageCount(StringToInt(value)); } },
|
||||
{ DOM_BADGE_LABEL,
|
||||
[](DOMBadge& badge, const std::string& value) { badge.badgeChild_->SetBadgeLabel(value); } },
|
||||
{ DOM_BADGE_MAX_COUNT,
|
||||
[](DOMBadge& badge, const std::string& value) { badge.badgeChild_->SetMaxCount(StringToInt(value)); } },
|
||||
{ DOM_BADGE_PLACEMENT,
|
||||
[](DOMBadge& badge, const std::string& value) {
|
||||
badge.badgeChild_->SetBadgePosition(ConvertStrToBadgePosition(value));
|
||||
} },
|
||||
{ DOM_BADGE_VISIBLE,
|
||||
[](DOMBadge& badge, const std::string& value) { badge.badgeChild_->SetShowMessage(StringToBool(value)); } }
|
||||
};
|
||||
auto operatorIter = BinarySearchFindIndex(badgeAttrOperators, ArraySize(badgeAttrOperators), attr.first.c_str());
|
||||
if (operatorIter != -1) {
|
||||
badgeAttrOperators[operatorIter].value(*this, attr.second);
|
||||
return true;
|
||||
if (declaration_) {
|
||||
declaration_->InitializeStyle();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DOMBadge::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
|
||||
{
|
||||
const static LinearMapNode<void (*)(DOMBadge&, const std::string&)> badgeOperators[] = {
|
||||
{ DOM_BADGE_COLOR,
|
||||
[](DOMBadge& badge, const std::string& value) {
|
||||
badge.badgeChild_->SetBadgeColor(badge.ParseColor(value));
|
||||
} },
|
||||
{ DOM_BADGE_CIRCLE_SIZE,
|
||||
[](DOMBadge& badge, const std::string& value) {
|
||||
badge.badgeChild_->SetBadgeCircleSize(badge.ParseDimension(value));
|
||||
} },
|
||||
{ DOM_BADGE_TEXT_FONT_SIZE,
|
||||
[](DOMBadge& badge, const std::string& value) {
|
||||
badge.badgeChild_->SetBadgeFontSize(badge.ParseDimension(value));
|
||||
} },
|
||||
{ DOM_BADGE_TEXT_COLOR,
|
||||
[](DOMBadge& badge, const std::string& value) {
|
||||
badge.badgeChild_->SetBadgeTextColor(badge.ParseColor(value));
|
||||
} },
|
||||
};
|
||||
auto operatorIter = BinarySearchFindIndex(badgeOperators, ArraySize(badgeOperators), style.first.c_str());
|
||||
if (operatorIter != -1) {
|
||||
badgeOperators[operatorIter].value(*this, style.second);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DOMBadge::AddSpecializedEvent(int32_t pageId, const std::string& event)
|
||||
{
|
||||
if (event == DOM_CLICK) {
|
||||
badgeClickEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
|
||||
badgeChild_->SetClickEvent(badgeClickEvent_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DOMBadge::PrepareSpecializedComponent()
|
||||
{
|
||||
if (!boxComponent_) {
|
||||
auto declaration = AceType::DynamicCast<BadgeDeclaration>(declaration_);
|
||||
badgeChild_->SetDeclaration(AceType::DynamicCast<BadgeDeclaration>(declaration));
|
||||
if (!boxComponent_ || !declaration) {
|
||||
return;
|
||||
}
|
||||
badgeChild_->SetTextDirection(declaration->IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
|
||||
boxComponent_->SetAlignment(Alignment::TOP_LEFT);
|
||||
auto edge = boxComponent_->GetPadding();
|
||||
if (edge == Edge::NONE) {
|
||||
return;
|
||||
}
|
||||
badgeChild_->SetPadding(edge);
|
||||
declaration->SetPadding(edge);
|
||||
boxComponent_->SetPadding(Edge());
|
||||
}
|
||||
|
||||
@ -123,35 +64,24 @@ void DOMBadge::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
|
||||
badgeChild_->SetChild(nullptr);
|
||||
}
|
||||
|
||||
void DOMBadge::InitializeStyle()
|
||||
{
|
||||
badgeTheme_ = GetTheme<BadgeTheme>();
|
||||
if (!badgeTheme_) {
|
||||
LOGE("badgeTheme is null");
|
||||
EventReport::SendComponentException(ComponentExcepType::GET_THEME_ERR);
|
||||
return;
|
||||
}
|
||||
badgeChild_->SetBadgeColor(badgeTheme_->GetBadgeColor());
|
||||
badgeChild_->SetMessageCount(badgeTheme_->GetMessageCount());
|
||||
badgeChild_->SetBadgePosition(badgeTheme_->GetBadgePosition());
|
||||
badgeChild_->SetShowMessage(badgeTheme_->GetShowMessage());
|
||||
badgeChild_->SetBadgeTextColor(badgeTheme_->GetBadgeTextColor());
|
||||
badgeChild_->SetBadgeFontSize(badgeTheme_->GetBadgeFontSize());
|
||||
}
|
||||
|
||||
void DOMBadge::SetBadgeConfig(const BadgeConfig& badgeConfig)
|
||||
{
|
||||
auto declaration = AceType::DynamicCast<BadgeDeclaration>(declaration_);
|
||||
if (!declaration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (badgeConfig.badgeColor.second) {
|
||||
badgeChild_->SetBadgeColor(badgeConfig.badgeColor.first);
|
||||
declaration->SetBadgeColor(badgeConfig.badgeColor.first);
|
||||
}
|
||||
if (badgeConfig.badgeSize.second) {
|
||||
badgeChild_->SetBadgeCircleSize(badgeConfig.badgeSize.first);
|
||||
declaration->SetBadgeCircleSize(badgeConfig.badgeSize.first);
|
||||
}
|
||||
if (badgeConfig.textColor.second) {
|
||||
badgeChild_->SetBadgeTextColor(badgeConfig.textColor.first);
|
||||
declaration->SetBadgeTextColor(badgeConfig.textColor.first);
|
||||
}
|
||||
if (badgeConfig.textSize.second) {
|
||||
badgeChild_->SetBadgeFontSize(badgeConfig.textSize.first);
|
||||
declaration->SetBadgeFontSize(badgeConfig.textSize.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user