1 /*
2  * Copyright (C) 2022 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 "devices_info_interact.h"
18 #include "application_context.h"
19 #include "media_log.h"
20 #include "medialibrary_db_const.h"
21 #include "medialibrary_device.h"
22 #include "medialibrary_errno.h"
23 
24 namespace OHOS {
25 namespace Media {
26 static const std::string ML_MULTIDEV_INFO_ID = "mediaLibrayMultiDevInfoFetch";
27 static const std::string MEDIA_LIBRARY_SERVICE_TYPE = "characteristic.medialibrary.version";
28 
DevicesInfoInteract()29 DevicesInfoInteract::DevicesInfoInteract() : bundleName_(BUNDLE_NAME)
30 {
31     MEDIA_DEBUG_LOG("DevicesInfoInteract::constructor");
32 }
33 
~DevicesInfoInteract()34 DevicesInfoInteract::~DevicesInfoInteract()
35 {
36     DistributedKv::DistributedKvDataManager kvManager;
37     DistributedKv::AppId appId = { BUNDLE_NAME };
38     if (kvStorePtr_ != nullptr) {
39         kvManager.CloseKvStore(appId, kvStorePtr_);
40         kvStorePtr_ = nullptr;
41     }
42     MEDIA_DEBUG_LOG("DevicesInfoInteract::deconstructor");
43 }
44 
Init()45 void DevicesInfoInteract::Init()
46 {
47     auto context = AbilityRuntime::Context::GetApplicationContext();
48     if (context == nullptr) {
49         MEDIA_ERR_LOG("context is null");
50         return;
51     }
52     DistributedKv::DistributedKvDataManager kvManager;
53     DistributedKv::Options options = {
54         .createIfMissing = true,
55         .persistent = true,
56         .backup = true,
57         .autoSync = true,
58         .securityLevel = DistributedKv::SecurityLevel::NO_LABEL,
59         .area = DistributedKv::Area::EL2,
60         .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
61         .baseDir = context->GetDatabaseDir()
62     };
63     DistributedKv::AppId appId = { BUNDLE_NAME };
64     DistributedKv::StoreId storeId = { ML_MULTIDEV_INFO_ID };
65     DistributedKv::Status status = kvManager.GetSingleKvStore(options, appId, storeId, kvStorePtr_);
66     if (status != DistributedKv::Status::SUCCESS) {
67         MEDIA_ERR_LOG("KvStore get failed! %{public}d", status);
68         return;
69     }
70     MEDIA_INFO_LOG("KvStore using for %{private}s init success!", ML_MULTIDEV_INFO_ID.c_str());
71 }
72 
GenerateKey(const std::string & udid)73 std::string DevicesInfoInteract::GenerateKey(const std::string &udid)
74 {
75     return (udid + bundleName_ + MEDIA_LIBRARY_SERVICE_TYPE);
76 }
77 
SyncMLDeviceInfos(const std::string & udid,const std::string & networkId)78 void DevicesInfoInteract::SyncMLDeviceInfos(const std::string &udid, const std::string &networkId)
79 {
80     if (kvStorePtr_ == nullptr) {
81         MEDIA_ERR_LOG("kvstore is nullptr");
82         return;
83     }
84 
85     std::string key = GenerateKey(udid);
86     DistributedKv::DataQuery dataQuery;
87     dataQuery.KeyPrefix(key);
88     std::vector<std::string> devices = { networkId };
89     DistributedKv::Status status = kvStorePtr_->Sync(devices, DistributedKv::SyncMode::PULL,
90         dataQuery, shared_from_this());
91     MEDIA_ERR_LOG("kvstore sync end, status %{public}d", status);
92 }
93 
GetMLDeviceInfos(const std::string & udid,std::string & val)94 bool DevicesInfoInteract::GetMLDeviceInfos(const std::string &udid, std::string &val)
95 {
96     if (kvStorePtr_ == nullptr) {
97         MEDIA_ERR_LOG("kvstore is nullptr");
98         return false;
99     }
100 
101     std::string key = GenerateKey(udid);
102 
103     DistributedKv::Key k(key);
104     DistributedKv::Value v;
105     DistributedKv::Status status = kvStorePtr_->Get(k, v);
106     if (status != DistributedKv::Status::SUCCESS) {
107         MEDIA_ERR_LOG("get kvstore failed %{public}d", status);
108         val = MEDIA_LIBRARY_VERSION;
109         return false;
110     }
111     std::string versionInfo = v.ToString();
112     nlohmann::json jsonObj = nlohmann::json::parse(versionInfo);
113     if (jsonObj.is_discarded()) {
114         MEDIA_ERR_LOG("parse json failed");
115         val = MEDIA_LIBRARY_VERSION;
116         return false;
117     }
118     val = jsonObj.at("medialibrary_version");
119     MEDIA_INFO_LOG("get kvstore success! ml version info %{private}s, val %{private}s",
120         versionInfo.c_str(), val.c_str());
121     return true;
122 }
123 
PutMLDeviceInfos(const std::string & udid)124 void DevicesInfoInteract::PutMLDeviceInfos(const std::string &udid)
125 {
126     if (kvStorePtr_ == nullptr) {
127         MEDIA_ERR_LOG("kvstore is nullptr");
128         return;
129     }
130 
131     std::string key = GenerateKey(udid);
132     nlohmann::json json;
133     json["medialibrary_version"] = MEDIA_LIBRARY_VERSION;
134     std::string val = json.dump();
135 
136     DistributedKv::Key k(key);
137     DistributedKv::Value v(val);
138     DistributedKv::Status status = kvStorePtr_->Put(k, v);
139     if (status != DistributedKv::Status::SUCCESS) {
140         MEDIA_ERR_LOG("put kvstore failed %{public}d", status);
141         return;
142     }
143     MEDIA_INFO_LOG("put kvstore success!, val %{private}s", val.c_str());
144 }
145 
SyncCompleted(const std::map<std::string,DistributedKv::Status> & results)146 void DevicesInfoInteract::SyncCompleted(const std::map<std::string, DistributedKv::Status> &results)
147 {
148     for (auto &[devId, status] : results) {
149         MediaLibraryDevice::GetInstance()->OnSyncCompleted(devId, status);
150     }
151 }
152 } // namespace Media
153 } // namespace OHOS
154