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