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