1 /*
2  * Copyright (c) 2022-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 "dinput_sa_manager.h"
17 
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20 
21 #include "constants_dinput.h"
22 #include "dinput_errcode.h"
23 #include "dinput_log.h"
24 
25 namespace OHOS {
26 namespace DistributedHardware {
27 namespace DistributedInput {
28 IMPLEMENT_SINGLE_INSTANCE(DInputSAManager);
29 const uint32_t DINPUT_CLIENT_HANDLER_MSG_DELAY_TIME = 100; // million seconds
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)30 void DInputSAManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
31 {
32     if (systemAbilityId == DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID) {
33         DInputSAManager::GetInstance().dInputSourceSAOnline_.store(false);
34         {
35             std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
36             DInputSAManager::GetInstance().dInputSourceProxy_ = nullptr;
37         }
38         {
39             std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().handlerMutex_);
40             if (DInputSAManager::GetInstance().eventHandler_ != nullptr) {
41                 DHLOGI("SendEvent DINPUT_CLIENT_CLEAR_SOURCE_CALLBACK_REGISTER_MSG");
42                 AppExecFwk::InnerEvent::Pointer msgEvent =
43                     AppExecFwk::InnerEvent::Get(DINPUT_CLIENT_CLEAR_SOURCE_CALLBACK_REGISTER_MSG, systemAbilityId);
44                 DInputSAManager::GetInstance().eventHandler_->SendEvent(msgEvent, DINPUT_CLIENT_HANDLER_MSG_DELAY_TIME,
45                     AppExecFwk::EventQueue::Priority::IMMEDIATE);
46             }
47         }
48     }
49 
50     if (systemAbilityId == DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID) {
51         DInputSAManager::GetInstance().dInputSinkSAOnline_.store(false);
52         {
53             std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
54             DInputSAManager::GetInstance().dInputSinkProxy_ = nullptr;
55         }
56         {
57             std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().handlerMutex_);
58             if (DInputSAManager::GetInstance().eventHandler_ != nullptr) {
59                 DHLOGI("SendEvent DINPUT_CLIENT_CLEAR_SINK_CALLBACK_REGISTER_MSG");
60                 AppExecFwk::InnerEvent::Pointer msgEvent =
61                     AppExecFwk::InnerEvent::Get(DINPUT_CLIENT_CLEAR_SINK_CALLBACK_REGISTER_MSG, systemAbilityId);
62                 DInputSAManager::GetInstance().eventHandler_->SendEvent(msgEvent, DINPUT_CLIENT_HANDLER_MSG_DELAY_TIME,
63                     AppExecFwk::EventQueue::Priority::IMMEDIATE);
64             }
65         }
66     }
67     DHLOGI("sa %{public}d is removed.", systemAbilityId);
68 }
69 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)70 void DInputSAManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
71 {
72     if (systemAbilityId == DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID) {
73         DInputSAManager::GetInstance().dInputSourceSAOnline_.store(true);
74         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().handlerMutex_);
75         if (DInputSAManager::GetInstance().eventHandler_ != nullptr) {
76             DHLOGI("SendEvent DINPUT_CLIENT_CHECK_SOURCE_CALLBACK_REGISTER_MSG");
77             AppExecFwk::InnerEvent::Pointer msgEvent =
78                 AppExecFwk::InnerEvent::Get(DINPUT_CLIENT_CHECK_SOURCE_CALLBACK_REGISTER_MSG, systemAbilityId);
79             DInputSAManager::GetInstance().eventHandler_->SendEvent(msgEvent,
80                 DINPUT_CLIENT_HANDLER_MSG_DELAY_TIME, AppExecFwk::EventQueue::Priority::IMMEDIATE);
81         }
82     }
83 
84     if (systemAbilityId == DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID) {
85         DInputSAManager::GetInstance().dInputSinkSAOnline_.store(true);
86         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().handlerMutex_);
87         if (DInputSAManager::GetInstance().eventHandler_ != nullptr) {
88             DHLOGI("SendEvent DINPUT_CLIENT_CHECK_SINK_CALLBACK_REGISTER_MSG");
89             AppExecFwk::InnerEvent::Pointer msgEvent =
90                 AppExecFwk::InnerEvent::Get(DINPUT_CLIENT_CHECK_SINK_CALLBACK_REGISTER_MSG, systemAbilityId);
91             DInputSAManager::GetInstance().eventHandler_->SendEvent(msgEvent,
92                 DINPUT_CLIENT_HANDLER_MSG_DELAY_TIME, AppExecFwk::EventQueue::Priority::IMMEDIATE);
93         }
94     }
95     DHLOGI("sa %{public}d is added.", systemAbilityId);
96 }
97 
Init()98 void DInputSAManager::Init()
99 {
100     saListenerCallback = new(std::nothrow) SystemAbilityListener();
101     sptr<ISystemAbilityManager> systemAbilityManager =
102         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
103 
104     if (!systemAbilityManager) {
105         DHLOGE("get system ability manager failed.");
106         return;
107     }
108 
109     if (!isSubscribeSrcSAChangeListener_.load()) {
110         DHLOGI("try subscribe source sa change listener, saId:%{public}d", DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID);
111         int32_t ret = systemAbilityManager->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID,
112             saListenerCallback);
113         if (ret != DH_SUCCESS) {
114             DHLOGE("subscribe source sa change failed: %{public}d", ret);
115             return;
116         }
117         isSubscribeSrcSAChangeListener_.store(true);
118     }
119 
120     if (!isSubscribeSinkSAChangeListener_.load()) {
121         DHLOGI("try subscribe sink sa change listener, saId:%{public}d", DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID);
122         int32_t ret = systemAbilityManager->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID,
123             saListenerCallback);
124         if (ret != DH_SUCCESS) {
125             DHLOGE("subscribe sink sa change failed: %{public}d", ret);
126             return;
127         }
128         isSubscribeSinkSAChangeListener_.store(true);
129     }
130 }
131 
RegisterEventHandler(std::shared_ptr<AppExecFwk::EventHandler> handler)132 void DInputSAManager::RegisterEventHandler(std::shared_ptr<AppExecFwk::EventHandler> handler)
133 {
134     std::lock_guard<std::mutex> lock(handlerMutex_);
135     eventHandler_ = handler;
136 }
137 
GetDInputSourceProxy()138 bool DInputSAManager::GetDInputSourceProxy()
139 {
140     if (!isSubscribeSrcSAChangeListener_.load()) {
141         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
142         if (!isSubscribeSrcSAChangeListener_.load()) {
143             sptr<ISystemAbilityManager> systemAbilityManager =
144                 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
145             if (!systemAbilityManager) {
146                 DHLOGE("get system ability manager failed.");
147                 return false;
148             }
149 
150             DHLOGI("try subscribe source sa change listener, saId:%{public}d", DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID);
151             int32_t ret = systemAbilityManager->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID,
152                 saListenerCallback);
153             if (ret != DH_SUCCESS) {
154                 DHLOGE("subscribe source sa change failed: %{public}d", ret);
155                 return false;
156             }
157             isSubscribeSrcSAChangeListener_.store(true);
158         }
159     }
160 
161     if (dInputSourceSAOnline_.load() && !dInputSourceProxy_) {
162         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
163         if (dInputSourceProxy_ != nullptr) {
164             DHLOGI("dinput source proxy has already got.");
165             return true;
166         }
167         sptr<ISystemAbilityManager> systemAbilityManager =
168             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
169         if (!systemAbilityManager) {
170             DHLOGE("get system ability manager failed.");
171             return false;
172         }
173 
174         DHLOGI("try get sa: %{public}d", DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID);
175         sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(
176             DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID);
177         if (!remoteObject) {
178             return false;
179         }
180 
181         dInputSourceProxy_ = iface_cast<IDistributedSourceInput>(remoteObject);
182 
183         if ((!dInputSourceProxy_) || (!dInputSourceProxy_->AsObject())) {
184             return false;
185         }
186     }
187     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
188     return dInputSourceProxy_ != nullptr;
189 }
190 
HasDInputSourceProxy()191 bool DInputSAManager::HasDInputSourceProxy()
192 {
193     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
194     return dInputSourceProxy_ != nullptr;
195 }
196 
SetDInputSourceProxy(const sptr<IRemoteObject> & remoteObject)197 bool DInputSAManager::SetDInputSourceProxy(const sptr<IRemoteObject> &remoteObject)
198 {
199     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sourceMutex_);
200     dInputSourceProxy_ = iface_cast<IDistributedSourceInput>(remoteObject);
201 
202     if ((!dInputSourceProxy_) || (!dInputSourceProxy_->AsObject())) {
203         DHLOGE("Failed to get dinput source proxy.");
204         return false;
205     }
206     return true;
207 }
208 
GetDInputSinkProxy()209 bool DInputSAManager::GetDInputSinkProxy()
210 {
211     if (!isSubscribeSinkSAChangeListener_.load()) {
212         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
213         if (!isSubscribeSinkSAChangeListener_.load()) {
214             sptr<ISystemAbilityManager> systemAbilityManager =
215                 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
216             if (!systemAbilityManager) {
217                 DHLOGE("get system ability manager failed.");
218                 return false;
219             }
220 
221             DHLOGI("try subscribe sink sa change listener, sa id: %{public}d", DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID);
222             int32_t ret = systemAbilityManager->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID,
223                 saListenerCallback);
224             if (ret != DH_SUCCESS) {
225                 DHLOGE("subscribe sink sa change failed: %{public}d", ret);
226                 return false;
227             }
228             isSubscribeSinkSAChangeListener_.store(true);
229         }
230     }
231 
232     if (dInputSinkSAOnline_.load() && !dInputSinkProxy_) {
233         std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
234         if (dInputSinkProxy_ != nullptr) {
235             DHLOGI("dinput sink proxy has already got.");
236             return true;
237         }
238         sptr<ISystemAbilityManager> systemAbilityManager =
239             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
240         if (!systemAbilityManager) {
241             DHLOGE("get system ability manager failed.");
242             return false;
243         }
244 
245         sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(
246             DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID);
247         if (!remoteObject) {
248             return false;
249         }
250 
251         dInputSinkProxy_ = iface_cast<IDistributedSinkInput>(remoteObject);
252 
253         if ((!dInputSinkProxy_) || (!dInputSinkProxy_->AsObject())) {
254             return false;
255         }
256     }
257     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
258     return dInputSinkProxy_ != nullptr;
259 }
260 
HasDInputSinkProxy()261 bool DInputSAManager::HasDInputSinkProxy()
262 {
263     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
264     return dInputSinkProxy_ != nullptr;
265 }
266 
SetDInputSinkProxy(const sptr<IRemoteObject> & remoteObject)267 bool DInputSAManager::SetDInputSinkProxy(const sptr<IRemoteObject> &remoteObject)
268 {
269     std::lock_guard<std::mutex> lock(DInputSAManager::GetInstance().sinkMutex_);
270     dInputSinkProxy_ = iface_cast<IDistributedSinkInput>(remoteObject);
271 
272     if ((!dInputSinkProxy_) || (!dInputSinkProxy_->AsObject())) {
273         DHLOGE("Failed to get dinput sink proxy.");
274         return false;
275     }
276     return true;
277 }
278 
RestoreRegisterListenerAndCallback()279 int32_t DInputSAManager::RestoreRegisterListenerAndCallback()
280 {
281     DHLOGI("Restore RegisterPublisherListener");
282     if (!DInputSAManager::GetInstance().GetDInputSourceProxy()) {
283         DHLOGE("RestoreRegisterSimulationEventListener proxy error, client fail");
284         return ERR_DH_INPUT_CLIENT_GET_SOURCE_PROXY_FAIL;
285     }
286 
287     int32_t result = DH_SUCCESS;
288     {
289         std::lock_guard<std::mutex> lock(simEventListenerCacheMtx_);
290         for (const auto& listener : simEventListenerCache_) {
291             if (listener == nullptr) {
292                 DHLOGE("simEventListenerCache_ is nullptr");
293                 continue;
294             }
295             int32_t ret = DInputSAManager::GetInstance().dInputSourceProxy_->RegisterSimulationEventListener(listener);
296             if (ret != DH_SUCCESS) {
297                 result = ret;
298                 DHLOGE("SA execute RegisterSimulationEventListener fail, ret = %{public}d", ret);
299             }
300         }
301     }
302     {
303         DHLOGI("Restore RegisterSessionStateCb");
304         std::lock_guard<std::mutex> lock(sessionStateCbCacheMtx_);
305         for (const auto& callback : sessionStateCbCache_) {
306             if (callback == nullptr) {
307                 DHLOGE("sessionStateCbCache_ is nullptr");
308                 continue;
309             }
310             int32_t ret = DInputSAManager::GetInstance().dInputSourceProxy_->RegisterSessionStateCb(callback);
311             if (ret != DH_SUCCESS) {
312                 result = ret;
313                 DHLOGE("SA execute RegisterSessionStateCb fail, ret = %{public}d", ret);
314             }
315         }
316     }
317     return result;
318 }
319 
AddSimEventListenerToCache(sptr<ISimulationEventListener> listener)320 void DInputSAManager::AddSimEventListenerToCache(sptr<ISimulationEventListener> listener)
321 {
322     std::lock_guard<std::mutex> simEventListenerLock(simEventListenerCacheMtx_);
323     if (listener != nullptr) {
324         simEventListenerCache_.insert(listener);
325     }
326 }
327 
RemoveSimEventListenerFromCache(sptr<ISimulationEventListener> listener)328 void DInputSAManager::RemoveSimEventListenerFromCache(sptr<ISimulationEventListener> listener)
329 {
330     std::lock_guard<std::mutex> simEventListenerLock(simEventListenerCacheMtx_);
331     if (listener != nullptr) {
332         simEventListenerCache_.erase(listener);
333     }
334 }
335 
AddSessionStateCbToCache(sptr<ISessionStateCallback> callback)336 void DInputSAManager::AddSessionStateCbToCache(sptr<ISessionStateCallback> callback)
337 {
338     std::lock_guard<std::mutex> sessionStateCbLock(sessionStateCbCacheMtx_);
339     if (callback != nullptr) {
340         sessionStateCbCache_.insert(callback);
341     }
342 }
343 
RemoveSessionStateCbFromCache()344 void DInputSAManager::RemoveSessionStateCbFromCache()
345 {
346     std::lock_guard<std::mutex> sessionStateCbLock(sessionStateCbCacheMtx_);
347     sessionStateCbCache_.clear();
348 }
349 } // namespace DistributedInput
350 } // namespace DistributedHardware
351 } // namespace OHOS