1 /*
2 * Copyright (c) 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 <unistd.h>
17
18 #include "ability_manager_errors.h"
19 #include "hilog_wrapper.h"
20 #include "device.h"
21
22 namespace OHOS {
23 namespace ExternalDeviceManager {
GetBundleName(const std::string & bundleInfo)24 std::string Device::GetBundleName(const std::string &bundleInfo)
25 {
26 std::string::size_type pos = bundleInfo.find(stiching_);
27 if (pos == std::string::npos) {
28 EDM_LOGI(MODULE_DEV_MGR, "bundleInfo not find stiching name");
29 return "";
30 }
31
32 return bundleInfo.substr(0, pos);
33 }
34
GetAbilityName(const std::string & bundleInfo)35 std::string Device::GetAbilityName(const std::string &bundleInfo)
36 {
37 std::string::size_type pos = bundleInfo.find(stiching_);
38 if (pos == std::string::npos) {
39 EDM_LOGI(MODULE_DEV_MGR, "bundleInfo not find stiching name");
40 return "";
41 }
42
43 return bundleInfo.substr(pos + stiching_.length());
44 }
45
Connect()46 int32_t Device::Connect()
47 {
48 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
49 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
50 uint32_t busDevId = GetDeviceInfo()->GetBusDevId();
51 std::string bundleInfo = GetBundleInfo();
52 std::string bundleName = Device::GetBundleName(bundleInfo);
53 std::string abilityName = Device::GetAbilityName(bundleInfo);
54 AddDrvExtConnNotify();
55 int32_t ret = DriverExtensionController::GetInstance().ConnectDriverExtension(
56 bundleName, abilityName, connectNofitier_, busDevId);
57 // RESOLVE_ABILITY_ERR maybe due to bms is not ready in the boot process, sleep 100ms and try again
58 if (ret == AAFwk::RESOLVE_ABILITY_ERR) {
59 EDM_LOGW(MODULE_DEV_MGR, "%{public}s sleep 100ms to reconnect %{public}s %{public}s", __func__,
60 bundleName.c_str(), abilityName.c_str());
61 const int waitTimeMs = 100;
62 const int msToUs = 1000;
63 usleep(waitTimeMs * msToUs);
64 drvExtRemote_ = nullptr;
65 connectNofitier_->ClearDrvExtConnectionInfo();
66 ret = DriverExtensionController::GetInstance().ConnectDriverExtension(
67 bundleName, abilityName, connectNofitier_, busDevId);
68 }
69 if (ret != UsbErrCode::EDM_OK) {
70 EDM_LOGE(MODULE_DEV_MGR, "failed to connect driver extension");
71 return ret;
72 }
73 return UsbErrCode::EDM_OK;
74 }
75
Connect(const sptr<IDriverExtMgrCallback> & connectCallback)76 int32_t Device::Connect(const sptr<IDriverExtMgrCallback> &connectCallback)
77 {
78 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
79 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
80 uint64_t deviceId = GetDeviceInfo()->GetDeviceId();
81 if (drvExtRemote_ != nullptr) {
82 connectCallback->OnConnect(deviceId, drvExtRemote_, {UsbErrCode::EDM_OK, ""});
83 int32_t ret = RegisterDrvExtMgrCallback(connectCallback);
84 if (ret != UsbErrCode::EDM_OK) {
85 EDM_LOGE(MODULE_DEV_MGR, "failed to register callback object");
86 return ret;
87 }
88 }
89
90 int32_t ret = RegisterDrvExtMgrCallback(connectCallback);
91 if (ret != UsbErrCode::EDM_OK) {
92 EDM_LOGE(MODULE_DEV_MGR, "failed to register callback object");
93 return ret;
94 }
95
96 UpdateDrvExtConnNotify();
97 std::string bundleInfo = GetBundleInfo();
98 std::string bundleName = Device::GetBundleName(bundleInfo);
99 std::string abilityName = Device::GetAbilityName(bundleInfo);
100 AddDrvExtConnNotify();
101 uint32_t busDevId = GetDeviceInfo()->GetBusDevId();
102 ret = DriverExtensionController::GetInstance().ConnectDriverExtension(
103 bundleName, abilityName, connectNofitier_, busDevId);
104 if (ret != UsbErrCode::EDM_OK) {
105 EDM_LOGE(MODULE_DEV_MGR, "failed to connect driver extension");
106 UnregisterDrvExtMgrCallback(connectCallback);
107 return ret;
108 }
109 return UsbErrCode::EDM_OK;
110 }
111
Disconnect()112 int32_t Device::Disconnect()
113 {
114 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
115 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
116 if (connectNofitier_ != nullptr && connectNofitier_->IsInvalidDrvExtConnectionInfo()) {
117 EDM_LOGI(MODULE_DEV_MGR, "driver extension has been disconnected");
118 return UsbErrCode::EDM_OK;
119 }
120 uint32_t busDevId = GetDeviceInfo()->GetBusDevId();
121 std::string bundleInfo = GetBundleInfo();
122 std::string bundleName = Device::GetBundleName(bundleInfo);
123 std::string abilityName = Device::GetAbilityName(bundleInfo);
124 int32_t ret = DriverExtensionController::GetInstance().DisconnectDriverExtension(
125 bundleName, abilityName, connectNofitier_, busDevId);
126 if (ret != UsbErrCode::EDM_OK) {
127 EDM_LOGE(MODULE_DEV_MGR, "failed to disconnect driver extension");
128 return ret;
129 }
130
131 return UsbErrCode::EDM_OK;
132 }
133
OnConnect(const sptr<IRemoteObject> & remote,int resultCode)134 void Device::OnConnect(const sptr<IRemoteObject> &remote, int resultCode)
135 {
136 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
137 if (remote == nullptr || resultCode != UsbErrCode::EDM_OK) {
138 EDM_LOGE(MODULE_DEV_MGR, "failed to connect driver extension %{public}d", resultCode);
139 }
140
141 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
142 drvExtRemote_ = remote;
143
144 // notify application
145 for (auto &callback : callbacks_) {
146 callback->OnConnect(GetDeviceInfo()->GetDeviceId(), drvExtRemote_, {static_cast<UsbErrCode>(resultCode), ""});
147 }
148 }
149
OnDisconnect(int resultCode)150 void Device::OnDisconnect(int resultCode)
151 {
152 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
153 if (resultCode != UsbErrCode::EDM_OK) {
154 EDM_LOGE(MODULE_DEV_MGR, "failed to disconnect driver extension %{public}d", resultCode);
155 }
156
157 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
158 drvExtRemote_ = nullptr;
159 connectNofitier_->ClearDrvExtConnectionInfo();
160 for (auto &callback : callbacks_) {
161 callback->OnUnBind(GetDeviceInfo()->GetDeviceId(), {static_cast<UsbErrCode>(resultCode), ""});
162 }
163 callbacks_.clear();
164 }
165
UpdateDrvExtConnNotify()166 void Device::UpdateDrvExtConnNotify()
167 {
168 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
169 connectNofitier_ = std::make_shared<DrvExtConnNotify>(shared_from_this());
170 }
171
RegisterDrvExtMgrCallback(const sptr<IDriverExtMgrCallback> & callback)172 int32_t Device::RegisterDrvExtMgrCallback(const sptr<IDriverExtMgrCallback> &callback)
173 {
174 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
175 if (callback == nullptr) {
176 EDM_LOGE(MODULE_DEV_MGR, "failed to register callback because of invalid callback object");
177 return UsbErrCode::EDM_ERR_INVALID_OBJECT;
178 }
179
180 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
181 auto ret = callbacks_.insert(callback);
182 if (ret.second == false) {
183 EDM_LOGD(MODULE_DEV_MGR, "insert callback object repeatedly");
184 }
185
186 if (!RegisteDeathRecipient(callback)) {
187 EDM_LOGE(MODULE_DEV_MGR, "failed to register death recipient");
188 return UsbErrCode::EDM_NOK;
189 }
190
191 return UsbErrCode::EDM_OK;
192 }
193
UnregisterDrvExtMgrCallback(const sptr<IDriverExtMgrCallback> & callback)194 void Device::UnregisterDrvExtMgrCallback(const sptr<IDriverExtMgrCallback> &callback)
195 {
196 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
197 auto resIter =
198 std::find_if(callbacks_.begin(), callbacks_.end(), [&callback](const sptr<IDriverExtMgrCallback> &element) {
199 return element->AsObject() == callback->AsObject();
200 });
201 if (resIter != callbacks_.end()) {
202 callbacks_.erase(resIter);
203 }
204 }
205
UnregisterDrvExtMgrCallback(const wptr<IRemoteObject> & object)206 void Device::UnregisterDrvExtMgrCallback(const wptr<IRemoteObject> &object)
207 {
208 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
209 std::lock_guard<std::recursive_mutex> lock(deviceMutex_);
210 auto resIter =
211 std::find_if(callbacks_.begin(), callbacks_.end(), [&object](const sptr<IDriverExtMgrCallback> &element) {
212 return element->AsObject() == object;
213 });
214 if (resIter != callbacks_.end()) {
215 callbacks_.erase(resIter);
216 }
217 }
218
RegisteDeathRecipient(const sptr<IDriverExtMgrCallback> & callback)219 bool Device::RegisteDeathRecipient(const sptr<IDriverExtMgrCallback> &callback)
220 {
221 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
222 sptr<DriverExtMgrCallbackDeathRecipient> callbackDeathRecipient =
223 new DriverExtMgrCallbackDeathRecipient(shared_from_this());
224 return callback->AsObject()->AddDeathRecipient(callbackDeathRecipient);
225 }
226
OnRemoteDied(const wptr<IRemoteObject> & remote)227 void DriverExtMgrCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
228 {
229 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
230 auto device = device_.lock();
231 if (device == nullptr) {
232 EDM_LOGE(MODULE_DEV_MGR, "invalid device object");
233 return;
234 }
235
236 device->UnregisterDrvExtMgrCallback(remote);
237 }
238
OnConnectDone(const sptr<IRemoteObject> & remote,int resultCode)239 int32_t DrvExtConnNotify::OnConnectDone(const sptr<IRemoteObject> &remote, int resultCode)
240 {
241 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
242 auto device = device_.lock();
243 if (device == nullptr) {
244 EDM_LOGE(MODULE_DEV_MGR, "invalid device object");
245 return UsbErrCode::EDM_ERR_INVALID_OBJECT;
246 }
247
248 device->OnConnect(remote, resultCode);
249 return UsbErrCode::EDM_OK;
250 }
251
OnDisconnectDone(int resultCode)252 int32_t DrvExtConnNotify::OnDisconnectDone(int resultCode)
253 {
254 EDM_LOGI(MODULE_DEV_MGR, "%{public}s enter", __func__);
255 auto device = device_.lock();
256 if (device == nullptr) {
257 EDM_LOGE(MODULE_DEV_MGR, "invalid device object");
258 return UsbErrCode::EDM_ERR_INVALID_OBJECT;
259 }
260
261 device->OnDisconnect(resultCode);
262 return UsbErrCode::EDM_OK;
263 }
264 } // namespace ExternalDeviceManager
265 } // namespace OHOS
266