/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "root_scene.h" #include #include #include #include #include #include #include "app_mgr_client.h" #include "input_transfer_station.h" #include "singleton.h" #include "singleton_container.h" #include "anr_manager.h" #include "intention_event_manager.h" #include "vsync_station.h" #include "window_manager_hilog.h" #include "window_rate_manager.h" namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "RootScene" }; const std::string INPUT_AND_VSYNC_THREAD = "InputAndVsyncThread"; class BundleStatusCallback : public IRemoteStub { public: explicit BundleStatusCallback(RootScene* rootScene) : rootScene_(rootScene) {} virtual ~BundleStatusCallback() = default; void OnBundleStateChanged(const uint8_t installType, const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {} void OnBundleAdded(const std::string& bundleName, const int userId) override { rootScene_->OnBundleUpdated(bundleName); } void OnBundleUpdated(const std::string& bundleName, const int userId) override { rootScene_->OnBundleUpdated(bundleName); } void OnBundleRemoved(const std::string& bundleName, const int userId) override {} private: RootScene* rootScene_; }; } // namespace sptr RootScene::staticRootScene_; RootScene::RootScene() { launcherService_ = new AppExecFwk::LauncherService(); if (!launcherService_->RegisterCallback(new BundleStatusCallback(this))) { WLOGFE("Failed to register bundle status callback."); } } RootScene::~RootScene() { uiContent_ = nullptr; } void RootScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage, AbilityRuntime::Context* context) { if (context == nullptr) { WLOGFE("context is nullptr!"); return; } uiContent_ = Ace::UIContent::Create(context, reinterpret_cast(env)); if (uiContent_ == nullptr) { WLOGFE("uiContent_ is nullptr!"); return; } uiContent_->Initialize(this, contentUrl, storage); uiContent_->Foreground(); uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_)); RegisterInputEventListener(); DelayedSingleton::GetInstance()->Init(); DelayedSingleton::GetInstance()->SetAnrObserver(([](int32_t pid) { WLOGFD("Receive anr notice enter"); AppExecFwk::AppFaultDataBySA faultData; faultData.faultType = AppExecFwk::FaultDataType::APP_FREEZE; faultData.pid = pid; faultData.errorObject.name = AppExecFwk::AppFreezeType::APP_INPUT_BLOCK; faultData.errorObject.message = "User input does not respond normally, report by sceneBoard."; faultData.errorObject.stack = ""; if (int32_t ret = DelayedSingleton::GetInstance()->NotifyAppFaultBySA(faultData); ret != 0) { WLOGFE("NotifyAppFaultBySA failed, pid:%{public}d, errcode:%{public}d", pid, ret); } WLOGFD("Receive anr notice leave"); })); DelayedSingleton::GetInstance()->SetAppInfoGetter( [](int32_t pid, std::string& bundleName, int32_t uid) { int32_t ret = DelayedSingleton::GetInstance()->GetBundleNameByPid( pid, bundleName, uid); if (ret != 0) { WLOGFE("GetBundleNameByPid failed, pid:%{public}d, errcode:%{public}d", pid, ret); } }); } void RootScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason) { if (uiContent_ == nullptr) { WLOGFE("uiContent_ is nullptr!"); return; } Ace::ViewportConfig config; config.SetSize(rect.width_, rect.height_); config.SetPosition(rect.posX_, rect.posY_); config.SetDensity(density_); uiContent_->UpdateViewportConfig(config, reason); } void RootScene::UpdateConfiguration(const std::shared_ptr& configuration) { if (uiContent_) { WLOGFD("notify root scene ace"); uiContent_->UpdateConfiguration(configuration); } } void RootScene::UpdateConfigurationForAll(const std::shared_ptr& configuration) { WLOGD("notify root scene ace for all"); if (staticRootScene_) { staticRootScene_->UpdateConfiguration(configuration); } } void RootScene::RegisterInputEventListener() { auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner(); if (mainEventRunner) { WLOGFD("MainEventRunner is available"); eventHandler_ = std::make_shared(mainEventRunner); } else { WLOGFD("MainEventRunner is not available"); eventHandler_ = AppExecFwk::EventHandler::Current(); if (!eventHandler_) { eventHandler_ = std::make_shared(AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD)); } VsyncStation::GetInstance().SetIsMainHandlerAvailable(false); VsyncStation::GetInstance().SetVsyncEventHandler(eventHandler_); } if (!(DelayedSingleton::GetInstance()->EnableInputEventListener( uiContent_.get(), eventHandler_))) { WLOGFE("EnableInputEventListener fail"); } InputTransferStation::GetInstance().MarkRegisterToMMI(); } void RootScene::RequestVsync(const std::shared_ptr& vsyncCallback) { std::lock_guard lock(mutex_); VsyncStation::GetInstance().RequestVsync(vsyncCallback); } int64_t RootScene::GetVSyncPeriod() { std::lock_guard lock(mutex_); return VsyncStation::GetInstance().GetVSyncPeriod(); } void RootScene::FlushFrameRate(uint32_t rate) { std::lock_guard lock(mutex_); WindowRateManager::GetInstance().FlushFrameRateForRootWindow(rate); } void RootScene::OnBundleUpdated(const std::string& bundleName) { WLOGFD("bundle %{public}s updated", bundleName.c_str()); if (uiContent_) { uiContent_->UpdateResource(); } } void RootScene::SetFrameLayoutFinishCallback(std::function&& callback) { frameLayoutFinishCb_ = callback; if (uiContent_) { uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_)); } WLOGFI("[WMSLayout] SetFrameLayoutFinishCallback end"); } } // namespace Rosen } // namespace OHOS