/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "setting_datashare.h" #include #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" #include "ipc_skeleton.h" #include "iservice_registry.h" #include "mmi_log.h" #include "rdb_errno.h" #include "result_set.h" #include "uri.h" namespace OHOS { namespace MMI { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "setting_DataShare" }; SettingDataShare* SettingDataShare::instance_; std::mutex SettingDataShare::mutex_; sptr SettingDataShare::remoteObj_; namespace { const std::string SETTING_COLUMN_KEYWORD = "KEYWORD"; const std::string SETTING_COLUMN_VALUE = "VALUE"; const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true"; constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility"; constexpr int32_t LONG_CAST_NUM = 10; } // namespace SettingDataShare::~SettingDataShare() { if (instance_ != nullptr) { delete instance_; } instance_ = nullptr; remoteObj_ = nullptr; } SettingDataShare& SettingDataShare::GetInstance(int32_t systemAbilityId) { if (instance_ == nullptr) { std::lock_guard lock(mutex_); if (instance_ == nullptr) { instance_ = new SettingDataShare(); Initialize(systemAbilityId); } } return *instance_; } ErrCode SettingDataShare::GetIntValue(const std::string& key, int32_t& value) { int64_t valueLong; ErrCode ret = GetLongValue(key, valueLong); if (ret != ERR_OK) { MMI_HILOGE("Get int value fail"); return ret; } value = static_cast(valueLong); return ERR_OK; } ErrCode SettingDataShare::GetLongValue(const std::string& key, int64_t& value) { std::string valueStr; ErrCode ret = GetStringValue(key, valueStr); if (ret != ERR_OK) { MMI_HILOGE("Get long value fail"); return ret; } value = static_cast(strtoll(valueStr.c_str(), nullptr, LONG_CAST_NUM)); return ERR_OK; } ErrCode SettingDataShare::GetBoolValue(const std::string& key, bool& value) { std::string valueStr; ErrCode ret = GetStringValue(key, valueStr); if (ret != ERR_OK) { MMI_HILOGE("Get bool value fail"); return ret; } value = (valueStr == "true"); return ERR_OK; } ErrCode SettingDataShare::PutIntValue(const std::string& key, int32_t value, bool needNotify) { return PutStringValue(key, std::to_string(value), needNotify); } ErrCode SettingDataShare::PutLongValue(const std::string& key, int64_t value, bool needNotify) { return PutStringValue(key, std::to_string(value), needNotify); } ErrCode SettingDataShare::PutBoolValue(const std::string& key, bool value, bool needNotify) { std::string valueStr = value ? "true" : "false"; return PutStringValue(key, valueStr, needNotify); } bool SettingDataShare::IsValidKey(const std::string& key) { std::string value; ErrCode ret = GetStringValue(key, value); return (ret != ERR_NAME_NOT_FOUND) && (!value.empty()); } sptr SettingDataShare::CreateObserver(const std::string& key, SettingObserver::UpdateFunc& func) { sptr observer = new SettingObserver(); observer->SetKey(key); observer->SetUpdateFunc(func); return observer; } void SettingDataShare::ExecRegisterCb(const sptr& observer) { if (observer == nullptr) { MMI_HILOGE("observer is null"); return; } observer->OnChange(); } ErrCode SettingDataShare::RegisterObserver(const sptr& observer) { if (observer == nullptr) { MMI_HILOGE("observer is null"); return RET_ERR; } std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); auto uri = AssembleUri(observer->GetKey()); auto helper = CreateDataShareHelper(); if (helper == nullptr) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_NO_INIT; } helper->RegisterObserver(uri, observer); helper->NotifyChange(uri); std::thread execCb(SettingDataShare::ExecRegisterCb, observer); execCb.detach(); ReleaseDataShareHelper(helper); IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_OK; } ErrCode SettingDataShare::UnregisterObserver(const sptr& observer) { if (observer == nullptr) { MMI_HILOGE("observer is null"); return RET_ERR; } std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); auto uri = AssembleUri(observer->GetKey()); auto helper = CreateDataShareHelper(); if (helper == nullptr) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_NO_INIT; } helper->UnregisterObserver(uri, observer); ReleaseDataShareHelper(helper); IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_OK; } void SettingDataShare::Initialize(int32_t systemAbilityId) { auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sam == nullptr) { return; } auto remoteObj = sam->GetSystemAbility(systemAbilityId); if (remoteObj == nullptr) { return; } remoteObj_ = remoteObj; } ErrCode SettingDataShare::GetStringValue(const std::string& key, std::string& value) { std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); auto helper = CreateDataShareHelper(); if (helper == nullptr) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_NO_INIT; } std::vector columns = {SETTING_COLUMN_VALUE}; DataShare::DataSharePredicates predicates; predicates.EqualTo(SETTING_COLUMN_KEYWORD, key); Uri uri(AssembleUri(key)); auto resultSet = helper->Query(uri, predicates, columns); ReleaseDataShareHelper(helper); if (resultSet == nullptr) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_INVALID_OPERATION; } int32_t count; resultSet->GetRowCount(count); if (count == 0) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_NAME_NOT_FOUND; } const int32_t INDEX = 0; resultSet->GoToRow(INDEX); int32_t ret = resultSet->GetString(INDEX, value); if (ret != NativeRdb::E_OK) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_INVALID_VALUE; } resultSet->Close(); IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_OK; } ErrCode SettingDataShare::PutStringValue(const std::string& key, const std::string& value, bool needNotify) { std::string callingIdentity = IPCSkeleton::ResetCallingIdentity(); auto helper = CreateDataShareHelper(); if (helper == nullptr) { IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_NO_INIT; } DataShare::DataShareValueObject keyObj(key); DataShare::DataShareValueObject valueObj(value); DataShare::DataShareValuesBucket bucket; bucket.Put(SETTING_COLUMN_KEYWORD, keyObj); bucket.Put(SETTING_COLUMN_VALUE, valueObj); DataShare::DataSharePredicates predicates; predicates.EqualTo(SETTING_COLUMN_KEYWORD, key); Uri uri(AssembleUri(key)); if (helper->Update(uri, predicates, bucket) <= 0) { helper->Insert(uri, bucket); } if (needNotify) { helper->NotifyChange(AssembleUri(key)); } ReleaseDataShareHelper(helper); IPCSkeleton::SetCallingIdentity(callingIdentity); return ERR_OK; } std::shared_ptr SettingDataShare::CreateDataShareHelper() { auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI); if (helper == nullptr) { return nullptr; } return helper; } bool SettingDataShare::ReleaseDataShareHelper(std::shared_ptr& helper) { if (!helper->Release()) { return false; } return true; } Uri SettingDataShare::AssembleUri(const std::string& key) { Uri uri(SETTING_URI_PROXY + "&key=" + key); return uri; } } } // namespace OHOS