* 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 "interfaces/inner_api/ace/ui_content.h"
#include <string>
#include "arkui_log.h"
#include "constants.h"
#include "utils.h"
#include "ace_forward_compatibility.h"
#ifdef UICAST_COMPONENT_SUPPORTED
#include "interfaces/inner_api/ace/uicast/uicast_subscriber.h"
#endif
namespace OHOS::Ace {
using CreateCardFunc = UIContent* (*)(void*, void*, bool);
using CreateFunc = UIContent* (*)(void*, void*, int32_t);
using CreateFunction = UIContent* (*)(void*);
using GetUIContentFunc = UIContent* (*)(int32_t);
using GetCurrentUIStackInfoFunction = char* (*)();
using GetWindowIdFuction = int32_t (*)(int32_t);
constexpr char UI_CONTENT_CREATE_FUNC[] = "OHOS_ACE_CreateUIContent";
constexpr char Card_CREATE_FUNC[] = "OHOS_ACE_CreateFormContent";
constexpr char SUB_WINDOW_UI_CONTENT_CREATE_FUNC[] = "OHOS_ACE_CreateSubWindowUIContent";
constexpr char GET_UI_CONTENT_CREATE_FUNC[] = "OHOS_ACE_GetUIContent";
constexpr char OHOS_ACE_GET_UI_CONTENT_WINDOW_ID[] = "OHOS_ACE_GetUIContentWindowID";
OHOS::AbilityRuntime::Context* context_ = nullptr;
std::atomic<bool> UIContent::successFlag_{false};
std::mutex UIContent::mtx_;
std::string UIContent::angleConfigJson_ = "";
std::atomic<bool> UIContent::setUICorrectionConfigSuccessFlag_{false};
std::mutex UIContent::setUICorrectionConfigMutex_;
std::string UIContent::uiCorrectionConfigJson_ = "";
UIContent* CreateUIContent(void* context, void* runtime, bool isFormRender)
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return nullptr;
}
auto entry = reinterpret_cast<CreateCardFunc>(LOADSYM(handle, Card_CREATE_FUNC));
if (entry == nullptr) {
FREELIB(handle);
return nullptr;
}
auto content = entry(context, runtime, isFormRender);
return content;
}
UIContent* CreateUIContent(void* context, void* runtime, VMType vmType)
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return nullptr;
}
auto entry = reinterpret_cast<CreateFunc>(LOADSYM(handle, UI_CONTENT_CREATE_FUNC));
if (entry == nullptr) {
FREELIB(handle);
return nullptr;
}
auto content = entry(context, runtime, static_cast<int32_t>(vmType));
#ifdef UICAST_COMPONENT_SUPPORTED
UICastEventSubscribeProxy::GetInstance()->SubscribeStartEvent(content);
#endif
return content;
}
UIContent* CreateUIContent(void* ability)
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return nullptr;
}
auto entry = reinterpret_cast<CreateFunction>(LOADSYM(handle, SUB_WINDOW_UI_CONTENT_CREATE_FUNC));
if (entry == nullptr) {
FREELIB(handle);
return nullptr;
}
auto content = entry(ability);
#ifdef UICAST_COMPONENT_SUPPORTED
UICastEventSubscribeProxy::GetInstance()->SubscribeStartEvent(content);
#endif
return content;
}
std::unique_ptr<UIContent> UIContent::Create(OHOS::AbilityRuntime::Context* context, NativeEngine* runtime)
{
return UIContent::CreateWithAnyRuntime(context, reinterpret_cast<void*>(runtime));
}
std::unique_ptr<UIContent> UIContent::CreateWithAnyRuntime(OHOS::AbilityRuntime::Context* context, void* runtime)
{
std::unique_ptr<UIContent> content;
content.reset(CreateUIContent(reinterpret_cast<void*>(context), reinterpret_cast<void*>(runtime), VMType::NORMAL));
return content;
}
std::unique_ptr<UIContent> UIContent::Create(
OHOS::AbilityRuntime::Context* context, NativeEngine* runtime, bool isFormRender)
{
std::unique_ptr<UIContent> content;
content.reset(CreateUIContent(reinterpret_cast<void*>(context), reinterpret_cast<void*>(runtime), isFormRender));
return content;
}
std::unique_ptr<UIContent> UIContent::Create(OHOS::AppExecFwk::Ability* ability)
{
std::unique_ptr<UIContent> content;
content.reset(CreateUIContent(reinterpret_cast<void*>(ability)));
return content;
}
std::unique_ptr<UIContent> UIContent::CreateWithAniEnv(OHOS::AbilityRuntime::Context* context, ani_env* env)
{
std::unique_ptr<UIContent> content;
content.reset(CreateUIContent(reinterpret_cast<void*>(context), reinterpret_cast<void*>(env), VMType::ARK_NATIVE));
return content;
}
void UIContent::ShowDumpHelp(std::vector<std::string>& info)
{
info.emplace_back(" -element |show element tree");
info.emplace_back(" -render |show render tree");
info.emplace_back(" -inspector |show inspector tree");
info.emplace_back(" -frontend |show path and components count of current page");
info.emplace_back(" -navigation |show navigation path stack");
}
UIContent* UIContent::GetUIContent(int32_t instanceId)
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return nullptr;
}
auto entry = reinterpret_cast<GetUIContentFunc>(LOADSYM(handle, GET_UI_CONTENT_CREATE_FUNC));
if (entry == nullptr) {
FREELIB(handle);
return nullptr;
}
auto content = entry(instanceId);
return content;
}
int32_t UIContent::GetUIContentWindowID(int32_t instanceId)
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return -1;
}
auto entry = reinterpret_cast<GetWindowIdFuction>(LOADSYM(handle, OHOS_ACE_GET_UI_CONTENT_WINDOW_ID));
if (entry == nullptr) {
FREELIB(handle);
return -1;
}
auto windowId = entry(instanceId);
return windowId;
}
bool UIContent::SetXComponentCompensationAngle(const std::string& configStr)
{
if (successFlag_.load(std::memory_order_acquire)) {
LOGI("UIContent set compensasion angle has successed!");
return true;
}
std::lock_guard<std::mutex> lock(mtx_);
if (successFlag_.load(std::memory_order_relaxed)) {
return true;
}
if (configStr.empty()) {
LOGE("can not set empty compensasion angle!");
return false;
}
UIContent::angleConfigJson_ = configStr;
LOGI("get angle info: %{public}s", configStr.c_str());
successFlag_.store(true, std::memory_order_release);
return true;
}
const std::string& UIContent::GetXComponentCompensationAngle()
{
return UIContent::angleConfigJson_;
}
std::string UIContent::GetCurrentUIStackInfo()
{
LIBHANDLE handle = LOADLIB(AceForwardCompatibility::GetAceLibName());
if (handle == nullptr) {
return std::string();
}
auto entry = reinterpret_cast<GetCurrentUIStackInfoFunction>(LOADSYM(handle, "OHOS_ACE_GetCurrentUIStackInfo"));
if (entry == nullptr) {
FREELIB(handle);
return std::string();
}
auto content = entry();
if (content == nullptr) {
return std::string();
}
return content;
}
bool UIContent::SetUICorrectionConfig(const std::string& configStr)
{
if (setUICorrectionConfigSuccessFlag_.load(std::memory_order_acquire)) {
LOGI("UIContent set ui correction config has successed!");
return true;
}
std::lock_guard<std::mutex> lock(setUICorrectionConfigMutex_);
if (setUICorrectionConfigSuccessFlag_.load(std::memory_order_relaxed)) {
return true;
}
if (configStr.empty()) {
LOGE("UIContent Can not set empty ui correction config!");
return false;
}
UIContent::uiCorrectionConfigJson_ = configStr;
setUICorrectionConfigSuccessFlag_.store(true, std::memory_order_release);
return true;
}
const std::string& UIContent::GetUICorrectionConfig()
{
return UIContent::uiCorrectionConfigJson_;
}
}