1 /*
2  * Copyright (c) 2021-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/ace_ability.h"
17 #include "adapter/preview/entrance/ace_view_preview.h"
18 
19 #ifdef INIT_ICU_DATA_PATH
20 #include "unicode/putil.h"
21 #endif
22 
23 #include <ui/rs_surface_node.h>
24 #include <ui/rs_ui_director.h>
25 
26 #include "include/core/SkFontMgr.h"
27 #include "previewer/include/window.h"
28 
29 #include "adapter/ohos/entrance/ace_new_pipe_judgement.h"
30 #include "adapter/preview/entrance/ace_application_info.h"
31 #include "adapter/preview/entrance/ace_container.h"
32 #include "adapter/preview/entrance/event_dispatcher.h"
33 #include "adapter/preview/entrance/rs_dir_asset_provider.h"
34 #include "adapter/preview/external/ability/stage/stage_context.h"
35 #include "adapter/preview/inspector/inspector_client.h"
36 #include "core/common/resource/resource_configuration.h"
37 #include "frameworks/base/utils/utils.h"
38 #include "frameworks/bridge/common/utils/utils.h"
39 #include "frameworks/bridge/js_frontend/js_frontend.h"
40 #include "frameworks/core/common/ace_engine.h"
41 
42 namespace OHOS::Ace::Platform {
43 namespace {
44 
45 constexpr char ASSET_PATH_SHARE[] = "share";
46 #ifdef WINDOWS_PLATFORM
47 constexpr char DELIMITER[] = "\\";
48 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources\\base\\profile";
49 #else
50 constexpr char DELIMITER[] = "/";
51 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources/base/profile";
52 #endif
53 
SetFontMgrConfig(const std::string & containerSdkPath)54 void SetFontMgrConfig(const std::string& containerSdkPath)
55 {
56     // To check if use ohos or container fonts.
57     std::string runtimeOS = "OHOS_Container";
58     std::string containerFontBasePath = containerSdkPath + DELIMITER + "resources" + DELIMITER + "fonts" + DELIMITER;
59     RSDirAssetProvider dirAsset(containerFontBasePath);
60     std::vector<std::string> fileList;
61     dirAsset.GetAssetList("", fileList);
62     if (containerSdkPath.empty() || fileList.empty()) {
63         runtimeOS = "OHOS";
64         containerFontBasePath = "";
65     }
66     SkFontMgr::SetFontMgrConfig(runtimeOS, containerFontBasePath);
67 }
68 
GetCustomAssetPath(std::string assetPath)69 std::string GetCustomAssetPath(std::string assetPath)
70 {
71     if (assetPath.empty()) {
72         LOGW("AssetPath is null.");
73         return std::string();
74     }
75     std::string customAssetPath;
76     if (OHOS::Ace::Framework::EndWith(assetPath, DELIMITER)) {
77         assetPath = assetPath.substr(0, assetPath.size() - 1);
78     }
79     customAssetPath = assetPath.substr(0, assetPath.find_last_of(DELIMITER) + 1);
80     return customAssetPath;
81 }
82 
DumpAceRunArgs(const AceRunArgs & runArgs)83 inline void DumpAceRunArgs(const AceRunArgs& runArgs)
84 {
85 #ifdef ACE_DEBUG
86     LOGI("runArgs.pageProfile: %{private}s", runArgs.pageProfile.c_str());
87     LOGI("runArgs.asset: %{private}s", runArgs.assetPath.c_str());
88     LOGI("runArgs.systemResources: %{private}s", runArgs.systemResourcesPath.c_str());
89     LOGI("runArgs.appResources: %{private}s", runArgs.appResourcesPath.c_str());
90     LOGI("runArgs.themeId: %{private}u", runArgs.themeId);
91     LOGI("runArgs.deviceConfig.orientation: %{private}d", static_cast<int>(runArgs.deviceConfig.orientation));
92     LOGI("runArgs.deviceConfig.density: %{private}lf", runArgs.deviceConfig.density);
93     LOGI("runArgs.deviceConfig.deviceType: %{private}d", static_cast<int>(runArgs.deviceConfig.deviceType));
94     LOGI("runArgs.deviceConfig.fontRatio: %{private}lf", runArgs.deviceConfig.fontRatio);
95     LOGI("runArgs.deviceConfig.colorMode: %{private}d", static_cast<int>(runArgs.deviceConfig.colorMode));
96     LOGI("runArgs.url: %{private}s", runArgs.url.c_str());
97     LOGI("runArgs.windowTitle: %{private}s", runArgs.windowTitle.c_str());
98     LOGI("runArgs.isRound: %{private}s", runArgs.isRound ? "true" : "false");
99     LOGI("runArgs.viewWidth: %{private}d", runArgs.viewWidth);
100     LOGI("runArgs.viewHeight: %{private}d", runArgs.viewHeight);
101     LOGI("runArgs.deviceWidth: %{private}d", runArgs.deviceWidth);
102     LOGI("runArgs.deviceHeight: %{private}d", runArgs.deviceHeight);
103 #endif
104 }
105 
106 } // namespace
107 
ConvertAvoidArea(const OHOS::Rosen::AvoidArea & avoidArea)108 NG::SafeAreaInsets ConvertAvoidArea(const OHOS::Rosen::AvoidArea& avoidArea)
109 {
110     return NG::SafeAreaInsets({ avoidArea.leftRect_.posX_, avoidArea.leftRect_.posX_ + avoidArea.leftRect_.width_ },
111         { avoidArea.topRect_.posY_, avoidArea.topRect_.posY_ + avoidArea.topRect_.height_ },
112         { avoidArea.rightRect_.posX_, avoidArea.rightRect_.posX_ + avoidArea.rightRect_.width_ },
113         { avoidArea.bottomRect_.posY_, avoidArea.bottomRect_.posY_ + avoidArea.bottomRect_.height_ });
114 }
115 
GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type,sptr<OHOS::Rosen::Window> rsWindow)116 NG::SafeAreaInsets GetViewSafeAreaByType(OHOS::Rosen::AvoidAreaType type, sptr<OHOS::Rosen::Window> rsWindow)
117 {
118     CHECK_NULL_RETURN(rsWindow, {});
119     Rosen::AvoidArea avoidArea;
120     Rosen::WMError ret = rsWindow->GetAvoidAreaByType(type, avoidArea);
121     if (ret == Rosen::WMError::WM_OK) {
122         auto safeAreaInsets = ConvertAvoidArea(avoidArea);
123         LOGI("SafeArea get success, area type is:%{public}d insets area is:%{public}s", static_cast<int32_t>(type),
124             safeAreaInsets.ToString().c_str());
125         return safeAreaInsets;
126     }
127     return {};
128 }
129 
130 class IIgnoreViewSafeAreaListenerPreview  : public OHOS::Rosen::IIgnoreViewSafeAreaListener {
131 public:
IIgnoreViewSafeAreaListenerPreview(int32_t instanceId)132     explicit IIgnoreViewSafeAreaListenerPreview(int32_t instanceId) : instanceId_(instanceId) {}
133     ~IIgnoreViewSafeAreaListenerPreview() = default;
134 
SetIgnoreViewSafeArea(bool ignoreViewSafeArea)135     void SetIgnoreViewSafeArea(bool ignoreViewSafeArea)
136     {
137         LOGD("[instanceId_:%{public}d]: SetIgnoreViewSafeArea:%{public}u", instanceId_, ignoreViewSafeArea);
138         auto container = AceEngine::Get().GetContainer(instanceId_);
139         CHECK_NULL_VOID(container);
140         auto pipelineContext = container->GetPipelineContext();
141         auto taskExecutor = container->GetTaskExecutor();
142         CHECK_NULL_VOID(taskExecutor);
143         taskExecutor->PostSyncTask(
144             [&pipelineContext, container, ignoreSafeArea = ignoreViewSafeArea]() {
145                 pipelineContext->SetIgnoreViewSafeArea(ignoreSafeArea);
146             },
147             TaskExecutor::TaskType::UI, "ArkUISetIgnoreViewSafeArea");
148     }
149 
150 private:
151     int32_t instanceId_ = -1;
152 };
153 
154 class AvoidAreaChangedListenerPreview : public OHOS::Rosen::IAvoidAreaChangedListener {
155 public:
AvoidAreaChangedListenerPreview(int32_t instanceId)156     explicit AvoidAreaChangedListenerPreview(int32_t instanceId) : instanceId_(instanceId) {}
157     ~AvoidAreaChangedListenerPreview() = default;
158 
OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea,OHOS::Rosen::AvoidAreaType type)159     void OnAvoidAreaChanged(const OHOS::Rosen::AvoidArea avoidArea, OHOS::Rosen::AvoidAreaType type)
160     {
161         LOGD("Avoid area changed, type:%{public}d, topRect: avoidArea:x:%{public}d, y:%{public}d, "
162              "width:%{public}d, height:%{public}d; bottomRect: avoidArea:x:%{public}d, y:%{public}d, "
163              "width:%{public}d, height:%{public}d",
164             type, avoidArea.topRect_.posX_, avoidArea.topRect_.posY_, (int32_t)avoidArea.topRect_.width_,
165             (int32_t)avoidArea.topRect_.height_, avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
166             (int32_t)avoidArea.bottomRect_.width_, (int32_t)avoidArea.bottomRect_.height_);
167         auto container = Platform::AceContainer::GetContainerInstance(instanceId_);
168         CHECK_NULL_VOID(container);
169         auto pipeline = container->GetPipelineContext();
170         CHECK_NULL_VOID(pipeline);
171         auto taskExecutor = container->GetTaskExecutor();
172         CHECK_NULL_VOID(taskExecutor);
173         if (type == Rosen::AvoidAreaType::TYPE_SYSTEM) {
174             systemSafeArea_ = ConvertAvoidArea(avoidArea);
175         } else if (type == Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
176             navigationBar_ = ConvertAvoidArea(avoidArea);
177         } else if (type == Rosen::AvoidAreaType::TYPE_CUTOUT) {
178             cutoutSafeArea_ = ConvertAvoidArea(avoidArea);
179         }
180         auto safeArea = systemSafeArea_;
181         auto navSafeArea = navigationBar_;
182         auto cutoutSafeArea = cutoutSafeArea_;
183         taskExecutor->PostTask(
184             [pipeline, safeArea, navSafeArea, cutoutSafeArea, type, avoidArea] {
185                 if (type == Rosen::AvoidAreaType::TYPE_SYSTEM) {
186                     pipeline->UpdateSystemSafeArea(safeArea);
187                 } else if (type == Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
188                     pipeline->UpdateNavSafeArea(navSafeArea);
189                 } else if (type == Rosen::AvoidAreaType::TYPE_CUTOUT && pipeline->GetUseCutout()) {
190                     pipeline->UpdateCutoutSafeArea(cutoutSafeArea);
191                 }
192                 // for ui extension component
193                 pipeline->UpdateOriginAvoidArea(avoidArea, static_cast<uint32_t>(type));
194             },
195             TaskExecutor::TaskType::UI, "ArkUIUpdateOriginAvoidArea");
196     }
197 
198 private:
199     NG::SafeAreaInsets systemSafeArea_;
200     NG::SafeAreaInsets navigationBar_;
201     NG::SafeAreaInsets cutoutSafeArea_;
202     int32_t instanceId_ = -1;
203 };
204 
AceAbility(const AceRunArgs & runArgs)205 AceAbility::AceAbility(const AceRunArgs& runArgs) : runArgs_(runArgs)
206 {
207     static std::once_flag onceFlag;
208     std::call_once(onceFlag, []() {
209         Container::UpdateCurrent(ACE_INSTANCE_ID);
210     });
211     SystemProperties::SetExtSurfaceEnabled(!runArgs.containerSdkPath.empty());
212     SystemProperties::InitDeviceInfo(runArgs.deviceWidth, runArgs.deviceHeight,
213         runArgs.deviceConfig.orientation == DeviceOrientation::PORTRAIT ? 0 : 1, runArgs.deviceConfig.density,
214         runArgs.isRound);
215     SystemProperties::InitDeviceType(runArgs.deviceConfig.deviceType);
216     SystemProperties::SetColorMode(runArgs.deviceConfig.colorMode);
217     InitializeAppInfo();
218     if (runArgs_.aceVersion == AceVersion::ACE_1_0) {
219         if (runArgs_.formsEnabled) {
220             LOGI("CreateContainer with JS_CARD frontend");
221             AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::JS_CARD, false);
222         } else {
223             LOGI("CreateContainer with JS frontend");
224             AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::JS, false);
225         }
226     } else if (runArgs_.aceVersion == AceVersion::ACE_2_0) {
227         if (runArgs_.formsEnabled) {
228             LOGI("CreateContainer with ETS_CARD frontend");
229             AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::ETS_CARD, useNewPipeline_);
230         } else {
231             LOGI("CreateContainer with JSDECLARATIVE frontend");
232             AceContainer::CreateContainer(ACE_INSTANCE_ID, FrontendType::DECLARATIVE_JS, useNewPipeline_);
233         }
234     } else {
235         LOGW("UnKnown frontend type");
236     }
237     AceContainer::SetComponentModeFlag(runArgs.isComponentMode);
238     SetConfigChanges(runArgs.configChanges);
239     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
240     CHECK_NULL_VOID(container);
241     container->SetContainerSdkPath(runArgs.containerSdkPath);
242     container->SetInstallationFree(installationFree_);
243     container->SetLabelId(labelId_);
244     auto config = container->GetResourceConfiguration();
245     config.SetDeviceType(SystemProperties::GetDeviceType());
246     config.SetOrientation(SystemProperties::GetDeviceOrientation());
247     config.SetDensity(SystemProperties::GetResolution());
248     config.SetColorMode(SystemProperties::GetColorMode());
249     config.SetFontRatio(runArgs.deviceConfig.fontRatio);
250     container->SetResourceConfiguration(config);
251     container->SetBundleName(bundleName_);
252     container->SetModuleName(moduleName_);
253     container->SetApiTargetVersion(AceApplicationInfo::GetInstance().GetApiTargetVersion());
254     InitializeClipboard();
255 }
256 
~AceAbility()257 AceAbility::~AceAbility()
258 {
259     AceContainer::DestroyContainer(ACE_INSTANCE_ID);
260 }
261 
SetMockModuleList(const std::map<std::string,std::string> & mockJsonInfo)262 void AceAbility::SetMockModuleList(const std::map<std::string, std::string>& mockJsonInfo)
263 {
264     // only support the stage model
265     if (runArgs_.projectModel == ProjectModel::STAGE) {
266         auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
267         CHECK_NULL_VOID(container);
268         container->SetMockModuleList(mockJsonInfo);
269     }
270 }
271 
CreateInstance(AceRunArgs & runArgs)272 std::unique_ptr<AceAbility> AceAbility::CreateInstance(AceRunArgs& runArgs)
273 {
274     DumpAceRunArgs(runArgs);
275     LOGI("Start create AceAbility instance");
276 #ifdef INIT_ICU_DATA_PATH
277     std::string icuPath = ".";
278     u_setDataDirectory(icuPath.c_str());
279 #endif
280     AceApplicationInfo::GetInstance().SetLocale(runArgs.language, runArgs.region, runArgs.script, "");
281     SetFontMgrConfig(runArgs.containerSdkPath);
282     EventDispatcher::GetInstance().Initialize();
283     auto aceAbility = std::make_unique<AceAbility>(runArgs);
284     return aceAbility;
285 }
286 
InitEnv()287 void AceAbility::InitEnv()
288 {
289     std::vector<std::string> paths;
290     paths.push_back(runArgs_.assetPath);
291     std::string appResourcesPath(runArgs_.appResourcesPath);
292     if (!OHOS::Ace::Framework::EndWith(appResourcesPath, DELIMITER)) {
293         appResourcesPath.append(DELIMITER);
294     }
295     if (runArgs_.projectModel == ProjectModel::STAGE) {
296         // eTS Card
297         if (runArgs_.aceVersion == AceVersion::ACE_2_0 && runArgs_.formsEnabled) {
298             paths.push_back(runArgs_.assetPath + DELIMITER + "ets");
299         }
300         paths.push_back(appResourcesPath);
301         paths.push_back(appResourcesPath + ASSET_PATH_SHARE_STAGE);
302     } else {
303         paths.push_back(GetCustomAssetPath(runArgs_.assetPath) + ASSET_PATH_SHARE);
304     }
305     if (!runArgs_.containerSdkPath.empty()) {
306         paths.push_back(runArgs_.containerSdkPath);
307     }
308     AceContainer::AddAssetPath(ACE_INSTANCE_ID, "", paths);
309     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
310     CHECK_NULL_VOID(container);
311     if (runArgs_.projectModel == ProjectModel::STAGE) {
312         auto pkgcontextinfo = Referenced::MakeRefPtr<StagePkgContextInfo>();
313         pkgcontextinfo->SetPkgNameList(runArgs_.packageNameList);
314         pkgcontextinfo->SetPkgContextInfoAndAliasMap(runArgs_.pkgContextInfoJsonStringMap);
315         container->SetPkgContextInfo(pkgcontextinfo);
316         if (runArgs_.formsEnabled) {
317             container->SetStageCardConfig(runArgs_.pageProfile, runArgs_.url);
318         } else {
319             container->SetPageProfile((runArgs_.pageProfile.empty() ? "" : runArgs_.pageProfile + ".json"));
320         }
321     }
322     AceContainer::SetResourcesPathAndThemeStyle(ACE_INSTANCE_ID, runArgs_.systemResourcesPath,
323         runArgs_.containerSdkPath, runArgs_.appResourcesPath, runArgs_.themeId, runArgs_.deviceConfig.colorMode);
324 
325     auto view = AceViewPreview::CreateView(ACE_INSTANCE_ID);
326     auto window = GetWindow();
327     avoidAreaChangedListener_ = new AvoidAreaChangedListenerPreview(ACE_INSTANCE_ID);
328     window->RegisterAvoidAreaChangeListener(avoidAreaChangedListener_);
329     ignoreViewSafeAreaListener_ = new IIgnoreViewSafeAreaListenerPreview(ACE_INSTANCE_ID);
330     window->RegisterIgnoreViewSafeAreaListener(ignoreViewSafeAreaListener_);
331     UIEnvCallback callback = [window, id = ACE_INSTANCE_ID](const OHOS::Ace::RefPtr<PipelineContext>& context) mutable {
332         CHECK_NULL_VOID(context);
333         CHECK_NULL_VOID(window);
334         auto director = OHOS::Rosen::RSUIDirector::Create();
335         CHECK_NULL_VOID(director);
336         director->SetRSSurfaceNode(window->GetSurfaceNode());
337         auto container = AceContainer::GetContainerInstance(id);
338         CHECK_NULL_VOID(container);
339         auto func = [taskExecutor = container->GetTaskExecutor(), id](
340             const std::function<void()>& task, uint32_t delay) {
341             CHECK_NULL_VOID(taskExecutor);
342             ContainerScope scope(id);
343             taskExecutor->PostDelayedTask(
344                 task, TaskExecutor::TaskType::UI, delay, "ArkUIRenderServiceTask", PriorityType::HIGH);
345         };
346         director->SetUITaskRunner(func, id);
347         director->Init();
348         context->SetRSUIDirector(director);
349     };
350 
351     if (runArgs_.aceVersion == AceVersion::ACE_2_0) {
352         AceContainer::SetView(
353             view, window, runArgs_.deviceConfig.density, runArgs_.deviceWidth, runArgs_.deviceHeight, callback);
354         AceContainer::RunPage(ACE_INSTANCE_ID, runArgs_.url, "");
355     } else {
356         AceContainer::RunPage(ACE_INSTANCE_ID, runArgs_.url, "");
357         AceContainer::SetView(
358             view, window, runArgs_.deviceConfig.density, runArgs_.deviceWidth, runArgs_.deviceHeight, callback);
359     }
360     // Drive the native engine with the platform thread.
361     container->RunNativeEngineLoop();
362     auto pipelineContext = container->GetPipelineContext();
363     if (pipelineContext) {
364         LOGI("Set MinPlatformVersion to %{public}d", compatibleVersion_);
365         pipelineContext->SetMinPlatformVersion(compatibleVersion_);
366         pipelineContext->SetDisplayWindowRectInfo(
367             Rect(Offset(0.0f, 0.0f), Size(runArgs_.deviceWidth, runArgs_.deviceHeight)));
368     }
369     container->InitializeAppConfig(runArgs_.assetPath, bundleName_, moduleName_, compileMode_);
370     pipelineContext->UpdateSystemSafeArea(GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_SYSTEM, window));
371     if (pipelineContext->GetUseCutout()) {
372         pipelineContext->UpdateCutoutSafeArea(GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_CUTOUT, window));
373     }
374     pipelineContext->UpdateNavSafeArea(GetViewSafeAreaByType(Rosen::AvoidAreaType::TYPE_NAVIGATION_INDICATOR, window));
375     AceContainer::AddRouterChangeCallback(ACE_INSTANCE_ID, runArgs_.onRouterChange);
376     OHOS::Ace::Framework::InspectorClient::GetInstance().RegisterFastPreviewErrorCallback(runArgs_.onError);
377     // Should make it possible to update surface changes by using viewWidth and viewHeight.
378     view->NotifySurfaceChanged(runArgs_.deviceWidth, runArgs_.deviceHeight);
379     view->NotifyDensityChanged(runArgs_.deviceConfig.density);
380 }
381 
InitializeClipboard() const382 void AceAbility::InitializeClipboard() const
383 {
384     ClipboardProxy::GetInstance()->SetDelegate(std::make_unique<Platform::ClipboardProxyImpl>());
385 }
386 
OnBackPressed() const387 void AceAbility::OnBackPressed() const
388 {
389     LOGI("Process Back Pressed Event");
390     EventDispatcher::GetInstance().DispatchBackPressedEvent();
391 }
392 
OnInputEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const393 bool AceAbility::OnInputEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
394 {
395     return EventDispatcher::GetInstance().DispatchTouchEvent(pointerEvent);
396 }
397 
OnInputEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const398 bool AceAbility::OnInputEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
399 {
400     return EventDispatcher::GetInstance().DispatchKeyEvent(keyEvent);
401 }
402 
OnInputEvent(const std::shared_ptr<MMI::AxisEvent> & axisEvent) const403 bool AceAbility::OnInputEvent(const std::shared_ptr<MMI::AxisEvent>& axisEvent) const
404 {
405     return false;
406 }
407 
OnInputMethodEvent(const unsigned int codePoint) const408 bool AceAbility::OnInputMethodEvent(const unsigned int codePoint) const
409 {
410     return EventDispatcher::GetInstance().DispatchInputMethodEvent(codePoint);
411 }
412 
InitializeAppInfo()413 void AceAbility::InitializeAppInfo()
414 {
415     RefPtr<Context> context =
416         Context::CreateContext(runArgs_.projectModel == ProjectModel::STAGE, runArgs_.appResourcesPath);
417     if (runArgs_.projectModel == ProjectModel::STAGE) {
418         auto stageContext = AceType::DynamicCast<StageContext>(context);
419         CHECK_NULL_VOID(stageContext);
420         auto appInfo = stageContext->GetAppInfo();
421         CHECK_NULL_VOID(appInfo);
422         auto hapModuleInfo = stageContext->GetHapModuleInfo();
423         CHECK_NULL_VOID(hapModuleInfo);
424         bundleName_ = appInfo->GetBundleName();
425         moduleName_ = hapModuleInfo->GetModuleName();
426         compileMode_ = hapModuleInfo->GetCompileMode();
427         compatibleVersion_ = appInfo->GetMinAPIVersion();
428         auto targetVersion = appInfo->GetTargetAPIVersion();
429         AceApplicationInfo::GetInstance().SetApiTargetVersion(static_cast<int32_t>(targetVersion));
430         auto releaseType = appInfo->GetApiReleaseType();
431         bool enablePartialUpdate = hapModuleInfo->GetPartialUpdateFlag();
432         // only app should have menubar, card don't need
433         if (!runArgs_.formsEnabled) {
434             installationFree_ = appInfo->IsInstallationFree();
435             labelId_ = hapModuleInfo->GetLabelId();
436         }
437         useNewPipeline_ = AceNewPipeJudgement::QueryAceNewPipeEnabledStage(
438             "", compatibleVersion_, targetVersion, releaseType, !enablePartialUpdate);
439     } else {
440         auto faContext = AceType::DynamicCast<FaContext>(context);
441         CHECK_NULL_VOID(faContext);
442         auto appInfo = faContext->GetAppInfo();
443         CHECK_NULL_VOID(appInfo);
444         auto hapModuleInfo = faContext->GetHapModuleInfo();
445         CHECK_NULL_VOID(hapModuleInfo);
446         bundleName_ = appInfo->GetBundleName();
447         compatibleVersion_ = appInfo->GetMinAPIVersion();
448         auto targetVersion = appInfo->GetTargetAPIVersion();
449         auto releaseType = appInfo->GetApiReleaseType();
450         useNewPipeline_ =
451             AceNewPipeJudgement::QueryAceNewPipeEnabledFA("", compatibleVersion_, targetVersion, releaseType);
452     }
453 }
454 
SetConfigChanges(const std::string & configChanges)455 void AceAbility::SetConfigChanges(const std::string& configChanges)
456 {
457     if (configChanges == "") {
458         return;
459     }
460     std::vector<std::string> configChangesSplitter;
461     OHOS::Ace::StringUtils::StringSplitter(configChanges, ',', configChangesSplitter);
462     for (const auto& singleConfig : configChangesSplitter) {
463         if (singleConfig == "locale") {
464             configChanges_.watchLocale = true;
465             continue;
466         } else if (singleConfig == "layout") {
467             configChanges_.watchLayout = true;
468             continue;
469         } else if (singleConfig == "fontSize") {
470             configChanges_.watchFontSize = true;
471             continue;
472         } else if (singleConfig == "orientation") {
473             configChanges_.watchOrientation = true;
474             continue;
475         } else if (singleConfig == "density") {
476             configChanges_.watchDensity = true;
477             continue;
478         } else {
479             LOGW("unsupported config %{public}s", singleConfig.c_str());
480         }
481     }
482 }
483 
OnConfigurationChanged(const DeviceConfig & newConfig)484 void AceAbility::OnConfigurationChanged(const DeviceConfig& newConfig)
485 {
486     if (newConfig.colorMode == runArgs_.deviceConfig.colorMode) {
487         return;
488     }
489     int32_t width = runArgs_.deviceWidth;
490     int32_t height = runArgs_.deviceHeight;
491     SurfaceChanged(runArgs_.deviceConfig.orientation, runArgs_.deviceConfig.density, width, height);
492     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
493     if (!container) {
494         LOGW("container is null, change configuration failed.");
495         return;
496     }
497     container->UpdateDeviceConfig(newConfig);
498     runArgs_.deviceConfig.colorMode = newConfig.colorMode;
499     if (container->GetType() == FrontendType::DECLARATIVE_JS) {
500         container->NativeOnConfigurationUpdated(ACE_INSTANCE_ID);
501     }
502 }
503 
SurfaceChanged(const DeviceOrientation & orientation,const double & resolution,int32_t & width,int32_t & height,WindowSizeChangeReason type)504 void AceAbility::SurfaceChanged(
505     const DeviceOrientation& orientation, const double& resolution, int32_t& width, int32_t& height,
506     WindowSizeChangeReason type)
507 {
508     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
509     CHECK_NULL_VOID(container);
510     auto viewPtr = AceType::DynamicCast<AceViewPreview>(container->GetAceView());
511     CHECK_NULL_VOID(viewPtr);
512     // Need to change the window resolution and then change the rendering resolution. Otherwise, the image may not adapt
513     // to the new window after the window is modified.
514     auto context = container->GetPipelineContext();
515     CHECK_NULL_VOID(context);
516     context->SetDisplayWindowRectInfo(Rect(Offset(0, 0), Size(width, height)));
517     SystemProperties::InitDeviceInfo(
518         width, height, orientation == DeviceOrientation::PORTRAIT ? 0 : 1, resolution, runArgs_.isRound);
519     DeviceConfig deviceConfig = runArgs_.deviceConfig;
520     deviceConfig.orientation = orientation;
521     deviceConfig.density = resolution;
522     container->UpdateDeviceConfig(deviceConfig);
523     viewPtr->NotifyDensityChanged(resolution);
524     viewPtr->NotifySurfaceChanged(width, height, type);
525     if ((orientation != runArgs_.deviceConfig.orientation && configChanges_.watchOrientation) ||
526         (resolution != runArgs_.deviceConfig.density && configChanges_.watchDensity) ||
527         ((width != runArgs_.deviceWidth || height != runArgs_.deviceHeight) && configChanges_.watchLayout)) {
528         container->NativeOnConfigurationUpdated(ACE_INSTANCE_ID);
529     }
530     if (orientation != runArgs_.deviceConfig.orientation || resolution != runArgs_.deviceConfig.density) {
531         container->NotifyConfigurationChange(false, ConfigurationChange({ false, false, true }));
532     }
533     runArgs_.deviceConfig.orientation = orientation;
534     runArgs_.deviceConfig.density = resolution;
535     runArgs_.deviceWidth = width;
536     runArgs_.deviceHeight = height;
537 }
538 
ReplacePage(const std::string & url,const std::string & params)539 void AceAbility::ReplacePage(const std::string& url, const std::string& params)
540 {
541     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
542     CHECK_NULL_VOID(container);
543     container->GetFrontend()->ReplacePage(url, params);
544 }
545 
LoadDocument(const std::string & url,const std::string & componentName,SystemParams & systemParams)546 void AceAbility::LoadDocument(const std::string& url, const std::string& componentName, SystemParams& systemParams)
547 {
548     LOGI("Component Preview start:%{public}s, ", componentName.c_str());
549     AceApplicationInfo::GetInstance().ChangeLocale(systemParams.language, systemParams.region);
550     runArgs_.isRound = systemParams.isRound;
551     SurfaceChanged(systemParams.orientation, systemParams.density, systemParams.deviceWidth, systemParams.deviceHeight);
552     DeviceConfig deviceConfig = {
553         .orientation = systemParams.orientation,
554         .density = systemParams.density,
555         .deviceType = systemParams.deviceType,
556         .colorMode = systemParams.colorMode,
557     };
558     OnConfigurationChanged(deviceConfig);
559     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
560     CHECK_NULL_VOID(container);
561     container->LoadDocument(url, componentName);
562     LOGI("Component Preview end");
563 }
564 
GetJSONTree()565 std::string AceAbility::GetJSONTree()
566 {
567     LOGI("Inspector start");
568     std::string jsonTreeStr;
569     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
570     CHECK_NULL_RETURN(container, "");
571     auto taskExecutor = container->GetTaskExecutor();
572     CHECK_NULL_RETURN(taskExecutor, "");
573     taskExecutor->PostSyncTask(
574         [&jsonTreeStr] { OHOS::Ace::Framework::InspectorClient::GetInstance().AssembleJSONTreeStr(jsonTreeStr); },
575         TaskExecutor::TaskType::UI, "ArkUIGetJsonTreeStr");
576     LOGI("Inspector end");
577     return jsonTreeStr;
578 }
579 
GetDefaultJSONTree()580 std::string AceAbility::GetDefaultJSONTree()
581 {
582     std::string defaultJsonTreeStr;
583     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
584     CHECK_NULL_RETURN(container, "");
585     auto taskExecutor = container->GetTaskExecutor();
586     CHECK_NULL_RETURN(taskExecutor, "");
587     taskExecutor->PostSyncTask(
588         [&defaultJsonTreeStr] {
589             OHOS::Ace::Framework::InspectorClient::GetInstance().AssembleDefaultJSONTreeStr(defaultJsonTreeStr);
590         },
591         TaskExecutor::TaskType::UI, "ArkUIGetDefaultJsonTreeStr");
592     return defaultJsonTreeStr;
593 }
594 
OperateComponent(const std::string & attrsJson)595 bool AceAbility::OperateComponent(const std::string& attrsJson)
596 {
597     LOGI("Fast Preview start");
598     auto root = JsonUtil::ParseJsonString(attrsJson);
599     if (!root || !root->IsValid()) {
600         LOGE("Fast Preview failed: the attrsJson is illegal json format");
601         return false;
602     }
603 
604     auto container = AceContainer::GetContainerInstance(ACE_INSTANCE_ID);
605     if (!container) {
606         LOGE("Fast Preview failed: container is null");
607         return false;
608     }
609     auto taskExecutor = container->GetTaskExecutor();
610     if (!taskExecutor) {
611         LOGE("Fast Preview failed: taskExecutor is null");
612         return false;
613     }
614     taskExecutor->PostTask(
615         [attrsJson, instanceId = ACE_INSTANCE_ID] {
616             ContainerScope scope(instanceId);
617             bool result = OHOS::Ace::Framework::InspectorClient::GetInstance().OperateComponent(attrsJson);
618             if (!result) {
619                 OHOS::Ace::Framework::InspectorClient::GetInstance().CallFastPreviewErrorCallback(attrsJson);
620             }
621         },
622         TaskExecutor::TaskType::UI, "ArkUIOperateComponent");
623     LOGI("Fast Preview end");
624     return true;
625 }
626 
SetWindow(sptr<OHOS::Rosen::Window> rsWindow)627 void AceAbility::SetWindow(sptr<OHOS::Rosen::Window> rsWindow)
628 {
629     rsWindow_ = rsWindow;
630 }
631 
GetWindow()632 sptr<OHOS::Rosen::Window> AceAbility::GetWindow()
633 {
634     return rsWindow_;
635 }
636 
637 } // namespace OHOS::Ace::Platform
638