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