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 ¶ms, 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, ¶ms.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, ¶ms.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 ¶ms)
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 ¶ms, 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, ¶ms.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 ¶ms, 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, ¶ms.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 ¶ms, 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, ¶ms.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