1 /*
2 * Copyright (c) 2024 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 "app_config_data_manager.h"
17
18 #include <unistd.h>
19
20 #include "errors.h"
21 #include "hilog_tag_wrapper.h"
22
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26 constexpr int32_t CHECK_INTERVAL = 100000; // 100ms
27 constexpr int32_t MAX_TIMES = 5;
28 constexpr const char *APP_CONFIG_STORAGE_DIR = "/data/service/el1/public/database/app_config_data";
29 const std::string KEY_WAITING_DEBUG_INFO = "WaitingDebugInfo";
30 } // namespace
31 const DistributedKv::AppId AppConfigDataManager::APP_ID = { "app_config_data_storage" };
32 const DistributedKv::StoreId AppConfigDataManager::STORE_ID = { "app_config_data_infos" };
AppConfigDataManager()33 AppConfigDataManager::AppConfigDataManager() {}
34
~AppConfigDataManager()35 AppConfigDataManager::~AppConfigDataManager()
36 {
37 if (kvStorePtr_ != nullptr) {
38 dataManager_.CloseKvStore(APP_ID, kvStorePtr_);
39 }
40 }
41
GetKvStore()42 DistributedKv::Status AppConfigDataManager::GetKvStore()
43 {
44 DistributedKv::Options options = {
45 .createIfMissing = true,
46 .encrypt = false,
47 .autoSync = false,
48 .syncable = false,
49 .securityLevel = DistributedKv::SecurityLevel::S2,
50 .area = DistributedKv::EL1,
51 .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
52 .baseDir = APP_CONFIG_STORAGE_DIR
53 };
54
55 DistributedKv::Status status = dataManager_.GetSingleKvStore(options, APP_ID, STORE_ID, kvStorePtr_);
56 if (status != DistributedKv::Status::SUCCESS) {
57 TAG_LOGE(AAFwkTag::APPMGR, "Return error is %{public}d.", status);
58 return status;
59 }
60
61 return status;
62 }
63
CheckKvStore()64 bool AppConfigDataManager::CheckKvStore()
65 {
66 if (kvStorePtr_ != nullptr) {
67 return true;
68 }
69
70 int32_t tryTimes = MAX_TIMES;
71 while (tryTimes > 0) {
72 DistributedKv::Status status = GetKvStore();
73 if (status == DistributedKv::Status::SUCCESS && kvStorePtr_ != nullptr) {
74 return true;
75 }
76 usleep(CHECK_INTERVAL);
77 tryTimes--;
78 }
79 return kvStorePtr_ != nullptr;
80 }
81
SetAppWaitingDebugInfo(const std::string & bundleName)82 int32_t AppConfigDataManager::SetAppWaitingDebugInfo(const std::string &bundleName)
83 {
84 TAG_LOGD(AAFwkTag::APPMGR, "Called, bundle name is %{public}s.", bundleName.c_str());
85 if (bundleName.empty()) {
86 TAG_LOGE(AAFwkTag::APPMGR, "Invalid value.");
87 return ERR_INVALID_VALUE;
88 }
89
90 {
91 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
92 if (!CheckKvStore()) {
93 TAG_LOGE(AAFwkTag::APPMGR, "The kvStore is nullptr.");
94 return ERR_NO_INIT;
95 }
96 }
97
98 DistributedKv::Key key(KEY_WAITING_DEBUG_INFO);
99 DistributedKv::Value value(bundleName);
100 DistributedKv::Status status;
101 {
102 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
103 status = kvStorePtr_->Put(key, value);
104 }
105
106 if (status != DistributedKv::Status::SUCCESS) {
107 TAG_LOGE(AAFwkTag::APPMGR, "Insert data to kvStore error is %{public}d.", status);
108 return ERR_INVALID_OPERATION;
109 }
110 return ERR_OK;
111 }
112
ClearAppWaitingDebugInfo()113 int32_t AppConfigDataManager::ClearAppWaitingDebugInfo()
114 {
115 TAG_LOGD(AAFwkTag::APPMGR, "called");
116 {
117 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
118 if (!CheckKvStore()) {
119 TAG_LOGE(AAFwkTag::APPMGR, "The kvStore is nullptr.");
120 return ERR_NO_INIT;
121 }
122 }
123
124 DistributedKv::Key key(KEY_WAITING_DEBUG_INFO);
125 DistributedKv::Status status;
126 {
127 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
128 status = kvStorePtr_->Delete(key);
129 }
130
131 if (status != DistributedKv::Status::SUCCESS) {
132 TAG_LOGE(AAFwkTag::APPMGR, "Delete data from kvStore error is %{public}d.", status);
133 return ERR_INVALID_OPERATION;
134 }
135 return ERR_OK;
136 }
137
GetAppWaitingDebugList(std::vector<std::string> & bundleNameList)138 int32_t AppConfigDataManager::GetAppWaitingDebugList(std::vector<std::string> &bundleNameList)
139 {
140 TAG_LOGD(AAFwkTag::APPMGR, "called");
141 {
142 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
143 if (!CheckKvStore()) {
144 TAG_LOGE(AAFwkTag::APPMGR, "The kvStore is nullptr.");
145 return ERR_NO_INIT;
146 }
147 }
148
149 DistributedKv::Status status;
150 std::vector<DistributedKv::Entry> allEntries;
151 {
152 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
153 status = kvStorePtr_->GetEntries(nullptr, allEntries);
154 }
155
156 if (status != DistributedKv::Status::SUCCESS) {
157 TAG_LOGE(AAFwkTag::APPMGR, "Get entries error is %{public}d.", status);
158 return ERR_INVALID_OPERATION;
159 }
160
161 for (const auto &item : allEntries) {
162 if (item.key.ToString() == KEY_WAITING_DEBUG_INFO) {
163 bundleNameList.emplace_back(item.value.ToString());
164 }
165 }
166 TAG_LOGD(AAFwkTag::APPMGR, "The bundle name list size is %{public}zu.", bundleNameList.size());
167 return ERR_OK;
168 }
169 } // namespace AbilityRuntime
170 } // namespace OHOS
171