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 <set>
17
18 #include "ipc_client_manager.h"
19
20 #include "device_manager_ipc_interface_code.h"
21 #include "device_manager_notify.h"
22 #include "device_manager_impl.h"
23 #include "dm_error_type.h"
24 #include "dm_log.h"
25 #include "dm_service_load.h"
26 #include "ipc_client_server_proxy.h"
27 #include "ipc_client_stub.h"
28 #include "ipc_register_listener_req.h"
29 #include "ipc_remote_broker.h"
30 #include "iremote_object.h"
31 #include "iservice_registry.h"
32 #include "system_ability_definition.h"
33 #include <unistd.h>
34
35 namespace OHOS {
36 namespace DistributedHardware {
OnRemoteDied(const wptr<IRemoteObject> & remote)37 void DmDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
38 {
39 LOGW("DmDeathRecipient : OnRemoteDied");
40 (void)remote;
41 }
42
ClientInit()43 int32_t IpcClientManager::ClientInit()
44 {
45 LOGI("Start");
46 if (dmInterface_ != nullptr) {
47 LOGI("DeviceManagerService Already Init");
48 return DM_OK;
49 }
50
51 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
52 if (samgr == nullptr) {
53 LOGE("Get SystemAbilityManager Failed");
54 return ERR_DM_INIT_FAILED;
55 }
56
57 auto object = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
58 if (object == nullptr) {
59 LOGE("Get DeviceManager SystemAbility Failed");
60 DmServiceLoad::GetInstance().LoadDMService();
61 return ERR_DM_INIT_FAILED;
62 }
63
64 if (dmRecipient_ == nullptr) {
65 dmRecipient_ = sptr<DmDeathRecipient>(new DmDeathRecipient());
66 }
67 if (!object->AddDeathRecipient(dmRecipient_)) {
68 LOGE("InitDeviceManagerService: AddDeathRecipient Failed");
69 }
70 dmInterface_ = iface_cast<IpcRemoteBroker>(object);
71 LOGI("Completed");
72 return DM_OK;
73 }
74
Init(const std::string & pkgName)75 int32_t IpcClientManager::Init(const std::string &pkgName)
76 {
77 if (pkgName.empty()) {
78 LOGE("Invalid parameter, pkgName is empty.");
79 return ERR_DM_INPUT_PARA_INVALID;
80 }
81 std::lock_guard<std::mutex> autoLock(lock_);
82 SubscribeDMSAChangeListener();
83 int32_t ret = ClientInit();
84 if (ret != DM_OK) {
85 LOGE("InitDeviceManager Failed with ret %{public}d", ret);
86 return ret;
87 }
88
89 sptr<IpcClientStub> listener = sptr<IpcClientStub>(new IpcClientStub());
90 std::shared_ptr<IpcRegisterListenerReq> req = std::make_shared<IpcRegisterListenerReq>();
91 std::shared_ptr<IpcRsp> rsp = std::make_shared<IpcRsp>();
92 req->SetPkgName(pkgName);
93 req->SetListener(listener);
94 ret = dmInterface_->SendCmd(REGISTER_DEVICE_MANAGER_LISTENER, req, rsp);
95 if (ret != DM_OK) {
96 LOGE("InitDeviceManager: RegisterDeviceManagerListener Failed with ret %{public}d", ret);
97 return ret;
98 }
99 ret = rsp->GetErrCode();
100 if (ret != DM_OK) {
101 return ret;
102 }
103 dmListener_[pkgName] = listener;
104 LOGI("completed, pkgName: %{public}s", pkgName.c_str());
105 return DM_OK;
106 }
107
UnInit(const std::string & pkgName)108 int32_t IpcClientManager::UnInit(const std::string &pkgName)
109 {
110 if (pkgName.empty()) {
111 LOGE("Invalid parameter, pkgName is empty.");
112 return ERR_DM_INPUT_PARA_INVALID;
113 }
114 LOGI("UnInit in, pkgName %{public}s", pkgName.c_str());
115 std::lock_guard<std::mutex> autoLock(lock_);
116 if (dmInterface_ == nullptr) {
117 LOGE("DeviceManager not Init");
118 return ERR_DM_INIT_FAILED;
119 }
120
121 if (dmListener_.count(pkgName) > 0) {
122 std::shared_ptr<IpcReq> req = std::make_shared<IpcReq>();
123 std::shared_ptr<IpcRsp> rsp = std::make_shared<IpcRsp>();
124 req->SetPkgName(pkgName);
125 int32_t ret = dmInterface_->SendCmd(UNREGISTER_DEVICE_MANAGER_LISTENER, req, rsp);
126 if (ret != DM_OK) {
127 LOGE("UnRegisterDeviceManagerListener Failed with ret %{public}d", ret);
128 return ret;
129 }
130 dmListener_.erase(pkgName);
131 }
132 if (dmListener_.empty()) {
133 if (dmRecipient_ != nullptr) {
134 dmInterface_->AsObject()->RemoveDeathRecipient(dmRecipient_);
135 dmRecipient_ = nullptr;
136 }
137 dmInterface_ = nullptr;
138 }
139 LOGI("completed, pkgName: %{public}s", pkgName.c_str());
140 return DM_OK;
141 }
142
SendRequest(int32_t cmdCode,std::shared_ptr<IpcReq> req,std::shared_ptr<IpcRsp> rsp)143 int32_t IpcClientManager::SendRequest(int32_t cmdCode, std::shared_ptr<IpcReq> req, std::shared_ptr<IpcRsp> rsp)
144 {
145 if (cmdCode < 0 || cmdCode >= IPC_MSG_BUTT) {
146 LOGE("IpcClientManager::SendRequest cmdCode param invalid!");
147 return ERR_DM_UNSUPPORTED_IPC_COMMAND;
148 }
149 if (req == nullptr || rsp == nullptr) {
150 return ERR_DM_INPUT_PARA_INVALID;
151 }
152 std::lock_guard<std::mutex> autoLock(lock_);
153 if (dmInterface_ != nullptr) {
154 LOGD("IpcClientManager::SendRequest cmdCode: %{public}d", cmdCode);
155 return dmInterface_->SendCmd(cmdCode, req, rsp);
156 } else {
157 LOGE("dmInterface_ is not init.");
158 return ERR_DM_INIT_FAILED;
159 }
160 }
161
OnDmServiceDied()162 int32_t IpcClientManager::OnDmServiceDied()
163 {
164 LOGI("IpcClientManager::OnDmServiceDied begin");
165 {
166 std::lock_guard<std::mutex> autoLock(lock_);
167 if (dmInterface_ == nullptr) {
168 LOGE("IpcClientManager::OnDmServiceDied, dmInterface_ null");
169 return ERR_DM_POINT_NULL;
170 }
171 if (dmRecipient_ != nullptr) {
172 dmInterface_->AsObject()->RemoveDeathRecipient(dmRecipient_);
173 dmRecipient_ = nullptr;
174 }
175 dmInterface_ = nullptr;
176 }
177 LOGI("IpcClientManager::OnDmServiceDied complete");
178 return DM_OK;
179 }
180
SubscribeDMSAChangeListener()181 void IpcClientManager::SubscribeDMSAChangeListener()
182 {
183 saListenerCallback = new (std::nothrow) SystemAbilityListener();
184 if (saListenerCallback == nullptr) {
185 LOGE("saListenerCallback is nullptr.");
186 return;
187 }
188 sptr<ISystemAbilityManager> systemAbilityManager =
189 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
190
191 if (systemAbilityManager == nullptr) {
192 LOGE("get system ability manager failed.");
193 return;
194 }
195
196 if (!isSubscribeDMSAChangeListener.load()) {
197 LOGI("try subscribe source sa change listener, sa id: %{public}d", DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
198 int32_t ret = systemAbilityManager->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID,
199 saListenerCallback);
200 if (ret != DM_OK) {
201 LOGE("subscribe source sa change failed: %{public}d", ret);
202 return;
203 }
204 isSubscribeDMSAChangeListener.store(true);
205 }
206 }
207
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)208 void IpcClientManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
209 const std::string &deviceId)
210 {
211 if (systemAbilityId == DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID) {
212 DeviceManagerImpl::GetInstance().OnDmServiceDied();
213 DeviceManagerNotify::GetInstance().OnRemoteDied();
214 }
215 LOGI("sa %{public}d is removed.", systemAbilityId);
216 }
217
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)218 void IpcClientManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
219 {
220 LOGI("sa %{public}d is added.", systemAbilityId);
221 if (systemAbilityId == DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID) {
222 std::map<std::string, std::shared_ptr<DmInitCallback>> dmInitCallback =
223 DeviceManagerNotify::GetInstance().GetDmInitCallback();
224 if (dmInitCallback.size() == 0) {
225 LOGI("dmInitCallback is empty when ReInit");
226 return;
227 }
228 for (auto iter : dmInitCallback) {
229 DeviceManagerImpl::GetInstance().InitDeviceManager(iter.first, iter.second);
230 }
231 std::map<DmCommonNotifyEvent, std::set<std::string>> callbackMap;
232 DeviceManagerNotify::GetInstance().GetCallBack(callbackMap);
233 if (callbackMap.size() == 0) {
234 LOGE("callbackMap is empty when ReInit");
235 return;
236 }
237 DeviceManagerImpl::GetInstance().SyncCallbacksToService(callbackMap);
238 }
239 }
240 } // namespace DistributedHardware
241 } // namespace OHOS
242