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