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