• 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 
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