/* * Copyright (c) 2024 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 "screen_scene.h" #include #include #include #include "app_mgr_client.h" #include "singleton.h" #include "singleton_container.h" #include "dm_common.h" #include "window_manager_hilog.h" namespace OHOS { namespace Rosen { namespace { constexpr float MIN_DPI = 1e-6; std::atomic g_ssIsDestroyed = false; } // namespace ScreenScene::ScreenScene(std::string name) : name_(name) { orientation_ = static_cast(DisplayOrientation::PORTRAIT); NodeId nodeId = 0; vsyncStation_ = std::make_shared(nodeId); handler_ = std::make_shared(AppExecFwk::EventRunner::GetMainEventRunner()); g_ssIsDestroyed = false; displayId_ = DISPLAY_ID_INVALID; } ScreenScene::~ScreenScene() { g_ssIsDestroyed = true; Destroy(); } WMError ScreenScene::Destroy() { std::function task; //延长task的生命周期 { std::lock_guard lock(mutex_); if (!uiContent_) { TLOGD(WmsLogTag::DMS, "Destroy uiContent_ is nullptr!"); return WMError::WM_OK; } std::shared_ptr uiContent = std::move(uiContent_); uiContent_ = nullptr; vsyncStation_->Destroy(); task = [uiContent]() { if (uiContent != nullptr) { uiContent->Destroy(); TLOGD(WmsLogTag::DMS, "ScreenScene: uiContent destroy success!"); } }; } if (handler_) { handler_->PostSyncTask(task, "ScreenScene:Destroy"); } else { task(); } return WMError::WM_OK; } void ScreenScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage, AbilityRuntime::Context* context) { if (g_ssIsDestroyed) { TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!"); return; } if (context == nullptr) { TLOGE(WmsLogTag::DMS, "context is nullptr!"); return; } std::lock_guard lock(mutex_); uiContent_ = Ace::UIContent::Create(context, reinterpret_cast(env)); if (uiContent_ == nullptr) { TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!"); return; } uiContent_->Initialize(this, contentUrl, storage); uiContent_->Foreground(); uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_)); } void ScreenScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason) { if (g_ssIsDestroyed) { TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!"); return; } std::lock_guard lock(mutex_); if (uiContent_ == nullptr) { TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!"); return; } Ace::ViewportConfig config; config.SetSize(rect.width_, rect.height_); config.SetPosition(rect.posX_, rect.posY_); config.SetDensity(density_); config.SetOrientation(orientation_); config.SetDisplayId(GetDisplayId()); uiContent_->UpdateViewportConfig(config, reason); } void ScreenScene::UpdateConfiguration(const std::shared_ptr& configuration) { if (g_ssIsDestroyed) { TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!"); return; } std::lock_guard lock(mutex_); if (uiContent_) { TLOGD(WmsLogTag::DMS, "notify root scene ace"); uiContent_->UpdateConfiguration(configuration); } } void ScreenScene::RequestVsync(const std::shared_ptr& vsyncCallback) { vsyncStation_->RequestVsync(vsyncCallback); } int64_t ScreenScene::GetVSyncPeriod() { return vsyncStation_->GetVSyncPeriod(); } void ScreenScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType) { vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType); } void ScreenScene::OnBundleUpdated(const std::string& bundleName) { if (g_ssIsDestroyed) { TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!"); return; } TLOGD(WmsLogTag::DMS, "bundle %{public}s updated", bundleName.c_str()); std::lock_guard lock(mutex_); if (uiContent_) { uiContent_->UpdateResource(); } } void ScreenScene::SetFrameLayoutFinishCallback(std::function&& callback) { if (g_ssIsDestroyed) { TLOGI(WmsLogTag::DMS, "ScreenScene has been destructed!"); return; } frameLayoutFinishCb_ = callback; std::lock_guard lock(mutex_); if (uiContent_) { uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_)); frameLayoutFinishCb_ = nullptr; } TLOGI(WmsLogTag::WMS_LAYOUT, "SetFrameLayoutFinishCallback end"); } void ScreenScene::SetDisplayDensity(float density) { if (density < MIN_DPI) { TLOGE(WmsLogTag::DMS, "invalid density"); return; } density_ = density; } uint64_t ScreenScene::GetDisplayId() const { return displayId_; } void ScreenScene::SetDisplayId(DisplayId displayId) { displayId_ = displayId; } void ScreenScene::SetDisplayOrientation(int32_t orientation) { if (orientation < static_cast(DisplayOrientation::PORTRAIT) || orientation > static_cast(DisplayOrientation::UNKNOWN)) { TLOGE(WmsLogTag::DMS, "invalid orientation"); return; } orientation_ = orientation; } Ace::UIContent* ScreenScene::GetUIContent() const { std::lock_guard lock(mutex_); if (uiContent_) { return uiContent_.get(); } else { TLOGE(WmsLogTag::DMS, "uiContent_ is nullptr!"); return nullptr; } } } // namespace Rosen } // namespace OHOS