• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #define MLOG_TAG "Distributed"
16 
17 #include "medialibrary_device.h"
18 #include "device_permission_verification.h"
19 #include "device_auth.h"
20 #include "media_log.h"
21 #include "medialibrary_data_manager.h"
22 #include "medialibrary_sync_table.h"
23 #include "medialibrary_tracer.h"
24 
25 namespace OHOS {
26 namespace Media {
27 using namespace std;
28 using namespace OHOS::AppExecFwk;
29 std::shared_ptr<MediaLibraryDevice> MediaLibraryDevice::mlDMInstance_ = nullptr;
30 
31 constexpr int TRIM_LENGTH = 4;
MediaLibraryDevice()32 MediaLibraryDevice::MediaLibraryDevice()
33 {
34     MEDIA_DEBUG_LOG("MediaLibraryDevice::constructor");
35 }
36 
~MediaLibraryDevice()37 MediaLibraryDevice::~MediaLibraryDevice()
38 {
39     MEDIA_DEBUG_LOG("MediaLibraryDevice::deconstructor");
40 }
41 
Start()42 void MediaLibraryDevice::Start()
43 {
44     MEDIA_DEBUG_LOG("MediaLibraryDevice::start");
45     bundleName_ = BUNDLE_NAME;
46     RegisterToDM();
47     if (deviceHandler_ == nullptr) {
48         auto runner = AppExecFwk::EventRunner::Create("MediaLibraryDevice");
49         deviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
50     }
51     devsInfoInter_ = make_shared<DevicesInfoInteract>();
52     if (devsInfoInter_ != nullptr) {
53         devsInfoInter_->Init();
54         std::string local = "";
55         localUdid_ = GetUdidByNetworkId(local);
56         devsInfoInter_->PutMLDeviceInfos(localUdid_);
57         isStart = true;
58     } else {
59         MEDIA_ERR_LOG("init devsInfoInter failed");
60     }
61 }
62 
Stop()63 void MediaLibraryDevice::Stop()
64 {
65     MEDIA_DEBUG_LOG("Stop enter");
66     UnRegisterFromDM();
67     ClearAllDevices();
68     isStart = false;
69     devsInfoInter_ = nullptr;
70     kvSyncDoneCv_.notify_all();
71 }
72 
GetInstance()73 std::shared_ptr<MediaLibraryDevice> MediaLibraryDevice::GetInstance()
74 {
75     static std::once_flag onceFlag;
76     std::call_once(onceFlag, []() mutable {
77         mlDMInstance_ = std::shared_ptr<MediaLibraryDevice>(new(std::nothrow) MediaLibraryDevice());
78         if (mlDMInstance_ != nullptr) {
79             mlDMInstance_ ->Start();
80         }
81     });
82     return mlDMInstance_;
83 }
84 
GetAllDeviceId(std::vector<OHOS::DistributedHardware::DmDeviceInfo> & deviceList)85 void MediaLibraryDevice::GetAllDeviceId(
86     std::vector<OHOS::DistributedHardware::DmDeviceInfo> &deviceList)
87 {
88     std::string extra = "";
89     auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
90     int32_t ret = deviceManager.GetTrustedDeviceList(bundleName_, extra, deviceList);
91     if (ret != 0) {
92         MEDIA_ERR_LOG("get trusted device list failed, ret %{public}d", ret);
93     }
94 }
OnSyncCompleted(const std::string & devId,const DistributedKv::Status status)95 void MediaLibraryDevice::OnSyncCompleted(const std::string &devId, const DistributedKv::Status status)
96 {
97     MEDIA_INFO_LOG("OnSyncCompleted dev id %{private}s, status %{public}d", devId.c_str(), status);
98     std::unique_lock<std::mutex> lock(cvMtx_);
99     kvSyncDoneCv_.notify_one();
100 }
101 
TryToGetTargetDevMLInfos(const std::string & udid,const std::string & networkId)102 void MediaLibraryDevice::TryToGetTargetDevMLInfos(const std::string &udid, const std::string &networkId)
103 {
104     static constexpr int SLEEP_WAITOUT = 500;
105     if (devsInfoInter_ == nullptr) {
106         MEDIA_ERR_LOG("devsInfoInter_ is nullptr");
107         return;
108     }
109     std::string version;
110     bool ret = devsInfoInter_->GetMLDeviceInfos(udid, version);
111     if (!ret) {
112         MEDIA_INFO_LOG("get ml infos failed, so try to sync pull first, wait...");
113         devsInfoInter_->SyncMLDeviceInfos(udid, networkId);
114         {
115             std::unique_lock<std::mutex> lock(cvMtx_);
116             if (kvSyncDoneCv_.wait_for(lock, std::chrono::milliseconds(SLEEP_WAITOUT)) == std::cv_status::timeout) {
117                 MEDIA_DEBUG_LOG("get ml infos sync timeout");
118             }
119             if (!isStart) {
120                 MEDIA_ERR_LOG("MediaLibraryDevice is stopped, this thread will exit");
121                 return;
122             }
123         }
124         MEDIA_DEBUG_LOG("get ml infos sync done, wakeup, try to get again");
125         ret = devsInfoInter_->GetMLDeviceInfos(udid, version);
126         if (!ret) {
127             MEDIA_ERR_LOG("get ml infos failed again, maybe target dev have never init");
128             return;
129         }
130     }
131     lock_guard<std::mutex> lock(devMtx_);
132     deviceInfoMap_[networkId].versionId = version;
133     MEDIA_INFO_LOG("get dev %{private}s ml infos, version %{private}s",
134         networkId.substr(0, TRIM_LENGTH).c_str(), version.c_str());
135 }
136 
OnGetDevSecLevel(const std::string & udid,const int32_t devLevel)137 void MediaLibraryDevice::OnGetDevSecLevel(const std::string &udid, const int32_t devLevel)
138 {
139     MEDIA_INFO_LOG("get dev %{public}s sec level %{public}d", udid.substr(0, TRIM_LENGTH).c_str(), devLevel);
140     if (udid == localUdid_) {
141         localDevLev_ = devLevel;
142         localSecLevelGot_.store(true);
143         localSecLevelDoneCv_.notify_all();
144         MEDIA_INFO_LOG("get local dev sec level %{public}d, notify all wait pids", devLevel);
145         return;
146     }
147     {
148         std::unique_lock<std::mutex> cvlock(gotSecLevelMtx_);
149         localSecLevelDoneCv_.wait(cvlock, [this] () { return localSecLevelGot_.load(); });
150         MEDIA_INFO_LOG("wakeup, get other dev sec level %{public}d", devLevel);
151     }
152 
153     if (localDevLev_ < devLevel || devLevel <= 0) {
154         MEDIA_ERR_LOG("local dev's sec lev %{public}d is lower than dev %{private}s %{public}d, or level invalid!",
155             localDevLev_, udid.substr(0, TRIM_LENGTH).c_str(), devLevel);
156         return;
157     }
158 
159     MediaLibraryDeviceInfo mldevInfo;
160     bool findTargetDev {false};
161     {
162         lock_guard<mutex> lock(devMtx_);
163         for (auto &[_, mlinfo] : deviceInfoMap_) {
164             if (mlinfo.deviceUdid == udid) {
165                 mldevInfo = mlinfo;
166                 findTargetDev = true;
167                 break;
168             }
169         }
170     }
171     if (!findTargetDev) {
172         MEDIA_ERR_LOG("not find this dev %{private}s in device map table", udid.substr(0, TRIM_LENGTH).c_str());
173         return;
174     }
175 
176     if (!MediaLibraryDeviceOperations::InsertDeviceInfo(rdbStore_, mldevInfo, bundleName_)) {
177         MEDIA_ERR_LOG("OnDeviceOnline InsertDeviceInfo failed!");
178         return;
179     }
180 
181     lock_guard<mutex> lock(devMtx_);
182     mldevInfo.devSecLevel = devLevel;
183     deviceInfoMap_[mldevInfo.networkId] = mldevInfo;
184 }
185 
DevOnlineProcess(const DistributedHardware::DmDeviceInfo & devInfo)186 void MediaLibraryDevice::DevOnlineProcess(const DistributedHardware::DmDeviceInfo &devInfo)
187 {
188     if (!localSecLevelGot_.load()) {
189         DevicePermissionVerification::ReqDestDevSecLevel(localUdid_);
190     }
191     MediaLibraryDeviceInfo mldevInfo;
192     GetMediaLibraryDeviceInfo(devInfo, mldevInfo);
193     {
194         lock_guard<mutex> autoLock(devMtx_);
195         deviceInfoMap_[devInfo.networkId] = mldevInfo;
196     }
197 
198     if (!DevicePermissionVerification::CheckPermission(mldevInfo.deviceUdid)) {
199         MEDIA_ERR_LOG("this dev has permission denied!");
200         return;
201     }
202 
203     std::vector<std::string> devices = { mldevInfo.networkId };
204     MediaLibrarySyncTable::SyncPullAllTableByDeviceId(rdbStore_, bundleName_, devices);
205 
206     auto getTargetMLInfoTask = std::make_unique<std::thread>(&MediaLibraryDevice::TryToGetTargetDevMLInfos,
207         this, mldevInfo.deviceUdid, mldevInfo.networkId);
208     getTargetMLInfoTask->detach();
209 }
210 
OnDeviceOnline(const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)211 void MediaLibraryDevice::OnDeviceOnline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
212 {
213     MEDIA_INFO_LOG("dev online network id %{private}s", deviceInfo.networkId);
214 }
215 
OnDeviceOffline(const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)216 void MediaLibraryDevice::OnDeviceOffline(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
217 {
218     MEDIA_INFO_LOG("OnDeviceOffline networkId = %{private}s", deviceInfo.networkId);
219 
220     if (deviceHandler_ == nullptr) {
221         MEDIA_ERR_LOG("OnDeviceOffline mediaLibraryDeviceHandler null");
222         return;
223     }
224     auto nodeOffline = [this, deviceInfo]() {
225         lock_guard<mutex> autoLock(devMtx_);
226         std::string networkId = deviceInfo.networkId;
227         auto info = deviceInfoMap_.find(networkId);
228         if (info == deviceInfoMap_.end()) {
229             MEDIA_ERR_LOG("OnDeviceOffline can not find networkId:%{private}s", networkId.c_str());
230             return;
231         }
232 
233         MediaLibraryDeviceOperations::UpdateDeviceInfo(rdbStore_, info->second, bundleName_);
234         deviceInfoMap_.erase(networkId);
235 
236         // 设备变更通知
237         NotifyDeviceChange();
238     };
239     if (!deviceHandler_->PostTask(nodeOffline)) {
240         MEDIA_ERR_LOG("OnDeviceOffline handler postTask failed");
241     }
242 }
243 
OnDeviceChanged(const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)244 void MediaLibraryDevice::OnDeviceChanged(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
245 {
246     MEDIA_INFO_LOG("MediaLibraryDevice OnDeviceChanged called networkId = %{private}s", deviceInfo.networkId);
247 }
248 
OnDeviceReady(const OHOS::DistributedHardware::DmDeviceInfo & deviceInfo)249 void MediaLibraryDevice::OnDeviceReady(const OHOS::DistributedHardware::DmDeviceInfo &deviceInfo)
250 {
251     MEDIA_INFO_LOG("OnDeviceReady network id %{private}s", deviceInfo.networkId);
252     if (deviceHandler_ == nullptr) {
253         MEDIA_ERR_LOG("mediaLibraryDeviceHandler null");
254         return;
255     }
256 
257     auto nodeOnline = [this, deviceInfo]() {
258         DevOnlineProcess(deviceInfo);
259         NotifyDeviceChange();
260     };
261     if (!deviceHandler_->PostTask(nodeOnline)) {
262         MEDIA_ERR_LOG("handler postTask failed");
263     }
264 }
265 
ClearAllDevices()266 void MediaLibraryDevice::ClearAllDevices()
267 {
268     lock_guard<mutex> autoLock(devMtx_);
269     deviceInfoMap_.clear();
270     excludeMap_.clear();
271 }
272 
NotifyDeviceChange()273 void MediaLibraryDevice::NotifyDeviceChange()
274 {
275     auto contextUri = make_unique<Uri>(MEDIALIBRARY_DEVICE_URI);
276     MediaLibraryDataManager::GetInstance()->NotifyChange(*contextUri);
277 }
278 
NotifyRemoteFileChange()279 void MediaLibraryDevice::NotifyRemoteFileChange()
280 {
281     auto contextUri = make_unique<Uri>(MEDIALIBRARY_REMOTEFILE_URI);
282     MediaLibraryDataManager::GetInstance()->NotifyChange(*contextUri);
283 }
284 
IsHasDevice(const string & deviceUdid)285 bool MediaLibraryDevice::IsHasDevice(const string &deviceUdid)
286 {
287     for (auto &[_, info] : deviceInfoMap_) {
288         if (!deviceUdid.compare(info.deviceUdid)) {
289             return true;
290         }
291     }
292     return false;
293 }
294 
InitDeviceRdbStore(const shared_ptr<NativeRdb::RdbStore> & rdbStore)295 bool MediaLibraryDevice::InitDeviceRdbStore(const shared_ptr<NativeRdb::RdbStore> &rdbStore)
296 {
297     rdbStore_ = rdbStore;
298 
299     if (!QueryDeviceTable()) {
300         MEDIA_ERR_LOG("MediaLibraryDevice InitDeviceRdbStore QueryDeviceTable fail!");
301         return false;
302     }
303     // 获取同一网络中的所有设备Id
304     std::vector<OHOS::DistributedHardware::DmDeviceInfo> deviceList;
305     GetAllDeviceId(deviceList);
306     MEDIA_ERR_LOG("MediaLibraryDevice InitDeviceRdbStore deviceList size = %{public}d", (int) deviceList.size());
307     for (auto& deviceInfo : deviceList) {
308         DevOnlineProcess(deviceInfo);
309     }
310 
311     std::vector<OHOS::Media::MediaLibraryDeviceInfo> deviceDataBaseList;
312     MediaLibraryDeviceOperations::GetAllDeviceData(rdbStore, deviceDataBaseList);
313     for (auto deviceInfo : deviceDataBaseList) {
314         if (!IsHasDevice(deviceInfo.deviceUdid)) {
315             MediaLibraryDeviceOperations::UpdateDeviceInfo(rdbStore_, deviceInfo, bundleName_);
316         }
317     }
318     MEDIA_INFO_LOG("deviceInfoMap size = %{public}d, deviceDataBaseList size = %{public}d",
319         (int) deviceInfoMap_.size(), (int) deviceDataBaseList.size());
320     return true;
321 }
322 
UpdateDeviceSyncStatus(const std::string & networkId,int32_t syncStatus)323 bool MediaLibraryDevice::UpdateDeviceSyncStatus(const std::string &networkId, int32_t syncStatus)
324 {
325     std::string udid;
326     {
327         lock_guard<mutex> autoLock(devMtx_);
328         auto iter = deviceInfoMap_.find(networkId);
329         if (iter == deviceInfoMap_.end()) {
330             MEDIA_ERR_LOG("UpdateDeviceSyncStatus can not find networkId:%{private}s", networkId.c_str());
331             return false;
332         }
333         udid = iter->second.deviceUdid;
334     }
335     return MediaLibraryDeviceOperations::UpdateSyncStatus(rdbStore_, udid, syncStatus);
336 }
337 
GetDevicieSyncStatus(const std::string & networkId,int32_t & syncStatus)338 bool MediaLibraryDevice::GetDevicieSyncStatus(const std::string &networkId, int32_t &syncStatus)
339 {
340     std::string udid;
341     {
342         lock_guard<mutex> autoLock(devMtx_);
343         auto info = deviceInfoMap_.find(networkId);
344         if (info == deviceInfoMap_.end()) {
345             MEDIA_ERR_LOG("GetDevicieSyncStatus can not find networkId:%{private}s", networkId.c_str());
346             return false;
347         }
348         udid = info->second.deviceUdid;
349     }
350     return MediaLibraryDeviceOperations::GetSyncStatusById(rdbStore_, udid, syncStatus);
351 }
352 
GetUdidByNetworkId(std::string & networkId)353 std::string MediaLibraryDevice::GetUdidByNetworkId(std::string &networkId)
354 {
355     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
356     if (networkId.empty()) {
357         OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
358         auto ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
359         if (ret != ERR_OK) {
360             MEDIA_ERR_LOG("get local device info failed, ret %{public}d", ret);
361             return "";
362         }
363         networkId = deviceInfo.networkId;
364     }
365 
366     std::string deviceUdid;
367     auto ret = deviceManager.GetUdidByNetworkId(bundleName_, networkId, deviceUdid);
368     if (ret != 0) {
369         MEDIA_INFO_LOG("GetDeviceUdid error networkId = %{private}s, ret %{public}d", networkId.c_str(), ret);
370         return std::string();
371     }
372     return deviceUdid;
373 }
374 
GetMediaLibraryDeviceInfo(const DistributedHardware::DmDeviceInfo & dmInfo,MediaLibraryDeviceInfo & mlInfo)375 void MediaLibraryDevice::GetMediaLibraryDeviceInfo(const DistributedHardware::DmDeviceInfo &dmInfo,
376     MediaLibraryDeviceInfo& mlInfo)
377 {
378     mlInfo.networkId = dmInfo.networkId;
379     mlInfo.deviceName = dmInfo.deviceName;
380     mlInfo.deviceTypeId = dmInfo.deviceTypeId;
381     mlInfo.deviceUdid = GetUdidByNetworkId(mlInfo.networkId);
382 }
383 
GetNetworkIdBySelfId(const std::string & selfId)384 string MediaLibraryDevice::GetNetworkIdBySelfId(const std::string &selfId)
385 {
386     for (auto &[_, info] : deviceInfoMap_) {
387         if (!selfId.compare(info.selfId)) {
388             return info.selfId;
389         }
390     }
391     MEDIA_ERR_LOG("GetNetworkIdBySelfId can not find selfId:%{private}s", selfId.c_str());
392     return "";
393 }
394 
QueryDeviceTable()395 bool MediaLibraryDevice::QueryDeviceTable()
396 {
397     if (rdbStore_ == nullptr) {
398         return false;
399     }
400     excludeMap_.clear();
401     return MediaLibraryDeviceOperations::QueryDeviceTable(rdbStore_, excludeMap_);
402 }
403 
OnRemoteDied()404 void MediaLibraryDevice::OnRemoteDied()
405 {
406     MEDIA_INFO_LOG("dm instance died");
407     UnRegisterFromDM();
408     RegisterToDM();
409 }
410 
RegisterToDM()411 void MediaLibraryDevice::RegisterToDM()
412 {
413     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
414     int errCode = deviceManager.InitDeviceManager(bundleName_, shared_from_this());
415     if (errCode != 0) {
416         MEDIA_ERR_LOG("RegisterToDm InitDeviceManager failed %{public}d", errCode);
417     }
418 
419     std::string extra = "";
420     errCode = deviceManager.RegisterDevStateCallback(bundleName_, extra, shared_from_this());
421     if (errCode != 0) {
422         MEDIA_ERR_LOG("RegisterDevStateCallback failed errCode %{public}d", errCode);
423     }
424     MEDIA_INFO_LOG("RegisterToDM success!");
425 }
426 
UnRegisterFromDM()427 void MediaLibraryDevice::UnRegisterFromDM()
428 {
429     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
430     int errCode = deviceManager.UnRegisterDevStateCallback(bundleName_);
431     if (errCode != 0) {
432         MEDIA_ERR_LOG("UnRegisterDevStateCallback failed errCode %{public}d", errCode);
433     }
434     errCode = deviceManager.UnInitDeviceManager(bundleName_);
435     if (errCode != 0) {
436         MEDIA_ERR_LOG("UnInitDeviceManager failed errCode %{public}d", errCode);
437     }
438     MEDIA_INFO_LOG("UnRegisterFromDM success");
439 }
440 
GetDeviceInfoMap(unordered_map<string,MediaLibraryDeviceInfo> & outDeviceMap)441 void MediaLibraryDevice::GetDeviceInfoMap(unordered_map<string, MediaLibraryDeviceInfo> &outDeviceMap)
442 {
443     outDeviceMap = deviceInfoMap_;
444 }
445 
QueryAgingDeviceInfos(vector<MediaLibraryDeviceInfo> & outDeviceInfos)446 bool MediaLibraryDevice::QueryAgingDeviceInfos(vector<MediaLibraryDeviceInfo> &outDeviceInfos)
447 {
448     return MediaLibraryDeviceOperations::GetAgingDeviceData(rdbStore_, outDeviceInfos);
449 }
450 
QueryAllDeviceUdid(vector<string> & deviceUdids)451 bool MediaLibraryDevice::QueryAllDeviceUdid(vector<string> &deviceUdids)
452 {
453     return MediaLibraryDeviceOperations::GetAllDeviceUdid(rdbStore_, deviceUdids);
454 }
455 
DeleteDeviceInfo(const string & udid)456 bool MediaLibraryDevice::DeleteDeviceInfo(const string &udid)
457 {
458     return MediaLibraryDeviceOperations::DeleteDeviceInfo(rdbStore_, udid);
459 }
460 } // namespace Media
461 } // namespace OHOS