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 "intention_event_manager.h"
33#include "window_manager_hilog.h"
34
35namespace OHOS {
36namespace Rosen {
37namespace {
38constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "RootScene" };
39const std::string INPUT_AND_VSYNC_THREAD = "InputAndVsyncThread";
40
41class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
42public:
43    explicit BundleStatusCallback(RootScene* rootScene) : rootScene_(rootScene) {}
44    virtual ~BundleStatusCallback() = default;
45
46    void OnBundleStateChanged(const uint8_t installType,
47        const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
48
49    void OnBundleAdded(const std::string& bundleName, const int userId) override
50    {
51        rootScene_->OnBundleUpdated(bundleName);
52    }
53
54    void OnBundleUpdated(const std::string& bundleName, const int userId) override
55    {
56        rootScene_->OnBundleUpdated(bundleName);
57    }
58
59    void OnBundleRemoved(const std::string& bundleName, const int userId) override {}
60
61private:
62    RootScene* rootScene_;
63};
64} // namespace
65
66sptr<RootScene> RootScene::staticRootScene_;
67std::function<void(const std::shared_ptr<AppExecFwk::Configuration>&)> RootScene::configurationUpdatedCallback_;
68
69RootScene::RootScene()
70{
71    launcherService_ = new AppExecFwk::LauncherService();
72    if (!launcherService_->RegisterCallback(new BundleStatusCallback(this))) {
73        WLOGFE("Failed to register bundle status callback.");
74    }
75
76    NodeId nodeId = 0;
77    vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
78}
79
80RootScene::~RootScene()
81{
82    uiContent_ = nullptr;
83}
84
85void RootScene::LoadContent(const std::string& contentUrl, napi_env env, napi_value storage,
86    AbilityRuntime::Context* context)
87{
88    if (context == nullptr) {
89        WLOGFE("context is nullptr!");
90        return;
91    }
92    uiContent_ = Ace::UIContent::Create(context, reinterpret_cast<NativeEngine*>(env));
93    if (uiContent_ == nullptr) {
94        WLOGFE("uiContent_ is nullptr!");
95        return;
96    }
97
98    uiContent_->Initialize(this, contentUrl, storage);
99    uiContent_->Foreground();
100    uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
101    RegisterInputEventListener();
102}
103
104void RootScene::SetDisplayOrientation(int32_t orientation)
105{
106    orientation_ = orientation;
107}
108
109void RootScene::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason)
110{
111    if (uiContent_ == nullptr) {
112        WLOGFE("uiContent_ is nullptr!");
113        return;
114    }
115    Ace::ViewportConfig config;
116    config.SetSize(rect.width_, rect.height_);
117    config.SetPosition(rect.posX_, rect.posY_);
118    config.SetDensity(density_);
119    config.SetOrientation(orientation_);
120    uiContent_->UpdateViewportConfig(config, reason);
121}
122
123void RootScene::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
124{
125    if (uiContent_) {
126        WLOGFD("in");
127        uiContent_->UpdateConfiguration(configuration);
128        if (configuration == nullptr) {
129            return;
130        }
131        std::string colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
132        bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
133        bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
134        if (ret == false) {
135            WLOGFE("SetGlobalDarkColorMode fail with colorMode : %{public}s", colorMode.c_str());
136        }
137    }
138}
139
140void RootScene::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
141{
142    WLOGFD("in");
143    if (staticRootScene_) {
144        staticRootScene_->UpdateConfiguration(configuration);
145        if (configurationUpdatedCallback_) {
146            configurationUpdatedCallback_(configuration);
147        }
148    }
149}
150
151void RootScene::RegisterInputEventListener()
152{
153    auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
154    if (mainEventRunner) {
155        WLOGFD("MainEventRunner is available");
156        eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
157    } else {
158        WLOGFD("MainEventRunner is not available");
159        eventHandler_ = AppExecFwk::EventHandler::Current();
160        if (!eventHandler_) {
161            eventHandler_ =
162                std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
163        }
164    }
165    if (!(DelayedSingleton<IntentionEventManager>::GetInstance()->EnableInputEventListener(
166        uiContent_.get(), eventHandler_))) {
167        WLOGFE("EnableInputEventListener fail");
168    }
169    InputTransferStation::GetInstance().MarkRegisterToMMI();
170}
171
172void RootScene::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
173{
174    vsyncStation_->RequestVsync(vsyncCallback);
175}
176
177int64_t RootScene::GetVSyncPeriod()
178{
179    return vsyncStation_->GetVSyncPeriod();
180}
181
182void RootScene::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
183{
184    vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType);
185}
186
187void RootScene::OnBundleUpdated(const std::string& bundleName)
188{
189    WLOGFD("bundle %{public}s updated", bundleName.c_str());
190    if (uiContent_) {
191        uiContent_->UpdateResource();
192    }
193}
194
195void RootScene::SetOnConfigurationUpdatedCallback(
196    const std::function<void(const std::shared_ptr<AppExecFwk::Configuration>&)>& callback)
197{
198    configurationUpdatedCallback_ = callback;
199}
200
201void RootScene::SetFrameLayoutFinishCallback(std::function<void()>&& callback)
202{
203    frameLayoutFinishCb_ = callback;
204    if (uiContent_) {
205        uiContent_->SetFrameLayoutFinishCallback(std::move(frameLayoutFinishCb_));
206    }
207    TLOGI(WmsLogTag::WMS_LAYOUT, "end");
208}
209
210void RootScene::SetUiDvsyncSwitch(bool dvsyncSwitch)
211{
212    vsyncStation_->SetUiDvsyncSwitch(dvsyncSwitch);
213}
214
215WMError RootScene::GetSessionRectByType(AvoidAreaType type, WSRect& rect)
216{
217    if (getSessionRectCallback_ == nullptr) {
218        TLOGE(WmsLogTag::WMS_IMMS, "getSessionRectCallback is nullptr");
219        return WMError::WM_ERROR_NULLPTR;
220    }
221    rect = getSessionRectCallback_(type);
222    return WMError::WM_OK;
223}
224} // namespace Rosen
225} // namespace OHOS
226