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