1fc223305Sopenharmony_ci/* 2fc223305Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3fc223305Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fc223305Sopenharmony_ci * you may not use this file except in compliance with the License. 5fc223305Sopenharmony_ci * You may obtain a copy of the License at 6fc223305Sopenharmony_ci * 7fc223305Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fc223305Sopenharmony_ci * 9fc223305Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fc223305Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fc223305Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fc223305Sopenharmony_ci * See the License for the specific language governing permissions and 13fc223305Sopenharmony_ci * limitations under the License. 14fc223305Sopenharmony_ci */ 15fc223305Sopenharmony_ci 16fc223305Sopenharmony_ci#include "oh_preferences.h" 17fc223305Sopenharmony_ci 18fc223305Sopenharmony_ci#include "application_context.h" 19fc223305Sopenharmony_ci#include "convertor_error_code.h" 20fc223305Sopenharmony_ci#include "log_print.h" 21fc223305Sopenharmony_ci#include "oh_preferences_err_code.h" 22fc223305Sopenharmony_ci#include "oh_preferences_impl.h" 23fc223305Sopenharmony_ci#include "oh_preferences_value_impl.h" 24fc223305Sopenharmony_ci#include "oh_preferences_value.h" 25fc223305Sopenharmony_ci#include "preferences_file_operation.h" 26fc223305Sopenharmony_ci#include "preferences_helper.h" 27fc223305Sopenharmony_ci#include "securec.h" 28fc223305Sopenharmony_ci 29fc223305Sopenharmony_ciusing namespace OHOS::PreferencesNdk; 30fc223305Sopenharmony_ciusing namespace OHOS::AbilityRuntime; 31fc223305Sopenharmony_ci 32fc223305Sopenharmony_ciOH_PreferencesImpl::OH_PreferencesImpl 33fc223305Sopenharmony_ci (std::shared_ptr<OHOS::NativePreferences::Preferences> preferences) : preferences_(preferences) 34fc223305Sopenharmony_ci{ 35fc223305Sopenharmony_ci} 36fc223305Sopenharmony_ci 37fc223305Sopenharmony_cibool NDKPreferencesUtils::PreferencesStructValidCheck(int64_t originCid, int64_t targetCid) 38fc223305Sopenharmony_ci{ 39fc223305Sopenharmony_ci if (originCid != targetCid) { 40fc223305Sopenharmony_ci LOG_ERROR("cid check failed, ori cid: %{public}ld, target cid: %{public}ld", static_cast<long>(originCid), 41fc223305Sopenharmony_ci static_cast<long>(targetCid)); 42fc223305Sopenharmony_ci return false; 43fc223305Sopenharmony_ci } 44fc223305Sopenharmony_ci return true; 45fc223305Sopenharmony_ci} 46fc223305Sopenharmony_ci 47fc223305Sopenharmony_cistd::pair<int, std::string> GetPreferencesDir(OH_PreferencesOption *options) 48fc223305Sopenharmony_ci{ 49fc223305Sopenharmony_ci auto context = OHOS::AbilityRuntime::Context::GetApplicationContext(); 50fc223305Sopenharmony_ci if (context == nullptr) { 51fc223305Sopenharmony_ci LOG_ERROR("get application context go wrong"); 52fc223305Sopenharmony_ci return { OH_Preferences_ErrCode::PREFERENCES_ERROR_STORAGE, "" }; 53fc223305Sopenharmony_ci } 54fc223305Sopenharmony_ci if (options->GetDataGroupId().empty()) { 55fc223305Sopenharmony_ci return { OH_Preferences_ErrCode::PREFERENCES_OK, context->GetPreferencesDir() }; 56fc223305Sopenharmony_ci } 57fc223305Sopenharmony_ci std::string stagePreferencesDir; 58fc223305Sopenharmony_ci int err = context->GetSystemPreferencesDir(options->GetDataGroupId(), false, stagePreferencesDir); 59fc223305Sopenharmony_ci if (err != 0) { 60fc223305Sopenharmony_ci LOG_ERROR("get system preferences dir failed, err: %{public}d", err); 61fc223305Sopenharmony_ci return { OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM, stagePreferencesDir }; 62fc223305Sopenharmony_ci } 63fc223305Sopenharmony_ci return { OH_Preferences_ErrCode::PREFERENCES_OK, stagePreferencesDir }; 64fc223305Sopenharmony_ci} 65fc223305Sopenharmony_ci 66fc223305Sopenharmony_ciOH_Preferences *OH_Preferences_Open(OH_PreferencesOption *option, int *errCode) 67fc223305Sopenharmony_ci{ 68fc223305Sopenharmony_ci int err = OH_Preferences_ErrCode::PREFERENCES_OK; 69fc223305Sopenharmony_ci if (option == nullptr || option->fileName.empty() || 70fc223305Sopenharmony_ci !NDKPreferencesUtils::PreferencesStructValidCheck( 71fc223305Sopenharmony_ci option->cid, PreferencesNdkStructId::PREFERENCES_OH_OPTION_CID) || 72fc223305Sopenharmony_ci errCode == nullptr) { 73fc223305Sopenharmony_ci LOG_ERROR("open preference cfg error, option is null: %{public}d, fileName is null: %{public}d, " 74fc223305Sopenharmony_ci "errCode is null: %{public}d, err:%{public}d", 75fc223305Sopenharmony_ci (option == nullptr), (option == nullptr) ? 1 : option->fileName.empty(), (errCode == nullptr), 76fc223305Sopenharmony_ci OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 77fc223305Sopenharmony_ci if (errCode != nullptr) { 78fc223305Sopenharmony_ci *errCode = OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 79fc223305Sopenharmony_ci } 80fc223305Sopenharmony_ci return nullptr; 81fc223305Sopenharmony_ci } 82fc223305Sopenharmony_ci 83fc223305Sopenharmony_ci auto dirRes = GetPreferencesDir(option); 84fc223305Sopenharmony_ci if (dirRes.first != OH_Preferences_ErrCode::PREFERENCES_OK) { 85fc223305Sopenharmony_ci *errCode = dirRes.first; 86fc223305Sopenharmony_ci return nullptr; 87fc223305Sopenharmony_ci } 88fc223305Sopenharmony_ci std::string filePath = dirRes.second + "/" + option->GetFileName(); 89fc223305Sopenharmony_ci 90fc223305Sopenharmony_ci OHOS::NativePreferences::Options nativeOptions(filePath, option->GetBundleName(), 91fc223305Sopenharmony_ci option->GetDataGroupId(), true); 92fc223305Sopenharmony_ci 93fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= 94fc223305Sopenharmony_ci OHOS::NativePreferences::PreferencesHelper::GetPreferences(nativeOptions, err); 95fc223305Sopenharmony_ci err = ConvertorErrorCode::NativeErrToNdk(err); 96fc223305Sopenharmony_ci *errCode = err; 97fc223305Sopenharmony_ci if (innerPreferences== nullptr || err != OH_Preferences_ErrCode::PREFERENCES_OK) { 98fc223305Sopenharmony_ci LOG_ERROR("Get native Preferences failed: %{public}s, errcode: %{public}d", 99fc223305Sopenharmony_ci OHOS::NativePreferences::ExtractFileName(nativeOptions.filePath).c_str(), err); 100fc223305Sopenharmony_ci return nullptr; 101fc223305Sopenharmony_ci } 102fc223305Sopenharmony_ci OH_PreferencesImpl *preferenceImpl = new (std::nothrow) OH_PreferencesImpl(innerPreferences); 103fc223305Sopenharmony_ci if (preferenceImpl == nullptr) { 104fc223305Sopenharmony_ci LOG_ERROR("new impl object failed"); 105fc223305Sopenharmony_ci *errCode = OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC; 106fc223305Sopenharmony_ci return nullptr; 107fc223305Sopenharmony_ci } 108fc223305Sopenharmony_ci preferenceImpl->SetPreferencesStoreFilePath(filePath); 109fc223305Sopenharmony_ci preferenceImpl->cid = PreferencesNdkStructId::PREFERENCES_OH_PREFERENCES_CID; 110fc223305Sopenharmony_ci return static_cast<OH_Preferences *>(preferenceImpl); 111fc223305Sopenharmony_ci} 112fc223305Sopenharmony_ci 113fc223305Sopenharmony_cistatic OH_PreferencesImpl *GetPreferencesImpl(OH_Preferences *preference) 114fc223305Sopenharmony_ci{ 115fc223305Sopenharmony_ci if (preference == nullptr || 116fc223305Sopenharmony_ci !NDKPreferencesUtils::PreferencesStructValidCheck( 117fc223305Sopenharmony_ci preference->cid, PreferencesNdkStructId::PREFERENCES_OH_PREFERENCES_CID)) { 118fc223305Sopenharmony_ci LOG_ERROR("preference invalid, is null: %{public}d", preference == nullptr); 119fc223305Sopenharmony_ci return nullptr; 120fc223305Sopenharmony_ci } 121fc223305Sopenharmony_ci return static_cast<OH_PreferencesImpl *>(preference); 122fc223305Sopenharmony_ci} 123fc223305Sopenharmony_ci 124fc223305Sopenharmony_cistatic std::shared_ptr<OHOS::NativePreferences::Preferences> GetNativePreferencesFromOH(OH_Preferences *preference) 125fc223305Sopenharmony_ci{ 126fc223305Sopenharmony_ci auto preferencesImpl = GetPreferencesImpl(preference); 127fc223305Sopenharmony_ci if (preferencesImpl == nullptr || 128fc223305Sopenharmony_ci !NDKPreferencesUtils::PreferencesStructValidCheck( 129fc223305Sopenharmony_ci preference->cid, PreferencesNdkStructId::PREFERENCES_OH_PREFERENCES_CID)) { 130fc223305Sopenharmony_ci LOG_ERROR("preferences is null: %{public}d when get native preferences from ohPreferences", 131fc223305Sopenharmony_ci (preferencesImpl == nullptr)); 132fc223305Sopenharmony_ci return nullptr; 133fc223305Sopenharmony_ci } 134fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= preferencesImpl->GetNativePreferences(); 135fc223305Sopenharmony_ci if (innerPreferences== nullptr) { 136fc223305Sopenharmony_ci LOG_ERROR("preference not open yet"); 137fc223305Sopenharmony_ci return nullptr; 138fc223305Sopenharmony_ci } 139fc223305Sopenharmony_ci return innerPreferences; 140fc223305Sopenharmony_ci} 141fc223305Sopenharmony_ci 142fc223305Sopenharmony_civoid OH_PreferencesImpl::SetPreferencesStoreFilePath(const std::string &filePath) 143fc223305Sopenharmony_ci{ 144fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(mutex_); 145fc223305Sopenharmony_ci filePath_ = filePath; 146fc223305Sopenharmony_ci} 147fc223305Sopenharmony_ci 148fc223305Sopenharmony_cistd::string OH_PreferencesImpl::GetPreferencesStoreFilePath() 149fc223305Sopenharmony_ci{ 150fc223305Sopenharmony_ci std::shared_lock<std::shared_mutex> readLock(mutex_); 151fc223305Sopenharmony_ci return filePath_; 152fc223305Sopenharmony_ci} 153fc223305Sopenharmony_ci 154fc223305Sopenharmony_ciint OH_Preferences_Close(OH_Preferences *preference) 155fc223305Sopenharmony_ci{ 156fc223305Sopenharmony_ci auto preferencesImpl = GetPreferencesImpl(preference); 157fc223305Sopenharmony_ci if (preferencesImpl == nullptr) { 158fc223305Sopenharmony_ci LOG_ERROR("preferences close failed, preferences is null"); 159fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 160fc223305Sopenharmony_ci } 161fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= preferencesImpl->GetNativePreferences(); 162fc223305Sopenharmony_ci if (innerPreferences== nullptr) { 163fc223305Sopenharmony_ci LOG_ERROR("preference not open yet"); 164fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 165fc223305Sopenharmony_ci } 166fc223305Sopenharmony_ci 167fc223305Sopenharmony_ci innerPreferences->FlushSync(); 168fc223305Sopenharmony_ci 169fc223305Sopenharmony_ci int errCode = OHOS::NativePreferences::PreferencesHelper::RemovePreferencesFromCache( 170fc223305Sopenharmony_ci preferencesImpl->GetPreferencesStoreFilePath()); 171fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 172fc223305Sopenharmony_ci LOG_ERROR("preference close failed: %{public}d", errCode); 173fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 174fc223305Sopenharmony_ci } 175fc223305Sopenharmony_ci delete preferencesImpl; 176fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_OK; 177fc223305Sopenharmony_ci} 178fc223305Sopenharmony_ci 179fc223305Sopenharmony_ciint OH_Preferences_GetInt(OH_Preferences *preference, const char *key, int *value) 180fc223305Sopenharmony_ci{ 181fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 182fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr || value == nullptr) { 183fc223305Sopenharmony_ci LOG_ERROR("get int failed, preference not open yet: %{public}d, key is null: %{public}d, " 184fc223305Sopenharmony_ci "value is null: %{public}d, err: %{public}d", (innerPreferences== nullptr), (key == nullptr), 185fc223305Sopenharmony_ci (value == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 186fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 187fc223305Sopenharmony_ci } 188fc223305Sopenharmony_ci 189fc223305Sopenharmony_ci auto res = innerPreferences->GetValue(key, OHOS::NativePreferences::PreferencesValue()); 190fc223305Sopenharmony_ci if (res.first != OHOS::NativePreferences::E_OK) { 191fc223305Sopenharmony_ci LOG_ERROR("Get Int failed, %{public}d", res.first); 192fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 193fc223305Sopenharmony_ci } 194fc223305Sopenharmony_ci 195fc223305Sopenharmony_ci if (res.second.IsInt()) { 196fc223305Sopenharmony_ci *value = (int)(res.second); 197fc223305Sopenharmony_ci } else { 198fc223305Sopenharmony_ci LOG_ERROR("Get Int failed, value's type is not int"); 199fc223305Sopenharmony_ci if (res.first == OHOS::NativePreferences::E_OK) { 200fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND; 201fc223305Sopenharmony_ci } 202fc223305Sopenharmony_ci } 203fc223305Sopenharmony_ci 204fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 205fc223305Sopenharmony_ci} 206fc223305Sopenharmony_ci 207fc223305Sopenharmony_ciint OH_Preferences_GetString(OH_Preferences *preference, const char *key, char **value, 208fc223305Sopenharmony_ci uint32_t *valueLen) 209fc223305Sopenharmony_ci{ 210fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 211fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr || value == nullptr || valueLen == nullptr) { 212fc223305Sopenharmony_ci LOG_ERROR("get str failed, preference not open yet: %{public}d, key is null: %{public}d, " 213fc223305Sopenharmony_ci "value is null: %{public}d, valueLen is null: %{public}d, err: %{public}d", 214fc223305Sopenharmony_ci (innerPreferences== nullptr), (key == nullptr), (value == nullptr), (valueLen == nullptr), 215fc223305Sopenharmony_ci OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 216fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 217fc223305Sopenharmony_ci } 218fc223305Sopenharmony_ci 219fc223305Sopenharmony_ci auto res = innerPreferences->GetValue(key, OHOS::NativePreferences::PreferencesValue()); 220fc223305Sopenharmony_ci if (res.first != OHOS::NativePreferences::E_OK) { 221fc223305Sopenharmony_ci LOG_ERROR("Get string failed, %{public}d", res.first); 222fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 223fc223305Sopenharmony_ci } 224fc223305Sopenharmony_ci 225fc223305Sopenharmony_ci if (res.second.IsString()) { 226fc223305Sopenharmony_ci std::string str = (std::string)(res.second); 227fc223305Sopenharmony_ci size_t strLen = str.size(); 228fc223305Sopenharmony_ci if (strLen >= SIZE_MAX) { 229fc223305Sopenharmony_ci LOG_ERROR(" string length overlimit: %{public}zu", strLen); 230fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 231fc223305Sopenharmony_ci } 232fc223305Sopenharmony_ci void *ptr = malloc(strLen + 1); // free by caller 233fc223305Sopenharmony_ci if (ptr == nullptr) { 234fc223305Sopenharmony_ci LOG_ERROR("malloc failed when get string, errno: %{public}d", errno); 235fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC; 236fc223305Sopenharmony_ci } 237fc223305Sopenharmony_ci *value = (char *)ptr; 238fc223305Sopenharmony_ci int sysErr = memset_s(*value, (strLen + 1), 0, (strLen + 1)); 239fc223305Sopenharmony_ci if (sysErr != EOK) { 240fc223305Sopenharmony_ci LOG_ERROR("memset failed when get string, errCode: %{public}d", sysErr); 241fc223305Sopenharmony_ci } 242fc223305Sopenharmony_ci if (strLen > 0) { 243fc223305Sopenharmony_ci sysErr = memcpy_s(*value, strLen, str.c_str(), strLen); 244fc223305Sopenharmony_ci if (sysErr != EOK) { 245fc223305Sopenharmony_ci LOG_ERROR("memcpy failed when get string, errCode: %{public}d", sysErr); 246fc223305Sopenharmony_ci free(ptr); 247fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC; 248fc223305Sopenharmony_ci } 249fc223305Sopenharmony_ci } 250fc223305Sopenharmony_ci *valueLen = strLen + 1; 251fc223305Sopenharmony_ci } else { 252fc223305Sopenharmony_ci LOG_ERROR("Get string failed, value's type is not string, err: %{public}d", res.first); 253fc223305Sopenharmony_ci if (res.first == OHOS::NativePreferences::E_OK) { 254fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND; 255fc223305Sopenharmony_ci } 256fc223305Sopenharmony_ci } 257fc223305Sopenharmony_ci 258fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 259fc223305Sopenharmony_ci} 260fc223305Sopenharmony_ci 261fc223305Sopenharmony_civoid OH_Preferences_FreeString(char *string) 262fc223305Sopenharmony_ci{ 263fc223305Sopenharmony_ci if (string == nullptr) { 264fc223305Sopenharmony_ci LOG_ERROR("free string failed, string is null"); 265fc223305Sopenharmony_ci return; 266fc223305Sopenharmony_ci } 267fc223305Sopenharmony_ci free(string); 268fc223305Sopenharmony_ci} 269fc223305Sopenharmony_ci 270fc223305Sopenharmony_ciint OH_Preferences_GetBool(OH_Preferences *preference, const char *key, bool *value) 271fc223305Sopenharmony_ci{ 272fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 273fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr || value == nullptr) { 274fc223305Sopenharmony_ci LOG_ERROR("get bool failed, preference not open yet: %{public}d, key is null: %{public}d, " 275fc223305Sopenharmony_ci "value is null: %{public}d, err: %{public}d", (innerPreferences== nullptr), (key == nullptr), 276fc223305Sopenharmony_ci (value == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 277fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 278fc223305Sopenharmony_ci } 279fc223305Sopenharmony_ci 280fc223305Sopenharmony_ci auto res = innerPreferences->GetValue(key, OHOS::NativePreferences::PreferencesValue()); 281fc223305Sopenharmony_ci if (res.first != OHOS::NativePreferences::E_OK) { 282fc223305Sopenharmony_ci LOG_ERROR("Get bool failed, %{public}d", res.first); 283fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 284fc223305Sopenharmony_ci } 285fc223305Sopenharmony_ci 286fc223305Sopenharmony_ci if (res.second.IsBool()) { 287fc223305Sopenharmony_ci *value = (bool)(res.second); 288fc223305Sopenharmony_ci } else { 289fc223305Sopenharmony_ci LOG_ERROR("Get bool failed, value's type is not bool, err: %{public}d", res.first); 290fc223305Sopenharmony_ci if (res.first == OHOS::NativePreferences::E_OK) { 291fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND; 292fc223305Sopenharmony_ci } 293fc223305Sopenharmony_ci } 294fc223305Sopenharmony_ci 295fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(res.first); 296fc223305Sopenharmony_ci} 297fc223305Sopenharmony_ci 298fc223305Sopenharmony_ciint OH_Preferences_SetInt(OH_Preferences *preference, const char *key, int value) 299fc223305Sopenharmony_ci{ 300fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 301fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr) { 302fc223305Sopenharmony_ci LOG_ERROR("set int failed, preference not open yet: %{public}d, key is null: %{public}d, err: %{public}d", 303fc223305Sopenharmony_ci (innerPreferences== nullptr), (key == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 304fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 305fc223305Sopenharmony_ci } 306fc223305Sopenharmony_ci 307fc223305Sopenharmony_ci int errCode = innerPreferences->PutInt(key, value); 308fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 309fc223305Sopenharmony_ci LOG_ERROR("preference put int failed, err: %{public}d", errCode); 310fc223305Sopenharmony_ci } 311fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 312fc223305Sopenharmony_ci} 313fc223305Sopenharmony_ci 314fc223305Sopenharmony_ciint OH_Preferences_SetBool(OH_Preferences *preference, const char *key, bool value) 315fc223305Sopenharmony_ci{ 316fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 317fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr) { 318fc223305Sopenharmony_ci LOG_ERROR("set bool failed, preference not open yet: %{public}d, key is null: %{public}d, err: %{public}d", 319fc223305Sopenharmony_ci (innerPreferences== nullptr), (key == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 320fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 321fc223305Sopenharmony_ci } 322fc223305Sopenharmony_ci 323fc223305Sopenharmony_ci int errCode = innerPreferences->PutBool(key, value); 324fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 325fc223305Sopenharmony_ci LOG_ERROR("preference put bool failed, err: %{public}d", errCode); 326fc223305Sopenharmony_ci } 327fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 328fc223305Sopenharmony_ci} 329fc223305Sopenharmony_ci 330fc223305Sopenharmony_ciint OH_Preferences_SetString(OH_Preferences *preference, const char *key, const char *value) 331fc223305Sopenharmony_ci{ 332fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 333fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr || value == nullptr) { 334fc223305Sopenharmony_ci LOG_ERROR("set str failed, preference not open yet: %{public}d, key is null: %{public}d, " 335fc223305Sopenharmony_ci "value is null: %{public}d, err: %{public}d", (innerPreferences== nullptr), (key == nullptr), 336fc223305Sopenharmony_ci (value == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 337fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 338fc223305Sopenharmony_ci } 339fc223305Sopenharmony_ci 340fc223305Sopenharmony_ci int errCode = innerPreferences->PutString(key, value); 341fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 342fc223305Sopenharmony_ci LOG_ERROR("preference put string failed, err: %{public}d", errCode); 343fc223305Sopenharmony_ci } 344fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 345fc223305Sopenharmony_ci} 346fc223305Sopenharmony_ci 347fc223305Sopenharmony_ciint OH_Preferences_Delete(OH_Preferences *preference, const char *key) 348fc223305Sopenharmony_ci{ 349fc223305Sopenharmony_ci std::shared_ptr<OHOS::NativePreferences::Preferences> innerPreferences= GetNativePreferencesFromOH(preference); 350fc223305Sopenharmony_ci if (innerPreferences== nullptr || key == nullptr) { 351fc223305Sopenharmony_ci LOG_ERROR("delete failed, preference not open yet: %{public}d, key is null: %{public}d, err: %{public}d", 352fc223305Sopenharmony_ci (innerPreferences== nullptr), (key == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 353fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 354fc223305Sopenharmony_ci } 355fc223305Sopenharmony_ci 356fc223305Sopenharmony_ci int errCode = innerPreferences->Delete(key); 357fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 358fc223305Sopenharmony_ci LOG_ERROR("preference delete value failed, err: %{public}d", errCode); 359fc223305Sopenharmony_ci } 360fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 361fc223305Sopenharmony_ci} 362fc223305Sopenharmony_ci 363fc223305Sopenharmony_ciint OH_Preferences_RegisterDataObserver(OH_Preferences *preference, void *context, 364fc223305Sopenharmony_ci OH_PreferencesDataObserver observer, const char *keys[], uint32_t keyCount) 365fc223305Sopenharmony_ci{ 366fc223305Sopenharmony_ci auto preferencesImpl = GetPreferencesImpl(preference); 367fc223305Sopenharmony_ci if (preferencesImpl == nullptr || observer == nullptr || keys == nullptr) { 368fc223305Sopenharmony_ci LOG_ERROR("register failed, sp is null ? %{public}d, obs is null ? %{public}d, " 369fc223305Sopenharmony_ci "keys is null: %{public}d, err: %{public}d", (preferencesImpl == nullptr), (observer == nullptr), 370fc223305Sopenharmony_ci (keys == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 371fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 372fc223305Sopenharmony_ci } 373fc223305Sopenharmony_ci 374fc223305Sopenharmony_ci std::vector<std::string> keysVec; 375fc223305Sopenharmony_ci for (uint32_t i = 0; i < keyCount; i++) { 376fc223305Sopenharmony_ci keysVec.push_back(keys[i]); 377fc223305Sopenharmony_ci } 378fc223305Sopenharmony_ci 379fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(preferencesImpl->RegisterDataObserver(observer, context, keysVec)); 380fc223305Sopenharmony_ci} 381fc223305Sopenharmony_ci 382fc223305Sopenharmony_ciint OH_Preferences_UnregisterDataObserver(OH_Preferences *preference, void *context, 383fc223305Sopenharmony_ci OH_PreferencesDataObserver observer, const char *keys[], uint32_t keyCount) 384fc223305Sopenharmony_ci{ 385fc223305Sopenharmony_ci auto preferencesImpl = GetPreferencesImpl(preference); 386fc223305Sopenharmony_ci if (preferencesImpl == nullptr || observer == nullptr || keys == nullptr) { 387fc223305Sopenharmony_ci LOG_ERROR("unregister failed, sp is null ? %{public}d, obs is null ? %{public}d, " 388fc223305Sopenharmony_ci "keys is null: %{public}d, err: %{public}d", (preferencesImpl == nullptr), (observer == nullptr), 389fc223305Sopenharmony_ci (keys == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM); 390fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM; 391fc223305Sopenharmony_ci } 392fc223305Sopenharmony_ci std::vector<std::string> keysVec; 393fc223305Sopenharmony_ci for (uint32_t i = 0; i < keyCount; i++) { 394fc223305Sopenharmony_ci keysVec.push_back(keys[i]); 395fc223305Sopenharmony_ci } 396fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(preferencesImpl->UnregisterDataObserver(observer, context, keysVec)); 397fc223305Sopenharmony_ci} 398fc223305Sopenharmony_ci 399fc223305Sopenharmony_ciint OH_PreferencesImpl::RegisterDataObserver( 400fc223305Sopenharmony_ci OH_PreferencesDataObserver observer, void *context, const std::vector<std::string> &keys) 401fc223305Sopenharmony_ci{ 402fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(obsMutex_); 403fc223305Sopenharmony_ci 404fc223305Sopenharmony_ci auto ndkObserver = std::make_shared<NDKPreferencesObserver>(observer, context); 405fc223305Sopenharmony_ci int errCode = preferences_->RegisterDataObserver(ndkObserver, keys); 406fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 407fc223305Sopenharmony_ci LOG_ERROR("register failed, err: %{public}d", errCode); 408fc223305Sopenharmony_ci } else { 409fc223305Sopenharmony_ci dataObservers_.emplace_back(std::make_pair(std::move(ndkObserver), context)); 410fc223305Sopenharmony_ci } 411fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 412fc223305Sopenharmony_ci} 413fc223305Sopenharmony_ci 414fc223305Sopenharmony_ciNDKPreferencesObserver::NDKPreferencesObserver(OH_PreferencesDataObserver observer, void *context) 415fc223305Sopenharmony_ci : dataObserver_(observer), context_(context) {} 416fc223305Sopenharmony_ci 417fc223305Sopenharmony_ciinline void FreePairValue(OH_PreferencesPair *pairs, size_t count) 418fc223305Sopenharmony_ci{ 419fc223305Sopenharmony_ci for (size_t i = 0; i < count; i++) { 420fc223305Sopenharmony_ci delete pairs[i].value; 421fc223305Sopenharmony_ci } 422fc223305Sopenharmony_ci} 423fc223305Sopenharmony_ci 424fc223305Sopenharmony_civoid NDKPreferencesObserver::OnChange(const std::map<std::string, OHOS::NativePreferences::PreferencesValue> &records) 425fc223305Sopenharmony_ci{ 426fc223305Sopenharmony_ci if (dataObserver_ == nullptr) { 427fc223305Sopenharmony_ci LOG_ERROR("failed to trigger change, data observer is null"); 428fc223305Sopenharmony_ci return; 429fc223305Sopenharmony_ci } 430fc223305Sopenharmony_ci auto count = records.size(); 431fc223305Sopenharmony_ci if (count == 0) { 432fc223305Sopenharmony_ci return; 433fc223305Sopenharmony_ci } 434fc223305Sopenharmony_ci OH_PreferencesPair *pairs = new (std::nothrow) OH_PreferencesPair[count]; 435fc223305Sopenharmony_ci if (pairs == nullptr) { 436fc223305Sopenharmony_ci LOG_ERROR("malloc pairs failed when on change, count: %{public}d, errno:%{public}d", static_cast<int>(count), 437fc223305Sopenharmony_ci errno); 438fc223305Sopenharmony_ci return; 439fc223305Sopenharmony_ci } 440fc223305Sopenharmony_ci int i = 0; 441fc223305Sopenharmony_ci for (const auto &[key, value] : records) { 442fc223305Sopenharmony_ci OH_PreferencesValueImpl *valueImpl = new (std::nothrow) OH_PreferencesValueImpl(); 443fc223305Sopenharmony_ci if (valueImpl == nullptr) { 444fc223305Sopenharmony_ci LOG_ERROR("new value object failed"); 445fc223305Sopenharmony_ci FreePairValue(pairs, i); 446fc223305Sopenharmony_ci delete []pairs; 447fc223305Sopenharmony_ci } 448fc223305Sopenharmony_ci valueImpl->cid = PreferencesNdkStructId::PREFERENCES_OH_VALUE_CID; 449fc223305Sopenharmony_ci valueImpl->value_ = value; 450fc223305Sopenharmony_ci pairs[i++] = OH_PreferencesPair { PreferencesNdkStructId::PREFERENCES_OH_PAIR_CID, key.c_str(), 451fc223305Sopenharmony_ci static_cast<OH_PreferencesValue *>(valueImpl), count}; 452fc223305Sopenharmony_ci } 453fc223305Sopenharmony_ci (dataObserver_)(context_, pairs, count); 454fc223305Sopenharmony_ci FreePairValue(pairs, count); 455fc223305Sopenharmony_ci delete []pairs; 456fc223305Sopenharmony_ci} 457fc223305Sopenharmony_ci 458fc223305Sopenharmony_civoid NDKPreferencesObserver::OnChange(const std::string &key) 459fc223305Sopenharmony_ci{ 460fc223305Sopenharmony_ci} 461fc223305Sopenharmony_ci 462fc223305Sopenharmony_ciint OH_PreferencesImpl::UnregisterDataObserver(OH_PreferencesDataObserver observer, void *context, 463fc223305Sopenharmony_ci const std::vector<std::string> &keys) 464fc223305Sopenharmony_ci{ 465fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(obsMutex_); 466fc223305Sopenharmony_ci for (size_t i = 0; i < dataObservers_.size(); i++) { 467fc223305Sopenharmony_ci if (!dataObservers_[i].first->ObserverCompare(observer) || dataObservers_[i].second != context) { 468fc223305Sopenharmony_ci continue; 469fc223305Sopenharmony_ci } 470fc223305Sopenharmony_ci 471fc223305Sopenharmony_ci int errCode = preferences_->UnRegisterDataObserver(dataObservers_[i].first, keys); 472fc223305Sopenharmony_ci if (errCode != OHOS::NativePreferences::E_OK) { 473fc223305Sopenharmony_ci LOG_ERROR("un register observer failed, err: %{public}d", errCode); 474fc223305Sopenharmony_ci return ConvertorErrorCode::NativeErrToNdk(errCode); 475fc223305Sopenharmony_ci } 476fc223305Sopenharmony_ci if (keys.empty()) { 477fc223305Sopenharmony_ci dataObservers_[i] = { nullptr, nullptr }; 478fc223305Sopenharmony_ci dataObservers_.erase(dataObservers_.begin() + i); 479fc223305Sopenharmony_ci } 480fc223305Sopenharmony_ci } 481fc223305Sopenharmony_ci return OH_Preferences_ErrCode::PREFERENCES_OK; 482fc223305Sopenharmony_ci} 483fc223305Sopenharmony_ci 484fc223305Sopenharmony_cibool NDKPreferencesObserver::ObserverCompare(OH_PreferencesDataObserver other) 485fc223305Sopenharmony_ci{ 486fc223305Sopenharmony_ci if (other == nullptr) { 487fc223305Sopenharmony_ci return false; 488fc223305Sopenharmony_ci } 489fc223305Sopenharmony_ci return other == dataObserver_; 490fc223305Sopenharmony_ci} 491