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 30namespace OHOS { 31namespace PowerMgr { 32SettingProvider* SettingProvider::instance_; 33std::mutex SettingProvider::settingMutex_; 34sptr<IRemoteObject> SettingProvider::remoteObj_; 35const int32_t INITIAL_USER_ID = 100; 36int32_t SettingProvider::currentUserId_ = INITIAL_USER_ID; 37namespace { 38const std::string SETTING_COLUMN_KEYWORD = "KEYWORD"; 39const std::string SETTING_COLUMN_VALUE = "VALUE"; 40const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true"; 41const std::string SETTING_URI_PROXY_USER = "datashare:///com.ohos.settingsdata/entry/settingsdata/"; 42const std::string SETTING_URI_PROXY_USER_ADAPT = "USER_SETTINGSDATA_SECURE_##USERID##?Proxy=true"; 43constexpr const char *USERID_REPLACE = "##USERID##"; 44constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility"; 45} // namespace 46 47SettingProvider::~SettingProvider() 48{ 49 instance_ = nullptr; 50 remoteObj_ = nullptr; 51} 52 53SettingProvider& 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 65ErrCode SettingProvider::GetIntValue(const std::string& key, int32_t& value) 66{ 67 int64_t valueLong; 68 ErrCode ret = GetLongValue(key, valueLong); 69 if (ret != ERR_OK) { 70 return ret; 71 } 72 value = static_cast<int32_t>(valueLong); 73 return ERR_OK; 74} 75 76ErrCode SettingProvider::GetLongValue(const std::string& key, int64_t& value) 77{ 78 std::string valueStr; 79 ErrCode ret = GetStringValue(key, valueStr); 80 if (ret != ERR_OK) { 81 return ret; 82 } 83 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, 10)); 84 return ERR_OK; 85} 86 87ErrCode SettingProvider::GetBoolValue(const std::string& key, bool& value) 88{ 89 std::string valueStr; 90 ErrCode ret = GetStringValue(key, valueStr); 91 if (ret != ERR_OK) { 92 return ret; 93 } 94 value = (valueStr == "true"); 95 return ERR_OK; 96} 97 98ErrCode SettingProvider::PutIntValue(const std::string& key, int32_t value, bool needNotify) 99{ 100 return PutStringValue(key, std::to_string(value), needNotify); 101} 102 103ErrCode SettingProvider::PutLongValue(const std::string& key, int64_t value, bool needNotify) 104{ 105 return PutStringValue(key, std::to_string(value), needNotify); 106} 107 108ErrCode SettingProvider::PutBoolValue(const std::string& key, bool value, bool needNotify) 109{ 110 std::string valueStr = value ? "true" : "false"; 111 return PutStringValue(key, valueStr, needNotify); 112} 113 114bool SettingProvider::IsValidKey(const std::string& key) 115{ 116 std::string value; 117 ErrCode ret = GetStringValue(key, value); 118 if (!value.empty()) { 119 POWER_HILOGI(COMP_UTILS, "the getValue is:%{public}s", value.c_str()); 120 } 121 POWER_HILOGI(COMP_UTILS, "the getRet is:%{public}u", ret); 122 return (ret != ERR_NAME_NOT_FOUND) && (!value.empty()); 123} 124 125sptr<SettingObserver> SettingProvider::CreateObserver(const std::string& key, SettingObserver::UpdateFunc& func) 126{ 127 sptr<SettingObserver> observer = new SettingObserver(); 128 observer->SetKey(key); 129 observer->SetUpdateFunc(func); 130 return observer; 131} 132 133void SettingProvider::ExecRegisterCb(const sptr<SettingObserver>& observer) 134{ 135 if (observer == nullptr) { 136 POWER_HILOGE(COMP_UTILS, "observer is nullptr"); 137 return; 138 } 139 observer->OnChange(); 140} 141 142ErrCode SettingProvider::RegisterObserver(const sptr<SettingObserver>& observer) 143{ 144 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); 145 auto uri = AssembleUri(observer->GetKey()); 146 auto helper = CreateDataShareHelper(observer->GetKey()); 147 if (helper == nullptr) { 148 IPCSkeleton::SetCallingIdentity(callingIdentity); 149 return ERR_NO_INIT; 150 } 151 helper->RegisterObserver(uri, observer); 152 helper->NotifyChange(uri); 153 std::thread execCb([this, observer] { this->ExecRegisterCb(observer); }); 154 execCb.detach(); 155 ReleaseDataShareHelper(helper); 156 IPCSkeleton::SetCallingIdentity(callingIdentity); 157 POWER_HILOGD(COMP_UTILS, "succeed to register observer of uri=%{public}s", uri.ToString().c_str()); 158 return ERR_OK; 159} 160 161ErrCode SettingProvider::UnregisterObserver(const sptr<SettingObserver>& observer) 162{ 163 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); 164 auto uri = AssembleUri(observer->GetKey()); 165 auto helper = CreateDataShareHelper(observer->GetKey()); 166 if (helper == nullptr) { 167 IPCSkeleton::SetCallingIdentity(callingIdentity); 168 return ERR_NO_INIT; 169 } 170 helper->UnregisterObserver(uri, observer); 171 ReleaseDataShareHelper(helper); 172 IPCSkeleton::SetCallingIdentity(callingIdentity); 173 POWER_HILOGD(COMP_UTILS, "succeed to unregister observer of uri=%{public}s", uri.ToString().c_str()); 174 return ERR_OK; 175} 176 177void SettingProvider::Initialize(int32_t systemAbilityId) 178{ 179 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 180 if (sam == nullptr) { 181 POWER_HILOGE(COMP_UTILS, "GetSystemAbilityManager return nullptr"); 182 return; 183 } 184 auto remoteObj = sam->GetSystemAbility(systemAbilityId); 185 if (remoteObj == nullptr) { 186 POWER_HILOGE(COMP_UTILS, "GetSystemAbility return nullptr, systemAbilityId=%{public}d", systemAbilityId); 187 return; 188 } 189 remoteObj_ = remoteObj; 190} 191 192ErrCode SettingProvider::GetStringValue(const std::string& key, std::string& value) 193{ 194 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); 195 auto helper = CreateDataShareHelper(key); 196 if (helper == nullptr) { 197 IPCSkeleton::SetCallingIdentity(callingIdentity); 198 return ERR_NO_INIT; 199 } 200 std::vector<std::string> columns = {SETTING_COLUMN_VALUE}; 201 DataShare::DataSharePredicates predicates; 202 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key); 203 Uri uri(AssembleUri(key)); 204 auto resultSet = helper->Query(uri, predicates, columns); 205 ReleaseDataShareHelper(helper); 206 if (resultSet == nullptr) { 207 POWER_HILOGE(COMP_UTILS, "helper->Query return nullptr"); 208 IPCSkeleton::SetCallingIdentity(callingIdentity); 209 return ERR_INVALID_OPERATION; 210 } 211 int32_t count; 212 resultSet->GetRowCount(count); 213 if (count == 0) { 214 POWER_HILOGW(COMP_UTILS, "not found value, key=%{public}s, count=%{public}d", key.c_str(), count); 215 IPCSkeleton::SetCallingIdentity(callingIdentity); 216 resultSet->Close(); 217 return ERR_NAME_NOT_FOUND; 218 } 219 const int32_t INDEX = 0; 220 resultSet->GoToRow(INDEX); 221 int32_t ret = resultSet->GetString(INDEX, value); 222 if (ret != NativeRdb::E_OK) { 223 POWER_HILOGW(COMP_UTILS, "resultSet->GetString return not ok, ret=%{public}d", ret); 224 IPCSkeleton::SetCallingIdentity(callingIdentity); 225 resultSet->Close(); 226 return ERR_INVALID_VALUE; 227 } 228 resultSet->Close(); 229 IPCSkeleton::SetCallingIdentity(callingIdentity); 230 return ERR_OK; 231} 232 233ErrCode SettingProvider::PutStringValue(const std::string& key, const std::string& value, bool needNotify) 234{ 235 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); 236 auto helper = CreateDataShareHelper(key); 237 if (helper == nullptr) { 238 IPCSkeleton::SetCallingIdentity(callingIdentity); 239 return ERR_NO_INIT; 240 } 241 DataShare::DataShareValueObject keyObj(key); 242 DataShare::DataShareValueObject valueObj(value); 243 DataShare::DataShareValuesBucket bucket; 244 bucket.Put(SETTING_COLUMN_KEYWORD, keyObj); 245 bucket.Put(SETTING_COLUMN_VALUE, valueObj); 246 DataShare::DataSharePredicates predicates; 247 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key); 248 Uri uri(AssembleUri(key)); 249 if (helper->Update(uri, predicates, bucket) <= 0) { 250 POWER_HILOGD(COMP_UTILS, "no data exist, insert one row"); 251 helper->Insert(uri, bucket); 252 } 253 if (needNotify) { 254 helper->NotifyChange(AssembleUri(key)); 255 } 256 ReleaseDataShareHelper(helper); 257 IPCSkeleton::SetCallingIdentity(callingIdentity); 258 return ERR_OK; 259} 260 261std::shared_ptr<DataShare::DataShareHelper> SettingProvider::CreateDataShareHelper(const std::string& key) 262{ 263 std::lock_guard<std::mutex> lock(settingMutex_); 264 std::string uriProxyStr; 265 if (IsNeedMultiUser(key)) { 266 uriProxyStr = SETTING_URI_PROXY_USER + "USER_SETTINGSDATA_SECURE_" + 267 std::to_string(currentUserId_) + "?Proxy=true"; 268 POWER_HILOGI(COMP_UTILS, "the uriProxyStr is %{public}s", uriProxyStr.c_str()); 269 } else { 270 uriProxyStr = SETTING_URI_PROXY; 271 } 272 auto helper = DataShare::DataShareHelper::Creator(remoteObj_, uriProxyStr, SETTINGS_DATA_EXT_URI); 273 if (helper == nullptr) { 274 POWER_HILOGW(COMP_UTILS, "helper is nullptr, uri=%{public}s", uriProxyStr.c_str()); 275 return nullptr; 276 } 277 return helper; 278} 279 280bool SettingProvider::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper) 281{ 282 if (!helper->Release()) { 283 POWER_HILOGW(COMP_UTILS, "release helper fail"); 284 return false; 285 } 286 return true; 287} 288 289Uri SettingProvider::AssembleUri(const std::string& key) 290{ 291 std::lock_guard<std::mutex> lock(settingMutex_); 292 if (IsNeedMultiUser(key)) { 293 std::string userSetting = ReplaceUserIdForUri(currentUserId_); 294 std::string specialUri = SETTING_URI_PROXY_USER + userSetting + "&key=" + key; 295 POWER_HILOGI(COMP_UTILS, "the non-global uri is %{public}s", specialUri.c_str()); 296 Uri uri(specialUri); 297 return uri; 298 } 299 Uri uri(SETTING_URI_PROXY + "&key=" + key); 300 return uri; 301} 302 303bool SettingProvider::IsNeedMultiUser(const std::string& key) 304{ 305 std::vector<std::string> needMultiUserStrVec { 306 SETTING_POWER_WAKEUP_DOUBLE_KEY, 307 SETTING_POWER_WAKEUP_PICKUP_KEY, 308 SETTING_POWER_WAKEUP_SOURCES_KEY, 309#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING 310 SETTING_DISPLAY_AC_OFF_TIME_KEY, 311 SETTING_DISPLAY_DC_OFF_TIME_KEY, 312 SETTING_POWER_AC_SUSPEND_SOURCES_KEY, 313 SETTING_POWER_DC_SUSPEND_SOURCES_KEY, 314#endif 315 }; 316 317 if (std::count(needMultiUserStrVec.begin(), needMultiUserStrVec.end(), key)) { 318 return true; 319 } 320 return false; 321} 322 323std::string SettingProvider::ReplaceUserIdForUri(int32_t userId) 324{ 325 std::string tempUri = SETTING_URI_PROXY_USER_ADAPT; 326 std::regex pattern(USERID_REPLACE); 327 return std::regex_replace(tempUri, pattern, std::to_string(userId)); 328} 329 330void SettingProvider::UpdateCurrentUserId() 331{ 332 std::lock_guard<std::mutex> lock(settingMutex_); 333 std::vector<int> activedIds; 334 int ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activedIds); 335 if (ret != 0) { 336 POWER_HILOGE(COMP_UTILS, "QueryActivedOsAccountIds failed, ret is %{public}d", ret); 337 return; 338 } 339 if (activedIds.empty()) { 340 POWER_HILOGE(COMP_UTILS, "QueryActivedOsAccountIds is empty"); 341 return; 342 } 343 currentUserId_ = activedIds[0]; 344 POWER_HILOGI(COMP_UTILS, "currentUserId_ is %{public}d", currentUserId_); 345} 346} // namespace PowerMgr 347} // namespace OHOS