1 /*
2 * Copyright (c) 2022-2023 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 "ipc_client_server_proxy.h"
24 #include "ipc_client_stub.h"
25 #include "ipc_register_listener_req.h"
26 #include "ipc_remote_broker.h"
27 #include "iremote_object.h"
28 #include "iservice_registry.h"
29 #include "system_ability_definition.h"
30
31 namespace OHOS {
32 namespace DistributedHardware {
OnRemoteDied(const wptr<IRemoteObject> & remote)33 void DmDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
34 {
35 LOGW("DmDeathRecipient : OnRemoteDied");
36 (void)remote;
37 DeviceManagerImpl::GetInstance().OnDmServiceDied();
38 DeviceManagerNotify::GetInstance().OnRemoteDied();
39 }
40
ClientInit()41 int32_t IpcClientManager::ClientInit()
42 {
43 LOGI("InitDeviceManagerService 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 return ERR_DM_INIT_FAILED;
59 }
60
61 if (dmRecipient_ == nullptr) {
62 dmRecipient_ = sptr<DmDeathRecipient>(new DmDeathRecipient());
63 }
64 if (!object->AddDeathRecipient(dmRecipient_)) {
65 LOGE("InitDeviceManagerService: AddDeathRecipient Failed");
66 }
67 dmInterface_ = iface_cast<IpcRemoteBroker>(object);
68 LOGI("DeviceManager::InitDeviceManagerService completed");
69 return DM_OK;
70 }
71
Init(const std::string & pkgName)72 int32_t IpcClientManager::Init(const std::string &pkgName)
73 {
74 if (pkgName.empty()) {
75 LOGE("Invalid parameter, pkgName is empty.");
76 return ERR_DM_INPUT_PARA_INVALID;
77 }
78 std::lock_guard<std::mutex> autoLock(lock_);
79 int32_t ret = ClientInit();
80 if (ret != DM_OK) {
81 LOGE("InitDeviceManager Failed with ret %d", ret);
82 return ret;
83 }
84
85 sptr<IpcClientStub> listener = sptr<IpcClientStub>(new IpcClientStub());
86 std::shared_ptr<IpcRegisterListenerReq> req = std::make_shared<IpcRegisterListenerReq>();
87 std::shared_ptr<IpcRsp> rsp = std::make_shared<IpcRsp>();
88 req->SetPkgName(pkgName);
89 req->SetListener(listener);
90 ret = dmInterface_->SendCmd(REGISTER_DEVICE_MANAGER_LISTENER, req, rsp);
91 if (ret != DM_OK) {
92 LOGE("InitDeviceManager: RegisterDeviceManagerListener Failed with ret %d", ret);
93 return ret;
94 }
95 ret = rsp->GetErrCode();
96 if (ret != DM_OK) {
97 return ret;
98 }
99 dmListener_[pkgName] = listener;
100 LOGI("completed, pkgName: %s", pkgName.c_str());
101 return DM_OK;
102 }
103
UnInit(const std::string & pkgName)104 int32_t IpcClientManager::UnInit(const std::string &pkgName)
105 {
106 if (pkgName.empty()) {
107 LOGE("Invalid parameter, pkgName is empty.");
108 return ERR_DM_INPUT_PARA_INVALID;
109 }
110 LOGI("UnInit in, pkgName %s", pkgName.c_str());
111 if (dmInterface_ == nullptr) {
112 LOGE("DeviceManager not Init");
113 return ERR_DM_INIT_FAILED;
114 }
115
116 std::lock_guard<std::mutex> autoLock(lock_);
117 if (dmListener_.count(pkgName) > 0) {
118 std::shared_ptr<IpcReq> req = std::make_shared<IpcReq>();
119 std::shared_ptr<IpcRsp> rsp = std::make_shared<IpcRsp>();
120 req->SetPkgName(pkgName);
121 int32_t ret = dmInterface_->SendCmd(UNREGISTER_DEVICE_MANAGER_LISTENER, req, rsp);
122 if (ret != DM_OK) {
123 LOGE("UnRegisterDeviceManagerListener Failed with ret %d", ret);
124 return ret;
125 }
126 dmListener_.erase(pkgName);
127 }
128 if (dmListener_.empty()) {
129 if (dmRecipient_ != nullptr) {
130 dmInterface_->AsObject()->RemoveDeathRecipient(dmRecipient_);
131 dmRecipient_ = nullptr;
132 }
133 dmInterface_ = nullptr;
134 }
135 LOGI("completed, pkgName: %s", pkgName.c_str());
136 return DM_OK;
137 }
138
SendRequest(int32_t cmdCode,std::shared_ptr<IpcReq> req,std::shared_ptr<IpcRsp> rsp)139 int32_t IpcClientManager::SendRequest(int32_t cmdCode, std::shared_ptr<IpcReq> req, std::shared_ptr<IpcRsp> rsp)
140 {
141 if (cmdCode < 0 || cmdCode >= IPC_MSG_BUTT) {
142 LOGE("IpcClientManager::SendRequest cmdCode param invalid!");
143 return ERR_DM_UNSUPPORTED_IPC_COMMAND;
144 }
145 if (req == nullptr || rsp == nullptr) {
146 return ERR_DM_INPUT_PARA_INVALID;
147 }
148 LOGI("IpcClientManager::SendRequest in");
149 std::string pkgName = req->GetPkgName();
150 if (!IsInit(pkgName)) {
151 LOGE("IpcClientManager::SendRequest ERR_DM_INIT_FAILED");
152 return ERR_DM_INIT_FAILED;
153 }
154
155 LOGI("IpcClientManager::SendRequest cmdCode: %d", cmdCode);
156 return dmInterface_->SendCmd(cmdCode, req, rsp);
157 }
158
IsInit(const std::string & pkgName)159 bool IpcClientManager::IsInit(const std::string &pkgName)
160 {
161 (void)pkgName;
162 if (dmInterface_ == nullptr) {
163 LOGE("DeviceManager not Init");
164 return false;
165 }
166
167 return true;
168 }
169
OnDmServiceDied()170 int32_t IpcClientManager::OnDmServiceDied()
171 {
172 LOGI("IpcClientManager::OnDmServiceDied begin");
173 if (dmInterface_ == nullptr) {
174 LOGE("IpcClientManager::OnDmServiceDied, dmInterface_ null");
175 return ERR_DM_POINT_NULL;
176 }
177 if (dmRecipient_ != nullptr) {
178 dmInterface_->AsObject()->RemoveDeathRecipient(dmRecipient_);
179 dmRecipient_ = nullptr;
180 }
181 dmInterface_ = nullptr;
182 LOGI("IpcClientManager::OnDmServiceDied complete");
183 return DM_OK;
184 }
185 } // namespace DistributedHardware
186 } // namespace OHOS
187