1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "adapter/preview/entrance/ui_content_impl.h"
17
18 #include <ui/rs_surface_node.h>
19 #include <ui/rs_ui_director.h>
20
21 #include "include/core/SkFontMgr.h"
22 #include "js_native_api.h"
23 #include "js_native_api_types.h"
24
25 #include "adapter/ohos/entrance/ace_new_pipe_judgement.h"
26 #include "adapter/ohos/entrance/platform_event_callback.h"
27 #include "adapter/preview/entrance/ace_application_info.h"
28 #include "adapter/preview/entrance/ace_container.h"
29 #include "adapter/preview/entrance/clipboard/clipboard_impl.h"
30 #include "adapter/preview/entrance/clipboard/clipboard_proxy_impl.h"
31 #include "adapter/preview/entrance/event_dispatcher.h"
32 #include "adapter/preview/entrance/rs_dir_asset_provider.h"
33 #include "adapter/preview/external/multimodalinput/axis_event.h"
34 #include "adapter/preview/external/multimodalinput/key_event.h"
35 #include "adapter/preview/external/multimodalinput/pointer_event.h"
36 #include "adapter/preview/inspector/inspector_client.h"
37 #include "base/log/log_wrapper.h"
38 #include "frameworks/base/log/log.h"
39 #include "frameworks/base/utils/utils.h"
40 #include "frameworks/bridge/common/utils/utils.h"
41 #include "frameworks/bridge/js_frontend/js_frontend.h"
42 #include "frameworks/core/common/ace_engine.h"
43 #ifdef INIT_ICU_DATA_PATH
44 #include "unicode/putil.h"
45 #endif
46
47 #include "frameworks/simulator/common/include/context.h"
48
49 namespace OHOS::Ace {
50
51 using namespace Platform;
52
53 namespace {
54
55 #ifdef WINDOWS_PLATFORM
56 constexpr char DELIMITER[] = "\\";
57 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources\\base\\profile";
58 #else
59 constexpr char DELIMITER[] = "/";
60 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources/base/profile";
61 #endif
62
ConvertAvoidArea(const OHOS::Rosen::AvoidArea & avoidArea)63 NG::SafeAreaInsets ConvertAvoidArea(const OHOS::Rosen::AvoidArea& avoidArea)
64 {
65 return NG::SafeAreaInsets({ avoidArea.leftRect_.posX_, avoidArea.leftRect_.posX_ + avoidArea.leftRect_.width_ },
66 { avoidArea.topRect_.posY_, avoidArea.topRect_.posY_ + avoidArea.topRect_.height_ },
67 { avoidArea.rightRect_.posX_, avoidArea.rightRect_.posX_ + avoidArea.rightRect_.width_ },
68 { avoidArea.bottomRect_.posY_, avoidArea.bottomRect_.posY_ + avoidArea.bottomRect_.height_ });
69 }
70
SetFontMgrConfig(const std::string & containerSdkPath)71 void SetFontMgrConfig(const std::string& containerSdkPath)
72 {
73 // To check if use ohos or container fonts.
74 std::string runtimeOS = "OHOS_Container";
75 std::string containerFontBasePath = containerSdkPath + DELIMITER + "resources" + DELIMITER + "fonts" + DELIMITER;
76 RSDirAssetProvider dirAsset(containerFontBasePath);
77 std::vector<std::string> fileList;
78 dirAsset.GetAssetList("", fileList);
79 if (containerSdkPath.empty() || fileList.empty()) {
80 runtimeOS = "OHOS";
81 containerFontBasePath = "";
82 }
83 SkFontMgr::SetFontMgrConfig(runtimeOS, containerFontBasePath);
84 }
85
86 } // namespace
87
88 using ContentFinishCallback = std::function<void()>;
89 using ContentStartAbilityCallback = std::function<void(const std::string& address)>;
90 class ContentEventCallback final : public PlatformEventCallback {
91 public:
ContentEventCallback(ContentFinishCallback onFinish)92 explicit ContentEventCallback(ContentFinishCallback onFinish) : onFinish_(onFinish) {}
ContentEventCallback(ContentFinishCallback onFinish,ContentStartAbilityCallback onStartAbility)93 ContentEventCallback(ContentFinishCallback onFinish, ContentStartAbilityCallback onStartAbility)
94 : onFinish_(onFinish), onStartAbility_(onStartAbility)
95 {}
96 ~ContentEventCallback() override = default;
97
OnFinish() const98 void OnFinish() const override
99 {
100 LOGI("UIContent OnFinish");
101 CHECK_NULL_VOID(onFinish_);
102 onFinish_();
103 }
104
OnStartAbility(const std::string & address)105 void OnStartAbility(const std::string& address) override
106 {
107 LOGI("UIContent OnStartAbility");
108 CHECK_NULL_VOID(onStartAbility_);
109 onStartAbility_(address);
110 }
111
OnStatusBarBgColorChanged(uint32_t color)112 void OnStatusBarBgColorChanged(uint32_t color) override
113 {
114 LOGI("UIContent OnStatusBarBgColorChanged");
115 }
116
117 private:
118 ContentFinishCallback onFinish_;
119 ContentStartAbilityCallback onStartAbility_;
120 };
121
122 class DragWindowListener : public OHOS::Rosen::IWindowDragListener {
123 public:
DragWindowListener(int32_t instanceId)124 explicit DragWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
125 ~DragWindowListener() = default;
OnDrag(int32_t x,int32_t y,OHOS::Rosen::DragEvent event)126 void OnDrag(int32_t x, int32_t y, OHOS::Rosen::DragEvent event)
127 {
128 LOGI("[Engine Log] The feature is not supported on the previewer, and instanceId_ = %{public}d", instanceId_);
129 }
130
131 private:
132 int32_t instanceId_ = -1;
133 };
134
135 class TouchOutsideListener : public OHOS::Rosen::ITouchOutsideListener {
136 public:
TouchOutsideListener(int32_t instanceId)137 explicit TouchOutsideListener(int32_t instanceId) : instanceId_(instanceId) {}
138 ~TouchOutsideListener() = default;
139
OnTouchOutside() const140 void OnTouchOutside() const
141 {
142 LOGI("[Engine Log] The feature is not supported on the previewer, and instanceId_ = %{public}d", instanceId_);
143 }
144
145 private:
146 int32_t instanceId_ = -1;
147 };
148
149 class IIgnoreViewSafeAreaListener : public OHOS::Rosen::IIgnoreViewSafeAreaListener {
150 public:
IIgnoreViewSafeAreaListener(int32_t instanceId)151 explicit IIgnoreViewSafeAreaListener(int32_t instanceId) : instanceId_(instanceId) {}
152 ~IIgnoreViewSafeAreaListener() = default;
153
SetIgnoreViewSafeArea(bool ignoreViewSafeArea)154 void SetIgnoreViewSafeArea(bool ignoreViewSafeArea)
155 {
156 LOGD("[instanceId_:%{public}d]: SetIgnoreViewSafeArea:%{public}u", instanceId_, ignoreViewSafeArea);
157 auto container = AceEngine::Get().GetContainer(instanceId_);
158 CHECK_NULL_VOID(container);
159 auto pipelineContext = container->GetPipelineContext();
160 auto taskExecutor = container->GetTaskExecutor();
161 CHECK_NULL_VOID(taskExecutor);
162 taskExecutor->PostSyncTask(
163 [&pipelineContext, container, ignoreSafeArea = ignoreViewSafeArea]() {
164 pipelineContext->SetIgnoreViewSafeArea(ignoreSafeArea);
165 },
166 TaskExecutor::TaskType::UI, "ArkUISetIgnoreViewSafeArea");
167 }
168
169 private:
170 int32_t instanceId_ = -1;
171 };
172
173 class AvoidAreaChangedListener : public OHOS::Rosen::IAvoidAreaChangedListener {
174 public:
AvoidAreaChangedListener(int32_t instanceId)175 explicit AvoidAreaChangedListener(int32_t instanceId) : instanceId_(instanceId) {}
176 ~AvoidAreaChangedListener() = default;
177
OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea,OHOS::Rosen::AvoidAreaType type)178 void OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea, OHOS::Rosen::AvoidAreaType type)
179 {
180 LOGD("Avoid area changed, type:%{public}d, topRect: avoidArea:x:%{public}d, y:%{public}d, "
181 "width:%{public}d, height:%{public}d; bottomRect: avoidArea:x:%{public}d, y:%{public}d, "
182 "width:%{public}d, height:%{public}d",
183 type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
184 (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
185 (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_);
186 auto container = Platform::AceContainer::GetContainerInstance(instanceId_);
187 CHECK_NULL_VOID(container);
188 auto pipeline = container->GetPipelineContext();
189 CHECK_NULL_VOID(pipeline);
190 auto taskExecutor = container->GetTaskExecutor();
191 CHECK_NULL_VOID(taskExecutor);
192 if (type == Rosen::AvoidAreaType::TYPE_SYSTEM) {
193 systemSafeArea_ = ConvertAvoidArea(avoidArea);
194 } else if (type == Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
195 navigationBar_ = ConvertAvoidArea(avoidArea);
196 } else if (type == Rosen::AvoidAreaType::TYPE_CUTOUT) {
197 cutoutSafeArea_ = ConvertAvoidArea(avoidArea);
198 }
199 auto safeArea = systemSafeArea_;
200 auto navSafeArea = navigationBar_;
201 auto cutoutSafeArea = cutoutSafeArea_;
202 ContainerScope scope(instanceId_);
203 taskExecutor->PostTask(
204 [pipeline, safeArea, navSafeArea, cutoutSafeArea, type, avoidArea] {
205 if (type == Rosen::AvoidAreaType::TYPE_SYSTEM) {
206 pipeline->UpdateSystemSafeArea(safeArea);
207 } else if (type == Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
208 pipeline->UpdateNavSafeArea(navSafeArea);
209 } else if (type == Rosen::AvoidAreaType::TYPE_CUTOUT) {
210 pipeline->UpdateCutoutSafeArea(cutoutSafeArea);
211 }
212 // for ui extension component
213 pipeline->UpdateOriginAvoidArea(avoidArea, static_cast<uint32_t>(type));
214 },
215 TaskExecutor::TaskType::UI, "ArkUIUpdateOriginAvoidArea");
216 }
217
218 private:
219 NG::SafeAreaInsets systemSafeArea_;
220 NG::SafeAreaInsets navigationBar_;
221 NG::SafeAreaInsets cutoutSafeArea_;
222 int32_t instanceId_ = -1;
223 };
224
OHOS_ACE_CreateUIContent(void * context,void * runtime)225 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateUIContent(void* context, void* runtime)
226 {
227 return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime);
228 }
229
OHOS_ACE_CreateFormContent(void * context,void * runtime,bool isCard)230 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateFormContent(void* context, void* runtime, bool isCard)
231 {
232 return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime, isCard);
233 }
234
OHOS_ACE_CreateSubWindowUIContent(void * ability)235 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateSubWindowUIContent(void* ability)
236 {
237 return new UIContentImpl(reinterpret_cast<OHOS::AppExecFwk::Ability*>(ability));
238 }
239
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime)240 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime)
241 : instanceId_(ACE_INSTANCE_ID), runtime_(runtime)
242 {
243 // 基于Options的方式传递参数
244 CHECK_NULL_VOID(context);
245 context_ = context->weak_from_this();
246 auto options = context->GetOptions();
247 assetPath_ = options.assetPath;
248 systemResourcesPath_ = options.systemResourcePath;
249 appResourcesPath_ = options.appResourcePath;
250 containerSdkPath_ = options.containerSdkPath;
251 language_ = options.language;
252 region_ = options.region;
253 script_ = options.script;
254 themeId_ = options.themeId;
255 deviceWidth_ = options.deviceWidth;
256 deviceHeight_ = options.deviceHeight;
257 isRound_ = options.isRound;
258 isComponentMode_ = options.isComponentMode;
259 onRouterChange_ = options.onRouterChange;
260 deviceConfig_.orientation = static_cast<DeviceOrientation>(options.deviceConfig.orientation);
261 deviceConfig_.deviceType = static_cast<DeviceType>(options.deviceConfig.deviceType);
262 deviceConfig_.colorMode = static_cast<ColorMode>(options.deviceConfig.colorMode);
263 deviceConfig_.density = options.deviceConfig.density;
264 deviceConfig_.fontRatio = options.deviceConfig.fontRatio;
265 runArgs_.deviceConfig.orientation = deviceConfig_.orientation;
266 runArgs_.deviceConfig.density = deviceConfig_.density;
267
268 bundleName_ = options.bundleName;
269 compatibleVersion_ = options.compatibleVersion;
270 installationFree_ = options.installationFree;
271 labelId_ = options.labelId;
272 moduleName_ = options.moduleName;
273 compileMode_ = options.compileMode;
274 pageProfile_ = options.pageProfile;
275 const std::string profilePrefix = "$profile:";
276 if (pageProfile_.compare(0, profilePrefix.size(), profilePrefix) == 0) {
277 pageProfile_ = pageProfile_.substr(profilePrefix.length()).append(".json");
278 }
279 targetVersion_ = options.targetVersion;
280 auto releaseType = options.releaseType;
281 bool enablePartialUpdate = options.enablePartialUpdate;
282 useNewPipeline_ = AceNewPipeJudgement::QueryAceNewPipeEnabledStage(
283 "", compatibleVersion_, targetVersion_, releaseType, !enablePartialUpdate);
284 }
285
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime,bool isCard)286 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime, bool isCard)
287 : instanceId_(ACE_INSTANCE_ID), runtime_(runtime), isFormRender_(isCard)
288 {
289 LOGI("The constructor is used to support ets card, isFormRender_ = %{public}d", isFormRender_);
290 if (context) {
291 auto options = context->GetOptions();
292 bundleName_ = options.bundleName;
293 moduleName_ = options.moduleName;
294 }
295 }
296
UIContentImpl(OHOS::AppExecFwk::Ability * ability)297 UIContentImpl::UIContentImpl(OHOS::AppExecFwk::Ability* ability) : instanceId_(ACE_INSTANCE_ID) {}
298
DestroyUIDirector()299 void UIContentImpl::DestroyUIDirector()
300 {
301 auto container = AceContainer::GetContainerInstance(instanceId_);
302 CHECK_NULL_VOID(container);
303 auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
304 CHECK_NULL_VOID(pipelineContext);
305 auto rsUIDirector = pipelineContext->GetRSUIDirector();
306 CHECK_NULL_VOID(rsUIDirector);
307 rsUIDirector->Destroy();
308 }
309
DestroyCallback() const310 void UIContentImpl::DestroyCallback() const
311 {
312 auto container = AceContainer::GetContainerInstance(instanceId_);
313 CHECK_NULL_VOID(container);
314 auto pipelineContext = container->GetPipelineContext();
315 CHECK_NULL_VOID(pipelineContext);
316 pipelineContext->SetNextFrameLayoutCallback(nullptr);
317 }
318
Initialize(OHOS::Rosen::Window * window,const std::string & url,napi_value storage)319 UIContentErrorCode UIContentImpl::Initialize(OHOS::Rosen::Window* window, const std::string& url,
320 napi_value storage)
321 {
322 auto errorCode = UIContentErrorCode::NO_ERRORS;
323 errorCode = CommonInitialize(window, url, storage);
324 CHECK_ERROR_CODE_RETURN(errorCode);
325 errorCode = AceContainer::RunPage(instanceId_, url, "");
326 return errorCode;
327 }
328
InitializeByName(OHOS::Rosen::Window * window,const std::string & name,napi_value storage)329 UIContentErrorCode UIContentImpl::InitializeByName(
330 OHOS::Rosen::Window* window, const std::string& name, napi_value storage)
331 {
332 return InitializeInner(window, name, storage, true);
333 }
334
InitializeInner(OHOS::Rosen::Window * window,const std::string & contentInfo,napi_value storage,bool isNamedRouter)335 UIContentErrorCode UIContentImpl::InitializeInner(
336 OHOS::Rosen::Window* window, const std::string& contentInfo, napi_value storage, bool isNamedRouter)
337 {
338 auto errorCode = UIContentErrorCode::NO_ERRORS;
339 if (window) {
340 errorCode = CommonInitialize(window, contentInfo, storage);
341 CHECK_ERROR_CODE_RETURN(errorCode);
342 }
343 LOGI("[%{public}s][%{public}s][%{public}d]: Initialize: %{public}s, isNameRouter: %{public}d", bundleName_.c_str(),
344 moduleName_.c_str(), instanceId_, startUrl_.c_str(), isNamedRouter);
345 return Platform::AceContainer::RunPage(instanceId_, startUrl_, "", isNamedRouter);
346 }
347
GetContentInfo(ContentInfoType type) const348 std::string UIContentImpl::GetContentInfo(ContentInfoType type) const
349 {
350 return AceContainer::GetContentInfo(instanceId_, type);
351 }
352
CommonInitialize(OHOS::Rosen::Window * window,const std::string & contentInfo,napi_value storage)353 UIContentErrorCode UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window,
354 const std::string& contentInfo, napi_value storage)
355 {
356 auto context = context_.lock();
357 static std::once_flag onceFlag;
358 std::call_once(onceFlag, []() {
359 #ifdef INIT_ICU_DATA_PATH
360 std::string icuPath = ".";
361 u_setDataDirectory(icuPath.c_str());
362 #endif
363 Container::UpdateCurrent(INSTANCE_ID_PLATFORM);
364 ClipboardProxy::GetInstance()->SetDelegate(std::make_unique<Platform::ClipboardProxyImpl>());
365 });
366 rsWindow_ = window;
367 CHECK_NULL_RETURN(rsWindow_, UIContentErrorCode::NULL_WINDOW);
368 startUrl_ = contentInfo;
369 AceApplicationInfo::GetInstance().SetLocale(language_, region_, script_, "");
370 AceApplicationInfo::GetInstance().SetApiTargetVersion(targetVersion_);
371 SetFontMgrConfig(containerSdkPath_);
372 EventDispatcher::GetInstance().Initialize();
373 SystemProperties::SetExtSurfaceEnabled(!containerSdkPath_.empty());
374 SystemProperties::InitDeviceInfo(deviceWidth_, deviceHeight_,
375 deviceConfig_.orientation == DeviceOrientation::PORTRAIT ? 0 : 1, deviceConfig_.density, isRound_);
376 SystemProperties::InitDeviceType(deviceConfig_.deviceType);
377 LOGI("CreateContainer with JSDECLARATIVE frontend, set MinPlatformVersion to %{public}d", compatibleVersion_);
378 AceContainer::CreateContainer(instanceId_, FrontendType::DECLARATIVE_JS, useNewPipeline_);
379 auto container = AceContainer::GetContainerInstance(instanceId_);
380 CHECK_NULL_RETURN(container, UIContentErrorCode::NULL_POINTER);
381 container->SetAbilityContext(context_);
382 container->SetContainerSdkPath(containerSdkPath_);
383 container->SetIsFRSCardContainer(false);
384 container->SetBundleName(bundleName_);
385 container->SetModuleName(moduleName_);
386 container->SetColorMode(deviceConfig_.colorMode);
387 LOGI("Save bundle %{public}s, module %{public}s", bundleName_.c_str(), moduleName_.c_str());
388 if (runtime_) {
389 container->GetSettings().SetUsingSharedRuntime(true);
390 container->SetSharedRuntime(runtime_);
391 } else {
392 container->GetSettings().SetUsingSharedRuntime(false);
393 }
394 container->SetInstallationFree(installationFree_);
395 container->SetLabelId(labelId_);
396 AceContainer::SetComponentModeFlag(isComponentMode_);
397 auto config = container->GetResourceConfiguration();
398 config.SetDeviceType(SystemProperties::GetDeviceType());
399 config.SetOrientation(SystemProperties::GetDeviceOrientation());
400 config.SetDensity(SystemProperties::GetResolution());
401 config.SetColorMode(container->GetColorMode());
402 config.SetFontRatio(deviceConfig_.fontRatio);
403 container->SetResourceConfiguration(config);
404 container->SetPageProfile(pageProfile_);
405 container->SetApiTargetVersion(targetVersion_);
406 std::vector<std::string> paths;
407 paths.push_back(assetPath_);
408 std::string appResourcesPath(appResourcesPath_);
409 if (!OHOS::Ace::Framework::EndWith(appResourcesPath, DELIMITER)) {
410 appResourcesPath.append(DELIMITER);
411 }
412 paths.push_back(appResourcesPath);
413 paths.push_back(appResourcesPath + ASSET_PATH_SHARE_STAGE);
414 if (!containerSdkPath_.empty()) {
415 paths.push_back(containerSdkPath_);
416 }
417 AceContainer::AddAssetPath(instanceId_, "", paths);
418 AceContainer::SetResourcesPathAndThemeStyle(
419 instanceId_, systemResourcesPath_, containerSdkPath_, appResourcesPath_, themeId_, deviceConfig_.colorMode);
420
421 auto view = AceViewPreview::CreateView(instanceId_, false, container->GetSettings().usePlatformAsUIThread);
422 UIEnvCallback callback = [window = rsWindow_, id = instanceId_](
423 const OHOS::Ace::RefPtr<PipelineContext>& context) mutable {
424 CHECK_NULL_VOID(context);
425 CHECK_NULL_VOID(window);
426 auto director = OHOS::Rosen::RSUIDirector::Create();
427 CHECK_NULL_VOID(director);
428 director->SetRSSurfaceNode(window->GetSurfaceNode());
429 auto container = AceContainer::GetContainerInstance(id);
430 CHECK_NULL_VOID(container);
431 auto func = [taskExecutor = container->GetTaskExecutor(), id](
432 const std::function<void()>& task, uint32_t delay) {
433 CHECK_NULL_VOID(taskExecutor);
434 ContainerScope scope(id);
435 taskExecutor->PostDelayedTask(
436 task, TaskExecutor::TaskType::UI, delay, "ArkUIRenderServiceTask", PriorityType::HIGH);
437 };
438 director->SetUITaskRunner(func, id);
439 director->Init();
440 context->SetRSUIDirector(director);
441 };
442 AceContainer::SetView(view, rsWindow_, deviceConfig_.density, deviceWidth_, deviceHeight_, callback);
443 // Drive the native engine with the platform thread.
444 container->RunNativeEngineLoop();
445 auto pipelineContext = container->GetPipelineContext();
446 if (pipelineContext) {
447 pipelineContext->SetMinPlatformVersion(compatibleVersion_);
448 pipelineContext->SetDisplayWindowRectInfo(
449 Rect(Offset(0.0f, 0.0f), Size(deviceWidth_, deviceHeight_)));
450 }
451 container->InitializeAppConfig(assetPath_, bundleName_, moduleName_, compileMode_);
452 AceContainer::AddRouterChangeCallback(instanceId_, onRouterChange_);
453 // Should make it possible to update surface changes by using viewWidth and viewHeight.
454 view->NotifySurfaceChanged(deviceWidth_, deviceHeight_);
455 view->NotifyDensityChanged(deviceConfig_.density);
456 avoidAreaChangedListener_ = new AvoidAreaChangedListener(instanceId_);
457 rsWindow_->RegisterAvoidAreaChangeListener(avoidAreaChangedListener_);
458 ignoreViewSafeAreaListener_ = new IIgnoreViewSafeAreaListener(instanceId_);
459 window->RegisterIgnoreViewSafeAreaListener(ignoreViewSafeAreaListener_);
460 OHOS::Rosen::AvoidArea avoidArea;
461 rsWindow_->GetAvoidAreaByType(OHOS::Rosen::AvoidAreaType::TYPE_SYSTEM, avoidArea);
462 avoidAreaChangedListener_->OnAvoidAreaChanged(avoidArea, OHOS::Rosen::AvoidAreaType::TYPE_SYSTEM);
463 rsWindow_->GetAvoidAreaByType(OHOS::Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR, avoidArea);
464 avoidAreaChangedListener_->OnAvoidAreaChanged(avoidArea, OHOS::Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
465 if (runtime_) {
466 auto nativeEngine = reinterpret_cast<NativeEngine*>(runtime_);
467 if (!storage) {
468 container->SetLocalStorage(nullptr, context);
469 } else {
470 auto env = reinterpret_cast<napi_env>(nativeEngine);
471 napi_ref ref = nullptr;
472 napi_create_reference(env, storage, 1, &ref);
473 container->SetLocalStorage(reinterpret_cast<NativeReference*>(ref), context);
474 }
475 }
476 return UIContentErrorCode::NO_ERRORS;
477 }
478
Destroy()479 void UIContentImpl::Destroy()
480 {
481 LOGI("UIContentImpl: window destroy");
482 AceContainer::DestroyContainer(instanceId_);
483 }
484
GetBackgroundColor()485 uint32_t UIContentImpl::GetBackgroundColor()
486 {
487 auto container = AceContainer::GetContainerInstance(instanceId_);
488 CHECK_NULL_RETURN(container, 0x000000);
489 auto taskExecutor = container->GetTaskExecutor();
490 CHECK_NULL_RETURN(taskExecutor, 0x000000);
491 ContainerScope scope(instanceId_);
492 uint32_t bgColor = 0x000000;
493 taskExecutor->PostSyncTask(
494 [&bgColor, container]() {
495 CHECK_NULL_VOID(container);
496 auto pipelineContext = container->GetPipelineContext();
497 CHECK_NULL_VOID(pipelineContext);
498 bgColor = pipelineContext->GetAppBgColor().GetValue();
499 },
500 TaskExecutor::TaskType::UI, "ArkUIGetAppBackgroundColor");
501
502 return bgColor;
503 }
504
SetBackgroundColor(uint32_t color)505 void UIContentImpl::SetBackgroundColor(uint32_t color)
506 {
507 LOGI("UIContentImpl: SetBackgroundColor color is %{public}u", color);
508 auto container = AceContainer::GetContainerInstance(instanceId_);
509 CHECK_NULL_VOID(container);
510 ContainerScope scope(instanceId_);
511 auto taskExecutor = container->GetTaskExecutor();
512 CHECK_NULL_VOID(taskExecutor);
513 taskExecutor->PostSyncTask(
514 [container, bgColor = color]() {
515 auto pipelineContext = container->GetPipelineContext();
516 CHECK_NULL_VOID(pipelineContext);
517 pipelineContext->SetAppBgColor(Color(bgColor));
518 },
519 TaskExecutor::TaskType::UI, "ArkUISetAppBackgroundColor");
520 }
521
SetWindowContainerColor(uint32_t activeColor,uint32_t inactiveColor)522 void UIContentImpl::SetWindowContainerColor(uint32_t activeColor, uint32_t inactiveColor)
523 {
524 TAG_LOGI(AceLogTag::ACE_APPBAR, "[%{public}s][%{public}s][%{public}d]: SetWindowContainerColor:"
525 "active color %{public}u, inactive color %{public}u",
526 bundleName_.c_str(), moduleName_.c_str(), instanceId_, activeColor, inactiveColor);
527 auto container = AceEngine::Get().GetContainer(instanceId_);
528 CHECK_NULL_VOID(container);
529 ContainerScope scope(instanceId_);
530 auto taskExecutor = container->GetTaskExecutor();
531 CHECK_NULL_VOID(taskExecutor);
532 taskExecutor->PostSyncTask(
533 [container, activeColor, inactiveColor]() {
534 auto pipelineContext = container->GetPipelineContext();
535 CHECK_NULL_VOID(pipelineContext);
536 pipelineContext->SetWindowContainerColor(Color(activeColor), Color(inactiveColor));
537 },
538 TaskExecutor::TaskType::UI, "ArkUISetWindowContainerColor");
539 }
540
ProcessBackPressed()541 bool UIContentImpl::ProcessBackPressed()
542 {
543 LOGI("Process Back Pressed Event");
544 return EventDispatcher::GetInstance().DispatchBackPressedEvent();
545 }
546
ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)547 bool UIContentImpl::ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
548 {
549 return EventDispatcher::GetInstance().DispatchTouchEvent(pointerEvent);
550 }
551
ProcessPointerEventWithCallback(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent,const std::function<void ()> & callback)552 bool UIContentImpl::ProcessPointerEventWithCallback(
553 const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent, const std::function<void()>& callback)
554 {
555 auto result = EventDispatcher::GetInstance().DispatchTouchEvent(pointerEvent);
556 if (callback) {
557 callback();
558 }
559 return result;
560 }
561
ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)562 bool UIContentImpl::ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
563 {
564 // previewer never gets preIme-key event because there is no window
565 return EventDispatcher::GetInstance().DispatchKeyEvent(keyEvent);
566 }
567
ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)568 bool UIContentImpl::ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
569 {
570 return false;
571 }
572
ProcessVsyncEvent(uint64_t timeStampNanos)573 bool UIContentImpl::ProcessVsyncEvent(uint64_t timeStampNanos)
574 {
575 return false;
576 }
577
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)578 void UIContentImpl::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config) {}
579
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config,const std::shared_ptr<Global::Resource::ResourceManager> & resourceManager)580 void UIContentImpl::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config,
581 const std::shared_ptr<Global::Resource::ResourceManager>& resourceManager) {}
582
UpdateViewportConfig(const ViewportConfig & config,OHOS::Rosen::WindowSizeChangeReason reason,const std::shared_ptr<OHOS::Rosen::RSTransaction> & rsTransaction,const std::map<OHOS::Rosen::AvoidAreaType,OHOS::Rosen::AvoidArea> & avoidAreas,const sptr<OHOS::Rosen::OccupiedAreaChangeInfo> & info)583 void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Rosen::WindowSizeChangeReason reason,
584 const std::shared_ptr<OHOS::Rosen::RSTransaction>& rsTransaction,
585 const std::map<OHOS::Rosen::AvoidAreaType, OHOS::Rosen::AvoidArea>& avoidAreas,
586 const sptr<OHOS::Rosen::OccupiedAreaChangeInfo>& info)
587 {
588 LOGI("ViewportConfig: %{public}s", config.ToString().c_str());
589 auto container = AceContainer::GetContainerInstance(instanceId_);
590 CHECK_NULL_VOID(container);
591 auto context = container->GetPipelineContext();
592 CHECK_NULL_VOID(context);
593 context->SetDisplayWindowRectInfo(
594 Rect(Offset(config.Left(), config.Top()), Size(config.Width(), config.Height())));
595 auto viewPtr = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
596 CHECK_NULL_VOID(viewPtr);
597 SystemProperties::InitDeviceInfo(
598 config.Width(), config.Height(), config.Height() >= config.Width() ? 0 : 1, config.Density(), false);
599 deviceConfig_.orientation =
600 config.Height() >= config.Width() ? DeviceOrientation::PORTRAIT : DeviceOrientation::LANDSCAPE;
601 deviceConfig_.density = config.Density();
602 // Unlike the real machine, previewer require updating device configuration information to change window size.
603 container->UpdateDeviceConfig(deviceConfig_);
604 viewPtr->NotifyDensityChanged(config.Density());
605 viewPtr->NotifySurfaceChanged(config.Width(), config.Height());
606 if (deviceConfig_.orientation != runArgs_.deviceConfig.orientation ||
607 deviceConfig_.density != runArgs_.deviceConfig.density) {
608 container->NotifyConfigurationChange(false, ConfigurationChange({ false, false, true }));
609 runArgs_.deviceConfig.orientation = deviceConfig_.orientation;
610 runArgs_.deviceConfig.density = deviceConfig_.density;
611 }
612 }
613
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)614 void UIContentImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
615 {
616 auto container = AceContainer::GetContainerInstance(instanceId_);
617 CHECK_NULL_VOID(container);
618 container->Dump(params, info);
619 }
620
SetNextFrameLayoutCallback(std::function<void ()> && callback)621 void UIContentImpl::SetNextFrameLayoutCallback(std::function<void()>&& callback)
622 {
623 CHECK_NULL_VOID(callback);
624 auto container = AceContainer::GetContainerInstance(instanceId_);
625 CHECK_NULL_VOID(container);
626 auto pipelineContext = container->GetPipelineContext();
627 CHECK_NULL_VOID(pipelineContext);
628 pipelineContext->SetNextFrameLayoutCallback(std::move(callback));
629 }
630
NotifyMemoryLevel(int32_t level)631 void UIContentImpl::NotifyMemoryLevel(int32_t level)
632 {
633 LOGI("Receive Memory level notification, level: %{public}d", level);
634 auto container = AceContainer::GetContainerInstance(instanceId_);
635 CHECK_NULL_VOID(container);
636 auto pipelineContext = container->GetPipelineContext();
637 CHECK_NULL_VOID(pipelineContext);
638 ContainerScope scope(instanceId_);
639 pipelineContext->NotifyMemoryLevel(level);
640 }
641
CreateModalUIExtension(const AAFwk::Want & want,const ModalUIExtensionCallbacks & callbacks,const ModalUIExtensionConfig & config)642 int32_t UIContentImpl::CreateModalUIExtension(
643 const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks, const ModalUIExtensionConfig& config)
644 {
645 return 0;
646 }
647
CloseModalUIExtension(int32_t sessionId)648 void UIContentImpl::CloseModalUIExtension(int32_t sessionId) {}
649
SetStatusBarItemColor(uint32_t color)650 void UIContentImpl::SetStatusBarItemColor(uint32_t color)
651 {
652 ContainerScope scope(instanceId_);
653 auto container = Platform::AceContainer::GetContainer(instanceId_);
654 CHECK_NULL_VOID(container);
655 auto appBar = container->GetAppBar();
656 CHECK_NULL_VOID(appBar);
657 appBar->SetStatusBarItemColor(IsDarkColor(color));
658 }
659
OnConfigurationChanged(const DeviceConfig & newConfig)660 void UIContentImpl::OnConfigurationChanged(const DeviceConfig& newConfig)
661 {
662 if (newConfig.colorMode == runArgs_.deviceConfig.colorMode) {
663 return;
664 }
665 int32_t width = runArgs_.deviceWidth;
666 int32_t height = runArgs_.deviceHeight;
667 SurfaceChanged(runArgs_.deviceConfig.orientation, runArgs_.deviceConfig.density, width, height);
668 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
669 if (!container) {
670 LOGW("container is null, change configuration failed.");
671 return;
672 }
673 container->UpdateDeviceConfig(newConfig);
674 runArgs_.deviceConfig.colorMode = newConfig.colorMode;
675 if (container->GetType() == FrontendType::DECLARATIVE_JS) {
676 container->NativeOnConfigurationUpdated(ACE_INSTANCE_ID);
677 }
678 }
679
SurfaceChanged(const DeviceOrientation & orientation,const double & resolution,int32_t & width,int32_t & height,WindowSizeChangeReason type)680 void UIContentImpl::SurfaceChanged(
681 const DeviceOrientation& orientation, const double& resolution, int32_t& width, int32_t& height,
682 WindowSizeChangeReason type)
683 {
684 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
685 CHECK_NULL_VOID(container);
686 auto viewPtr = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
687 CHECK_NULL_VOID(viewPtr);
688 // Need to change the window resolution and then change the rendering resolution. Otherwise, the image may not adapt
689 // to the new window after the window is modified.
690 auto context = container->GetPipelineContext();
691 CHECK_NULL_VOID(context);
692 context->SetDisplayWindowRectInfo(Rect(Offset(0, 0), Size(width, height)));
693 SystemProperties::InitDeviceInfo(
694 width, height, orientation == DeviceOrientation::PORTRAIT ? 0 : 1, resolution, runArgs_.isRound);
695 DeviceConfig deviceConfig = runArgs_.deviceConfig;
696 deviceConfig.orientation = orientation;
697 deviceConfig.density = resolution;
698 container->UpdateDeviceConfig(deviceConfig);
699 viewPtr->NotifyDensityChanged(resolution);
700 viewPtr->NotifySurfaceChanged(width, height, type);
701 if ((orientation != runArgs_.deviceConfig.orientation && configChanges_.watchOrientation) ||
702 (resolution != runArgs_.deviceConfig.density && configChanges_.watchDensity) ||
703 ((width != runArgs_.deviceWidth || height != runArgs_.deviceHeight) && configChanges_.watchLayout)) {
704 container->NativeOnConfigurationUpdated(ACE_INSTANCE_ID);
705 }
706 if (orientation != runArgs_.deviceConfig.orientation || resolution != runArgs_.deviceConfig.density) {
707 container->NotifyConfigurationChange(false, ConfigurationChange({ false, false, true }));
708 }
709 runArgs_.deviceConfig.orientation = orientation;
710 runArgs_.deviceConfig.density = resolution;
711 runArgs_.deviceWidth = width;
712 runArgs_.deviceHeight = height;
713 }
714
LoadDocument(const std::string & url,const std::string & componentName,Platform::SystemParams & systemParams)715 void UIContentImpl::LoadDocument(const std::string& url, const std::string& componentName,
716 Platform::SystemParams& systemParams)
717 {
718 LOGI("Component Preview start:%{public}s, ", componentName.c_str());
719 AceApplicationInfo::GetInstance().ChangeLocale(systemParams.language, systemParams.region);
720 runArgs_.isRound = systemParams.isRound;
721 runArgs_.deviceConfig.deviceType = systemParams.deviceType;
722 SurfaceChanged(systemParams.orientation, systemParams.density, systemParams.deviceWidth, systemParams.deviceHeight);
723 DeviceConfig deviceConfig = {
724 .orientation = systemParams.orientation,
725 .density = systemParams.density,
726 .deviceType = systemParams.deviceType,
727 .colorMode = systemParams.colorMode,
728 };
729 OnConfigurationChanged(deviceConfig);
730 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
731 CHECK_NULL_VOID(container);
732 container->LoadDocument(url, componentName);
733 LOGI("Component Preview end");
734 }
735
GetJSONTree()736 std::string UIContentImpl::GetJSONTree()
737 {
738 LOGI("Inspector start");
739 std::string jsonTreeStr;
740 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
741 CHECK_NULL_RETURN(container, "");
742 auto taskExecutor = container->GetTaskExecutor();
743 CHECK_NULL_RETURN(taskExecutor, "");
744 taskExecutor->PostSyncTask(
745 [&jsonTreeStr] { OHOS::Ace::Framework::InspectorClient::GetInstance().AssembleJSONTreeStr(jsonTreeStr); },
746 TaskExecutor::TaskType::UI, "ArkUIGetJsonTreeStr");
747 LOGI("Inspector end");
748 return jsonTreeStr;
749 }
750
OperateComponent(const std::string & attrsJson)751 bool UIContentImpl::OperateComponent(const std::string& attrsJson)
752 {
753 LOGI("Fast Preview start");
754 auto root = JsonUtil::ParseJsonString(attrsJson);
755 if (!root || !root->IsValid()) {
756 LOGE("Fast Preview failed: the attrsJson is illegal json format");
757 return false;
758 }
759
760 auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
761 if (!container) {
762 LOGE("Fast Preview failed: container is null");
763 return false;
764 }
765 auto taskExecutor = container->GetTaskExecutor();
766 if (!taskExecutor) {
767 LOGE("Fast Preview failed: taskExecutor is null");
768 return false;
769 }
770 taskExecutor->PostTask(
771 [attrsJson, instanceId = ACE_INSTANCE_ID] {
772 ContainerScope scope(instanceId);
773 bool result = OHOS::Ace::Framework::InspectorClient::GetInstance().OperateComponent(attrsJson);
774 if (!result) {
775 OHOS::Ace::Framework::InspectorClient::GetInstance().CallFastPreviewErrorCallback(attrsJson);
776 }
777 },
778 TaskExecutor::TaskType::UI, "ArkUIOperateComponent");
779 LOGI("Fast Preview end");
780 return true;
781 }
782 } // namespace OHOS::Ace
783