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