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
16 #include "setting_provider.h"
17 #include <thread>
18 #include <regex>
19 #include "datashare_predicates.h"
20 #include "datashare_result_set.h"
21 #include "datashare_values_bucket.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "os_account_manager.h"
25 #include "power_log.h"
26 #include "rdb_errno.h"
27 #include "result_set.h"
28 #include "uri.h"
29
30 namespace OHOS {
31 namespace PowerMgr {
32 SettingProvider* SettingProvider::instance_;
33 std::mutex SettingProvider::settingMutex_;
34 sptr<IRemoteObject> SettingProvider::remoteObj_;
35 const int32_t INITIAL_USER_ID = 100;
36 int32_t SettingProvider::currentUserId_ = INITIAL_USER_ID;
37 namespace {
38 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
39 const std::string SETTING_COLUMN_VALUE = "VALUE";
40 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
41 const std::string SETTING_URI_PROXY_USER = "datashare:///com.ohos.settingsdata/entry/settingsdata/";
42 const std::string SETTING_URI_PROXY_USER_ADAPT = "USER_SETTINGSDATA_SECURE_##USERID##?Proxy=true";
43 constexpr const char *USERID_REPLACE = "##USERID##";
44 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
45 } // namespace
46
~SettingProvider()47 SettingProvider::~SettingProvider()
48 {
49 instance_ = nullptr;
50 remoteObj_ = nullptr;
51 }
52
GetInstance(int32_t systemAbilityId)53 SettingProvider& SettingProvider::GetInstance(int32_t systemAbilityId)
54 {
55 if (instance_ == nullptr) {
56 std::lock_guard<std::mutex> lock(settingMutex_);
57 if (instance_ == nullptr) {
58 instance_ = new SettingProvider();
59 Initialize(systemAbilityId);
60 }
61 }
62 return *instance_;
63 }
64
CopyDataForUpdateScene()65 void SettingProvider::CopyDataForUpdateScene()
66 {
67 if (IsNeedDataMigrationCopy()) {
68 DataMigrationCopy();
69 }
70 }
71
GetIntValue(const std::string & key,int32_t & value)72 ErrCode SettingProvider::GetIntValue(const std::string& key, int32_t& value)
73 {
74 int64_t valueLong;
75 ErrCode ret = GetLongValue(key, valueLong);
76 if (ret != ERR_OK) {
77 return ret;
78 }
79 value = static_cast<int32_t>(valueLong);
80 return ERR_OK;
81 }
82
GetLongValue(const std::string & key,int64_t & value)83 ErrCode SettingProvider::GetLongValue(const std::string& key, int64_t& value)
84 {
85 std::string valueStr;
86 ErrCode ret = GetStringValue(key, valueStr);
87 if (ret != ERR_OK) {
88 return ret;
89 }
90 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, 10));
91 return ERR_OK;
92 }
93
GetBoolValue(const std::string & key,bool & value)94 ErrCode SettingProvider::GetBoolValue(const std::string& key, bool& value)
95 {
96 std::string valueStr;
97 ErrCode ret = GetStringValue(key, valueStr);
98 if (ret != ERR_OK) {
99 return ret;
100 }
101 value = (valueStr == "true");
102 return ERR_OK;
103 }
104
PutIntValue(const std::string & key,int32_t value,bool needNotify)105 ErrCode SettingProvider::PutIntValue(const std::string& key, int32_t value, bool needNotify)
106 {
107 return PutStringValue(key, std::to_string(value), needNotify);
108 }
109
PutLongValue(const std::string & key,int64_t value,bool needNotify)110 ErrCode SettingProvider::PutLongValue(const std::string& key, int64_t value, bool needNotify)
111 {
112 return PutStringValue(key, std::to_string(value), needNotify);
113 }
114
PutBoolValue(const std::string & key,bool value,bool needNotify)115 ErrCode SettingProvider::PutBoolValue(const std::string& key, bool value, bool needNotify)
116 {
117 std::string valueStr = value ? "true" : "false";
118 return PutStringValue(key, valueStr, needNotify);
119 }
120
IsValidKey(const std::string & key)121 bool SettingProvider::IsValidKey(const std::string& key)
122 {
123 std::string value;
124 ErrCode ret = GetStringValue(key, value);
125 if (!value.empty()) {
126 POWER_HILOGI(COMP_UTILS, "the getValue is:%{public}s", value.c_str());
127 }
128 POWER_HILOGI(COMP_UTILS, "the getRet is:%{public}u", ret);
129 return (ret != ERR_NAME_NOT_FOUND) && (!value.empty());
130 }
131
IsValidKeyGlobal(const std::string & key)132 bool SettingProvider::IsValidKeyGlobal(const std::string& key)
133 {
134 std::string value;
135 ErrCode ret = GetStringValueGlobal(key, value);
136 if (!value.empty()) {
137 POWER_HILOGI(COMP_UTILS, "the getValueGlobal is:%{public}s", value.c_str());
138 }
139 POWER_HILOGI(COMP_UTILS, "the getRetGlobal is:%{public}u", ret);
140 return (ret != ERR_NAME_NOT_FOUND) && (!value.empty());
141 }
142
CreateObserver(const std::string & key,SettingObserver::UpdateFunc & func)143 sptr<SettingObserver> SettingProvider::CreateObserver(const std::string& key, SettingObserver::UpdateFunc& func)
144 {
145 sptr<SettingObserver> observer = new SettingObserver();
146 observer->SetKey(key);
147 observer->SetUpdateFunc(func);
148 return observer;
149 }
150
ExecRegisterCb(const sptr<SettingObserver> & observer)151 void SettingProvider::ExecRegisterCb(const sptr<SettingObserver>& observer)
152 {
153 if (observer == nullptr) {
154 POWER_HILOGE(COMP_UTILS, "observer is nullptr");
155 return;
156 }
157 observer->OnChange();
158 }
159
RegisterObserver(const sptr<SettingObserver> & observer)160 ErrCode SettingProvider::RegisterObserver(const sptr<SettingObserver>& observer)
161 {
162 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
163 auto uri = AssembleUri(observer->GetKey());
164 auto helper = CreateDataShareHelper(observer->GetKey());
165 if (helper == nullptr) {
166 IPCSkeleton::SetCallingIdentity(callingIdentity);
167 return ERR_NO_INIT;
168 }
169 helper->RegisterObserver(uri, observer);
170 helper->NotifyChange(uri);
171 std::thread execCb([this, observer] { this->ExecRegisterCb(observer); });
172 execCb.detach();
173 ReleaseDataShareHelper(helper);
174 IPCSkeleton::SetCallingIdentity(callingIdentity);
175 POWER_HILOGD(COMP_UTILS, "succeed to register observer of uri=%{public}s", uri.ToString().c_str());
176 return ERR_OK;
177 }
178
UnregisterObserver(const sptr<SettingObserver> & observer)179 ErrCode SettingProvider::UnregisterObserver(const sptr<SettingObserver>& observer)
180 {
181 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
182 auto uri = AssembleUri(observer->GetKey());
183 auto helper = CreateDataShareHelper(observer->GetKey());
184 if (helper == nullptr) {
185 IPCSkeleton::SetCallingIdentity(callingIdentity);
186 return ERR_NO_INIT;
187 }
188 helper->UnregisterObserver(uri, observer);
189 ReleaseDataShareHelper(helper);
190 IPCSkeleton::SetCallingIdentity(callingIdentity);
191 POWER_HILOGD(COMP_UTILS, "succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
192 return ERR_OK;
193 }
194
Initialize(int32_t systemAbilityId)195 void SettingProvider::Initialize(int32_t systemAbilityId)
196 {
197 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
198 if (sam == nullptr) {
199 POWER_HILOGE(COMP_UTILS, "GetSystemAbilityManager return nullptr");
200 return;
201 }
202 auto remoteObj = sam->GetSystemAbility(systemAbilityId);
203 if (remoteObj == nullptr) {
204 POWER_HILOGE(COMP_UTILS, "GetSystemAbility return nullptr, systemAbilityId=%{public}d", systemAbilityId);
205 return;
206 }
207 remoteObj_ = remoteObj;
208 }
209
GetStringValue(const std::string & key,std::string & value)210 ErrCode SettingProvider::GetStringValue(const std::string& key, std::string& value)
211 {
212 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
213 auto helper = CreateDataShareHelper(key);
214 if (helper == nullptr) {
215 IPCSkeleton::SetCallingIdentity(callingIdentity);
216 return ERR_NO_INIT;
217 }
218 std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
219 DataShare::DataSharePredicates predicates;
220 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
221 Uri uri(AssembleUri(key));
222 auto resultSet = helper->Query(uri, predicates, columns);
223 ReleaseDataShareHelper(helper);
224 if (resultSet == nullptr) {
225 POWER_HILOGE(COMP_UTILS, "helper->Query return nullptr");
226 IPCSkeleton::SetCallingIdentity(callingIdentity);
227 return ERR_INVALID_OPERATION;
228 }
229 int32_t count;
230 resultSet->GetRowCount(count);
231 if (count == 0) {
232 POWER_HILOGW(COMP_UTILS, "not found value, key=%{public}s, count=%{public}d", key.c_str(), count);
233 IPCSkeleton::SetCallingIdentity(callingIdentity);
234 resultSet->Close();
235 return ERR_NAME_NOT_FOUND;
236 }
237 const int32_t INDEX = 0;
238 resultSet->GoToRow(INDEX);
239 int32_t ret = resultSet->GetString(INDEX, value);
240 if (ret != NativeRdb::E_OK) {
241 POWER_HILOGW(COMP_UTILS, "resultSet->GetString return not ok, ret=%{public}d", ret);
242 IPCSkeleton::SetCallingIdentity(callingIdentity);
243 resultSet->Close();
244 return ERR_INVALID_VALUE;
245 }
246 resultSet->Close();
247 IPCSkeleton::SetCallingIdentity(callingIdentity);
248 return ERR_OK;
249 }
250
PutStringValue(const std::string & key,const std::string & value,bool needNotify)251 ErrCode SettingProvider::PutStringValue(const std::string& key, const std::string& value, bool needNotify)
252 {
253 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
254 auto helper = CreateDataShareHelper(key);
255 if (helper == nullptr) {
256 IPCSkeleton::SetCallingIdentity(callingIdentity);
257 return ERR_NO_INIT;
258 }
259 DataShare::DataShareValueObject keyObj(key);
260 DataShare::DataShareValueObject valueObj(value);
261 DataShare::DataShareValuesBucket bucket;
262 bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
263 bucket.Put(SETTING_COLUMN_VALUE, valueObj);
264 DataShare::DataSharePredicates predicates;
265 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
266 Uri uri(AssembleUri(key));
267 if (helper->Update(uri, predicates, bucket) <= 0) {
268 POWER_HILOGD(COMP_UTILS, "no data exist, insert one row");
269 helper->Insert(uri, bucket);
270 }
271 if (needNotify) {
272 helper->NotifyChange(AssembleUri(key));
273 }
274 ReleaseDataShareHelper(helper);
275 IPCSkeleton::SetCallingIdentity(callingIdentity);
276 return ERR_OK;
277 }
278
CreateDataShareHelper(const std::string & key)279 std::shared_ptr<DataShare::DataShareHelper> SettingProvider::CreateDataShareHelper(const std::string& key)
280 {
281 std::lock_guard<std::mutex> lock(settingMutex_);
282 std::string uriProxyStr;
283 if (IsNeedMultiUser(key)) {
284 uriProxyStr = SETTING_URI_PROXY_USER + "USER_SETTINGSDATA_SECURE_" +
285 std::to_string(currentUserId_) + "?Proxy=true";
286 POWER_HILOGI(COMP_UTILS, "the uriProxyStr is %{public}s", uriProxyStr.c_str());
287 } else {
288 uriProxyStr = SETTING_URI_PROXY;
289 }
290 auto helper = DataShare::DataShareHelper::Creator(remoteObj_, uriProxyStr, SETTINGS_DATA_EXT_URI);
291 if (helper == nullptr) {
292 POWER_HILOGW(COMP_UTILS, "helper is nullptr, uri=%{public}s", uriProxyStr.c_str());
293 return nullptr;
294 }
295 return helper;
296 }
297
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)298 bool SettingProvider::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)
299 {
300 if (!helper->Release()) {
301 POWER_HILOGW(COMP_UTILS, "release helper fail");
302 return false;
303 }
304 return true;
305 }
306
AssembleUri(const std::string & key)307 Uri SettingProvider::AssembleUri(const std::string& key)
308 {
309 std::lock_guard<std::mutex> lock(settingMutex_);
310 if (IsNeedMultiUser(key)) {
311 std::string userSetting = ReplaceUserIdForUri(currentUserId_);
312 std::string specialUri = SETTING_URI_PROXY_USER + userSetting + "&key=" + key;
313 POWER_HILOGI(COMP_UTILS, "the non-global uri is %{public}s", specialUri.c_str());
314 Uri uri(specialUri);
315 return uri;
316 }
317 Uri uri(SETTING_URI_PROXY + "&key=" + key);
318 return uri;
319 }
320
IsNeedDataMigrationCopy()321 bool SettingProvider::IsNeedDataMigrationCopy()
322 {
323 bool isNeedMigrationCopy = false;
324 if (IsValidKeyGlobal(SETTING_POWER_WAKEUP_PICKUP_KEY)) {
325 if (!IsValidKey(SETTING_POWER_WAKEUP_PICKUP_KEY)) {
326 isNeedMigrationCopy = true;
327 }
328 }
329 POWER_HILOGI(COMP_UTILS, "IsNeedDataMigrationCopy:(%{public}d)", isNeedMigrationCopy);
330 return isNeedMigrationCopy;
331 }
332
DataMigrationCopy()333 void SettingProvider::DataMigrationCopy()
334 {
335 std::string value;
336 GetStringValueGlobal(SETTING_POWER_WAKEUP_DOUBLE_KEY, value);
337 PutStringValue(SETTING_POWER_WAKEUP_DOUBLE_KEY, value);
338 GetStringValueGlobal(SETTING_POWER_WAKEUP_PICKUP_KEY, value);
339 PutStringValue(SETTING_POWER_WAKEUP_PICKUP_KEY, value);
340 GetStringValueGlobal(SETTING_POWER_WAKEUP_SOURCES_KEY, value);
341 PutStringValue(SETTING_POWER_WAKEUP_SOURCES_KEY, value);
342 }
343
GetStringValueGlobal(const std::string & key,std::string & value)344 ErrCode SettingProvider::GetStringValueGlobal(const std::string& key, std::string& value)
345 {
346 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
347 auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
348 if (helper == nullptr) {
349 IPCSkeleton::SetCallingIdentity(callingIdentity);
350 return ERR_NO_INIT;
351 }
352 std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
353 DataShare::DataSharePredicates predicates;
354 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
355 Uri uri(SETTING_URI_PROXY + "&key=" + key);
356 auto resultSet = helper->Query(uri, predicates, columns);
357 ReleaseDataShareHelper(helper);
358 if (resultSet == nullptr) {
359 POWER_HILOGE(COMP_UTILS, "helper->Query return nullptr");
360 IPCSkeleton::SetCallingIdentity(callingIdentity);
361 return ERR_INVALID_OPERATION;
362 }
363 int32_t count;
364 resultSet->GetRowCount(count);
365 if (count == 0) {
366 POWER_HILOGW(COMP_UTILS, "not found value, key=%{public}s, count=%{public}d", key.c_str(), count);
367 IPCSkeleton::SetCallingIdentity(callingIdentity);
368 resultSet->Close();
369 return ERR_NAME_NOT_FOUND;
370 }
371 const int32_t INDEX = 0;
372 resultSet->GoToRow(INDEX);
373 int32_t ret = resultSet->GetString(INDEX, value);
374 if (ret != NativeRdb::E_OK) {
375 POWER_HILOGW(COMP_UTILS, "resultSet->GetString return not ok, ret=%{public}d", ret);
376 IPCSkeleton::SetCallingIdentity(callingIdentity);
377 resultSet->Close();
378 return ERR_INVALID_VALUE;
379 }
380 resultSet->Close();
381 IPCSkeleton::SetCallingIdentity(callingIdentity);
382 return ERR_OK;
383 }
384
IsNeedMultiUser(const std::string & key)385 bool SettingProvider::IsNeedMultiUser(const std::string& key)
386 {
387 std::vector<std::string> needMultiUserStrVec {
388 SETTING_POWER_WAKEUP_DOUBLE_KEY,
389 SETTING_POWER_WAKEUP_PICKUP_KEY,
390 SETTING_POWER_WAKEUP_SOURCES_KEY,
391 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
392 SETTING_DISPLAY_AC_OFF_TIME_KEY,
393 SETTING_DISPLAY_DC_OFF_TIME_KEY,
394 SETTING_POWER_AC_SUSPEND_SOURCES_KEY,
395 SETTING_POWER_DC_SUSPEND_SOURCES_KEY,
396 #endif
397 };
398
399 if (std::count(needMultiUserStrVec.begin(), needMultiUserStrVec.end(), key)) {
400 return true;
401 }
402 return false;
403 }
404
ReplaceUserIdForUri(int32_t userId)405 std::string SettingProvider::ReplaceUserIdForUri(int32_t userId)
406 {
407 std::string tempUri = SETTING_URI_PROXY_USER_ADAPT;
408 std::regex pattern(USERID_REPLACE);
409 return std::regex_replace(tempUri, pattern, std::to_string(userId));
410 }
411
UpdateCurrentUserId()412 void SettingProvider::UpdateCurrentUserId()
413 {
414 std::lock_guard<std::mutex> lock(settingMutex_);
415 std::vector<int> activedIds;
416 int ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedIds);
417 if (ret != 0) {
418 POWER_HILOGE(COMP_UTILS, "QueryActivedOsAccountIds failed, ret is %{public}d", ret);
419 return;
420 }
421 if (activedIds.empty()) {
422 POWER_HILOGE(COMP_UTILS, "QueryActivedOsAccountIds is empty");
423 return;
424 }
425 currentUserId_ = activedIds[0];
426 POWER_HILOGI(COMP_UTILS, "currentUserId_ is %{public}d", currentUserId_);
427 }
428 } // namespace PowerMgr
429 } // namespace OHOS