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 "hgm_config_callback_manager.h"
17 
18 #include "hgm_core.h"
19 #include "hgm_frame_rate_manager.h"
20 #include "hgm_log.h"
21 
22 namespace OHOS::Rosen {
23 std::once_flag HgmConfigCallbackManager::createFlag_;
24 sptr<HgmConfigCallbackManager> HgmConfigCallbackManager::instance_ = nullptr;
25 
GetInstance()26 sptr<HgmConfigCallbackManager> HgmConfigCallbackManager::GetInstance() noexcept
27 {
28     std::call_once(createFlag_, []() {
29         instance_ = new HgmConfigCallbackManager();
30     });
31     return instance_;
32 }
33 
HgmConfigCallbackManager()34 HgmConfigCallbackManager::HgmConfigCallbackManager()
35 {
36 }
37 
~HgmConfigCallbackManager()38 HgmConfigCallbackManager::~HgmConfigCallbackManager() noexcept
39 {
40     animDynamicCfgCallbacks_.clear();
41     refreshRateModeCallbacks_.clear();
42     instance_ = nullptr;
43 }
44 
RegisterHgmConfigChangeCallback(pid_t pid,const sptr<RSIHgmConfigChangeCallback> & callback)45 void HgmConfigCallbackManager::RegisterHgmConfigChangeCallback(
46     pid_t pid, const sptr<RSIHgmConfigChangeCallback>& callback)
47 {
48     if (callback == nullptr) {
49         HGM_LOGE("HgmConfigCallbackManager %{public}s : callback is null.", __func__);
50         return;
51     }
52     std::lock_guard<std::mutex> lock(mtx_);
53     animDynamicCfgCallbacks_[pid] = callback;
54     HGM_LOGD("HgmConfigCallbackManager %{public}s : add a remote callback succeed.", __func__);
55 
56     auto& hgmCore = HgmCore::Instance();
57     auto data = std::make_shared<RSHgmConfigData>();
58 
59     auto screenType = hgmCore.GetFrameRateMgr()->GetCurScreenStrategyId();
60     auto settingMode = std::to_string(hgmCore.GetCurrentRefreshRateMode());
61     auto configData = hgmCore.GetPolicyConfigData();
62     if (configData != nullptr) {
63         auto dynamicSettingMap = configData->GetAceSceneDynamicSettingMap(screenType, settingMode);
64         for (auto& [animType, dynamicSetting] : dynamicSettingMap) {
65             for (auto& [animName, dynamicConfig] : dynamicSetting) {
66                 data->AddAnimDynamicItem({
67                     animType, animName, dynamicConfig.min, dynamicConfig.max, dynamicConfig.preferred_fps});
68             }
69         }
70     }
71 
72     auto screen = hgmCore.GetActiveScreen();
73     if (screen != nullptr) {
74         data->SetPpi(screen->GetPpi());
75         data->SetXDpi(screen->GetXDpi());
76         data->SetYDpi(screen->GetYDpi());
77     }
78     callback->OnHgmConfigChanged(data);
79 }
80 
RegisterHgmRefreshRateModeChangeCallback(pid_t pid,const sptr<RSIHgmConfigChangeCallback> & callback)81 void HgmConfigCallbackManager::RegisterHgmRefreshRateModeChangeCallback(
82     pid_t pid, const sptr<RSIHgmConfigChangeCallback>& callback)
83 {
84     if (callback == nullptr) {
85         HGM_LOGE("HgmRefreshRateModeCallbackManager %{public}s : callback is null.", __func__);
86         return;
87     }
88     std::lock_guard<std::mutex> lock(mtx_);
89     refreshRateModeCallbacks_[pid] = callback;
90     HGM_LOGD("HgmRefreshRateModeCallbackManager %{public}s : add a remote callback succeed.", __func__);
91 
92     int32_t currentRefreshRateModeName = HgmCore::Instance().GetCurrentRefreshRateModeName();
93     callback->OnHgmRefreshRateModeChanged(currentRefreshRateModeName);
94 }
95 
RegisterHgmRefreshRateUpdateCallback(pid_t pid,const sptr<RSIHgmConfigChangeCallback> & callback)96 void HgmConfigCallbackManager::RegisterHgmRefreshRateUpdateCallback(
97     pid_t pid, const sptr<RSIHgmConfigChangeCallback>& callback)
98 {
99     std::lock_guard<std::mutex> lock(mtx_);
100     if (callback == nullptr) {
101         if (refreshRateUpdateCallbacks_.find(pid) != refreshRateUpdateCallbacks_.end()) {
102             refreshRateUpdateCallbacks_.erase(pid);
103             HGM_LOGD("refreshRateUpdateCallbacks unregister succ, remove pid %{public}u", pid);
104         }
105         return;
106     }
107     refreshRateUpdateCallbacks_[pid] = callback;
108     uint32_t currentRefreshRate =
109         HgmCore::Instance().GetScreenCurrentRefreshRate(HgmCore::Instance().GetActiveScreenId());
110     HGM_LOGD("%{public}s : currentRefreshRate = %{public}d", __func__, currentRefreshRate);
111     callback->OnHgmRefreshRateUpdate(currentRefreshRate);
112 }
113 
SyncHgmConfigChangeCallback()114 void HgmConfigCallbackManager::SyncHgmConfigChangeCallback()
115 {
116     std::lock_guard<std::mutex> lock(mtx_);
117     if (animDynamicCfgCallbacks_.empty()) {
118         return;
119     }
120 
121     auto& hgmCore = HgmCore::Instance();
122     auto data = std::make_shared<RSHgmConfigData>();
123 
124     auto screenType = hgmCore.GetFrameRateMgr()->GetCurScreenStrategyId();
125     auto settingMode = std::to_string(hgmCore.GetCurrentRefreshRateMode());
126     auto configData = hgmCore.GetPolicyConfigData();
127     if (configData != nullptr) {
128         auto dynamicSettingMap = configData->GetAceSceneDynamicSettingMap(screenType, settingMode);
129         for (auto& [animType, dynamicSetting] : dynamicSettingMap) {
130             for (auto& [animName, dynamicConfig] : dynamicSetting) {
131                 data->AddAnimDynamicItem({
132                     animType, animName, dynamicConfig.min, dynamicConfig.max, dynamicConfig.preferred_fps});
133             }
134         }
135     }
136 
137     auto screen = hgmCore.GetActiveScreen();
138     if (screen != nullptr) {
139         data->SetPpi(screen->GetPpi());
140         data->SetXDpi(screen->GetXDpi());
141         data->SetYDpi(screen->GetYDpi());
142     }
143 
144     for (auto& callback : animDynamicCfgCallbacks_) {
145         if (callback.second) {
146             callback.second->OnHgmConfigChanged(data);
147         }
148     }
149 }
150 
SyncRefreshRateModeChangeCallback(int32_t refreshRateMode)151 void HgmConfigCallbackManager::SyncRefreshRateModeChangeCallback(int32_t refreshRateMode)
152 {
153     std::lock_guard<std::mutex> lock(mtx_);
154     for (const auto& [_, callback] : refreshRateModeCallbacks_) {
155         if (callback) {
156             callback->OnHgmRefreshRateModeChanged(refreshRateMode);
157         }
158     }
159 }
160 
SyncRefreshRateUpdateCallback(int32_t refreshRate)161 void HgmConfigCallbackManager::SyncRefreshRateUpdateCallback(int32_t refreshRate)
162 {
163     std::lock_guard<std::mutex> lock(mtx_);
164     for (const auto& callback : refreshRateUpdateCallbacks_) {
165         if (callback.second != nullptr) {
166             callback.second->OnHgmRefreshRateUpdate(refreshRate);
167         }
168     }
169 }
170 
UnRegisterHgmConfigChangeCallback(pid_t pid)171 void HgmConfigCallbackManager::UnRegisterHgmConfigChangeCallback(pid_t pid)
172 {
173     std::lock_guard<std::mutex> lock(mtx_);
174     if (animDynamicCfgCallbacks_.find(pid) != animDynamicCfgCallbacks_.end()) {
175         animDynamicCfgCallbacks_.erase(pid);
176         HGM_LOGD("HgmConfigCallbackManager %{public}s : remove a remote callback succeed.", __func__);
177     }
178 
179     if (refreshRateModeCallbacks_.find(pid) != refreshRateModeCallbacks_.end()) {
180         refreshRateModeCallbacks_.erase(pid);
181         HGM_LOGD("HgmRefreshRateModeCallbackManager %{public}s : remove a remote callback succeed.", __func__);
182     }
183 }
184 } // namespace OHOS::Rosen