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