• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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