• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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