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