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 <string>
17
18 #include <uv.h>
19 #include "securec.h"
20
21 #include "bundle_active_log.h"
22 #include "bundle_state_common.h"
23 #include "bundle_state_data.h"
24 #include "bundle_state_inner_errors.h"
25 #include "app_group_callback_info.h"
26
27 #include "bundle_active_app_group_napi.h"
28
29 namespace OHOS {
30 namespace DeviceUsageStats {
31 const uint32_t UN_REGISTER_GROUP_CALLBACK_MIN_PARAMS = 0;
32 const uint32_t UN_REGISTER_GROUP_CALLBACK_PARAMS = 1;
33 const uint32_t REGISTER_GROUP_CALLBACK_MIN_PARAMS = 1;
34 const uint32_t REGISTER_GROUP_CALLBACK_PARAMS = 2;
35 const uint32_t PRIORITY_GROUP_MIN_PARAMS = 0;
36 const uint32_t PRIORITY_GROUP_MIDDLE_PARAMS = 1;
37 const uint32_t PRIORITY_GROUP_PARAMS = 2;
38 const uint32_t APP_USAGE_MIN_PARAMS_BUNDLE_GROUP = 2;
39 const uint32_t APP_USAGE_PARAMS_BUNDLE_GROUP = 3;
40 const uint32_t SECOND_ARG = 2;
41 const std::vector<int32_t> GROUP_TYPE {10, 20, 30, 40, 50, 60};
42
43 static sptr<AppGroupObserver> registerObserver = nullptr;
44 std::mutex g_observerMutex_;
45
ParseQueryAppGroupParameters(const napi_env & env,const napi_callback_info & info,QueryAppGroupParamsInfo & params,AsyncQueryAppGroupCallbackInfo * & asyncCallbackInfo)46 napi_value ParseQueryAppGroupParameters(const napi_env &env, const napi_callback_info &info,
47 QueryAppGroupParamsInfo ¶ms, AsyncQueryAppGroupCallbackInfo* &asyncCallbackInfo)
48 {
49 size_t argc = PRIORITY_GROUP_PARAMS;
50 napi_value argv[PRIORITY_GROUP_PARAMS] = {nullptr};
51 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
52 if ((argc != PRIORITY_GROUP_MIN_PARAMS) && (argc != PRIORITY_GROUP_MIDDLE_PARAMS) &&
53 (argc != PRIORITY_GROUP_PARAMS)) {
54 params.errorCode = ERR_PARAMETERS_NUMBER;
55 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_NUMBER, "");
56 }
57 std::string result = "";
58 params.bundleName = "";
59 if (argc == PRIORITY_GROUP_MIDDLE_PARAMS) {
60 napi_valuetype valuetype = napi_undefined;
61 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
62 if (valuetype == napi_function) {
63 napi_valuetype inputValueType = napi_undefined;
64 NAPI_CALL(env, napi_typeof(env, argv[0], &inputValueType));
65 if (inputValueType != napi_function) {
66 params.errorCode = ERR_CALL_BACK_TYPE;
67 return BundleStateCommon::HandleParamErr(env, ERR_CALL_BACK_TYPE, "");
68 }
69 napi_create_reference(env, argv[0], 1, ¶ms.callback);
70 } else {
71 params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result);
72 if (params.bundleName.empty()) {
73 BUNDLE_ACTIVE_LOGE("ParseQueryAppGroupParameters failed, bundleName is empty.");
74 params.errorCode = ERR_PARAMETERS_EMPTY;
75 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_EMPTY, "bundleName");
76 }
77 }
78 } else if (argc == PRIORITY_GROUP_PARAMS) {
79 // argv[0] : bundleName
80 params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result);
81 if (params.bundleName.empty()) {
82 BUNDLE_ACTIVE_LOGE("ParseQueryAppGroupParameters failed, bundleName is empty.");
83 params.errorCode = ERR_PARAMETERS_EMPTY;
84 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_EMPTY, "bundleName");
85 }
86 // argv[1]: callback
87 napi_valuetype inputValueType = napi_undefined;
88 NAPI_CALL(env, napi_typeof(env, argv[1], &inputValueType));
89 if (inputValueType != napi_function) {
90 params.errorCode = ERR_CALL_BACK_TYPE;
91 return BundleStateCommon::HandleParamErr(env, ERR_CALL_BACK_TYPE, "");
92 }
93 napi_create_reference(env, argv[1], 1, ¶ms.callback);
94 }
95 BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo);
96 return BundleStateCommon::NapiGetNull(env);
97 }
98
QueryAppGroup(napi_env env,napi_callback_info info)99 napi_value QueryAppGroup(napi_env env, napi_callback_info info)
100 {
101 BUNDLE_ACTIVE_LOGI("QueryAppGroup");
102 QueryAppGroupParamsInfo params;
103 AsyncQueryAppGroupCallbackInfo *asyncCallbackInfo = nullptr;
104 ParseQueryAppGroupParameters(env, info, params, asyncCallbackInfo);
105 if (params.errorCode != ERR_OK) {
106 return BundleStateCommon::NapiGetNull(env);
107 }
108 std::unique_ptr<AsyncQueryAppGroupCallbackInfo> callbackPtr {asyncCallbackInfo};
109 callbackPtr->bundleName = params.bundleName;
110 BUNDLE_ACTIVE_LOGD("QueryAppGroup callbackPtr->bundleName: %{public}s",
111 callbackPtr->bundleName.c_str());
112 napi_value promise = nullptr;
113 BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
114 napi_value resourceName = nullptr;
115 NAPI_CALL(env, napi_create_string_latin1(env, "QueryAppGroup", NAPI_AUTO_LENGTH, &resourceName));
116 NAPI_CALL(env, napi_create_async_work(env,
117 nullptr,
118 resourceName,
119 [](napi_env env, void *data) {
120 AsyncQueryAppGroupCallbackInfo *asyncCallbackInfo = (AsyncQueryAppGroupCallbackInfo *)data;
121 if (asyncCallbackInfo) {
122 asyncCallbackInfo->errorCode = BundleActiveClient::GetInstance().QueryAppGroup(
123 asyncCallbackInfo->priorityGroup, asyncCallbackInfo->bundleName);
124 } else {
125 BUNDLE_ACTIVE_LOGE("QueryAppGroup, asyncCallbackInfo == nullptr");
126 }
127 },
128 [](napi_env env, napi_status status, void *data) {
129 AsyncQueryAppGroupCallbackInfo *asyncCallbackInfo = (AsyncQueryAppGroupCallbackInfo *)data;
130 if (asyncCallbackInfo) {
131 napi_value result = nullptr;
132 napi_create_int32(env, asyncCallbackInfo->priorityGroup, &result);
133 BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result);
134 }
135 },
136 static_cast<void*>(asyncCallbackInfo),
137 &asyncCallbackInfo->asyncWork));
138 NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork));
139 if (callbackPtr->isCallback) {
140 callbackPtr.release();
141 return BundleStateCommon::NapiGetNull(env);
142 } else {
143 callbackPtr.release();
144 return promise;
145 }
146 }
147
ParseSetAppGroupParameters(const napi_env & env,const napi_callback_info & info,ParamsBundleGroupInfo & params,AsyncCallbackInfoSetAppGroup * & asyncCallbackInfo)148 napi_value ParseSetAppGroupParameters(const napi_env &env, const napi_callback_info &info,
149 ParamsBundleGroupInfo ¶ms, AsyncCallbackInfoSetAppGroup* &asyncCallbackInfo)
150 {
151 size_t argc = APP_USAGE_PARAMS_BUNDLE_GROUP;
152 napi_value argv[APP_USAGE_PARAMS_BUNDLE_GROUP] = {nullptr};
153 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
154 if ((argc != APP_USAGE_MIN_PARAMS_BUNDLE_GROUP) && (argc != APP_USAGE_PARAMS_BUNDLE_GROUP)) {
155 params.errorCode = ERR_PARAMETERS_NUMBER;
156 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_NUMBER, "");
157 }
158 // argv[0] : bundleName
159 std::string result = "";
160 params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result);
161 if (params.bundleName.empty()) {
162 BUNDLE_ACTIVE_LOGE("ParseSetAppGroupParameters failed, bundleName is empty.");
163 params.errorCode = ERR_PARAMETERS_EMPTY;
164 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_EMPTY, "bundleName");
165 }
166 napi_valuetype valuetype;
167 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
168 if ((valuetype != napi_string) && (params.errorCode == ERR_OK)) {
169 BUNDLE_ACTIVE_LOGE("Wrong argument type, string expected.");
170 params.errorCode = ERR_BUNDLE_NAME_TYPE;
171 return BundleStateCommon::HandleParamErr(env, ERR_BUNDLE_NAME_TYPE, "");
172 }
173 // argv[1] : newGroup
174 if ((params.errorCode == ERR_OK)
175 && (BundleStateCommon::GetInt32NumberValue(env, argv[1], params.newGroup) == nullptr)) {
176 BUNDLE_ACTIVE_LOGE("ParseSetAppGroupParameters failed, newGroup type is invalid.");
177 params.errorCode = ERR_NEW_GROUP_TYPE;
178 return BundleStateCommon::HandleParamErr(env, ERR_NEW_GROUP_TYPE, "");
179 }
180 bool flag = false;
181 if (params.errorCode == ERR_OK) {
182 for (const auto& item : GROUP_TYPE) {
183 if (item == params.newGroup) {
184 flag = true;
185 break;
186 }
187 }
188 }
189 if ((params.errorCode == ERR_OK) && !flag) {
190 BUNDLE_ACTIVE_LOGE("ParseSetAppGroupParameters failed, newGroup value is invalid.");
191 params.errorCode = ERR_NEW_GROUP_OUT_OF_RANGE;
192 return BundleStateCommon::HandleParamErr(env, ERR_NEW_GROUP_OUT_OF_RANGE, "");
193 }
194 // argv[SECOND_ARG]: callback
195 if (argc == APP_USAGE_PARAMS_BUNDLE_GROUP) {
196 napi_valuetype inputValueType = napi_undefined;
197 NAPI_CALL(env, napi_typeof(env, argv[SECOND_ARG], &inputValueType));
198 if (inputValueType != napi_function) {
199 params.errorCode = ERR_CALL_BACK_TYPE;
200 return BundleStateCommon::HandleParamErr(env, ERR_CALL_BACK_TYPE, "");
201 }
202 napi_create_reference(env, argv[SECOND_ARG], 1, ¶ms.callback);
203 }
204 BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo);
205 return BundleStateCommon::NapiGetNull(env);
206 }
207
SetAppGroup(napi_env env,napi_callback_info info)208 napi_value SetAppGroup(napi_env env, napi_callback_info info)
209 {
210 ParamsBundleGroupInfo params;
211 AsyncCallbackInfoSetAppGroup *asyncCallbackInfo = nullptr;
212 ParseSetAppGroupParameters(env, info, params, asyncCallbackInfo);
213 if (params.errorCode != ERR_OK) {
214 return BundleStateCommon::NapiGetNull(env);
215 }
216 std::unique_ptr<AsyncCallbackInfoSetAppGroup> callbackPtr {asyncCallbackInfo};
217 callbackPtr->newGroup = params.newGroup;
218 callbackPtr->bundleName = params.bundleName;
219 BUNDLE_ACTIVE_LOGD("SetAppGroup, bundleName is %{public}s, newGroup is %{public}d",
220 callbackPtr->bundleName.c_str(), callbackPtr->newGroup);
221 napi_value promise = nullptr;
222 BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
223 napi_value resourceName = nullptr;
224 NAPI_CALL(env, napi_create_string_latin1(env, "SetAppGroup", NAPI_AUTO_LENGTH, &resourceName));
225 NAPI_CALL(env, napi_create_async_work(env,
226 nullptr,
227 resourceName,
228 [](napi_env env, void *data) {
229 AsyncCallbackInfoSetAppGroup *asyncCallbackInfo = (AsyncCallbackInfoSetAppGroup *)data;
230 if (asyncCallbackInfo) {
231 asyncCallbackInfo->errorCode = BundleActiveClient::GetInstance().SetAppGroup(
232 asyncCallbackInfo->bundleName, asyncCallbackInfo->newGroup);
233 } else {
234 BUNDLE_ACTIVE_LOGE("SetAppGroup, asyncCallbackInfo == nullptr");
235 }
236 },
237 [](napi_env env, napi_status status, void *data) {
238 AsyncCallbackInfoSetAppGroup *asyncCallbackInfo = (AsyncCallbackInfoSetAppGroup *)data;
239 if (asyncCallbackInfo) {
240 napi_value result = nullptr;
241 napi_get_null(env, &result);
242 BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result);
243 }
244 },
245 static_cast<void*>(asyncCallbackInfo),
246 &asyncCallbackInfo->asyncWork));
247 NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork));
248 if (callbackPtr->isCallback) {
249 callbackPtr.release();
250 return BundleStateCommon::NapiGetNull(env);
251 } else {
252 callbackPtr.release();
253 return promise;
254 }
255 }
256
GetAppGroupChangeCallback(const napi_env & env,const napi_value & value)257 napi_value GetAppGroupChangeCallback(const napi_env &env, const napi_value &value)
258 {
259 napi_ref result = nullptr;
260
261 registerObserver = new (std::nothrow) AppGroupObserver();
262 if (!registerObserver) {
263 BUNDLE_ACTIVE_LOGE("RegisterAppGroupCallBack callback is null");
264 return nullptr;
265 }
266 napi_create_reference(env, value, 1, &result);
267 registerObserver->SetCallbackInfo(env, result);
268
269 return BundleStateCommon::NapiGetNull(env);
270 }
271
ParseRegisterAppGroupCallBackParameters(const napi_env & env,const napi_callback_info & info,RegisterCallbackInfo & params,AsyncRegisterCallbackInfo * & asyncCallbackInfo)272 napi_value ParseRegisterAppGroupCallBackParameters(const napi_env &env, const napi_callback_info &info,
273 RegisterCallbackInfo ¶ms, AsyncRegisterCallbackInfo* &asyncCallbackInfo)
274 {
275 size_t argc = REGISTER_GROUP_CALLBACK_PARAMS;
276 napi_value argv[REGISTER_GROUP_CALLBACK_PARAMS] = {nullptr};
277 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
278 if ((argc != REGISTER_GROUP_CALLBACK_MIN_PARAMS) && (argc != REGISTER_GROUP_CALLBACK_PARAMS)) {
279 params.errorCode = ERR_PARAMETERS_NUMBER;
280 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_NUMBER, "");
281 }
282
283 // arg[0] : callback
284 napi_valuetype valuetype = napi_undefined;
285 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
286 std::lock_guard<std::mutex> lock(g_observerMutex_);
287 if (registerObserver) {
288 BUNDLE_ACTIVE_LOGI("RegisterAppGroupCallBack repeat!");
289 params.errorCode = ERR_REPEAT_REGISTER_APP_GROUP_OBSERVER;
290 return BundleStateCommon::HandleParamErr(env, ERR_REPEAT_REGISTER_APP_GROUP_OBSERVER, "");
291 } else if (valuetype != napi_function || !GetAppGroupChangeCallback(env, argv[0])) {
292 BUNDLE_ACTIVE_LOGE("RegisterAppGroupCallBack bundleActiveGroupObserverInfo parse failed");
293 params.errorCode = ERR_APP_GROUP_OBSERVER_CALLBACK_TYPE;
294 return BundleStateCommon::HandleParamErr(env, ERR_APP_GROUP_OBSERVER_CALLBACK_TYPE, "");
295 }
296
297 // argv[1]: asyncCallback
298 if (argc == REGISTER_GROUP_CALLBACK_PARAMS) {
299 napi_valuetype inputValueType = napi_undefined;
300 NAPI_CALL(env, napi_typeof(env, argv[1], &inputValueType));
301 if (inputValueType != napi_function) {
302 params.errorCode = ERR_CALL_BACK_TYPE;
303 return BundleStateCommon::HandleParamErr(env, ERR_CALL_BACK_TYPE, "");
304 }
305 napi_create_reference(env, argv[1], 1, ¶ms.callback);
306 }
307 BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo);
308 return BundleStateCommon::NapiGetNull(env);
309 }
310
RegisterAppGroupCallBack(napi_env env,napi_callback_info info)311 napi_value RegisterAppGroupCallBack(napi_env env, napi_callback_info info)
312 {
313 RegisterCallbackInfo params;
314 AsyncRegisterCallbackInfo *asyncCallbackInfo = nullptr;
315 ParseRegisterAppGroupCallBackParameters(env, info, params, asyncCallbackInfo);
316 if (params.errorCode != ERR_OK) {
317 // return BundleStateCommon::JSParaError(env, params.callback, params.errorCode);
318 return BundleStateCommon::NapiGetNull(env);
319 }
320 std::unique_ptr<AsyncRegisterCallbackInfo> callbackPtr {asyncCallbackInfo};
321 callbackPtr->observer = registerObserver;
322 napi_value promise = nullptr;
323 BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
324 napi_value resourceName = nullptr;
325 NAPI_CALL(env, napi_create_string_latin1(env, "RegisterAppGroupCallBack", NAPI_AUTO_LENGTH, &resourceName));
326 NAPI_CALL(env, napi_create_async_work(env,
327 nullptr,
328 resourceName,
329 [](napi_env env, void *data) {
330 AsyncRegisterCallbackInfo *asyncCallbackInfo = (AsyncRegisterCallbackInfo *)data;
331 if (asyncCallbackInfo) {
332 asyncCallbackInfo->errorCode =
333 BundleActiveClient::GetInstance().RegisterAppGroupCallBack(asyncCallbackInfo->observer);
334 } else {
335 BUNDLE_ACTIVE_LOGE("RegisterAppGroupCallBack, asyncCallbackInfo == nullptr");
336 }
337 },
338 [](napi_env env, napi_status status, void *data) {
339 AsyncRegisterCallbackInfo *asyncCallbackInfo = (AsyncRegisterCallbackInfo *)data;
340 if (asyncCallbackInfo) {
341 if (asyncCallbackInfo->errorCode != ERR_OK) {
342 std::lock_guard<std::mutex> lock(g_observerMutex_);
343 registerObserver = nullptr;
344 }
345 napi_value result = nullptr;
346 napi_get_null(env, &result);
347 BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result);
348 }
349 },
350 static_cast<void*>(asyncCallbackInfo),
351 &asyncCallbackInfo->asyncWork));
352 NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork));
353 if (callbackPtr->isCallback) {
354 callbackPtr.release();
355 return BundleStateCommon::NapiGetNull(env);
356 } else {
357 callbackPtr.release();
358 return promise;
359 }
360 }
361
ParseUnRegisterAppGroupCallBackParameters(const napi_env & env,const napi_callback_info & info,UnRegisterCallbackInfo & params,AsyncUnRegisterCallbackInfo * & asyncCallbackInfo)362 napi_value ParseUnRegisterAppGroupCallBackParameters(const napi_env &env, const napi_callback_info &info,
363 UnRegisterCallbackInfo ¶ms, AsyncUnRegisterCallbackInfo* &asyncCallbackInfo)
364 {
365 size_t argc = UN_REGISTER_GROUP_CALLBACK_PARAMS;
366 napi_value argv[UN_REGISTER_GROUP_CALLBACK_PARAMS] = {nullptr};
367 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
368 if ((argc != UN_REGISTER_GROUP_CALLBACK_MIN_PARAMS) && (argc != UN_REGISTER_GROUP_CALLBACK_PARAMS)) {
369 params.errorCode = ERR_PARAMETERS_NUMBER;
370 return BundleStateCommon::HandleParamErr(env, ERR_PARAMETERS_NUMBER, "");
371 }
372
373 if (argc == UN_REGISTER_GROUP_CALLBACK_PARAMS) {
374 napi_valuetype valuetype = napi_undefined;
375 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
376 if (valuetype != napi_function) {
377 params.errorCode = ERR_CALL_BACK_TYPE;
378 return BundleStateCommon::HandleParamErr(env, ERR_CALL_BACK_TYPE, "");
379 }
380 napi_create_reference(env, argv[0], 1, ¶ms.callback);
381 }
382 std::lock_guard<std::mutex> lock(g_observerMutex_);
383 if (!registerObserver) {
384 BUNDLE_ACTIVE_LOGI("UnRegisterAppGroupCallBack observer is not exist");
385 params.errorCode = ERR_APP_GROUP_OBSERVER_IS_NULLPTR;
386 return BundleStateCommon::HandleParamErr(env, ERR_APP_GROUP_OBSERVER_IS_NULLPTR, "");
387 }
388 BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo);
389 return BundleStateCommon::NapiGetNull(env);
390 }
391
UnRegisterAppGroupCallBack(napi_env env,napi_callback_info info)392 napi_value UnRegisterAppGroupCallBack(napi_env env, napi_callback_info info)
393 {
394 UnRegisterCallbackInfo params;
395 AsyncUnRegisterCallbackInfo *asyncCallbackInfo = nullptr;
396 ParseUnRegisterAppGroupCallBackParameters(env, info, params, asyncCallbackInfo);
397 if (params.errorCode != ERR_OK) {
398 return BundleStateCommon::NapiGetNull(env);
399 }
400 std::unique_ptr<AsyncUnRegisterCallbackInfo> callbackPtr {asyncCallbackInfo};
401 callbackPtr->observer = registerObserver;
402 napi_value promise = nullptr;
403 BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
404 napi_value resourceName = nullptr;
405 NAPI_CALL(env, napi_create_string_latin1(env, "UnRegisterAppGroupCallBack", NAPI_AUTO_LENGTH, &resourceName));
406 NAPI_CALL(env, napi_create_async_work(env,
407 nullptr,
408 resourceName,
409 [](napi_env env, void *data) {
410 AsyncUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncUnRegisterCallbackInfo *)data;
411 if (asyncCallbackInfo != nullptr) {
412 asyncCallbackInfo->errorCode =
413 BundleActiveClient::GetInstance().UnRegisterAppGroupCallBack(asyncCallbackInfo->observer);
414 } else {
415 BUNDLE_ACTIVE_LOGE("UnRegisterAppGroupCallBack, asyncCallbackInfo == nullptr");
416 }
417 },
418 [](napi_env env, napi_status status, void *data) {
419 AsyncUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncUnRegisterCallbackInfo *)data;
420 if (asyncCallbackInfo != nullptr) {
421 if (asyncCallbackInfo->errorCode == ERR_OK) {
422 std::lock_guard<std::mutex> lock(g_observerMutex_);
423 registerObserver = nullptr;
424 }
425 napi_value result = nullptr;
426 napi_get_null(env, &result);
427 BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result);
428 }
429 },
430 static_cast<void*>(asyncCallbackInfo),
431 &asyncCallbackInfo->asyncWork));
432 NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork));
433 if (callbackPtr->isCallback) {
434 callbackPtr.release();
435 return BundleStateCommon::NapiGetNull(env);
436 } else {
437 callbackPtr.release();
438 return promise;
439 }
440 }
441 } // namespace DeviceUsageStats
442 } // namespace OHOS