1 /*
2  * Copyright (c) 2024 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 "window_register_manager.h"
17 #include <transaction/rs_interfaces.h>
18 #include "window_manager_hilog.h"
19 
20 namespace OHOS {
21 namespace Rosen {
CjWindowRegisterManager()22 CjWindowRegisterManager::CjWindowRegisterManager()
23 {
24     listenerProcess_[CaseType::CASE_WINDOW_MANAGER] = {
25         {SYSTEM_BAR_TINT_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
26             {return this->ProcessSystemBarChangeRegister(listener, window, isRegister); } },
27         {GESTURE_NAVIGATION_ENABLED_CHANGE_CB,
28             [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
29             {return this->ProcessGestureNavigationEnabledChangeRegister(listener, window, isRegister); } },
30         {WATER_MARK_FLAG_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
31             {return this->ProcessWaterMarkFlagChangeRegister(listener, window, isRegister); } },
32     };
33     listenerProcess_[CaseType::CASE_WINDOW] = {
34         {WINDOW_SIZE_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
35             {return this->ProcessWindowChangeRegister(listener, window, isRegister); } },
36         {SYSTEM_AVOID_AREA_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
37             {return this->ProcessSystemAvoidAreaChangeRegister(listener, window, isRegister); } },
38         {AVOID_AREA_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
39             {return this->ProcessAvoidAreaChangeRegister(listener, window, isRegister); } },
40         {LIFECYCLE_EVENT_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
41             {return this->ProcessLifeCycleEventRegister(listener, window, isRegister); } },
42         {WINDOW_EVENT_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
43             {return this->ProcessLifeCycleEventRegister(listener, window, isRegister); } },
44         {KEYBOARD_HEIGHT_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
45             {return this->ProcessOccupiedAreaChangeRegister(listener, window, isRegister); } },
46         {TOUCH_OUTSIDE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
47             {return this->ProcessTouchOutsideRegister(listener, window, isRegister); } },
48         {SCREENSHOT_EVENT_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
49             {return this->ProcessScreenshotRegister(listener, window, isRegister); } },
50         {DIALOG_TARGET_TOUCH_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
51             {return this->ProcessDialogTargetTouchRegister(listener, window, isRegister); } },
52         {DIALOG_DEATH_RECIPIENT_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
53             {return this->ProcessDialogDeathRecipientRegister(listener, window, isRegister); } },
54         {WINDOW_STATUS_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
55             {return this->ProcessWindowStatusChangeRegister(listener, window, isRegister); } },
56         {WINDOW_TITLE_BUTTON_RECT_CHANGE_CB,
57             [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
58             {return this->ProcessWindowTitleButtonRectChangeRegister(listener, window, isRegister); } },
59         {WINDOW_VISIBILITY_CHANGE_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
60             {return this->ProcessWindowVisibilityChangeRegister(listener, window, isRegister); } },
61         {WINDOW_DISPLAYID_CHANGE_CB,
62             [this](const sptr<CjWindowListener>& listener, const sptr<Window>& window, bool isRegister)
63             { return this->ProcessDisplayIdChangeRegister(listener, window, isRegister); } },
64     };
65     listenerProcess_[CaseType::CASE_STAGE] = {
66         {WINDOW_STAGE_EVENT_CB, [this](sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
67             {return this->ProcessLifeCycleEventRegister(listener, window, isRegister); } },
68     };
69 }
70 
ProcessSystemBarChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)71 WmErrorCode CjWindowRegisterManager::ProcessSystemBarChangeRegister(
72     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
73 {
74     return WmErrorCode::WM_OK;
75 }
76 
ProcessGestureNavigationEnabledChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)77 WmErrorCode CjWindowRegisterManager::ProcessGestureNavigationEnabledChangeRegister(
78     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
79 {
80     return WmErrorCode::WM_OK;
81 }
82 
ProcessWaterMarkFlagChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)83 WmErrorCode CjWindowRegisterManager::ProcessWaterMarkFlagChangeRegister(
84     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
85 {
86     return WmErrorCode::WM_OK;
87 }
88 
ProcessWindowChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)89 WmErrorCode CjWindowRegisterManager::ProcessWindowChangeRegister(
90     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
91 {
92     return WmErrorCode::WM_OK;
93 }
94 
ProcessSystemAvoidAreaChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)95 WmErrorCode CjWindowRegisterManager::ProcessSystemAvoidAreaChangeRegister(
96     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
97 {
98     return WmErrorCode::WM_OK;
99 }
100 
ProcessAvoidAreaChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)101 WmErrorCode CjWindowRegisterManager::ProcessAvoidAreaChangeRegister(
102     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
103 {
104     return WmErrorCode::WM_OK;
105 }
106 
ProcessLifeCycleEventRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)107 WmErrorCode CjWindowRegisterManager::ProcessLifeCycleEventRegister(
108     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
109 {
110     return WmErrorCode::WM_OK;
111 }
112 
ProcessOccupiedAreaChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)113 WmErrorCode CjWindowRegisterManager::ProcessOccupiedAreaChangeRegister(
114     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
115 {
116     if (window == nullptr) {
117         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister] window is nullptr");
118         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
119     }
120     sptr<IOccupiedAreaChangeListener> thisListener(listener);
121     WmErrorCode ret;
122     if (isRegister) {
123         ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterOccupiedAreaChangeListener(thisListener));
124     } else {
125         ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterOccupiedAreaChangeListener(thisListener));
126     }
127     return ret;
128 }
129 
ProcessTouchOutsideRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)130 WmErrorCode CjWindowRegisterManager::ProcessTouchOutsideRegister(
131     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
132 {
133     return WmErrorCode::WM_OK;
134 }
135 
ProcessScreenshotRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)136 WmErrorCode CjWindowRegisterManager::ProcessScreenshotRegister(
137     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
138 {
139     return WmErrorCode::WM_OK;
140 }
141 
ProcessDialogTargetTouchRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)142 WmErrorCode CjWindowRegisterManager::ProcessDialogTargetTouchRegister(
143     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
144 {
145     return WmErrorCode::WM_OK;
146 }
147 
ProcessDialogDeathRecipientRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)148 WmErrorCode CjWindowRegisterManager::ProcessDialogDeathRecipientRegister(
149     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
150 {
151     return WmErrorCode::WM_OK;
152 }
153 
ProcessWindowStatusChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)154 WmErrorCode CjWindowRegisterManager::ProcessWindowStatusChangeRegister(
155     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
156 {
157     return WmErrorCode::WM_OK;
158 }
159 
ProcessWindowTitleButtonRectChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)160 WmErrorCode CjWindowRegisterManager::ProcessWindowTitleButtonRectChangeRegister(
161     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
162 {
163     return WmErrorCode::WM_OK;
164 }
165 
ProcessWindowVisibilityChangeRegister(sptr<CjWindowListener> listener,sptr<Window> window,bool isRegister)166 WmErrorCode CjWindowRegisterManager::ProcessWindowVisibilityChangeRegister(
167     sptr<CjWindowListener> listener, sptr<Window> window, bool isRegister)
168 {
169     return WmErrorCode::WM_OK;
170 }
171 
ProcessDisplayIdChangeRegister(const sptr<CjWindowListener> & listener,const sptr<Window> & window,bool isRegister)172 WmErrorCode CjWindowRegisterManager::ProcessDisplayIdChangeRegister(
173     const sptr<CjWindowListener>& listener, const sptr<Window>& window, bool isRegister)
174 {
175     return WmErrorCode::WM_OK;
176 }
177 
IsCallbackRegistered(std::string type,int64_t callbackObject)178 bool CjWindowRegisterManager::IsCallbackRegistered(std::string type, int64_t callbackObject)
179 {
180     if (cjCbMap_.empty() || cjCbMap_.find(type) == cjCbMap_.end()) {
181         TLOGI(WmsLogTag::WMS_SUB, "[WindowRegister]Method %{public}s has not been registerted", type.c_str());
182         return false;
183     }
184 
185     for (auto iter = cjCbMap_[type].begin(); iter != cjCbMap_[type].end(); ++iter) {
186         if (callbackObject == iter->first) {
187             TLOGE(WmsLogTag::WMS_SUB,
188                 "[WindowRegister]Method %{public}s has already been registered", type.c_str());
189             return true;
190         }
191     }
192     return false;
193 }
194 
RegisterListener(sptr<Window> window,std::string type,CaseType caseType,int64_t callbackObject)195 WmErrorCode CjWindowRegisterManager::RegisterListener(sptr<Window> window, std::string type,
196     CaseType caseType, int64_t callbackObject)
197 {
198     std::lock_guard<std::shared_mutex> lock(mtx_);
199     if (IsCallbackRegistered(type, callbackObject)) {
200         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
201     }
202     if (listenerProcess_[caseType].count(type) == 0) {
203         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]Type %{public}s is not supported", type.c_str());
204         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
205     }
206     if (callbackObject == NONE_CALLBACK_OBJECT) {
207         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]Invalid callback object %{public}" PRId64, callbackObject);
208         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
209     }
210     sptr<CjWindowListener> windowManagerListener = new(std::nothrow) CjWindowListener(callbackObject);
211     if (windowManagerListener == nullptr) {
212         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]New CjWindowListener failed");
213         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
214     }
215     windowManagerListener->SetMainEventHandler();
216     WmErrorCode ret = listenerProcess_[caseType][type](windowManagerListener, window, true);
217     if (ret != WmErrorCode::WM_OK) {
218         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]Register type %{public}s failed", type.c_str());
219         return ret;
220     }
221     cjCbMap_[type][callbackObject] = windowManagerListener;
222     TLOGI(WmsLogTag::WMS_SUB, "[WindowRegister]Register type %{public}s success! callback map size: %{public}zu",
223         type.c_str(), cjCbMap_[type].size());
224     return WmErrorCode::WM_OK;
225 }
226 
UnregisterListener(sptr<Window> window,std::string type,CaseType caseType,int64_t callbackObject)227 WmErrorCode CjWindowRegisterManager::UnregisterListener(sptr<Window> window, std::string type,
228     CaseType caseType, int64_t callbackObject)
229 {
230     std::lock_guard<std::shared_mutex> lock(mtx_);
231     if (cjCbMap_.empty() || cjCbMap_.find(type) == cjCbMap_.end()) {
232         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]Type %{public}s was not registerted", type.c_str());
233         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
234     }
235     if (listenerProcess_[caseType].count(type) == 0) {
236         TLOGE(WmsLogTag::WMS_SUB, "[WindowRegister]Type %{public}s is not supported", type.c_str());
237         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
238     }
239     if (callbackObject == NONE_CALLBACK_OBJECT) {
240         for (auto it = cjCbMap_[type].begin(); it != cjCbMap_[type].end();) {
241             WmErrorCode ret = listenerProcess_[caseType][type](it->second, window, false);
242             if (ret != WmErrorCode::WM_OK) {
243                 TLOGE(WmsLogTag::WMS_SUB,
244                     "[WindowRegister]Unregister type %{public}s failed, no value", type.c_str());
245                 return ret;
246             }
247             cjCbMap_[type].erase(it++);
248         }
249     } else {
250         TLOGE(WmsLogTag::WMS_SUB,
251             "[WindowRegister]Unregister type %{public}s failed because not found callback!", type.c_str());
252         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
253     }
254     return WmErrorCode::WM_OK;
255 }
256 }
257 }
258