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 <thread>
20 #include "account_delegate.h"
21 #include "device_manager_adapter.h"
22 #include "log_print.h"
23 #include "metadata/meta_data_manager.h"
24 #include "utils/anonymous.h"
25 #include "utils/constant.h"
26
27 namespace OHOS::DistributedData {
28 using namespace OHOS::DistributedKv;
29 using DmAdapter = DistributedData::DeviceManagerAdapter;
GetInstance()30 UpgradeManager &UpgradeManager::GetInstance()
31 {
32 static UpgradeManager instance;
33 return instance;
34 }
35
Init(std::shared_ptr<ExecutorPool> executors)36 void UpgradeManager::Init(std::shared_ptr<ExecutorPool> executors)
37 {
38 if (executors_) {
39 return;
40 }
41 executors_ = std::move(executors);
42 executors_->Execute(GetTask());
43 }
44
GetTask()45 ExecutorPool::Task UpgradeManager::GetTask()
46 {
47 return [this] {
48 auto succ = InitLocalCapability();
49 if (succ) {
50 return;
51 }
52 executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GetTask());
53 };
54 }
55
GetCapability(const std::string & deviceId,bool & status)56 CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &status)
57 {
58 status = true;
59 auto index = capabilities_.Find(deviceId);
60 if (index.first) {
61 return index.second;
62 }
63 ZLOGI("load capability from meta");
64 CapMetaData capMetaData;
65 auto dbKey = CapMetaRow::GetKeyFor(deviceId);
66 ZLOGD("cap key:%{public}s", Anonymous::Change(std::string(dbKey.begin(), dbKey.end())).c_str());
67 status = MetaDataManager::GetInstance().LoadMeta(std::string(dbKey.begin(), dbKey.end()), capMetaData);
68 if (status) {
69 capabilities_.Insert(deviceId, capMetaData);
70 }
71 ZLOGI("device:%{public}s, version:%{public}d, insert:%{public}d", Anonymous::Change(deviceId).c_str(),
72 capMetaData.version, status);
73 return capMetaData;
74 }
75
InitLocalCapability()76 bool UpgradeManager::InitLocalCapability()
77 {
78 auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
79 CapMetaData capMetaData;
80 capMetaData.version = CapMetaData::CURRENT_VERSION;
81 auto dbKey = CapMetaRow::GetKeyFor(localDeviceId);
82 bool status = MetaDataManager::GetInstance().SaveMeta({ dbKey.begin(), dbKey.end() }, capMetaData);
83 if (status) {
84 capabilities_.Insert(localDeviceId, capMetaData);
85 }
86 ZLOGI("put capability meta data ret %{public}d", status);
87 return status;
88 }
89
SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate * storeDelegate,const KvStoreTuple & tuple,DistributedData::AUTH_GROUP_TYPE groupType)90 void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate,
91 const KvStoreTuple &tuple, DistributedData::AUTH_GROUP_TYPE groupType)
92 {
93 if (storeDelegate == nullptr) {
94 ZLOGE("null store delegate");
95 return;
96 }
97 auto localDevice = DmAdapter::GetInstance().GetLocalDevice().uuid;
98 auto devices =
99 AuthDelegate::GetInstance()->GetTrustedDevicesByType(groupType, std::stoi(tuple.userId), tuple.appId);
100 auto result = std::remove_if(devices.begin(), devices.end(), [&localDevice](const std::string &device) {
101 if (localDevice == device) {
102 return true;
103 }
104 bool flag = false;
105 auto capability = DistributedData::UpgradeManager::GetInstance().GetCapability(device, flag);
106 return !flag || capability.version >= DistributedData::CapMetaData::CURRENT_VERSION;
107 });
108 devices.erase(result, devices.end());
109
110 bool isSuccess = false;
111 auto compatibleUser = UpgradeManager::GetIdentifierByType(groupType, isSuccess);
112 if (!isSuccess) {
113 ZLOGW("get identifier by type failed");
114 return;
115 }
116
117 auto syncIdentifier =
118 DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId);
119 ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s",
120 Anonymous::Change(tuple.storeId).c_str(), compatibleUser.c_str(),
121 DistributedData::Serializable::Marshall(devices).c_str());
122 storeDelegate->SetEqualIdentifier(syncIdentifier, devices);
123 }
124
GetIdentifierByType(int32_t groupType,bool & isSuccess)125 std::string UpgradeManager::GetIdentifierByType(int32_t groupType, bool &isSuccess)
126 {
127 isSuccess = true;
128 if (groupType == PEER_TO_PEER_GROUP) {
129 return "default";
130 } else if (groupType == IDENTICAL_ACCOUNT_GROUP) {
131 auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
132 if (accountId.empty()) {
133 ZLOGE("failed to get current account id");
134 isSuccess = false;
135 return {};
136 }
137 return accountId;
138 } else {
139 ZLOGW("not supported group type:%{public}d", groupType);
140 isSuccess = false;
141 return {};
142 }
143 }
144 } // namespace OHOS::DistributedData
145