1 /* 2 * Copyright (c) 2023 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 "napi_settings_observer.h" 17 18 #include <map> 19 20 #include "napi_settings_log.h" 21 #include "abs_shared_result_set.h" 22 #include "values_bucket.h" 23 24 #include "napi_base_context.h" 25 #include "os_account_manager.h" 26 27 28 using namespace OHOS::AppExecFwk; 29 using namespace OHOS::DataShare; 30 using namespace OHOS::AccountSA; 31 32 33 namespace OHOS { 34 namespace Settings { 35 36 std::map<std::string, sptr<SettingsObserver>> g_observerMap; 37 OnChange()38 void SettingsObserver::OnChange() 39 { 40 OnChangeRet(); 41 } 42 OnChangeRet()43 napi_value SettingsObserver::OnChangeRet() 44 { 45 SETTING_LOG_INFO("%{public}s, O_C.", __func__); 46 napi_value resource = nullptr; 47 NAPI_CALL(cbInfo->env, napi_create_string_utf8(cbInfo->env, __func__, NAPI_AUTO_LENGTH, &resource)); 48 napi_create_async_work( 49 cbInfo->env, 50 nullptr, 51 resource, 52 [](napi_env env, void* data) {}, 53 [](napi_env env, napi_status status, void* data) { 54 if (data == nullptr) { 55 SETTING_LOG_INFO("%{public}s, null.", __func__); 56 return; 57 } 58 napi_value callback = nullptr; 59 napi_value undefined; 60 napi_get_undefined(env, &undefined); 61 // create error code 62 napi_value error = nullptr; 63 napi_create_object(env, &error); 64 int unSupportCode = 802; 65 napi_value errCode = nullptr; 66 napi_create_int32(env, unSupportCode, &errCode); 67 napi_set_named_property(env, error, "code", errCode); 68 napi_value result[PARAM2] = {0}; 69 result[0] = error; 70 result[1] = wrap_bool_to_js(env, false); 71 72 AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data; 73 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback); 74 napi_value callResult; 75 napi_call_function(env, undefined, callback, PARAM2, result, &callResult); 76 77 napi_delete_async_work(env, asyncCallbackInfo->asyncWork); 78 SETTING_LOG_INFO("%{public}s, O_C complete.", __func__); 79 }, 80 (void*)cbInfo, 81 &(cbInfo->asyncWork) 82 ); 83 NAPI_CALL(cbInfo->env, napi_queue_async_work(cbInfo->env, cbInfo->asyncWork)); 84 return wrap_void_to_js(cbInfo->env); 85 } 86 GetObserverIdStr()87 std::string GetObserverIdStr() 88 { 89 std::vector<int> tmpId; 90 OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(tmpId); 91 std::string tmpIdStr = "100"; 92 if (tmpId.size() > 0) { 93 tmpIdStr = std::to_string(tmpId[0]); 94 } else { 95 SETTING_LOG_INFO("%{public}s, user id 100.", __func__); 96 } 97 return tmpIdStr; 98 } 99 npai_settings_register_observer(napi_env env,napi_callback_info info)100 napi_value npai_settings_register_observer(napi_env env, napi_callback_info info) 101 { 102 SETTING_LOG_INFO("n_s_r_o"); 103 // Check the number of the arguments 104 size_t argc = ARGS_FOUR; 105 napi_value args[ARGS_FOUR] = {nullptr}; 106 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); 107 if (argc != ARGS_FOUR) { 108 SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__); 109 return wrap_bool_to_js(env, false); 110 } 111 112 // Check the value type of the arguments 113 napi_valuetype valueType; 114 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType)); 115 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected."); 116 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType)); 117 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected."); 118 NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType)); 119 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected."); 120 121 bool stageMode = false; 122 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode); 123 if (status != napi_ok) { 124 SETTING_LOG_ERROR("%{public}s, not stage mode.", __func__); 125 return wrap_bool_to_js(env, false); 126 } 127 AsyncCallbackInfo *callbackInfo = new AsyncCallbackInfo(); 128 callbackInfo->env = env; 129 callbackInfo->key = unwrap_string_from_js(env, args[PARAM1]); 130 callbackInfo->tableName = unwrap_string_from_js(env, args[PARAM2]); 131 napi_create_reference(env, args[PARAM3], 1, &(callbackInfo->callbackRef)); 132 133 if (g_observerMap.find(callbackInfo->key) != g_observerMap.end() && 134 g_observerMap[callbackInfo->key] != nullptr) { 135 SETTING_LOG_INFO("%{public}s, already registered.", __func__); 136 delete callbackInfo; 137 return wrap_bool_to_js(env, false); 138 } 139 140 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = nullptr; 141 dataShareHelper = getDataShareHelper(env, args[PARAM0], stageMode, callbackInfo->tableName); 142 if (dataShareHelper == nullptr) { 143 delete callbackInfo; 144 return wrap_bool_to_js(env, false); 145 } 146 147 std::string strUri = GetStageUriStr(callbackInfo->tableName, GetObserverIdStr(), callbackInfo->key); 148 OHOS::Uri uri(strUri); 149 sptr<SettingsObserver> settingsObserver = sptr<SettingsObserver> 150 (new (std::nothrow)SettingsObserver(callbackInfo)); 151 settingsObserver->dataShareHelper = dataShareHelper; 152 g_observerMap[callbackInfo->key] = settingsObserver; 153 dataShareHelper->RegisterObserver(uri, settingsObserver); 154 155 return wrap_bool_to_js(env, true); 156 } 157 npai_settings_unregister_observer(napi_env env,napi_callback_info info)158 napi_value npai_settings_unregister_observer(napi_env env, napi_callback_info info) 159 { 160 SETTING_LOG_INFO("n_s_u_o"); 161 // Check the number of the arguments 162 size_t argc = ARGS_THREE; 163 napi_value args[ARGS_THREE] = {nullptr}; 164 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); 165 if (argc != ARGS_THREE) { 166 SETTING_LOG_ERROR("%{public}s, wrong number of arguments.", __func__); 167 return wrap_bool_to_js(env, false); 168 } 169 // Check the value type of the arguments 170 napi_valuetype valueType; 171 NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valueType)); 172 NAPI_ASSERT(env, valueType == napi_object, "Wrong argument[0] type. Object expected."); 173 NAPI_CALL(env, napi_typeof(env, args[PARAM1], &valueType)); 174 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[1] type. String expected."); 175 NAPI_CALL(env, napi_typeof(env, args[PARAM2], &valueType)); 176 NAPI_ASSERT(env, valueType == napi_string, "Wrong argument[2] type. String expected."); 177 178 bool stageMode = false; 179 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, args[PARAM0], stageMode); 180 if (status != napi_ok) { 181 SETTING_LOG_ERROR("%{public}s, not stage mode.", __func__); 182 return wrap_bool_to_js(env, false); 183 } 184 185 std::string key = unwrap_string_from_js(env, args[PARAM1]); 186 std::string tableName = unwrap_string_from_js(env, args[PARAM2]); 187 188 if (g_observerMap.find(key) == g_observerMap.end()) { 189 SETTING_LOG_ERROR("%{public}s, null.", __func__); 190 return wrap_bool_to_js(env, false); 191 } 192 std::shared_ptr<OHOS::DataShare::DataShareHelper> dataShareHelper = g_observerMap[key]->dataShareHelper; 193 194 if (g_observerMap[key] == nullptr) { 195 g_observerMap.erase(key); 196 return wrap_bool_to_js(env, false); 197 } 198 std::string strUri = GetStageUriStr(tableName, GetObserverIdStr(), key); 199 OHOS::Uri uri(strUri); 200 201 napi_delete_reference(g_observerMap[key]->cbInfo->env, g_observerMap[key]->cbInfo->callbackRef); 202 dataShareHelper->UnregisterObserver(uri, g_observerMap[key]); 203 dataShareHelper->Release(); 204 delete g_observerMap[key]->cbInfo; 205 g_observerMap[key]->cbInfo = nullptr; 206 g_observerMap[key] = nullptr; 207 g_observerMap.erase(key); 208 209 return wrap_bool_to_js(env, true); 210 } 211 } 212 }