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