• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 #include "adapter/ohos/entrance/ace_new_pipe_judgement.h"
24 #include "adapter/ohos/entrance/platform_event_callback.h"
25 #include "adapter/preview/entrance/ace_application_info.h"
26 #include "adapter/preview/entrance/ace_container.h"
27 #include "adapter/preview/entrance/clipboard/clipboard_impl.h"
28 #include "adapter/preview/entrance/clipboard/clipboard_proxy_impl.h"
29 #include "adapter/preview/entrance/event_dispatcher.h"
30 #include "adapter/preview/entrance/rs_dir_asset_provider.h"
31 #include "adapter/preview/external/multimodalinput/axis_event.h"
32 #include "adapter/preview/external/multimodalinput/key_event.h"
33 #include "adapter/preview/external/multimodalinput/pointer_event.h"
34 #include "adapter/preview/inspector/inspector_client.h"
35 #include "frameworks/base/log/log.h"
36 #include "frameworks/base/utils/utils.h"
37 #include "frameworks/bridge/common/utils/utils.h"
38 #include "frameworks/bridge/js_frontend/js_frontend.h"
39 #ifdef INIT_ICU_DATA_PATH
40 #include "unicode/putil.h"
41 #endif
42 
43 #include "frameworks/simulator/common/include/context.h"
44 
45 namespace OHOS::Ace {
46 
47 using namespace Platform;
48 
49 namespace {
50 
51 constexpr int32_t UNUSED_PAGE_ID = 1;
52 
53 #ifdef WINDOWS_PLATFORM
54 constexpr char DELIMITER[] = "\\";
55 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources\\base\\profile";
56 #else
57 constexpr char DELIMITER[] = "/";
58 constexpr char ASSET_PATH_SHARE_STAGE[] = "resources/base/profile";
59 #endif
60 
SetFontMgrConfig(const std::string & containerSdkPath)61 void SetFontMgrConfig(const std::string& containerSdkPath)
62 {
63     // To check if use ohos or container fonts.
64     std::string runtimeOS = "OHOS_Container";
65     std::string containerFontBasePath = containerSdkPath + DELIMITER + "resources" + DELIMITER + "fonts" + DELIMITER;
66     RSDirAssetProvider dirAsset(containerFontBasePath);
67     std::vector<std::string> fileList;
68     dirAsset.GetAssetList("", fileList);
69     if (containerSdkPath.empty() || fileList.empty()) {
70         runtimeOS = "OHOS";
71         containerFontBasePath = "";
72     }
73     LOGI("Runtime OS is %{public}s, and the container fontBasePath is %{public}s", runtimeOS.c_str(),
74         containerFontBasePath.c_str());
75     SkFontMgr::SetFontMgrConfig(runtimeOS, containerFontBasePath);
76 }
77 
78 } // namespace
79 
80 using ContentFinishCallback = std::function<void()>;
81 using ContentStartAbilityCallback = std::function<void(const std::string& address)>;
82 class ContentEventCallback final : public PlatformEventCallback {
83 public:
ContentEventCallback(ContentFinishCallback onFinish)84     explicit ContentEventCallback(ContentFinishCallback onFinish) : onFinish_(onFinish) {}
ContentEventCallback(ContentFinishCallback onFinish,ContentStartAbilityCallback onStartAbility)85     ContentEventCallback(ContentFinishCallback onFinish, ContentStartAbilityCallback onStartAbility)
86         : onFinish_(onFinish), onStartAbility_(onStartAbility)
87     {}
88     ~ContentEventCallback() override = default;
89 
OnFinish() const90     void OnFinish() const override
91     {
92         LOGI("UIContent OnFinish");
93         CHECK_NULL_VOID_NOLOG(onFinish_);
94         onFinish_();
95     }
96 
OnStartAbility(const std::string & address)97     void OnStartAbility(const std::string& address) override
98     {
99         LOGI("UIContent OnStartAbility");
100         CHECK_NULL_VOID_NOLOG(onStartAbility_);
101         onStartAbility_(address);
102     }
103 
OnStatusBarBgColorChanged(uint32_t color)104     void OnStatusBarBgColorChanged(uint32_t color) override
105     {
106         LOGI("UIContent OnStatusBarBgColorChanged");
107     }
108 
109 private:
110     ContentFinishCallback onFinish_;
111     ContentStartAbilityCallback onStartAbility_;
112 };
113 
114 class DragWindowListener : public OHOS::Rosen::IWindowDragListener {
115 public:
DragWindowListener(int32_t instanceId)116     explicit DragWindowListener(int32_t instanceId) : instanceId_(instanceId) {}
117     ~DragWindowListener() = default;
OnDrag(int32_t x,int32_t y,OHOS::Rosen::DragEvent event)118     void OnDrag(int32_t x, int32_t y, OHOS::Rosen::DragEvent event)
119     {
120         LOGI("[Engine Log] The feature is not supported on the previewer, and instanceId_ = %{public}d", instanceId_);
121     }
122 
123 private:
124     int32_t instanceId_ = -1;
125 };
126 
127 class TouchOutsideListener : public OHOS::Rosen::ITouchOutsideListener {
128 public:
TouchOutsideListener(int32_t instanceId)129     explicit TouchOutsideListener(int32_t instanceId) : instanceId_(instanceId) {}
130     ~TouchOutsideListener() = default;
131 
OnTouchOutside() const132     void OnTouchOutside() const
133     {
134         LOGI("[Engine Log] The feature is not supported on the previewer, and instanceId_ = %{public}d", instanceId_);
135     }
136 
137 private:
138     int32_t instanceId_ = -1;
139 };
140 
OHOS_ACE_CreateUIContent(void * context,void * runtime)141 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateUIContent(void* context, void* runtime)
142 {
143     LOGI("Ace lib loaded, CreateUIContent.");
144     return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime);
145 }
146 
OHOS_ACE_CreateFormContent(void * context,void * runtime,bool isCard)147 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateFormContent(void* context, void* runtime, bool isCard)
148 {
149     LOGI("Ace lib loaded, CreateFormUIContent.");
150     return new UIContentImpl(reinterpret_cast<OHOS::AbilityRuntime::Context*>(context), runtime, isCard);
151 }
152 
OHOS_ACE_CreateSubWindowUIContent(void * ability)153 extern "C" ACE_FORCE_EXPORT void* OHOS_ACE_CreateSubWindowUIContent(void* ability)
154 {
155     LOGI("Ace lib loaded, Create SubWindowUIContent.");
156     return new UIContentImpl(reinterpret_cast<OHOS::AppExecFwk::Ability*>(ability));
157 }
158 
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime)159 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime)
160     : instanceId_(ACE_INSTANCE_ID), runtime_(runtime)
161 {
162     // 基于Options的方式传递参数
163     auto options = context->GetOptions();
164     assetPath_ = options.assetPath;
165     systemResourcesPath_ = options.systemResourcePath;
166     appResourcesPath_ = options.appResourcePath;
167     containerSdkPath_ = options.containerSdkPath;
168     language_ = options.language;
169     region_ = options.region;
170     script_ = options.script;
171     themeId_ = options.themeId;
172     deviceWidth_ = options.deviceWidth;
173     deviceHeight_ = options.deviceHeight;
174     isRound_ = options.isRound;
175     onRouterChange_ = options.onRouterChange;
176     deviceConfig_.orientation = static_cast<DeviceOrientation>(options.deviceConfig.orientation);
177     deviceConfig_.deviceType = static_cast<DeviceType>(options.deviceConfig.deviceType);
178     deviceConfig_.colorMode = static_cast<ColorMode>(options.deviceConfig.colorMode);
179     deviceConfig_.density = options.deviceConfig.density;
180     deviceConfig_.fontRatio = options.deviceConfig.fontRatio;
181 
182     bundleName_ = options.bundleName;
183     compatibleVersion_ = options.compatibleVersion;
184     installationFree_ = options.installationFree;
185     labelId_ = options.labelId;
186     moduleName_ = options.moduleName;
187     compileMode_ = options.compileMode;
188     pageProfile_ = options.pageProfile;
189     const std::string profilePrefix = "$profile:";
190     if (pageProfile_.compare(0, profilePrefix.size(), profilePrefix) == 0) {
191         pageProfile_ = pageProfile_.substr(profilePrefix.length()).append(".json");
192     }
193     auto targetVersion = options.targetVersion;
194     auto releaseType = options.releaseType;
195     bool enablePartialUpdate = options.enablePartialUpdate;
196     useNewPipeline_ = AceNewPipeJudgement::QueryAceNewPipeEnabledStage(
197         "", compatibleVersion_, targetVersion, releaseType, !enablePartialUpdate);
198 }
199 
UIContentImpl(OHOS::AbilityRuntime::Context * context,void * runtime,bool isCard)200 UIContentImpl::UIContentImpl(OHOS::AbilityRuntime::Context* context, void* runtime, bool isCard)
201     : instanceId_(ACE_INSTANCE_ID), runtime_(runtime), isFormRender_(isCard)
202 {
203     LOGI("The constructor is used to support ets card, isFormRender_ = %{public}d", isFormRender_);
204 }
205 
UIContentImpl(OHOS::AppExecFwk::Ability * ability)206 UIContentImpl::UIContentImpl(OHOS::AppExecFwk::Ability* ability) : instanceId_(ACE_INSTANCE_ID) {}
207 
DestroyUIDirector()208 void UIContentImpl::DestroyUIDirector()
209 {
210     auto container = AceContainer::GetContainerInstance(instanceId_);
211     CHECK_NULL_VOID_NOLOG(container);
212     auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
213     CHECK_NULL_VOID_NOLOG(pipelineContext);
214     auto rsUIDirector = pipelineContext->GetRSUIDirector();
215     CHECK_NULL_VOID_NOLOG(rsUIDirector);
216     rsUIDirector->Destroy();
217 }
218 
DestroyCallback() const219 void UIContentImpl::DestroyCallback() const
220 {
221     auto container = AceContainer::GetContainerInstance(instanceId_);
222     CHECK_NULL_VOID(container);
223     auto pipelineContext = container->GetPipelineContext();
224     CHECK_NULL_VOID(pipelineContext);
225     pipelineContext->SetNextFrameLayoutCallback(nullptr);
226 }
227 
Initialize(OHOS::Rosen::Window * window,const std::string & url,NativeValue * storage)228 void UIContentImpl::Initialize(OHOS::Rosen::Window* window, const std::string& url, NativeValue* storage)
229 {
230     CommonInitialize(window, url, storage);
231     AceContainer::RunPage(instanceId_, UNUSED_PAGE_ID, url, "");
232 }
233 
GetContentInfo() const234 std::string UIContentImpl::GetContentInfo() const
235 {
236     LOGI("UIContent GetContentInfo");
237     return AceContainer::GetContentInfo(instanceId_);
238 }
239 
CommonInitialize(OHOS::Rosen::Window * window,const std::string & contentInfo,NativeValue * storage)240 void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
241 {
242     static std::once_flag onceFlag;
243     std::call_once(onceFlag, []() {
244         LOGI("Initialize for current process.");
245 #ifdef INIT_ICU_DATA_PATH
246         std::string icuPath = ".";
247         u_setDataDirectory(icuPath.c_str());
248 #endif
249         Container::UpdateCurrent(INSTANCE_ID_PLATFORM);
250         ClipboardProxy::GetInstance()->SetDelegate(std::make_unique<Platform::ClipboardProxyImpl>());
251     });
252     rsWindow_ = window;
253 
254     AceApplicationInfo::GetInstance().SetLocale(language_, region_, script_, "");
255     SetFontMgrConfig(containerSdkPath_);
256     EventDispatcher::GetInstance().Initialize();
257     SystemProperties::SetExtSurfaceEnabled(!containerSdkPath_.empty());
258     SystemProperties::InitDeviceInfo(deviceWidth_, deviceHeight_,
259         deviceConfig_.orientation == DeviceOrientation::PORTRAIT ? 0 : 1, deviceConfig_.density, isRound_);
260     SystemProperties::InitDeviceType(deviceConfig_.deviceType);
261     SystemProperties::SetColorMode(deviceConfig_.colorMode);
262     LOGI("CreateContainer with JSDECLARATIVE frontend");
263     AceContainer::CreateContainer(instanceId_, FrontendType::DECLARATIVE_JS, useNewPipeline_);
264     auto container = AceContainer::GetContainerInstance(instanceId_);
265     CHECK_NULL_VOID(container);
266     container->SetContainerSdkPath(containerSdkPath_);
267     container->SetIsFRSCardContainer(false);
268     if (runtime_) {
269         container->GetSettings().SetUsingSharedRuntime(true);
270         container->SetSharedRuntime(runtime_);
271     } else {
272         container->GetSettings().SetUsingSharedRuntime(false);
273     }
274     container->SetInstallationFree(installationFree_);
275     container->SetLabelId(labelId_);
276     auto config = container->GetResourceConfiguration();
277     config.SetDeviceType(SystemProperties::GetDeviceType());
278     config.SetOrientation(SystemProperties::GetDeviceOrientation());
279     config.SetDensity(SystemProperties::GetResolution());
280     config.SetColorMode(SystemProperties::GetColorMode());
281     config.SetFontRatio(deviceConfig_.fontRatio);
282     container->SetResourceConfiguration(config);
283     container->SetPageProfile(pageProfile_);
284     std::vector<std::string> paths;
285     paths.push_back(assetPath_);
286     std::string appResourcesPath(appResourcesPath_);
287     if (!OHOS::Ace::Framework::EndWith(appResourcesPath, DELIMITER)) {
288         appResourcesPath.append(DELIMITER);
289     }
290     paths.push_back(appResourcesPath);
291     paths.push_back(appResourcesPath + ASSET_PATH_SHARE_STAGE);
292     if (!containerSdkPath_.empty()) {
293         paths.push_back(containerSdkPath_);
294     }
295     AceContainer::AddAssetPath(instanceId_, "", paths);
296     AceContainer::SetResourcesPathAndThemeStyle(
297         instanceId_, systemResourcesPath_ + "/entry", appResourcesPath_, themeId_, deviceConfig_.colorMode);
298 
299     auto view = AceViewPreview::CreateView(instanceId_, false, container->GetSettings().usePlatformAsUIThread);
300     UIEnvCallback callback = [window = rsWindow_, id = instanceId_](
301                                  const OHOS::Ace::RefPtr<PipelineContext>& context) mutable {
302         CHECK_NULL_VOID(context);
303         CHECK_NULL_VOID(window);
304         auto director = OHOS::Rosen::RSUIDirector::Create();
305         CHECK_NULL_VOID(director);
306         director->SetRSSurfaceNode(window->GetSurfaceNode());
307         auto container = AceContainer::GetContainerInstance(id);
308         CHECK_NULL_VOID(container);
309         auto func = [taskExecutor = container->GetTaskExecutor(), id](const std::function<void()>& task) {
310             CHECK_NULL_VOID(taskExecutor);
311             ContainerScope scope(id);
312             taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
313         };
314         director->SetUITaskRunner(func);
315         director->Init();
316         context->SetRSUIDirector(director);
317     };
318     AceContainer::SetView(view, rsWindow_, deviceConfig_.density, deviceWidth_, deviceHeight_, callback);
319     // Drive the native engine with the platform thread.
320     container->RunNativeEngineLoop();
321     auto pipelineContext = container->GetPipelineContext();
322     if (pipelineContext) {
323         LOGI("Set MinPlatformVersion to %{public}d", compatibleVersion_);
324         pipelineContext->SetMinPlatformVersion(compatibleVersion_);
325     }
326     container->InitializeStageAppConfig(assetPath_, bundleName_, moduleName_, compileMode_);
327     AceContainer::AddRouterChangeCallback(instanceId_, onRouterChange_);
328     // Should make it possible to update surface changes by using viewWidth and viewHeight.
329     view->NotifySurfaceChanged(deviceWidth_, deviceHeight_);
330     view->NotifyDensityChanged(deviceConfig_.density);
331 }
332 
Destroy()333 void UIContentImpl::Destroy()
334 {
335     LOGI("UIContentImpl: window destroy");
336     AceContainer::DestroyContainer(instanceId_);
337 }
338 
GetBackgroundColor()339 uint32_t UIContentImpl::GetBackgroundColor()
340 {
341     auto container = AceContainer::GetContainerInstance(instanceId_);
342     CHECK_NULL_RETURN(container, 0x000000);
343     auto taskExecutor = container->GetTaskExecutor();
344     CHECK_NULL_RETURN(taskExecutor, 0x000000);
345     ContainerScope scope(instanceId_);
346     uint32_t bgColor = 0x000000;
347     taskExecutor->PostSyncTask(
348         [&bgColor, container]() {
349             CHECK_NULL_VOID(container);
350             auto pipelineContext = container->GetPipelineContext();
351             CHECK_NULL_VOID(pipelineContext);
352             bgColor = pipelineContext->GetAppBgColor().GetValue();
353         },
354         TaskExecutor::TaskType::UI);
355 
356     LOGI("UIContentImpl::GetBackgroundColor, value is %{public}u", bgColor);
357     return bgColor;
358 }
359 
SetBackgroundColor(uint32_t color)360 void UIContentImpl::SetBackgroundColor(uint32_t color)
361 {
362     LOGI("UIContentImpl: SetBackgroundColor color is %{public}u", color);
363     auto container = AceContainer::GetContainerInstance(instanceId_);
364     CHECK_NULL_VOID(container);
365     ContainerScope scope(instanceId_);
366     auto taskExecutor = container->GetTaskExecutor();
367     CHECK_NULL_VOID(taskExecutor);
368     taskExecutor->PostSyncTask(
369         [container, bgColor = color]() {
370             auto pipelineContext = container->GetPipelineContext();
371             CHECK_NULL_VOID(pipelineContext);
372             pipelineContext->SetAppBgColor(Color(bgColor));
373         },
374         TaskExecutor::TaskType::UI);
375 }
376 
ProcessBackPressed()377 bool UIContentImpl::ProcessBackPressed()
378 {
379     LOGI("Process Back Pressed Event");
380     return EventDispatcher::GetInstance().DispatchBackPressedEvent();
381 }
382 
ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)383 bool UIContentImpl::ProcessPointerEvent(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
384 {
385     LOGI("Process MMI::PointerEvent");
386     return EventDispatcher::GetInstance().DispatchTouchEvent(pointerEvent);
387 }
388 
ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent)389 bool UIContentImpl::ProcessKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent)
390 {
391     LOGI("Process MMI::KeyEvent");
392     return EventDispatcher::GetInstance().DispatchKeyEvent(keyEvent);
393 }
394 
ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent> & axisEvent)395 bool UIContentImpl::ProcessAxisEvent(const std::shared_ptr<OHOS::MMI::AxisEvent>& axisEvent)
396 {
397     LOGI("Process MMI::AxisEvent");
398     return false;
399 }
400 
ProcessVsyncEvent(uint64_t timeStampNanos)401 bool UIContentImpl::ProcessVsyncEvent(uint64_t timeStampNanos)
402 {
403     LOGI("Process VsyncEvent");
404     return false;
405 }
406 
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)407 void UIContentImpl::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config) {}
408 
UpdateViewportConfig(const ViewportConfig & config,OHOS::Rosen::WindowSizeChangeReason reason,const std::shared_ptr<OHOS::Rosen::RSTransaction> & rsTransaction)409 void UIContentImpl::UpdateViewportConfig(const ViewportConfig& config, OHOS::Rosen::WindowSizeChangeReason reason,
410     const std::shared_ptr<OHOS::Rosen::RSTransaction>& rsTransaction)
411 {
412     LOGI("ViewportConfig: %{public}s", config.ToString().c_str());
413     auto container = AceContainer::GetContainerInstance(instanceId_);
414     CHECK_NULL_VOID(container);
415     auto viewPtr = container->GetAceView();
416     CHECK_NULL_VOID(viewPtr);
417     SystemProperties::InitDeviceInfo(
418         config.Width(), config.Height(), config.Height() >= config.Width() ? 0 : 1, config.Density(), false);
419     deviceConfig_.orientation =
420         config.Height() >= config.Width() ? DeviceOrientation::PORTRAIT : DeviceOrientation::LANDSCAPE;
421     deviceConfig_.density = config.Density();
422     // Unlike the real machine, previewer require updating device configuration information to change window size.
423     container->UpdateDeviceConfig(deviceConfig_);
424     viewPtr->NotifyDensityChanged(config.Density());
425     viewPtr->NotifySurfaceChanged(config.Width(), config.Height());
426 }
427 
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)428 void UIContentImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
429 {
430     auto container = AceContainer::GetContainerInstance(instanceId_);
431     CHECK_NULL_VOID(container);
432     container->Dump(params, info);
433 }
434 
SetNextFrameLayoutCallback(std::function<void ()> && callback)435 void UIContentImpl::SetNextFrameLayoutCallback(std::function<void()>&& callback)
436 {
437     CHECK_NULL_VOID(callback);
438     auto container = AceContainer::GetContainerInstance(instanceId_);
439     CHECK_NULL_VOID(container);
440     auto pipelineContext = container->GetPipelineContext();
441     CHECK_NULL_VOID(pipelineContext);
442     pipelineContext->SetNextFrameLayoutCallback(std::move(callback));
443 }
444 
NotifyMemoryLevel(int32_t level)445 void UIContentImpl::NotifyMemoryLevel(int32_t level)
446 {
447     LOGI("Receive Memory level notification, level: %{public}d", level);
448     auto container = AceContainer::GetContainerInstance(instanceId_);
449     CHECK_NULL_VOID(container);
450     auto pipelineContext = container->GetPipelineContext();
451     CHECK_NULL_VOID(pipelineContext);
452     ContainerScope scope(instanceId_);
453     pipelineContext->NotifyMemoryLevel(level);
454 }
455 
CreateModalUIExtension(const AAFwk::Want & want,const ModalUIExtensionCallbacks & callbacks)456 int32_t UIContentImpl::CreateModalUIExtension(const AAFwk::Want& want, const ModalUIExtensionCallbacks& callbacks)
457 {
458     return 0;
459 }
460 
CloseModalUIExtension(int32_t sessionId)461 void UIContentImpl::CloseModalUIExtension(int32_t sessionId) {}
462 } // namespace OHOS::Ace
463