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 "distributed_input_source_sa_cli_mgr.h"
17 
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 
22 #include "dinput_log.h"
23 #include "dinput_utils_tool.h"
24 
25 namespace OHOS {
26 namespace DistributedHardware {
27 namespace DistributedInput {
28 IMPLEMENT_SINGLE_INSTANCE(DInputSourceSACliMgr);
DInputSourceSACliMgr()29 DInputSourceSACliMgr::DInputSourceSACliMgr()
30 {
31     DHLOGI("Ctor DInputSourceSACliMgr");
32     remoteCliDeathRcv = new RemoteCliDeathRecipient();
33 
34     auto dinputMgrRunner = AppExecFwk::EventRunner::Create("DInputMgrHandler");
35     if (!dinputMgrRunner) {
36         DHLOGE("DInputSourceSACliMgr, dinputMgrRunner is null!");
37         return;
38     }
39     dinputMgrHandler_ = std::make_shared<AppExecFwk::EventHandler>(dinputMgrRunner);
40     if (!dinputMgrHandler_) {
41         DHLOGE("DInputSourceSACliMgr, dinputMgrHandler_ is null!");
42     }
43 }
44 
~DInputSourceSACliMgr()45 DInputSourceSACliMgr::~DInputSourceSACliMgr()
46 {
47     DHLOGI("Dtor DInputSourceSACliMgr");
48 }
49 
OnRemoteDied(const wptr<IRemoteObject> & remote)50 void DInputSourceSACliMgr::RemoteCliDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
51 {
52     DHLOGI("RemoteCliDeathRecipient::OnRemoteDied received died notify!");
53     sptr<IRemoteObject> diedRemote = remote.promote();
54     if (diedRemote == nullptr) {
55         DHLOGE("RemoteCliDeathRecipient::OnRemoteDied promote failedy!");
56         return;
57     }
58 
59     DInputSourceSACliMgr::GetInstance().ProcRemoteCliDied(diedRemote);
60 }
61 
GetRemoteCli(const std::string & deviceId)62 sptr<IDistributedSourceInput> DInputSourceSACliMgr::GetRemoteCli(const std::string &deviceId)
63 {
64     if (deviceId.empty()) {
65         DHLOGE("DInputSourceSACliMgr::GetRemoteCli deviceId is empty");
66         return nullptr;
67     }
68     DHLOGI("DInputSourceSACliMgr::GetRemoteCli remote deviceid is %{public}s", GetAnonyString(deviceId).c_str());
69     auto remoteCli = GetRemoteCliFromCache(deviceId);
70     if (remoteCli != nullptr) {
71         DHLOGD("VirtualHardwareManager::GetRemoteCli get from cache!");
72         return remoteCli;
73     }
74 
75     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
76     if (samgr == nullptr) {
77         DHLOGE("GetRemoteCli failed to connect to systemAbilityMgr!");
78         return nullptr;
79     }
80 
81     auto object = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID, deviceId);
82     if (object == nullptr) {
83         DHLOGE("GetRemoteCli failed get remote Cli %{public}s", GetAnonyString(deviceId).c_str());
84         return nullptr;
85     }
86 
87     AddRemoteCli(deviceId, object);
88     return iface_cast<IDistributedSourceInput>(object);
89 }
90 
GetRemoteCliFromCache(const std::string & devId)91 sptr<IDistributedSourceInput> DInputSourceSACliMgr::GetRemoteCliFromCache(const std::string &devId)
92 {
93     std::lock_guard<std::mutex> lock(remoteCliLock);
94     auto iter = remoteCliMap.find(devId);
95     if (iter != remoteCliMap.end()) {
96         return iter->second;
97     }
98     return nullptr;
99 }
100 
AddRemoteCli(const std::string & devId,sptr<IRemoteObject> object)101 void DInputSourceSACliMgr::AddRemoteCli(const std::string &devId, sptr<IRemoteObject> object)
102 {
103     if (devId.empty() || (object == nullptr)) {
104         DHLOGW("DInputSourceSACliMgr::AddRemoteCli param error! devId=%{public}s", GetAnonyString(devId).c_str());
105         return;
106     }
107 
108     DHLOGI("DInputSourceSACliMgr::AddRemoteCli devId=%{public}s", GetAnonyString(devId).c_str());
109     object->AddDeathRecipient(remoteCliDeathRcv);
110 
111     std::lock_guard<std::mutex> lock(remoteCliLock);
112     auto item = remoteCliMap.find(devId);
113     if ((item != remoteCliMap.end()) && item->second != nullptr) {
114         item->second->AsObject()->RemoveDeathRecipient(remoteCliDeathRcv);
115     }
116     remoteCliMap[devId] = iface_cast<IDistributedSourceInput>(object);
117 }
118 
DeleteRemoteCli(const std::string & devId)119 void DInputSourceSACliMgr::DeleteRemoteCli(const std::string &devId)
120 {
121     DHLOGI("DInputSourceSACliMgr::DeleteRemoteCli devId=%{public}s", GetAnonyString(devId).c_str());
122     std::lock_guard<std::mutex> lock(remoteCliLock);
123     auto item = remoteCliMap.find(devId);
124     if (item == remoteCliMap.end()) {
125         DHLOGI("DInputSourceSACliMgr::DeleteRemoteCli not found device");
126         return;
127     }
128 
129     if (item->second != nullptr) {
130         item->second->AsObject()->RemoveDeathRecipient(remoteCliDeathRcv);
131     }
132     remoteCliMap.erase(item);
133 }
134 
DeleteRemoteCli(const sptr<IRemoteObject> remote)135 void DInputSourceSACliMgr::DeleteRemoteCli(const sptr<IRemoteObject> remote)
136 {
137     std::lock_guard<std::mutex> lock(remoteCliLock);
138     auto iter = std::find_if(remoteCliMap.begin(), remoteCliMap.end(), [&](
139         const std::pair<std::string, sptr<IDistributedSourceInput>> &item)->bool {
140             return item.second->AsObject() == remote;
141         });
142     if (iter == remoteCliMap.end()) {
143         DHLOGI("VirtualHardwareManager::DeleteRemoteCli not found remote object");
144         return;
145     }
146 
147     DHLOGI("VirtualHardwareManager::DeleteRemoteCli remote.devId=%{public}s", GetAnonyString(iter->first).c_str());
148     if (iter->second != nullptr) {
149         iter->second->AsObject()->RemoveDeathRecipient(remoteCliDeathRcv);
150     }
151     remoteCliMap.erase(iter);
152 }
153 
ProcRemoteCliDied(const sptr<IRemoteObject> & remote)154 void DInputSourceSACliMgr::ProcRemoteCliDied(const sptr<IRemoteObject> &remote)
155 {
156     auto remoteCliDiedProc = [this, remote]() {
157         DeleteRemoteCli(remote);
158     };
159     if (!(dinputMgrHandler_ && dinputMgrHandler_->PostTask(remoteCliDiedProc))) {
160         DHLOGE("DInputSourceSACliMgr::OnRemoteDied PostTask fail");
161     }
162 }
163 }
164 }
165 }