• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LOG_TAG "UpgradeManager"
16 
17 #include "upgrade_manager.h"
18 
19 #include "account_delegate.h"
20 #include "device_kvstore_impl.h"
21 #include "executor_factory.h"
22 #include "log_print.h"
23 #include "utils/constant.h"
24 
25 namespace OHOS::DistributedData {
26 using namespace OHOS::DistributedKv;
GetInstance()27 UpgradeManager &UpgradeManager::GetInstance()
28 {
29     static UpgradeManager instance;
30     return instance;
31 }
32 
Init()33 void UpgradeManager::Init()
34 {
35     OHOS::DistributedKv::KvStoreTask retryTask([this]() {
36         do {
37             if (InitLocalCapability()) {
38                 break;
39             }
40             static constexpr int RETRY_INTERVAL = 500; // millisecond
41             std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL));
42         } while (true);
43     });
44     ExecutorFactory::GetInstance().Execute(std::move(retryTask));
45 }
46 
GetCapability(const std::string & deviceId,bool & status)47 CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &status)
48 {
49     status = true;
50     if (capabilityMap_.Contains(deviceId)) {
51         return capabilityMap_.Find(deviceId).second;
52     }
53     ZLOGI("load capability from meta");
54     CapMetaData capMetaData;
55     auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore();
56     if (metaDelegate == nullptr) {
57         ZLOGE("GetMetaKvStore return nullptr.");
58         status = false;
59         return capMetaData;
60     }
61     auto dbKey = CapMetaRow::GetKeyFor(deviceId);
62     ZLOGD("cap key:%{public}s", std::string(dbKey.begin(), dbKey.end()).c_str());
63     DistributedDB::Value dbValue;
64     auto ret = metaDelegate->Get(dbKey, dbValue);
65     if (ret != DistributedDB::DBStatus::OK) {
66         ZLOGE("get cap meta failed, ret:%{public}d", ret);
67         status = false;
68         return capMetaData;
69     }
70     capMetaData.Unmarshall({ dbValue.begin(), dbValue.end() });
71     bool isOk = capabilityMap_.Insert(deviceId, capMetaData);
72     ZLOGI("device:%{public}.10s, version:%{public}d, insert:%{public}d", deviceId.c_str(), capMetaData.version, isOk);
73     return capMetaData;
74 }
75 
InitLocalCapability()76 bool UpgradeManager::InitLocalCapability()
77 {
78     auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore();
79     if (metaDelegate == nullptr) {
80         ZLOGE("GetMetaKvStore return nullptr.");
81         return false;
82     }
83     auto localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId();
84     CapMetaData capMetaData;
85     capMetaData.version = CapMetaData::CURRENT_VERSION;
86     auto dbKey = CapMetaRow::GetKeyFor(localDeviceId);
87     std::string jsonData = CapMetaData::Marshall(capMetaData);
88     DistributedDB::Value dbValue { jsonData.begin(), jsonData.end() };
89     auto ret = metaDelegate->Put(dbKey, dbValue);
90     ZLOGI("put capability meta data ret %{public}d", ret);
91     bool isOk = capabilityMap_.Insert(localDeviceId, capMetaData);
92     return ret == DistributedDB::DBStatus::OK && isOk;
93 }
94 
SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate * storeDelegate,const KvStoreTuple & tuple,DistributedData::AUTH_GROUP_TYPE groupType)95 void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate,
96     const KvStoreTuple &tuple, DistributedData::AUTH_GROUP_TYPE groupType)
97 {
98     if (storeDelegate == nullptr) {
99         ZLOGE("null store delegate");
100         return;
101     }
102     auto localDevice = DeviceKvStoreImpl::GetLocalDeviceId();
103     auto devices =
104         AuthDelegate::GetInstance()->GetTrustedDevicesByType(groupType, std::stoi(tuple.userId), tuple.appId);
105     auto result = std::remove_if(devices.begin(), devices.end(), [&localDevice](const std::string &device) {
106         if (localDevice == device) {
107             return true;
108         }
109         bool flag = false;
110         auto capability = DistributedData::UpgradeManager::GetInstance().GetCapability(device, flag);
111         return !flag || capability.version >= DistributedData::CapMetaData::CURRENT_VERSION;
112     });
113     devices.erase(result, devices.end());
114 
115     bool isSuccess = false;
116     auto compatibleUser = UpgradeManager::GetIdentifierByType(groupType, isSuccess);
117     if (!isSuccess) {
118         ZLOGW("get identifier by type failed");
119         return;
120     }
121 
122     auto syncIdentifier =
123         DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId);
124     ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s", tuple.storeId.c_str(),
125         compatibleUser.c_str(), DistributedData::Serializable::Marshall(devices).c_str());
126     storeDelegate->SetEqualIdentifier(syncIdentifier, devices);
127 }
128 
GetIdentifierByType(int32_t groupType,bool & isSuccess)129 std::string UpgradeManager::GetIdentifierByType(int32_t groupType, bool &isSuccess)
130 {
131     isSuccess = true;
132     if (groupType == PEER_TO_PEER_GROUP) {
133         return "default";
134     } else if (groupType == IDENTICAL_ACCOUNT_GROUP) {
135         auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
136         if (accountId.empty()) {
137             ZLOGE("failed to get current account id");
138             isSuccess = false;
139             return {};
140         }
141         return accountId;
142     } else {
143         ZLOGW("not supported group type:%{public}d", groupType);
144         isSuccess = false;
145         return {};
146     }
147 }
148 } // namespace OHOS::DistributedData
149