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 "root_scene.h"
17  
18  #include <bundlemgr/launcher_service.h>
19  #include <event_handler.h>
20  #include <input_manager.h>
21  #include <iremote_stub.h>
22  #include <transaction/rs_interfaces.h>
23  #include <ui_content.h>
24  #include <viewport_config.h>
25  
26  #include "app_mgr_client.h"
27  #include "fold_screen_state_internel.h"
28  #include "input_transfer_station.h"
29  #include "singleton.h"
30  #include "singleton_container.h"
31  
32  #include "anr_manager.h"
33  #include "intention_event_manager.h"
34  #include "window_manager_hilog.h"
35  
36  namespace OHOS {
37  namespace Rosen {
38  namespace {
39  constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "RootScene" };
40  const std::string INPUT_AND_VSYNC_THREAD = "InputAndVsyncThread";
41  
42  class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
43  public:
BundleStatusCallback(RootScene * rootScene)44      explicit BundleStatusCallback(RootScene* rootScene) : rootScene_(rootScene) {}
45      virtual ~BundleStatusCallback() = default;
46  
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)47      void OnBundleStateChanged(const uint8_t installType,
48          const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
49  
OnBundleAdded(const std::string & bundleName,const int userId)50      void OnBundleAdded(const std::string& bundleName, const int userId) override
51      {
52          rootScene_->OnBundleUpdated(bundleName);
53      }
54  
OnBundleUpdated(const std::string & bundleName,const int userId)55      void OnBundleUpdated(const std::string& bundleName, const int userId) override
56      {
57          rootScene_->OnBundleUpdated(bundleName);
58      }
59  
OnBundleRemoved(const std::string & bundleName,const int userId)60      void OnBundleRemoved(const std::string& bundleName, const int userId) override {}
61  
62  private:
63      RootScene* rootScene_;
64  };
65  } // namespace
66  
67  sptr<RootScene> RootScene::staticRootScene_;
68  std::function<void(const std::shared_ptr<AppExecFwk::Configuration>&)> RootScene::configurationUpdatedCallback_;
69  
RootScene()70  RootScene::RootScene()
71  {
72      launcherService_ = new AppExecFwk::LauncherService();
73      if (!launcherService_->RegisterCallback(new BundleStatusCallback(this))) {
74          WLOGFE("Failed to register bundle status callback.");
75      }
76  
77      NodeId nodeId = 0;
78      vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
79  }
80  
~RootScene()81  RootScene::~RootScene()
82  {
83      uiContent_ = nullptr;
84  }
85  
LoadContent(const std::string & contentUrl,napi_env env,napi_value storage,AbilityRuntime::Context * context)86  void RootScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage,
87      AbilityRuntime::Context* context)
88  {
89      if (context == nullptr) {
90          WLOGFE("context is nullptr!");
91          return;
92      }
93      uiContent_ = Ace::UIContent::Create(context, reinterpret_cast<NativeEngine*>(env));
94      if (uiContent_ == nullptr) {
95          WLOGFE("uiContent_ is nullptr!");
96          return;
97      }
98  
99      uiContent_->Initialize(this, contentUrl, storage);
100      uiContent_->Foreground();
101      uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
102      RegisterInputEventListener();
103      DelayedSingleton<ANRManager>::GetInstance()->Init();
104      DelayedSingleton<ANRManager>::GetInstance()->SetAnrObserver(([](int32_t pid) {
105          WLOGFD("Receive anr notice enter");
106          AppExecFwk::AppFaultDataBySA faultData;
107          faultData.faultType = AppExecFwk::FaultDataType::APP_FREEZE;
108          faultData.pid = pid;
109          faultData.errorObject.name = AppExecFwk::AppFreezeType::APP_INPUT_BLOCK;
110          faultData.errorObject.message = "User input does not respond normally, report by sceneBoard.";
111          faultData.errorObject.stack = "";
112          if (int32_t ret = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultData);
113              ret != 0) {
114              WLOGFE("NotifyAppFaultBySA failed, pid:%{public}d, errcode:%{public}d", pid, ret);
115          }
116          WLOGFD("Receive anr notice leave");
117      }));
118      DelayedSingleton<ANRManager>::GetInstance()->SetAppInfoGetter(
119          [](int32_t pid, std::string& bundleName, int32_t uid) {
120              int32_t ret = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetBundleNameByPid(
121                  pid, bundleName, uid);
122              if (ret != 0) {
123                  WLOGFE("GetBundleNameByPid failed, pid:%{public}d, errcode:%{public}d", pid, ret);
124              }
125          });
126  }
127  
SetDisplayOrientation(int32_t orientation)128  void RootScene::SetDisplayOrientation(int32_t orientation)
129  {
130      orientation_ = orientation;
131  }
132  
UpdateViewportConfig(const Rect & rect,WindowSizeChangeReason reason)133  void RootScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)
134  {
135      if (uiContent_ == nullptr) {
136          WLOGFE("uiContent_ is nullptr!");
137          return;
138      }
139      Ace::ViewportConfig config;
140      config.SetSize(rect.width_, rect.height_);
141      config.SetPosition(rect.posX_, rect.posY_);
142      config.SetDensity(density_);
143      config.SetOrientation(orientation_);
144      uiContent_->UpdateViewportConfig(config, reason);
145  }
146  
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)147  void RootScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
148  {
149      if (uiContent_) {
150          WLOGFD("in");
151          uiContent_->UpdateConfiguration(configuration);
152          if (configuration == nullptr) {
153              return;
154          }
155          std::string colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
156          bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
157          bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
158          if (ret == false) {
159              WLOGFE("SetGlobalDarkColorMode fail with colorMode : %{public}s", colorMode.c_str());
160          }
161      }
162  }
163  
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)164  void RootScene::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
165  {
166      WLOGFD("in");
167      if (staticRootScene_) {
168          staticRootScene_->UpdateConfiguration(configuration);
169          if (configurationUpdatedCallback_) {
170              configurationUpdatedCallback_(configuration);
171          }
172      }
173  }
174  
UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration> & configuration)175  void RootScene::UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
176  {
177      if (uiContent_ == nullptr) {
178          TLOGE(WmsLogTag::WMS_IMMS, "uiContent is null, winId: %{public}d", GetWindowId());
179          return;
180      }
181      TLOGI(WmsLogTag::WMS_IMMS, "winId: %{public}d", GetWindowId());
182      uiContent_->UpdateConfigurationSyncForAll(configuration);
183  }
184  
UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)185  void RootScene::UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
186  {
187      TLOGD(WmsLogTag::WMS_IMMS, "in");
188      if (staticRootScene_ != nullptr) {
189          staticRootScene_->UpdateConfigurationSync(configuration);
190      }
191  }
192  
RegisterInputEventListener()193  void RootScene::RegisterInputEventListener()
194  {
195      auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
196      if (mainEventRunner) {
197          WLOGFD("MainEventRunner is available");
198          eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
199      } else {
200          WLOGFD("MainEventRunner is not available");
201          eventHandler_ = AppExecFwk::EventHandler::Current();
202          if (!eventHandler_) {
203              eventHandler_ =
204                  std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
205          }
206      }
207      if (!(DelayedSingleton<IntentionEventManager>::GetInstance()->EnableInputEventListener(
208          uiContent_.get(), eventHandler_))) {
209          WLOGFE("EnableInputEventListener fail");
210      }
211      InputTransferStation::GetInstance().MarkRegisterToMMI();
212  }
213  
RequestVsync(const std::shared_ptr<VsyncCallback> & vsyncCallback)214  void RootScene::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
215  {
216      vsyncStation_->RequestVsync(vsyncCallback);
217  }
218  
GetVSyncPeriod()219  int64_t RootScene::GetVSyncPeriod()
220  {
221      return vsyncStation_->GetVSyncPeriod();
222  }
223  
FlushFrameRate(uint32_t rate,int32_t animatorExpectedFrameRate,uint32_t rateType)224  void RootScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
225  {
226      vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType);
227  }
228  
IsLastFrameLayoutFinished()229  bool RootScene::IsLastFrameLayoutFinished()
230  {
231      int32_t requestTimes = vsyncStation_->GetRequestVsyncTimes();
232      TLOGI(WmsLogTag::WMS_LAYOUT, "vsync request times: %{public}d", requestTimes);
233      return requestTimes <= 0;
234  }
235  
OnFlushUIParams()236  void RootScene::OnFlushUIParams()
237  {
238      vsyncStation_->DecreaseRequestVsyncTimes();
239  }
240  
OnBundleUpdated(const std::string & bundleName)241  void RootScene::OnBundleUpdated(const std::string& bundleName)
242  {
243      WLOGFD("bundle %{public}s updated", bundleName.c_str());
244      if (uiContent_) {
245          uiContent_->UpdateResource();
246      }
247  }
248  
SetOnConfigurationUpdatedCallback(const std::function<void (const std::shared_ptr<AppExecFwk::Configuration> &)> & callback)249  void RootScene::SetOnConfigurationUpdatedCallback(
250      const std::function<void(const std::shared_ptr<AppExecFwk::Configuration>&)>& callback)
251  {
252      configurationUpdatedCallback_ = callback;
253  }
254  
SetFrameLayoutFinishCallback(std::function<void ()> && callback)255  void RootScene::SetFrameLayoutFinishCallback(std::function<void()>&& callback)
256  {
257      frameLayoutFinishCb_ = callback;
258      if (uiContent_) {
259          uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
260      }
261      TLOGI(WmsLogTag::WMS_LAYOUT, "end");
262  }
263  
SetUiDvsyncSwitch(bool dvsyncSwitch)264  void RootScene::SetUiDvsyncSwitch(bool dvsyncSwitch)
265  {
266      vsyncStation_->SetUiDvsyncSwitch(dvsyncSwitch);
267  }
268  
GetSessionRectByType(AvoidAreaType type,WSRect & rect)269  WMError RootScene::GetSessionRectByType(AvoidAreaType type, WSRect& rect)
270  {
271      if (getSessionRectCallback_ == nullptr) {
272          TLOGE(WmsLogTag::WMS_IMMS, "getSessionRectCallback is nullptr");
273          return WMError::WM_ERROR_NULLPTR;
274      }
275      rect = getSessionRectCallback_(type);
276      return WMError::WM_OK;
277  }
278  } // namespace Rosen
279  } // namespace OHOS
280