1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci#include "screen_manager_lite.h"
16e0dac50fSopenharmony_ci#include <cinttypes>
17e0dac50fSopenharmony_ci#include "display_manager_adapter_lite.h"
18e0dac50fSopenharmony_ci#include "display_manager_agent_default.h"
19e0dac50fSopenharmony_ci#include "singleton_delegator.h"
20e0dac50fSopenharmony_ci#include "window_manager_hilog.h"
21e0dac50fSopenharmony_ci
22e0dac50fSopenharmony_cinamespace OHOS::Rosen {
23e0dac50fSopenharmony_cinamespace {
24e0dac50fSopenharmony_ci    constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenManagerLite"};
25e0dac50fSopenharmony_ci}
26e0dac50fSopenharmony_ci
27e0dac50fSopenharmony_ci/*
28e0dac50fSopenharmony_ci * used by powermgr
29e0dac50fSopenharmony_ci */
30e0dac50fSopenharmony_ciclass ScreenManagerLite::Impl : public RefBase {
31e0dac50fSopenharmony_cipublic:
32e0dac50fSopenharmony_ci    Impl() = default;
33e0dac50fSopenharmony_ci    ~Impl();
34e0dac50fSopenharmony_ci
35e0dac50fSopenharmony_ci    static inline SingletonDelegator<ScreenManagerLite> delegator;
36e0dac50fSopenharmony_ci    DMError RegisterScreenListener(sptr<IScreenListener> listener);
37e0dac50fSopenharmony_ci    DMError UnregisterScreenListener(sptr<IScreenListener> listener);
38e0dac50fSopenharmony_ci    DMError RegisterDisplayManagerAgent();
39e0dac50fSopenharmony_ci    DMError UnregisterDisplayManagerAgent();
40e0dac50fSopenharmony_ci    void OnRemoteDied();
41e0dac50fSopenharmony_ci
42e0dac50fSopenharmony_ciprivate:
43e0dac50fSopenharmony_ci    void NotifyScreenConnect(sptr<ScreenInfo> info);
44e0dac50fSopenharmony_ci    void NotifyScreenDisconnect(ScreenId);
45e0dac50fSopenharmony_ci    void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
46e0dac50fSopenharmony_ci
47e0dac50fSopenharmony_ci    class ScreenManagerListener;
48e0dac50fSopenharmony_ci    sptr<ScreenManagerListener> screenManagerListener_;
49e0dac50fSopenharmony_ci    std::mutex mutex_;
50e0dac50fSopenharmony_ci    std::set<sptr<IScreenListener>> screenListeners_;
51e0dac50fSopenharmony_ci};
52e0dac50fSopenharmony_ci
53e0dac50fSopenharmony_ciclass ScreenManagerLite::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
54e0dac50fSopenharmony_cipublic:
55e0dac50fSopenharmony_ci    explicit ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
56e0dac50fSopenharmony_ci    {
57e0dac50fSopenharmony_ci    }
58e0dac50fSopenharmony_ci
59e0dac50fSopenharmony_ci    void OnScreenConnect(sptr<ScreenInfo> screenInfo)
60e0dac50fSopenharmony_ci    {
61e0dac50fSopenharmony_ci        if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
62e0dac50fSopenharmony_ci            WLOGFE("OnScreenConnect, screenInfo is invalid.");
63e0dac50fSopenharmony_ci            return;
64e0dac50fSopenharmony_ci        }
65e0dac50fSopenharmony_ci        if (pImpl_ == nullptr) {
66e0dac50fSopenharmony_ci            WLOGFE("OnScreenConnect, impl is nullptr.");
67e0dac50fSopenharmony_ci            return;
68e0dac50fSopenharmony_ci        }
69e0dac50fSopenharmony_ci        std::lock_guard<std::mutex> lock(pImpl_->mutex_);
70e0dac50fSopenharmony_ci        for (auto listener : pImpl_->screenListeners_) {
71e0dac50fSopenharmony_ci            listener->OnConnect(screenInfo->GetScreenId());
72e0dac50fSopenharmony_ci        }
73e0dac50fSopenharmony_ci    };
74e0dac50fSopenharmony_ci
75e0dac50fSopenharmony_ci    void OnScreenDisconnect(ScreenId screenId)
76e0dac50fSopenharmony_ci    {
77e0dac50fSopenharmony_ci        if (screenId == SCREEN_ID_INVALID) {
78e0dac50fSopenharmony_ci            WLOGFE("OnScreenDisconnect, screenId is invalid.");
79e0dac50fSopenharmony_ci            return;
80e0dac50fSopenharmony_ci        }
81e0dac50fSopenharmony_ci        if (pImpl_ == nullptr) {
82e0dac50fSopenharmony_ci            WLOGFE("OnScreenDisconnect, impl is nullptr.");
83e0dac50fSopenharmony_ci            return;
84e0dac50fSopenharmony_ci        }
85e0dac50fSopenharmony_ci        std::lock_guard<std::mutex> lock(pImpl_->mutex_);
86e0dac50fSopenharmony_ci        for (auto listener : pImpl_->screenListeners_) {
87e0dac50fSopenharmony_ci            listener->OnDisconnect(screenId);
88e0dac50fSopenharmony_ci        }
89e0dac50fSopenharmony_ci    };
90e0dac50fSopenharmony_ci
91e0dac50fSopenharmony_ci    void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
92e0dac50fSopenharmony_ci    {
93e0dac50fSopenharmony_ci        if (screenInfo == nullptr) {
94e0dac50fSopenharmony_ci            WLOGFE("OnScreenChange, screenInfo is null.");
95e0dac50fSopenharmony_ci            return;
96e0dac50fSopenharmony_ci        }
97e0dac50fSopenharmony_ci        if (pImpl_ == nullptr) {
98e0dac50fSopenharmony_ci            WLOGFE("OnScreenChange, impl is nullptr.");
99e0dac50fSopenharmony_ci            return;
100e0dac50fSopenharmony_ci        }
101e0dac50fSopenharmony_ci        WLOGFD("OnScreenChange. event %{public}u", event);
102e0dac50fSopenharmony_ci        std::lock_guard<std::mutex> lock(pImpl_->mutex_);
103e0dac50fSopenharmony_ci        for (auto listener: pImpl_->screenListeners_) {
104e0dac50fSopenharmony_ci            listener->OnChange(screenInfo->GetScreenId());
105e0dac50fSopenharmony_ci        }
106e0dac50fSopenharmony_ci    };
107e0dac50fSopenharmony_ciprivate:
108e0dac50fSopenharmony_ci    sptr<Impl> pImpl_;
109e0dac50fSopenharmony_ci};
110e0dac50fSopenharmony_ci
111e0dac50fSopenharmony_ciWM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)
112e0dac50fSopenharmony_ci
113e0dac50fSopenharmony_ciScreenManagerLite::ScreenManagerLite()
114e0dac50fSopenharmony_ci{
115e0dac50fSopenharmony_ci    pImpl_ = new Impl();
116e0dac50fSopenharmony_ci    WLOGFD("Create ScreenManagerLite instance");
117e0dac50fSopenharmony_ci}
118e0dac50fSopenharmony_ci
119e0dac50fSopenharmony_ciScreenManagerLite::~ScreenManagerLite()
120e0dac50fSopenharmony_ci{
121e0dac50fSopenharmony_ci    WLOGFD("Destroy ScreenManagerLite instance");
122e0dac50fSopenharmony_ci}
123e0dac50fSopenharmony_ci
124e0dac50fSopenharmony_ciScreenManagerLite::Impl::~Impl()
125e0dac50fSopenharmony_ci{
126e0dac50fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
127e0dac50fSopenharmony_ci    UnregisterDisplayManagerAgent();
128e0dac50fSopenharmony_ci}
129e0dac50fSopenharmony_ci
130e0dac50fSopenharmony_ciDMError ScreenManagerLite::Impl::RegisterDisplayManagerAgent()
131e0dac50fSopenharmony_ci{
132e0dac50fSopenharmony_ci    DMError regSucc = DMError::DM_OK;
133e0dac50fSopenharmony_ci    if (screenManagerListener_ == nullptr) {
134e0dac50fSopenharmony_ci        screenManagerListener_ = new ScreenManagerListener(this);
135e0dac50fSopenharmony_ci        regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
136e0dac50fSopenharmony_ci            screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
137e0dac50fSopenharmony_ci        if (regSucc != DMError::DM_OK) {
138e0dac50fSopenharmony_ci            screenManagerListener_ = nullptr;
139e0dac50fSopenharmony_ci            WLOGFW("RegisterDisplayManagerAgent failed !");
140e0dac50fSopenharmony_ci        }
141e0dac50fSopenharmony_ci    }
142e0dac50fSopenharmony_ci    return regSucc;
143e0dac50fSopenharmony_ci}
144e0dac50fSopenharmony_ci
145e0dac50fSopenharmony_ciDMError ScreenManagerLite::Impl::UnregisterDisplayManagerAgent()
146e0dac50fSopenharmony_ci{
147e0dac50fSopenharmony_ci    DMError unRegSucc = DMError::DM_OK;
148e0dac50fSopenharmony_ci    if (screenManagerListener_ != nullptr) {
149e0dac50fSopenharmony_ci        unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
150e0dac50fSopenharmony_ci            screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
151e0dac50fSopenharmony_ci        screenManagerListener_ = nullptr;
152e0dac50fSopenharmony_ci        if (unRegSucc != DMError::DM_OK) {
153e0dac50fSopenharmony_ci            WLOGFW("UnregisterDisplayManagerAgent failed!");
154e0dac50fSopenharmony_ci        }
155e0dac50fSopenharmony_ci    }
156e0dac50fSopenharmony_ci    return unRegSucc;
157e0dac50fSopenharmony_ci}
158e0dac50fSopenharmony_ci
159e0dac50fSopenharmony_ciDMError ScreenManagerLite::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
160e0dac50fSopenharmony_ci{
161e0dac50fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
162e0dac50fSopenharmony_ci    DMError regSucc = RegisterDisplayManagerAgent();
163e0dac50fSopenharmony_ci    if (regSucc == DMError::DM_OK) {
164e0dac50fSopenharmony_ci        screenListeners_.insert(listener);
165e0dac50fSopenharmony_ci    }
166e0dac50fSopenharmony_ci    return regSucc;
167e0dac50fSopenharmony_ci}
168e0dac50fSopenharmony_ci
169e0dac50fSopenharmony_ciDMError ScreenManagerLite::RegisterScreenListener(sptr<IScreenListener> listener)
170e0dac50fSopenharmony_ci{
171e0dac50fSopenharmony_ci    if (listener == nullptr) {
172e0dac50fSopenharmony_ci        WLOGFE("RegisterScreenListener listener is nullptr.");
173e0dac50fSopenharmony_ci        return DMError::DM_ERROR_NULLPTR;
174e0dac50fSopenharmony_ci    }
175e0dac50fSopenharmony_ci    return pImpl_->RegisterScreenListener(listener);
176e0dac50fSopenharmony_ci}
177e0dac50fSopenharmony_ci
178e0dac50fSopenharmony_ciDMError ScreenManagerLite::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
179e0dac50fSopenharmony_ci{
180e0dac50fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
181e0dac50fSopenharmony_ci    auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
182e0dac50fSopenharmony_ci    if (iter == screenListeners_.end()) {
183e0dac50fSopenharmony_ci        WLOGFE("could not find this listener");
184e0dac50fSopenharmony_ci        return DMError::DM_ERROR_NULLPTR;
185e0dac50fSopenharmony_ci    }
186e0dac50fSopenharmony_ci    screenListeners_.erase(iter);
187e0dac50fSopenharmony_ci    return UnregisterDisplayManagerAgent();
188e0dac50fSopenharmony_ci}
189e0dac50fSopenharmony_ci
190e0dac50fSopenharmony_ciDMError ScreenManagerLite::UnregisterScreenListener(sptr<IScreenListener> listener)
191e0dac50fSopenharmony_ci{
192e0dac50fSopenharmony_ci    if (listener == nullptr) {
193e0dac50fSopenharmony_ci        WLOGFE("UnregisterScreenListener listener is nullptr.");
194e0dac50fSopenharmony_ci        return DMError::DM_ERROR_NULLPTR;
195e0dac50fSopenharmony_ci    }
196e0dac50fSopenharmony_ci    return pImpl_->UnregisterScreenListener(listener);
197e0dac50fSopenharmony_ci}
198e0dac50fSopenharmony_ci
199e0dac50fSopenharmony_cibool ScreenManagerLite::SetSpecifiedScreenPower(ScreenId screenId,
200e0dac50fSopenharmony_ci    ScreenPowerState state, PowerStateChangeReason reason)
201e0dac50fSopenharmony_ci{
202e0dac50fSopenharmony_ci    WLOGFI("screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason);
203e0dac50fSopenharmony_ci    return SingletonContainer::Get<ScreenManagerAdapterLite>().SetSpecifiedScreenPower(screenId, state, reason);
204e0dac50fSopenharmony_ci}
205e0dac50fSopenharmony_ci
206e0dac50fSopenharmony_cibool ScreenManagerLite::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
207e0dac50fSopenharmony_ci{
208e0dac50fSopenharmony_ci    WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
209e0dac50fSopenharmony_ci    return SingletonContainer::Get<ScreenManagerAdapterLite>().SetScreenPowerForAll(state, reason);
210e0dac50fSopenharmony_ci}
211e0dac50fSopenharmony_ci
212e0dac50fSopenharmony_ciScreenPowerState ScreenManagerLite::GetScreenPower(ScreenId dmsScreenId)
213e0dac50fSopenharmony_ci{
214e0dac50fSopenharmony_ci    return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenPower(dmsScreenId);
215e0dac50fSopenharmony_ci}
216e0dac50fSopenharmony_ci
217e0dac50fSopenharmony_civoid ScreenManagerLite::Impl::OnRemoteDied()
218e0dac50fSopenharmony_ci{
219e0dac50fSopenharmony_ci    WLOGFD("dms is died");
220e0dac50fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
221e0dac50fSopenharmony_ci    screenManagerListener_ = nullptr;
222e0dac50fSopenharmony_ci}
223e0dac50fSopenharmony_ci
224e0dac50fSopenharmony_civoid ScreenManagerLite::OnRemoteDied()
225e0dac50fSopenharmony_ci{
226e0dac50fSopenharmony_ci    pImpl_->OnRemoteDied();
227e0dac50fSopenharmony_ci}
228e0dac50fSopenharmony_ci
229e0dac50fSopenharmony_ci} // namespace OHOS::Rosen