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