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