diff --git a/BUILD.gn b/BUILD.gn index 1a9d6724d82300c3c140c9e7936fd6489cb35eb2..1c7f27d7a0202e83a06486ed87092d1651a3c856 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -34,6 +34,9 @@ ohos_shared_library("usagestatsinner") { "interfaces/innerkits/src/bundle_active_proxy.cpp", "services/packageusage/src/bundle_active_event.cpp", "services/packageusage/src/bundle_active_package_stats.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_info.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_stub.cpp", ] public_configs = [ ":usagestatsinner_public_config" ] public_deps = [ ":usagestatservice" ] @@ -61,12 +64,14 @@ ohos_shared_library("bundlestate") { "frameworks/src/bundle_state_common.cpp", "frameworks/src/bundle_state_init.cpp", "frameworks/src/bundle_state_query.cpp", + "frameworks/src/bundle_active_group_observer.cpp", ] include_dirs = [ "interfaces/kits/bundlestats/napi/include", "services/common/include", "interfaces/innerkits/include", "services/packageusage/include", + "services/packagegroup/include" ] deps = [ @@ -119,16 +124,18 @@ ohos_shared_library("usagestatservice") { "services/packageusage/src/bundle_active_report_handler.cpp", "services/packageusage/src/bundle_active_stats_combiner.cpp", "services/packageusage/src/bundle_active_user_service.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_info.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp", ] include_dirs = [ ":bundle_active_config", "services/common/include", "services/packageusage/include", "services/packagegroup/include", + "interfaces/innerkits/include", ] external_deps = [ - "ability_base:configuration", "ability_base:want", "ability_runtime:app_manager", "ability_runtime:wantagent_innerkits", @@ -140,9 +147,9 @@ ohos_shared_library("usagestatservice") { "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "native_appdatamgr:native_rdb", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", - "relational_store:native_rdb", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", "startup_l2:syspara", diff --git a/README.md b/README.md index b0efeabb09a11cdbf6214cb6c5a5bdd6e6e423af..f28be986a2664edae4fb546d7b98beeabcd843b9 100644 --- a/README.md +++ b/README.md @@ -97,4 +97,4 @@ resource_schedule_service appexecfwk_standard -relational_store \ No newline at end of file +native_appdatamgr \ No newline at end of file diff --git a/bundle.json b/bundle.json index cccf5f4b1588a4a293505b2ff6e4e874bf97284c..051e76f024005cffd1b03851c4b5bdb51d0bfb28 100644 --- a/bundle.json +++ b/bundle.json @@ -68,8 +68,7 @@ ], "test": [ "//foundation/resourceschedule/device_usage_statistics/test/unittest:unittest", - "//foundation/resourceschedule/device_usage_statistics/interfaces/test/unittest/device_usage_statistics_jsunittest:js_unittest", - "//foundation/resourceschedule/device_usage_statistics/test/fuzztest/bundleactiveonremoterequest_fuzzer:fuzztest" + "//foundation/resourceschedule/device_usage_statistics/interfaces/test/unittest/device_usage_statistics_jsunittest:js_unittest" ] } } diff --git a/frameworks/src/bundle_active_group_observer.cpp b/frameworks/src/bundle_active_group_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..35b745ce4695e2773b3d10b5454db2575e02d64b --- /dev/null +++ b/frameworks/src/bundle_active_group_observer.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "securec.h" + +#include "bundle_active_log.h" +#include "bundle_state_common.h" +#include "bundle_state_data.h" +#include "bundle_active_group_observer.h" +#include "bundle_state_inner_errors.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +const uint32_t UN_REGISTER_GROUP_CALLBACK_MIN_PARAMS = 0; +const uint32_t UN_REGISTER_GROUP_CALLBACK_PARAMS = 1; +const uint32_t REGISTER_GROUP_CALLBACK_MIN_PARAMS = 1; +const uint32_t REGISTER_GROUP_CALLBACK_PARAMS = 2; + +static sptr registerObserver = nullptr; + +BundleActiveGroupObserver::~BundleActiveGroupObserver() +{ + if (bundleGroupCallbackInfo_.ref) { + napi_delete_reference(bundleGroupCallbackInfo_.env, bundleGroupCallbackInfo_.ref); + } +} + +void BundleActiveGroupObserver::SetCallbackInfo(const napi_env &env, const napi_ref &ref) +{ + bundleGroupCallbackInfo_.env=env; + bundleGroupCallbackInfo_.ref=ref; +} + +napi_value SetBundleGroupChangedData(const CallbackReceiveDataWorker *commonEventDataWorkerData, napi_value &result) +{ + BUNDLE_ACTIVE_LOGI("enter"); + + if (!commonEventDataWorkerData) { + BUNDLE_ACTIVE_LOGE("commonEventDataWorkerData is null"); + return nullptr; + } + napi_value value = nullptr; + + // oldGroup + napi_create_int32(commonEventDataWorkerData->env, commonEventDataWorkerData->oldGroup, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "oldGroup", value); + + // newGroup + napi_create_int32(commonEventDataWorkerData->env, commonEventDataWorkerData->newGroup, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "newGroup", value); + + // userId + napi_create_int32(commonEventDataWorkerData->env, commonEventDataWorkerData->userId, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "userId", value); + + // changeReason + napi_create_uint32(commonEventDataWorkerData->env, commonEventDataWorkerData->changeReason, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "changeReason", value); + //bundleName + napi_create_string_utf8(commonEventDataWorkerData->env, commonEventDataWorkerData->bundleName.c_str(), NAPI_AUTO_LENGTH, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "bundleName", value); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack, result's oldGroup= %{public}d", commonEventDataWorkerData->oldGroup); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack, result's newGroup= %{public}d", commonEventDataWorkerData->newGroup); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack, result's userId= %{public}d", commonEventDataWorkerData->userId); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack, result's changeReason= %{public}d", commonEventDataWorkerData->changeReason); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack, result's bundleName= %{public}s", commonEventDataWorkerData->bundleName.c_str()); + + return BundleStateCommon::NapiGetNull(commonEventDataWorkerData->env); +} + +void UvQueueWorkOnBundleGroupChanged(uv_work_t *work, int status) +{ + BUNDLE_ACTIVE_LOGI("OnBundleGroupChanged uv_work_t start"); + if (!work) { + return; + } + CallbackReceiveDataWorker *callbackReceiveDataWorkerData = (CallbackReceiveDataWorker *)work->data; + if (!callbackReceiveDataWorkerData || !callbackReceiveDataWorkerData->ref) { + BUNDLE_ACTIVE_LOGE("OnBundleGroupChanged commonEventDataWorkerData or ref is null"); + delete work; + work = nullptr; + return; + } + + napi_value result = nullptr; + napi_create_object(callbackReceiveDataWorkerData->env, &result); + if (!SetBundleGroupChangedData(callbackReceiveDataWorkerData, result)) { + delete work; + work = nullptr; + delete callbackReceiveDataWorkerData; + callbackReceiveDataWorkerData = nullptr; + return; + } + + napi_value undefined = nullptr; + napi_get_undefined(callbackReceiveDataWorkerData->env, &undefined); + + napi_value callback = nullptr; + napi_value resultout = nullptr; + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack OnBundleGroupChanged ref = %{public}p", callbackReceiveDataWorkerData->ref); + napi_get_reference_value(callbackReceiveDataWorkerData->env, callbackReceiveDataWorkerData->ref, &callback); + + napi_value results[ARGS_TWO] = {nullptr}; + results[PARAM_FIRST] = BundleStateCommon::GetErrorValue(callbackReceiveDataWorkerData->env, NO_ERROR); + results[PARAM_SECOND] = result; + NAPI_CALL_RETURN_VOID(callbackReceiveDataWorkerData->env, napi_call_function(callbackReceiveDataWorkerData->env, undefined, callback, ARGS_TWO, &results[PARAM_FIRST], &resultout)); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack OnBundleGroupChanged return void --------------------------"); + delete callbackReceiveDataWorkerData; + callbackReceiveDataWorkerData = nullptr; + delete work; + work = nullptr; +} + +/* +* observer calbback when group change +*/ +void BundleActiveGroupObserver::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) +{ + BUNDLE_ACTIVE_LOGI("OnBundleGroupChanged start"); + + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(bundleGroupCallbackInfo_.env, &loop); + if (!loop) { + BUNDLE_ACTIVE_LOGE("loop instance is nullptr"); + return; + } + + uv_work_t *work = new (std::nothrow) uv_work_t; + if (!work) { + BUNDLE_ACTIVE_LOGE("work is null"); + return; + } + CallbackReceiveDataWorker *callbackReceiveDataWorker = new (std::nothrow) CallbackReceiveDataWorker(); + if (!callbackReceiveDataWorker) { + BUNDLE_ACTIVE_LOGE("callbackReceiveDataWorker is null"); + delete work; + work = nullptr; + return; + } + MessageParcel data; + if(!bundleActiveGroupCallbackInfo.Marshalling(data)) + { + BUNDLE_ACTIVE_LOGE("Marshalling fail"); + } + BundleActiveGroupCallbackInfo* callBackInfo=bundleActiveGroupCallbackInfo.Unmarshalling(data); + callbackReceiveDataWorker->oldGroup = callBackInfo->GetOldGroup(); + callbackReceiveDataWorker->newGroup = callBackInfo->GetNewGroup(); + callbackReceiveDataWorker->changeReason = callBackInfo->GetChangeReason(); + callbackReceiveDataWorker->userId = callBackInfo->GetUserId(); + callbackReceiveDataWorker->bundleName = callBackInfo->GetBundleName(); + + callbackReceiveDataWorker->env = bundleGroupCallbackInfo_.env; + callbackReceiveDataWorker->ref = bundleGroupCallbackInfo_.ref; + + work->data = (void *)callbackReceiveDataWorker; + + BUNDLE_ACTIVE_LOGI("OnReceiveEvent this = %{public}p", this); + + int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, UvQueueWorkOnBundleGroupChanged); + if (ret != 0) { + delete callbackReceiveDataWorker; + callbackReceiveDataWorker = nullptr; + delete work; + work = nullptr; + } + + BUNDLE_ACTIVE_LOGI("OnBundleGroupChanged end"); +} + +napi_value GetBundleGroupChangeCallback( + const napi_env &env, const napi_value &value, BundleActiveGroupObserverInfo &bundleActiveGroupObserverInfo) +{ + napi_ref result = nullptr; + + bundleActiveGroupObserverInfo.callback = new (std::nothrow) BundleActiveGroupObserver(); + if (!bundleActiveGroupObserverInfo.callback) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack callback is null"); + return BundleStateCommon::NapiGetNull(env); + } + + napi_create_reference(env, value, 1, &result); + bundleActiveGroupObserverInfo.callback->SetCallbackInfo(env, result); + + return BundleStateCommon::NapiGetNull(env); +} + +napi_value ParseRegisterGroupCallBackParameters( + const napi_env &env, const napi_callback_info &info, RegisterCallbackInfo ¶ms, sptr &observer) +{ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter RegisterGroupCallBack, 2!-------------------------------------"); + size_t argc = REGISTER_GROUP_CALLBACK_PARAMS; + napi_value argv[REGISTER_GROUP_CALLBACK_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == REGISTER_GROUP_CALLBACK_MIN_PARAMS || argc == REGISTER_GROUP_CALLBACK_PARAMS, + "Invalid number of parameters"); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter RegisterGroupCallBack, 3!-------------------------------------"); + // arg[0] : callback + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "RegisterGroupCallBack Wrong argument type. Object expected."); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack parseParameters callback success!"); + + BundleActiveGroupObserverInfo bundleActiveGroupObserverInfo; + if (!GetBundleGroupChangeCallback(env, argv[0], bundleActiveGroupObserverInfo)) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack bundleActiveGroupObserverInfo parse failed"); + return nullptr; + } + observer = bundleActiveGroupObserverInfo.callback; + + // argv[1]: asyncCallback + if (argc == REGISTER_GROUP_CALLBACK_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseStatesParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[1], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value RegisterGroupCallBack(napi_env env, napi_callback_info info) +{ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter RegisterGroupCallBack, !-------------------------------------"); + RegisterCallbackInfo params; + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack create RegisterCallbackInfo, 1-------------------------------------"); + ParseRegisterGroupCallBackParameters(env, info, params, registerObserver); + + if (params.errorCode != ERR_OK || !registerObserver) { + if (registerObserver) { + delete registerObserver; + registerObserver = nullptr; + } + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncCallbackInfoRegisterCallbackInfo *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoRegisterCallbackInfo(env); + if (!asyncCallbackInfo) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoRegisterCallbackInfo), 0, sizeof(AsyncCallbackInfoRegisterCallbackInfo)) + != EOK) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->observer = registerObserver; + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "RegisterGroupCallBack", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoRegisterCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfoRegisterCallbackInfo *)data; + if (asyncCallbackInfo) { + asyncCallbackInfo->state = BundleActiveClient::GetInstance().RegisterGroupCallBack(asyncCallbackInfo->observer); + } else { + BUNDLE_ACTIVE_LOGE("QueryCurrentBundleActiveStates, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoRegisterCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfoRegisterCallbackInfo *)data; + std::unique_ptr callbackPtr {asyncCallbackInfo}; + if (asyncCallbackInfo) { + napi_value result = nullptr; + napi_get_boolean(env, asyncCallbackInfo->state, &result); + BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result); + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork)); + + NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork)); + if (callbackPtr->isCallback) { + callbackPtr.release(); + return BundleStateCommon::NapiGetNull(env); + } else { + callbackPtr.release(); + return promise; + } +} + +napi_value ParseUnRegisterGroupCallBackParameters(const napi_env &env, const napi_callback_info &info, UnRegisterCallbackInfo ¶ms) +{ + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack enter parseParameters, !-------------------------------------"); + size_t argc = UN_REGISTER_GROUP_CALLBACK_PARAMS; + napi_value argv[UN_REGISTER_GROUP_CALLBACK_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == UN_REGISTER_GROUP_CALLBACK_MIN_PARAMS || argc == UN_REGISTER_GROUP_CALLBACK_PARAMS, + "Invalid number of parameters"); + + // argv[1]: callback + if (argc == UN_REGISTER_GROUP_CALLBACK_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseStatesParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[0], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value UnRegisterGroupCallBack(napi_env env, napi_callback_info info) +{ + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack enter napi, !-------------------------------------"); + if(!registerObserver){ + return BundleStateCommon::NapiGetNull(env); + } + + UnRegisterCallbackInfo params; + ParseUnRegisterGroupCallBackParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + + napi_value promise = nullptr; + AsyncCallbackInfoUnRegisterCallbackInfo *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoUnRegisterCallbackInfo(env); + if (!asyncCallbackInfo) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoUnRegisterCallbackInfo), 0, sizeof(AsyncCallbackInfoUnRegisterCallbackInfo)) + != EOK) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->observer = registerObserver; + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "UnRegisterGroupCallBack", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfoUnRegisterCallbackInfo *)data; + std::unique_ptr callbackPtr {asyncCallbackInfo}; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->state = BundleActiveClient::GetInstance().UnregisterGroupCallBack(asyncCallbackInfo->observer); + } else { + BUNDLE_ACTIVE_LOGE("UnRegisterGroupCallBack, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfoUnRegisterCallbackInfo *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_get_boolean(env, asyncCallbackInfo->state, &result); + BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result); + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork)); + //registerObserver的析构 + NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork)); + if (callbackPtr->isCallback) { + callbackPtr.release(); + return BundleStateCommon::NapiGetNull(env); + } else { + callbackPtr.release(); + return promise; + } + delete registerObserver; + registerObserver = nullptr; +} + +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/src/bundle_state_init.cpp b/frameworks/src/bundle_state_init.cpp index 56e36f89b19d0ca4be68425304fcf744fb134228..5274674aab6745580b27ea6a5f2246897fd46c92 100644 --- a/frameworks/src/bundle_state_init.cpp +++ b/frameworks/src/bundle_state_init.cpp @@ -15,6 +15,7 @@ #include "bundle_state_condition.h" #include "bundle_state_query.h" +#include "bundle_active_group_observer.h" #include "bundle_state_init.h" namespace OHOS { @@ -40,7 +41,10 @@ static napi_value BundleStateInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("queryBundleActiveStates", QueryBundleActiveStates), DECLARE_NAPI_FUNCTION("queryBundleStateInfoByInterval", QueryBundleStateInfoByInterval), DECLARE_NAPI_FUNCTION("queryBundleStateInfos", QueryBundleStateInfos), - DECLARE_NAPI_FUNCTION("getRecentlyUsedModules", GetModuleUsageRecord) + DECLARE_NAPI_FUNCTION("getRecentlyUsedModules", GetModuleUsageRecord), + DECLARE_NAPI_FUNCTION("setBundleGroup", SetBundleGroup), + DECLARE_NAPI_FUNCTION("registerGroupCallBack", RegisterGroupCallBack), + DECLARE_NAPI_FUNCTION("unRegisterGroupCallBack", UnRegisterGroupCallBack), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); diff --git a/frameworks/src/bundle_state_query.cpp b/frameworks/src/bundle_state_query.cpp index 7b840ef2e1889b1c220f3b79fb1a8df34223bee5..3802b385acabfe6fca514ecd16e0717d641b028d 100644 --- a/frameworks/src/bundle_state_query.cpp +++ b/frameworks/src/bundle_state_query.cpp @@ -19,18 +19,21 @@ #include "bundle_active_log.h" #include "bundle_state_common.h" #include "bundle_state_data.h" +#include "bundle_active_group_observer.h" #include "bundle_state_inner_errors.h" namespace OHOS { namespace DeviceUsageStats { const uint32_t IS_IDLE_STATE_MIN_PARAMS = 1; const uint32_t IS_IDLE_STATE_PARAMS = 2; -const uint32_t PRIORITY_GROUP_MIN_PARAMS = 0; -const uint32_t PRIORITY_GROUP_PARAMS = 1; +const uint32_t PRIORITY_GROUP_MIN_PARAMS = 1; +const uint32_t PRIORITY_GROUP_PARAMS = 2; const uint32_t STATES_MIN_PARAMS = 2; const uint32_t STATES_PARAMS = 3; const uint32_t APP_USAGE_MIN_PARAMS_BY_INTERVAL = 3; const uint32_t APP_USAGE_PARAMS_BY_INTERVAL = 4; +const uint32_t APP_USAGE_MIN_PARAMS_BUNDLE_GROUP = 2; +const uint32_t APP_USAGE_PARAMS_BUNDLE_GROUP = 3; const uint32_t APP_USAGE_MIN_PARAMS = 2; const uint32_t APP_USAGE_PARAMS = 3; const uint32_t MODULE_RECORDS_MIN_PARAMS = 0; @@ -39,6 +42,7 @@ const uint32_t MODULE_RECORDS_PARAMS = 2; const uint32_t SECOND_ARG = 2; const uint32_t THIRD_ARG = 3; const int32_t MAXNUM_UP_LIMIT = 1000; +const std::vector GROUP_TYPE {5, 10, 20, 30, 40, 50, 60}; napi_value ParseModuleRecordsParameters(const napi_env &env, const napi_callback_info &info, ModuleRecordParamsInfo ¶ms) @@ -103,7 +107,8 @@ napi_value GetModuleUsageRecord(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoModuleRecord), 0, + sizeof(AsyncCallbackInfoModuleRecord)) != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -196,7 +201,8 @@ napi_value IsIdleState(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoIsIdleState), 0, sizeof(AsyncCallbackInfoIsIdleState)) + != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -248,13 +254,27 @@ napi_value ParsePriorityGroupParameters(const napi_env &env, const napi_callback NAPI_ASSERT(env, argc == PRIORITY_GROUP_MIN_PARAMS || argc == PRIORITY_GROUP_PARAMS, "Invalid number of parameters"); - // argv[0]: callback + // argv[0] : bundleName + std::string result = ""; + params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result); + if (params.bundleName.empty()) { + BUNDLE_ACTIVE_LOGE("ParsePriorityGroupParameters failed, bundleName is empty."); + params.errorCode = ERR_USAGE_STATS_BUNDLENAME_EMPTY; + } + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + if ((valuetype != napi_string) && (params.errorCode == ERR_OK)) { + BUNDLE_ACTIVE_LOGE("Wrong argument type, string expected."); + params.errorCode = ERR_USAGE_STATS_BUNDLENAME_TYPE; + } + + // argv[1]: callback if (argc == PRIORITY_GROUP_PARAMS) { napi_valuetype valuetype = napi_undefined; - NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); NAPI_ASSERT(env, valuetype == napi_function, "ParsePriorityGroupParameters invalid parameter type. " "Function expected."); - napi_create_reference(env, argv[0], 1, ¶ms.callback); + napi_create_reference(env, argv[1], 1, ¶ms.callback); } return BundleStateCommon::NapiGetNull(env); } @@ -263,6 +283,9 @@ napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) { PriorityGroupParamsInfo params; ParsePriorityGroupParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } napi_value promise = nullptr; AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfoPriorityGroup(env); @@ -270,13 +293,17 @@ napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoPriorityGroup), 0, sizeof(AsyncCallbackInfoPriorityGroup)) + != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGI("QueryAppUsagePriorityGroup QueryPackageGroup callbackPtr->bundleName: %{public}s", + callbackPtr->bundleName.c_str()); BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); napi_value resourceName = nullptr; NAPI_CALL(env, napi_create_string_latin1(env, "QueryAppUsagePriorityGroup", NAPI_AUTO_LENGTH, &resourceName)); @@ -285,15 +312,16 @@ napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) resourceName, [](napi_env env, void *data) { AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = (AsyncCallbackInfoPriorityGroup *)data; - if (asyncCallbackInfo != nullptr) { - asyncCallbackInfo->priorityGroup = BundleActiveClient::GetInstance().QueryPackageGroup(); + if (asyncCallbackInfo) { + asyncCallbackInfo->priorityGroup = BundleActiveClient::GetInstance().QueryPackageGroup(asyncCallbackInfo->bundleName); } else { BUNDLE_ACTIVE_LOGE("QueryAppUsagePriorityGroup, asyncCallbackInfo == nullptr"); } }, [](napi_env env, napi_status status, void *data) { AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = (AsyncCallbackInfoPriorityGroup *)data; - if (asyncCallbackInfo != nullptr) { + std::unique_ptr callbackPtr {asyncCallbackInfo}; + if (asyncCallbackInfo) { napi_value result = nullptr; napi_create_int32(env, asyncCallbackInfo->priorityGroup, &result); BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result); @@ -302,11 +330,10 @@ napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork)); NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork)); - if (callbackPtr->isCallback) { - callbackPtr.release(); + callbackPtr.release(); + if (callbackPtr->isCallback) { return BundleStateCommon::NapiGetNull(env); } else { - callbackPtr.release(); return promise; } } @@ -372,7 +399,8 @@ napi_value QueryCurrentBundleActiveStates(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoStates), 0, sizeof(AsyncCallbackInfoStates)) + != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -438,7 +466,8 @@ napi_value QueryBundleActiveStates(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoStates), 0, sizeof(AsyncCallbackInfoStates)) + != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -564,7 +593,8 @@ napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoAppUsageByInterval), 0, + sizeof(AsyncCallbackInfoAppUsageByInterval)) != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -676,7 +706,8 @@ napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } - if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoAppUsage), 0, sizeof(AsyncCallbackInfoAppUsage)) + != EOK) { params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; delete asyncCallbackInfo; asyncCallbackInfo = nullptr; @@ -716,14 +747,128 @@ napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork)); NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork)); + callbackPtr.release(); + if (callbackPtr->isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseAppUsageBundleGroupInfoParameters(const napi_env &env, const napi_callback_info &info, + AppUsageParamsBundleGroupInfo ¶ms) +{ + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter parseParameters,2--------------------"); + size_t argc = APP_USAGE_PARAMS_BUNDLE_GROUP; + napi_value argv[APP_USAGE_PARAMS_BUNDLE_GROUP] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == APP_USAGE_MIN_PARAMS_BUNDLE_GROUP || argc == APP_USAGE_PARAMS_BUNDLE_GROUP, + "Invalid number of parameters"); + + // argv[0] : bundleName + std::string result = ""; + params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result); + if (params.bundleName.empty()) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageBundleGroupInfoParameters failed, bundleName is empty."); + params.errorCode = ERR_USAGE_STATS_BUNDLENAME_EMPTY; + } + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + if ((valuetype != napi_string) && (params.errorCode == ERR_OK)) { + BUNDLE_ACTIVE_LOGE("Wrong argument type, string expected."); + params.errorCode = ERR_USAGE_STATS_BUNDLENAME_TYPE; + } + + // argv[1] : newGroup + if ((params.errorCode == ERR_OK) + && (BundleStateCommon::GetInt32NumberValue(env, argv[1], params.newGroup) == nullptr)) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageBundleGroupInfoParameters failed, beginTime type is invalid."); + params.errorCode = ERR_USAGE_STATS_GROUP_INVALID; + } + bool flag = false; + for (const auto& item : GROUP_TYPE) { + if (item == params.newGroup) + { + flag = true; + break; + } + } + if ((params.errorCode == ERR_OK) && !flag) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageBundleGroupInfoParameters failed, newGroup value is invalid."); + params.errorCode = ERR_USAGE_STATS_GROUP_INVALID; + } + + // argv[SECOND_ARG]: callback + if (argc == APP_USAGE_PARAMS_BUNDLE_GROUP) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[SECOND_ARG], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseAppUsageBundleGroupInfoParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[SECOND_ARG], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value SetBundleGroup(napi_env env, napi_callback_info info) +{ + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter napi,1--------------------"); + AppUsageParamsBundleGroupInfo params; + ParseAppUsageBundleGroupInfoParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncCallbackInfoAppUsageBundleGroup *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoAppUsageBundleGroup(env); + if (!asyncCallbackInfo) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + if (memset_s(asyncCallbackInfo, sizeof(AsyncCallbackInfoAppUsageBundleGroup), 0, sizeof(AsyncCallbackInfoAppUsageBundleGroup)) + != EOK) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->newGroup = params.newGroup; + callbackPtr->bundleName = params.bundleName; + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "SetBundleGroup", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoAppUsageBundleGroup *asyncCallbackInfo = (AsyncCallbackInfoAppUsageBundleGroup *)data; + if (asyncCallbackInfo) { + asyncCallbackInfo->state = BundleActiveClient::GetInstance().SetBundleGroup(asyncCallbackInfo->bundleName, + asyncCallbackInfo->newGroup, asyncCallbackInfo->errorCode); + } else { + BUNDLE_ACTIVE_LOGE("SetBundleGroup, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoAppUsageBundleGroup *asyncCallbackInfo = (AsyncCallbackInfoAppUsageBundleGroup *)data; + std::unique_ptr callbackPtr {asyncCallbackInfo}; + if (asyncCallbackInfo) { + napi_value result = nullptr; + napi_get_boolean(env, asyncCallbackInfo->state, &result); + BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result); + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork)); + NAPI_CALL(env, napi_queue_async_work(env, callbackPtr->asyncWork)); + callbackPtr.release(); if (callbackPtr->isCallback) { - callbackPtr.release(); return BundleStateCommon::NapiGetNull(env); } else { - callbackPtr.release(); return promise; } } + } // namespace DeviceUsageStats } // namespace OHOS diff --git a/init/device_usage_statistics_service.cfg b/init/device_usage_statistics_service.cfg index fe224844abef7213d1e3c861f79fc4e64892623f..193ac5da3de3bfd67ba68bfb10797288be375ad5 100644 --- a/init/device_usage_statistics_service.cfg +++ b/init/device_usage_statistics_service.cfg @@ -2,7 +2,6 @@ "jobs" : [{ "name" : "post-fs-data", "cmds" : [ - "mkdir /data/service/el1/public/bundle_usage 0711 device_usage_stats device_usage_stats", "start device_usage_stats_service" ] } @@ -10,10 +9,9 @@ "services" : [{ "name" : "device_usage_stats_service", "path" : ["/system/bin/sa_main", "/system/profile/device_usage_stats_service.xml"], - "uid" : "device_usage_stats", - "gid" : ["device_usage_stats", "shell"], - "secon" : "u:r:device_usage_stats_service:s0", - "apl" : "system_basic" + "uid" : "system", + "gid" : ["system", "shell"], + "secon" : "u:r:device_usage_stats_service:s0" } ] } \ No newline at end of file diff --git a/interfaces/innerkits/include/bundle_active_client.h b/interfaces/innerkits/include/bundle_active_client.h index 3e60e1c5a45a18df265baf8e351adb3bfdd48302..4bdbf2da9f8eef4da7bab26edd49b8ba6fa0edc5 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -19,7 +19,6 @@ #include "ibundle_active_service.h" #include "bundle_active_package_stats.h" #include "bundle_active_event.h" -#include "bundle_active_package_stats.h" #include "bundle_active_module_record.h" namespace OHOS { @@ -57,8 +56,9 @@ public: /* * function: SetBundleGroup, set specific bundle of specific user to a priority group. * parameters: bundleName, newGroup, userId + * return : void */ - void SetBundleGroup(std::string bundleName, const int32_t newGroup, const int32_t userId); + bool SetBundleGroup(std::string bundleName, const int32_t newGroup, int32_t& errCode, int32_t userId =-1); /* * function: QueryCurrentPackageStats, query bundle usage statistics in specific time span for calling bundle. * parameters: intervalType, beginTime, endTime @@ -74,9 +74,10 @@ public: std::vector QueryCurrentEvents(const int64_t beginTime, const int64_t endTime); /* * function: QueryPackageGroup, query bundle priority group calling bundle. + * parameters: bundleName,userId * return: the priority group of calling bundle. */ - int32_t QueryPackageGroup(); + int32_t QueryPackageGroup(const std::string& bundleName, const int32_t userId = -1); /* * function: QueryFormStatistics, query all from usage statistics in specific time span for calling user. * parameters: maxNum, results, userId, default userId is -1 for JS API, @@ -85,6 +86,18 @@ public: */ int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId = -1); /* + * function: observe bundle group change event + * parameters: observer + * return: errorcode. + */ + int32_t RegisterGroupCallBack(const sptr &observer); + /* + * function: unobserve bundle group change event + * parameters: observer + * return: errorcode. + */ + int32_t UnregisterGroupCallBack(const sptr &observer); + /* * function: GetInstance, get instance of client. * return: object of BundleActiveClient. */ diff --git a/interfaces/innerkits/include/bundle_active_group_callback_info.h b/interfaces/innerkits/include/bundle_active_group_callback_info.h new file mode 100644 index 0000000000000000000000000000000000000000..b774fcf624a3a3b1cfbf7c1457daafabd17b7d2a --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_info.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackInfo : public Parcelable { +public: + BundleActiveGroupCallbackInfo() {}; + BundleActiveGroupCallbackInfo(int32_t userId, int32_t oldGroup, int32_t newGroup, uint32_t changeReason, + std::string bundleName); + + /** + * @brief Get the user id. + * + * @return The id of user. + */ + int32_t GetUserId() const; + + /** + * @brief Get the old group. + * + * @return old group of app. + */ + int32_t GetOldGroup() const; + + /** + * @brief Get the new group. + * + * @return the new group of app. + */ + int32_t GetNewGroup() const; + + /** + * @brief Get the reason of change group. + * + * @return the reason of change group. + */ + uint32_t GetChangeReason() const; + + /** + * @brief Get the name of bundle. + * + * @return The name of bundle. + */ + std::string GetBundleName() const; + + /** + * @brief Marshals a purpose into a parcel. + * + * @param parcel Indicates the parcel object for marshalling. + * @return True if success, else false. + */ + bool Marshalling(Parcel &parcel) const; + static BundleActiveGroupCallbackInfo* Unmarshalling(Parcel &parcel); + +private: + bool ReadFromParcel(Parcel &parcel); + +private: + int32_t oldGroup_ {0}; + int32_t newGroup_ {0}; + int32_t userId_ {-1}; + uint32_t changeReason_ {0}; + std::string bundleName_ {""}; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H \ No newline at end of file diff --git a/interfaces/innerkits/include/bundle_active_group_callback_proxy.h b/interfaces/innerkits/include/bundle_active_group_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..e9b958b8288e5969246d1be6baeb106db50d83a3 --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_proxy.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H + +#include "iremote_proxy.h" +#include "ibundle_active_group_callback.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackProxy : public IRemoteProxy { +public: + BundleActiveGroupCallbackProxy() = delete; + explicit BundleActiveGroupCallbackProxy(const sptr& impl); + virtual ~BundleActiveGroupCallbackProxy() override; + // DISALLOW_COPY_AND_MOVE(BundleActiveGroupCallbackProxy); + + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo& continuousTaskCallbackInfo) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H \ No newline at end of file diff --git a/interfaces/innerkits/include/bundle_active_group_callback_stub.h b/interfaces/innerkits/include/bundle_active_group_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..988fed6deafd24a932730909d14e28a9dc6ead04 --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_stub.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H + +#include "iremote_stub.h" +#include "ibundle_active_group_callback.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackStub : public IRemoteStub { +public: + BundleActiveGroupCallbackStub()=default; + virtual ~BundleActiveGroupCallbackStub()=default; + + virtual int OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) override; + //BundleActiveGroupCallbackInfo curInfo_; +private: + static std::mutex callbackMutex_; + DISALLOW_COPY_AND_MOVE(BundleActiveGroupCallbackStub); +}; + +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H diff --git a/interfaces/innerkits/include/bundle_active_proxy.h b/interfaces/innerkits/include/bundle_active_proxy.h index 50db119b8562420253f222480a039971aa6cc1ff..ced023fa6adb8597039fdef661dd6de8b7de954c 100644 --- a/interfaces/innerkits/include/bundle_active_proxy.h +++ b/interfaces/innerkits/include/bundle_active_proxy.h @@ -19,8 +19,8 @@ #include "ibundle_active_service.h" #include "bundle_active_event.h" #include "bundle_active_package_stats.h" -#include "bundle_active_package_stats.h" #include "bundle_active_module_record.h" +#include "ibundle_active_group_callback.h" namespace OHOS { namespace DeviceUsageStats { @@ -56,7 +56,7 @@ public: * function: SetBundleGroup, set specific bundle of specific user to a priority group. * parameters: bundleName, newGroup, userId */ - void SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) override; + bool SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t& errCode, int32_t userId) override; /* * function: QueryCurrentPackageStats, query bundle usage statistics in specific time span for calling bundle. * parameters: intervalType, beginTime, endTime @@ -74,7 +74,7 @@ public: * function: QueryPackageGroup, query bundle priority group calling bundle. * return: the priority group of calling bundle. */ - int32_t QueryPackageGroup() override; + int32_t QueryPackageGroup(const std::string& bundleName, const int32_t userId) override; /* * function: QueryFormStatistics, query all from usage statistics in specific time span for calling user. * parameters: maxNum, results, userId, default userId is -1 for JS API, @@ -89,6 +89,9 @@ public: */ explicit BundleActiveProxy(const sptr& impl) : IRemoteProxy(impl) {} + + int32_t RegisterGroupCallBack(const sptr &observer) override; + int32_t UnregisterGroupCallBack(const sptr &observer) override; /* * function: ~BundleActiveProxy, default destructor. */ diff --git a/interfaces/innerkits/include/ibundle_active_group_callback.h b/interfaces/innerkits/include/ibundle_active_group_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..296ed9f619e2225361a3045ec7e7fc13eb947ca5 --- /dev/null +++ b/interfaces/innerkits/include/ibundle_active_group_callback.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IBUNDLE_ACTIVE_GROUP_CALLBACK +#define IBUNDLE_ACTIVE_GROUP_CALLBACK + +#include +#include +#include "iremote_object.h" + +#include "bundle_active_log.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +class IBundleActiveGroupCallback : public IRemoteBroker { +public: + + /** + * @brief Called back when a continuous task stop. + * + * @param continuousTaskCallbackInfo Continuous task app info. + */ + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) = 0; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveGroupCallback"); + +protected: + enum class message { + ON_BUNDLE_GROUP_CHANGED = 1 + }; +}; +} // namespace BackgroundTaskMgr +} // namespace OHOS +#endif // IBUNDLE_ACTIVE_GROUP_CALLBACK \ No newline at end of file diff --git a/interfaces/innerkits/src/bundle_active_client.cpp b/interfaces/innerkits/src/bundle_active_client.cpp index ae9f26322e15ab40394d62a5db1d5eed1c763af5..499d74e6900051e9acf955a1e59e41078673f1b5 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -85,13 +85,12 @@ std::vector BundleActiveClient::QueryEvents(const int64_t beg return bundleActiveProxy_->QueryEvents(beginTime, endTime, errCode, userId); } -void BundleActiveClient::SetBundleGroup(std::string bundleName, const int32_t newGroup, const int32_t userId) +bool BundleActiveClient::SetBundleGroup(std::string bundleName, const int32_t newGroup, int32_t& errCode, int32_t userId) { if (!GetBundleActiveProxy()) { - return; + return false; } - bundleActiveProxy_->SetBundleGroup(bundleName, newGroup, userId); - return; + return bundleActiveProxy_->SetBundleGroup(bundleName, newGroup, errCode, userId); } std::vector BundleActiveClient::QueryCurrentPackageStats(const int32_t intervalType, @@ -111,12 +110,12 @@ std::vector BundleActiveClient::QueryCurrentEvents(const int6 return bundleActiveProxy_->QueryCurrentEvents(beginTime, endTime); } -int32_t BundleActiveClient::QueryPackageGroup() +int32_t BundleActiveClient::QueryPackageGroup(const std::string& bundleName, const int32_t userId) { if (!GetBundleActiveProxy()) { return -1; } - return bundleActiveProxy_->QueryPackageGroup(); + return bundleActiveProxy_->QueryPackageGroup(bundleName, userId); } int32_t BundleActiveClient::QueryFormStatistics(int32_t maxNum, std::vector& results, @@ -132,6 +131,24 @@ int32_t BundleActiveClient::QueryFormStatistics(int32_t maxNum, std::vectorQueryFormStatistics(maxNum, results, userId); } +int32_t BundleActiveClient::RegisterGroupCallBack(const sptr &observer) +{ + if(!GetBundleActiveProxy()){ + BUNDLE_ACTIVE_LOGE("GetBackgroundTaskManagerProxy failed."); + return false; + } + return bundleActiveProxy_->RegisterGroupCallBack(observer); +} + +int32_t BundleActiveClient::UnregisterGroupCallBack(const sptr &observer) +{ + if(!GetBundleActiveProxy()){ + BUNDLE_ACTIVE_LOGE("GetBackgroundTaskManagerProxy failed."); + return false; + } + return bundleActiveProxy_->UnregisterGroupCallBack(observer); +} + int32_t BundleActiveClient::ShellDump(const std::vector &dumpOption, std::vector &dumpInfo) { int32_t ret = -1; diff --git a/interfaces/innerkits/src/bundle_active_group_callback_info.cpp b/interfaces/innerkits/src/bundle_active_group_callback_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e21f4cc7927ede524a1511311f4e8f72f9e9cb8 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_info.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bundle_active_log.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveGroupCallbackInfo::BundleActiveGroupCallbackInfo(int32_t userId, int32_t oldGroup, int32_t newGroup, + uint32_t changeReason, std::string bundleName) +{ + userId_ = userId; + oldGroup_ = oldGroup; + newGroup_ = newGroup; + changeReason_ = changeReason; + bundleName_ = bundleName; +} + +int32_t BundleActiveGroupCallbackInfo::GetUserId() const +{ + return userId_; +} + +int32_t BundleActiveGroupCallbackInfo::GetOldGroup() const +{ + return oldGroup_; +} + +int32_t BundleActiveGroupCallbackInfo::GetNewGroup() const +{ + return newGroup_; +} + +uint32_t BundleActiveGroupCallbackInfo::GetChangeReason() const +{ + return changeReason_; +} + +std::string BundleActiveGroupCallbackInfo::GetBundleName() const +{ + return bundleName_; +} + +bool BundleActiveGroupCallbackInfo::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteInt32(userId_)) { + BUNDLE_ACTIVE_LOGE("Failed to write userId_"); + return false; + } + + if (!parcel.WriteInt32(oldGroup_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator oldGroup_"); + return false; + } + + if (!parcel.WriteInt32(newGroup_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator newGroup_"); + return false; + } + + if (!parcel.WriteUint32(changeReason_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator changeReason_"); + return false; + } + + if (!parcel.WriteString(bundleName_)) { + BUNDLE_ACTIVE_LOGE("Failed to write bundleName_"); + return false; + } + return true; +} + +BundleActiveGroupCallbackInfo* BundleActiveGroupCallbackInfo::Unmarshalling(Parcel &parcel) +{ + BundleActiveGroupCallbackInfo* result = new (std::nothrow) BundleActiveGroupCallbackInfo(); + result->userId_ = parcel.ReadInt32(); + result->oldGroup_ = parcel.ReadInt32(); + result->newGroup_ = parcel.ReadInt32(); + result->changeReason_ = parcel.ReadUint32(); + result->bundleName_ = parcel.ReadString(); + return result; +} +} +} + diff --git a/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp b/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e49c3a21090ef7667a91334b12936001ff67bce9 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include "errors.h" +#include "bundle_active_log.h" +#include "bundle_active_group_callback_proxy.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveGroupCallbackProxy::BundleActiveGroupCallbackProxy(const sptr& impl) + : IRemoteProxy(impl) {} +BundleActiveGroupCallbackProxy::~BundleActiveGroupCallbackProxy() {} + +void BundleActiveGroupCallbackProxy::OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack remote is dead."); + return; + } + MessageParcel data; + if (!data.WriteInterfaceToken(BundleActiveGroupCallbackProxy::GetDescriptor())) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack write interface token failed."); + return; + } + if (!data.WriteParcelable(&bundleActiveGroupCallbackInfo)) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack write parcel failed."); + return; + } + MessageParcel reply; + MessageOption option = {MessageOption::TF_ASYNC}; + int32_t ret = remote->SendRequest(static_cast(IBundleActiveGroupCallback::message::ON_BUNDLE_GROUP_CHANGED), data, reply, option); + if (ret!= ERR_OK) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack SendRequest failed, error code: %{public}d", ret); + } +} +} // namespace BackgroundTaskMgr +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/src/bundle_active_group_callback_stub.cpp b/interfaces/innerkits/src/bundle_active_group_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b6346f93b23cbf82f88479cb8f882b6fb6bf085c --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_stub.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bundle_active_group_callback_stub.h" + +namespace OHOS { +namespace DeviceUsageStats { +std::mutex BundleActiveGroupCallbackStub::callbackMutex_; +int32_t BundleActiveGroupCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) +{ + std::u16string descriptor = BundleActiveGroupCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack BundleActiveGroupCallbackStub::OnRemoteRequest cannot get power mgr service"); + return -1; + } + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack BundleActiveGroupCallbackStub will switch"); + switch (code) { + case static_cast(IBundleActiveGroupCallback::message::ON_BUNDLE_GROUP_CHANGED): { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack BundleActiveGroupCallbackStub::OnRemoteRequest is nowing ON_BUNDLE_GROUP_CHANGED"); + BundleActiveGroupCallbackInfo* groupInfo = nullptr; + std::unique_lock lock(callbackMutex_); + groupInfo = data.ReadParcelable(); + if (!groupInfo) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack ReadParcelable failed"); + return -1; + } + OnBundleGroupChanged(*groupInfo); + delete groupInfo; + break; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return 0; +} + +void BundleActiveGroupCallbackStub::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) +{ +} + +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/interfaces/innerkits/src/bundle_active_proxy.cpp b/interfaces/innerkits/src/bundle_active_proxy.cpp index 43cfd63e8681295e3d7a08d577c8521bcda09e03..f30c4a897c2719e0a66acffb12de99f5472cdee9 100644 --- a/interfaces/innerkits/src/bundle_active_proxy.cpp +++ b/interfaces/innerkits/src/bundle_active_proxy.cpp @@ -116,18 +116,22 @@ std::vector BundleActiveProxy::QueryEvents(const int64_t begi return result; } -void BundleActiveProxy::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) +bool BundleActiveProxy::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t& errCode, int32_t userId) { + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter bundleActiveProxy,3--------------------"); MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - return; + return false; } data.WriteString(bundleName); data.WriteInt32(newGroup); + data.WriteInt32(errCode); data.WriteInt32(userId); + Remote() -> SendRequest(SET_BUNDLE_GROUP, data, reply, option); + return reply.ReadInt32(); } std::vector BundleActiveProxy::QueryCurrentPackageStats(const int32_t intervalType, @@ -193,18 +197,20 @@ std::vector BundleActiveProxy::QueryCurrentEvents(const int64 return result; } -int32_t BundleActiveProxy::QueryPackageGroup() +int32_t BundleActiveProxy::QueryPackageGroup(const std::string& bundleName, const int32_t userId) { MessageParcel data; MessageParcel reply; MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { return -1; } + data.WriteString(bundleName); + data.WriteInt32(userId); Remote() -> SendRequest(QUERY_BUNDLE_GROUP, data, reply, option); - int32_t packageGroup = reply.ReadInt32(); - BUNDLE_ACTIVE_LOGI("QueryPackageGroup result is %{public}d", packageGroup); - return packageGroup; + + return reply.ReadInt32(); } int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector& results, @@ -242,6 +248,53 @@ int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector &observer) +{ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter proxy---------------------"); + if (!observer) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack observer null"); + return false; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack WriteInterfaceToken fail"); + return false; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack observer write failed."); + return false; + } + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack proxy is ok"); + int32_t ret = Remote()->SendRequest(REGISTER_GROUP_CALLBACK, data, reply, option); + if (ret!= ERR_OK) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack SendRequest failed, error code: %{public}d", ret); + } + return true; +} + +int32_t BundleActiveProxy::UnregisterGroupCallBack(const sptr &observer) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGE("observer null"); + return false; + } + BUNDLE_ACTIVE_LOGI("unRegisterApplicationStateObserver start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return false; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("observer write failed."); + return false; + } + Remote()->SendRequest(UNREGISTER_GROUP_CALLBACK, data, reply, option); + return true; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts b/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts index 100791b48bf5abf63c747a480b2f3a3fbbeb150b..7fde404357ece13f259eda23fbc370b8ef936b3d 100644 --- a/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts +++ b/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { AsyncCallback } from './basic'; +import { AsyncCallback , Callback} from './basic'; /** * Provides methods for managing bundle usage statistics, @@ -204,6 +204,32 @@ declare namespace bundleState { */ stateType?: number; } + /** + * @since 7 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + */ + interface BundleActiveGroupCallbackInfo{ + /* + * the usage old group of the application + */ + appUsageOldGroup?: number; + /* + * the usage new group of the application + */ + appUsageNewGroup?: number; + /* + * the use id + */ + useId?: number; + /* + * the change reason + */ + changeReason?: number; + /* + * the bundle name + */ + bundleName?: string; + } /** * Checks whether the application with a specified bundle name is in the idle state. @@ -228,9 +254,8 @@ declare namespace bundleState { * @syscap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup * @return Returns the usage priority group of the calling application. */ - function queryAppUsagePriorityGroup(callback: AsyncCallback): void; - function queryAppUsagePriorityGroup(): Promise; - + function queryAppUsagePriorityGroup(bundleName: string, callback: AsyncCallback): void; + function queryAppUsagePriorityGroup(bundleName: string): Promise; /** * @since 7 * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App @@ -343,6 +368,15 @@ declare namespace bundleState { */ function getRecentlyUsedModules(maxNum?: number, callback: AsyncCallback>): void; function getRecentlyUsedModules(maxNum?: number): Promise>; + + function setBundleGroup(bundleName: string, newGroup: number, callback: AsyncCallback): void; + function setBundleGroup(bundleName: string, newGroup: number): Promise; + + function registerGroupCallBack(callback: Callback, callback: AsyncCallback): void; + function registerGroupCallBack(callback: Callback): Promise; + + function unRegisterGroupCallBack(callback: AsyncCallback): void; + function unRegisterGroupCallBack(): Promise; } export default bundleState; diff --git a/interfaces/kits/bundlestats/napi/include/bundle_active_group_observer.h b/interfaces/kits/bundlestats/napi/include/bundle_active_group_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..3bd0df06c5e186dd73b813bfaa10e98988cf80c4 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_active_group_observer.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_ACTIVE_GROUP_OBSERVER_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_ACTIVE_GROUP_OBSERVER_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "bundle_active_group_callback_stub.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +static const int8_t NO_ERROR = 0; + +class BundleActiveGroupObserver : public BundleActiveGroupCallbackStub { +public: + BundleActiveGroupObserver() =default; + + ~BundleActiveGroupObserver(); + + virtual void OnBundleGroupChanged(const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) override; + + void SetCallbackInfo(const napi_env &env, const napi_ref &ref); + +private: + struct BundleGroupCallbackInfo { + napi_env env = nullptr; + napi_ref ref = nullptr; + }; + BundleGroupCallbackInfo bundleGroupCallbackInfo_; +}; + +struct BundleActiveGroupObserverInfo { + napi_ref ref = nullptr; + sptr callback = nullptr; +}; + +static std::map> observerIds_; +static int64_t serialNumber_ = 0; + +napi_value RegisterGroupCallBack(napi_env env, napi_callback_info info); +napi_value UnRegisterGroupCallBack(napi_env env, napi_callback_info info); + + +} // namespace DeviceUsageStats +} // namespace OHOS + +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_ACTIVE_GROUP_OBSERVER_H \ No newline at end of file diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_data.h b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h index b27b51d8a639e7ccc8e6501b1caca69cced3f1f1..2b8ef49222be9ca81f0215151cf176ed44c646a1 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_data.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h @@ -24,6 +24,7 @@ #include "bundle_active_event.h" #include "bundle_active_package_stats.h" +#include "bundle_active_group_observer.h" namespace OHOS { namespace DeviceUsageStats { @@ -42,6 +43,8 @@ namespace DeviceUsageStats { #define INTERVAL_NUMBER_MIN 0 #define INTERVAL_NUMBER_MAX 4 #define TIME_NUMBER_MIN 0 +#define GROUP_NUMBER_MIN 5 +#define GROUP_NUMBER_MAX 50 struct AsyncWorkData { explicit AsyncWorkData(napi_env napiEnv); @@ -54,83 +57,137 @@ struct AsyncWorkData { int32_t errorCode = 0; }; +struct CallbackReceiveDataWorker { + napi_env env = nullptr; + napi_ref ref = nullptr; + int oldGroup=0; + int newGroup=0; + int userId=-1; + int changeReason=0; + std::string bundleName; +}; + struct AsyncCallbackInfoIsIdleState : public AsyncWorkData { explicit AsyncCallbackInfoIsIdleState(napi_env env) : AsyncWorkData(env) {} - std::string bundleName = ""; - bool state = true; + std::string bundleName; + bool state; }; struct AsyncCallbackInfoPriorityGroup : public AsyncWorkData { explicit AsyncCallbackInfoPriorityGroup(napi_env env) : AsyncWorkData(env) {} - int32_t priorityGroup = 60; + std::string bundleName; + int32_t priorityGroup; }; struct AsyncCallbackInfoStates : public AsyncWorkData { explicit AsyncCallbackInfoStates(napi_env env) : AsyncWorkData(env) {} - int64_t beginTime = -1; - int64_t endTime = -1; + int64_t beginTime; + int64_t endTime; std::vector BundleActiveState; }; struct AsyncCallbackInfoAppUsageByInterval : public AsyncWorkData { explicit AsyncCallbackInfoAppUsageByInterval(napi_env env) : AsyncWorkData(env) {} - int32_t intervalType = -1; - int64_t beginTime = -1; - int64_t endTime = -1; + int32_t intervalType; + int64_t beginTime; + int64_t endTime; std::vector packageStats; }; struct AsyncCallbackInfoAppUsage : public AsyncWorkData { explicit AsyncCallbackInfoAppUsage(napi_env env) : AsyncWorkData(env) {} - int64_t beginTime = -1; - int64_t endTime = -1; + int64_t beginTime; + int64_t endTime; std::shared_ptr> packageStats; }; +struct AsyncCallbackInfoAppUsageBundleGroup : public AsyncWorkData +{ + explicit AsyncCallbackInfoAppUsageBundleGroup(napi_env env):AsyncWorkData(env){} + int32_t newGroup; + std::string bundleName; + int32_t errorCode; + bool state; +}; + struct AsyncCallbackInfoModuleRecord : public AsyncWorkData { explicit AsyncCallbackInfoModuleRecord(napi_env env) : AsyncWorkData(env) {} - int32_t maxNum = -1; + int32_t maxNum; std::vector moduleRecords; }; +struct AsyncCallbackInfoUnRegisterCallbackInfo : public AsyncWorkData { + explicit AsyncCallbackInfoUnRegisterCallbackInfo(napi_env env) : AsyncWorkData(env) {} + sptr observer; + bool state; +}; + +struct AsyncCallbackInfoRegisterCallbackInfo : public AsyncWorkData { + explicit AsyncCallbackInfoRegisterCallbackInfo(napi_env env) : AsyncWorkData(env) {} + sptr observer; + bool state; +}; + struct IsIdleStateParamsInfo { - std::string bundleName = ""; + std::string bundleName; napi_ref callback = nullptr; int32_t errorCode = 0; }; struct PriorityGroupParamsInfo { + std::string bundleName; napi_ref callback = nullptr; int32_t errorCode = 0; }; struct StatesParamsInfo { - int64_t beginTime = -1; - int64_t endTime = -1; + int64_t beginTime; + int64_t endTime; napi_ref callback = nullptr; int32_t errorCode = 0; }; struct AppUsageParamsByIntervalInfo { - int32_t intervalType = -1; - int64_t beginTime = -1; - int64_t endTime = -1; + int32_t intervalType; + int64_t beginTime; + int64_t endTime; napi_ref callback = nullptr; int32_t errorCode = 0; }; struct AppUsageParamsInfo { - int64_t beginTime = -1; - int64_t endTime = -1; + int64_t beginTime; + int64_t endTime; napi_ref callback = nullptr; int32_t errorCode = 0; }; struct ModuleRecordParamsInfo { - int32_t maxNum = -1; + int32_t maxNum; + napi_ref callback = nullptr; + int32_t errorCode = 0; +}; + +struct AppUsageParamsBundleGroupInfo +{ + std::string bundleName; + int32_t newGroup; + napi_ref callback = nullptr; + int32_t errorCode = 0; +}; + +struct RegisterCallbackInfo +{ napi_ref callback = nullptr; int32_t errorCode = 0; }; + +struct UnRegisterCallbackInfo +{ + napi_ref callback = nullptr; + int32_t errorCode = 0; +}; + } // namespace DeviceUsageStats } // namespace OHOS #endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_DATA_H diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h b/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h index 3576ab1afd0f8e4c371058740de79e2157ce5509..680b889b0fbd6ca197ede0fd6f0d118e9b4fc3d0 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h @@ -49,6 +49,7 @@ enum : int32_t { ERR_USAGE_STATS_TIME_INTERVAL, ERR_USAGE_STATS_INTERVAL_TYPE, ERR_USAGE_STATS_INTERVAL_NUMBER, + ERR_USAGE_STATS_GROUP_INVALID, ERR_MODULE_STATS_MAXNUM_INVALID, }; } // namespace DeviceUsageStats diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_query.h b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h index 0a0492aaa541cfe9d4e674c5668a6ad8513e28e5..594d9530204e1a84e409da3959e33c29df70a07b 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_query.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h @@ -28,6 +28,7 @@ namespace DeviceUsageStats { napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info); napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info); napi_value GetModuleUsageRecord(napi_env env, napi_callback_info info); + napi_value SetBundleGroup(napi_env env, napi_callback_info info); } // namespace DeviceUsageStats } // namespace OHOS #endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_QUERY_H diff --git a/interfaces/test/unittest/device_usage_statistics_jsunittest/device_usage_statistics_jsunit.test.js b/interfaces/test/unittest/device_usage_statistics_jsunittest/device_usage_statistics_jsunit.test.js index cf5f74292cbc653ef4058119827971a6a130a465..145c59efca036567da460c8c31da4bd961059768 100644 --- a/interfaces/test/unittest/device_usage_statistics_jsunittest/device_usage_statistics_jsunit.test.js +++ b/interfaces/test/unittest/device_usage_statistics_jsunittest/device_usage_statistics_jsunit.test.js @@ -100,7 +100,9 @@ describe("DeviceUsageStatisticsJsTest", function () { */ it("DeviceUsageStatisticsJsTest003", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest003---------------------------'); - bundleState.queryAppUsagePriorityGroup().then( res => { + let bundleName = 'com.example.deviceUsageStatistics'; + let userId = 10; + bundleState.queryAppUsagePriorityGroup(bundleName, userId).then( res => { console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise success.'); expect(true).assertEqual(true); }).catch( err => { @@ -121,7 +123,9 @@ describe("DeviceUsageStatisticsJsTest", function () { */ it("DeviceUsageStatisticsJsTest004", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest004---------------------------'); - bundleState.queryAppUsagePriorityGroup((err, res) => { + let bundleName = 'com.example.deviceUsageStatistics'; + let userId = 10; + bundleState.queryAppUsagePriorityGroup(bundleName, userId, (err, res) => { if (err) { console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failure.'); expect(false).assertEqual(true); @@ -375,5 +379,64 @@ describe("DeviceUsageStatisticsJsTest", function () { done(); }, 500); }) + + it("DeviceUsageStatisticsJsTest015", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest015---------------------------'); + let bundleName = 'com.example.deviceUsageStatistics'; + let newGroup = 10; + bundleState.setBundleGroup(bundleName, newGroup, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE setBundleGroup callback failure.'); + expect(false).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE setBundleGroup callback success.'); + expect(true).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + // it("DeviceUsageStatisticsJsTest016", 0, async function (done) { + // console.info('----------------------DeviceUsageStatisticsJsTest016---------------------------'); + // let bundleName = 'com.example.deviceUsageStatistics'; + // let newGroup = 20; + // bundleState.registerGroupCallBack().then((res) => { + // console.info('BUNDLE_ACTIVE registerGroupCallBack promise success.'); + // expect(true).assertEqual(true); + // }).catch((err) => { + // console.info('BUNDLE_ACTIVE registerGroupCallBack promise failure.'); + // expect(false).assertEqual(true); + // }); + + // setTimeout(()=>{ + // done(); + // }, 500); + // }) + /* + * @tc.name: DeviceUsageStatisticsJsTest015 + * @tc.desc: test getRecentlyUsedModules promise. + * @tc.type: FUNC + * @tc.require: SR000GU2UE AR0003GU3EQ + */ + + it("DeviceUsageStatisticsJsTest016", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest017---------------------------'); + bundleState.registerGroupCallBack((err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback failure.'); + expect(false).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback success.'); + expect(true).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) }) diff --git a/services/common/include/bundle_active_constant.h b/services/common/include/bundle_active_constant.h index 82bf37e637b0716c61507e2978d5664c2ad387d3..e20b850c7dc002c4d37d6f91fcad0ac0c537ba1e 100644 --- a/services/common/include/bundle_active_constant.h +++ b/services/common/include/bundle_active_constant.h @@ -121,7 +121,7 @@ const std::string BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME = "bundleDailyTimeo const std::string BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION = "bootBasedDuration"; const std::string BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION = "screenOnDuration"; const std::string REFRESH_DATABASE_RUNNER_NAME = "RefreshDatabase"; -const std::string BUNDLE_ACTIVE_DATABASE_DIR = "/data/service/el1/public/bundle_usage/"; +const std::string BUNDLE_ACTIVE_DATABASE_DIR = "/data/system_ce/bundle_usage/"; const std::string BUNDLE_ACTIVE_VERSION_FILE = "/version"; const std::string DATABASE_FILE_TABLE_NAME = "table"; const std::string SQLITE_MASTER_NAME = "name"; diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h index 3c861ce114a3dc465d943d84b8c1a01a188a2cd9..285847fafa97589d246b04531b6b0f190f07753b 100644 --- a/services/common/include/bundle_active_core.h +++ b/services/common/include/bundle_active_core.h @@ -19,10 +19,13 @@ #include #include "power_mgr_client.h" +#include "accesstoken_kit.h" #ifdef OS_ACCOUNT_PART_ENABLED #include "os_account_manager.h" #endif // OS_ACCOUNT_PART_ENABLED #include "ibundle_active_service.h" +#include "remote_deatch_recipient.h" +#include "ibundle_active_group_callback.h" #include "bundle_active_debug_mode.h" #include "bundle_active_stats_update_listener.h" #include "bundle_active_user_service.h" @@ -33,6 +36,8 @@ namespace OHOS { namespace DeviceUsageStats { +using namespace OHOS::Security; + class BundleActiveReportHandlerObject { public: BundleActiveEvent event_; @@ -46,7 +51,7 @@ public: class BundleActiveReportHandler; -class BundleActiveCore : public BundleActiveStatsUpdateListener { +class BundleActiveCore : public BundleActiveStatsUpdateListener, public std::enable_shared_from_this { public: BundleActiveCore(); virtual ~BundleActiveCore(); @@ -124,7 +129,7 @@ public: // check the app idle state for calling user. int32_t IsBundleIdle(const std::string& bundleName, const int32_t userId); // query the app group for calling app. - int32_t QueryPackageGroup(const int32_t userId, const std::string bundleName); + int32_t QueryPackageGroup(const std::string bundleName, const int32_t userId); int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId); // get the wall time and check if the wall time is changed. int64_t CheckTimeChangeAndGetWallTime(int32_t userId = 0); @@ -138,16 +143,23 @@ public: // when user switched, restore old userdata. void OnUserSwitched(const int32_t userId); // force set app group. - void SetBundleGroup(const std::string& bundleName, const int32_t newGroup, const int32_t userId); + int32_t SetBundleGroup(const std::string& bundleName, const int32_t newGroup, const int32_t userId); // get all user in device. void GetAllActiveUser(std::vector& activatedOsAccountIds); // when service stop, call it to unregister commen event and shutdown call back. void UnRegisterSubscriber(); // get system time in MS. int64_t GetSystemTimeMs(); + int32_t RegisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, const sptr &observer); + int32_t UnregisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, const sptr &observer); int32_t currentUsedUser_; + void OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo); private: + void AddObserverDeathRecipient(const sptr &observer); + void RemoveObserverDeathRecipient(const sptr &observer); + void OnObserverDied(const wptr &remote); + void OnObserverDiedInner(const wptr &remote); int64_t flushInterval_; static const int64_t TIME_CHANGE_THRESHOLD_MILLIS = TWO_SECONDS; const int32_t DEFAULT_USER_ID = -1; @@ -159,10 +171,14 @@ private: int64_t systemTimeShot_; int64_t realTimeShot_; std::mutex mutex_; + std::mutex callbackMutex_; + std::mutex deathRecipientMutex_; std::map> userStatServices_; void RegisterSubscriber(); std::shared_ptr commonEventSubscriber_; void RestoreAllData(); + std::map> groupChangeObservers_; + std::map, sptr> recipientMap_; bool debugCore_; }; } // namespace DeviceUsageStats diff --git a/services/common/include/bundle_active_log.h b/services/common/include/bundle_active_log.h index 0dae499429053ba09c28100bea212a8274618293..4a19c08592af596d305605ac35ac9967c0baad71 100644 --- a/services/common/include/bundle_active_log.h +++ b/services/common/include/bundle_active_log.h @@ -60,7 +60,7 @@ private: static BundleActiveLogLevel logLevel_; }; -#define PRINT_LOG(LEVEL, Level, fmt, ...) \ +#define BUNDLE_ACTIVE_PRINT_LOG(LEVEL, Level, fmt, ...) \ if (BundleActiveLog::JudgeValidLevel(BundleActiveLogLevel::LEVEL)) \ OHOS::HiviewDFX::HiLog::Level(BUNDLE_ACTIVE_LOG_LABEL, \ "[%{public}s(%{public}s):%{public}d] " fmt, \ @@ -69,11 +69,11 @@ private: __LINE__, \ ##__VA_ARGS__) -#define BUNDLE_ACTIVE_LOGD(fmt, ...) PRINT_LOG(DEBUG, Debug, fmt, ##__VA_ARGS__) -#define BUNDLE_ACTIVE_LOGI(fmt, ...) PRINT_LOG(INFO, Info, fmt, ##__VA_ARGS__) -#define BUNDLE_ACTIVE_LOGW(fmt, ...) PRINT_LOG(WARN, Warn, fmt, ##__VA_ARGS__) -#define BUNDLE_ACTIVE_LOGE(fmt, ...) PRINT_LOG(ERROR, Error, fmt, ##__VA_ARGS__) -#define BUNDLE_ACTIVE_LOGF(fmt, ...) PRINT_LOG(FATAL, Fatal, fmt, ##__VA_ARGS__) +#define BUNDLE_ACTIVE_LOGD(fmt, ...) BUNDLE_ACTIVE_PRINT_LOG(DEBUG, Debug, fmt, ##__VA_ARGS__) +#define BUNDLE_ACTIVE_LOGI(fmt, ...) BUNDLE_ACTIVE_PRINT_LOG(INFO, Info, fmt, ##__VA_ARGS__) +#define BUNDLE_ACTIVE_LOGW(fmt, ...) BUNDLE_ACTIVE_PRINT_LOG(WARN, Warn, fmt, ##__VA_ARGS__) +#define BUNDLE_ACTIVE_LOGE(fmt, ...) BUNDLE_ACTIVE_PRINT_LOG(ERROR, Error, fmt, ##__VA_ARGS__) +#define BUNDLE_ACTIVE_LOGF(fmt, ...) BUNDLE_ACTIVE_PRINT_LOG(FATAL, Fatal, fmt, ##__VA_ARGS__) } // namespace DeviceUsageStats } // namespace OHOS #endif // BUNDLE_ACTIVE_LOG_H diff --git a/services/common/include/bundle_active_service.h b/services/common/include/bundle_active_service.h index e8921a47ed0ed02e28fe2e4b927f54cd366407a9..e60efb3b70a68c80d34c72d7129efcfd14f332e1 100644 --- a/services/common/include/bundle_active_service.h +++ b/services/common/include/bundle_active_service.h @@ -75,7 +75,7 @@ public: * function: SetBundleGroup, set specific bundle of specific user to a priority group. * parameters: bundleName, newGroup, userId */ - void SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) override; + bool SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t& errCode, int32_t userId) override; /* * function: QueryCurrentPackageStats, query bundle usage statistics in specific time span for calling bundle. * parameters: intervalType, beginTime, endTime @@ -93,7 +93,7 @@ public: * function: QueryPackageGroup, query bundle priority group calling bundle. * return: the priority group of calling bundle. */ - int32_t QueryPackageGroup() override; + int32_t QueryPackageGroup(const std::string& bundleName, int32_t userId) override; /* * function: QueryFormStatistics, query all from usage statistics in specific time span for calling user. * parameters: maxNum, results, userId, default userId is -1 for JS API, @@ -107,13 +107,11 @@ public: * parameters: systemAbilityId, runOnCreate */ BundleActiveService(const int32_t systemAbilityId, bool runOnCreate); - /** - * @brief The OnStart callback. - */ + int32_t RegisterGroupCallBack(const sptr &observer) override; + int32_t UnregisterGroupCallBack(const sptr &observer) override; + +protected: void OnStart() override; - /** - * @brief The OnStop callback. - */ void OnStop() override; private: @@ -125,7 +123,6 @@ private: sptr shutdownCallback_; std::shared_ptr runner_; std::shared_ptr handler_; - bool ready_ {false}; int32_t ConvertIntervalType(const int32_t intervalType); void InitNecessaryState(); void InitService(); diff --git a/services/common/include/ibundle_active_service.h b/services/common/include/ibundle_active_service.h index 63d332c2bac2a7d65d779fb9dccf9ecdce54b91f..ddc41779fb33f6d5b36932b59532bd46a7484980 100644 --- a/services/common/include/ibundle_active_service.h +++ b/services/common/include/ibundle_active_service.h @@ -33,6 +33,8 @@ #include "system_ability_definition.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" +#include "ibundle_active_group_callback.h" +#include "bundle_active_group_callback_proxy.h" #include "bundle_active_log.h" @@ -90,12 +92,12 @@ public: * function: QueryPackageGroup, query bundle priority group calling bundle. * return: the priority group of calling bundle. */ - virtual int32_t QueryPackageGroup() = 0; + virtual int32_t QueryPackageGroup(const std::string& bundleName,int32_t userId) = 0; /* * function: SetBundleGroup, set specific bundle of specific user to a priority group. * parameters: bundleName, newGroup, userId */ - virtual void SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) = 0; + virtual bool SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t& errCode, int32_t userId) = 0; /* * function: QueryFormStatistics, query all from usage statistics in specific time span for calling user. * parameters: maxNum, results, userId, default userId is -1 for JS API, @@ -105,6 +107,9 @@ public: virtual int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId) = 0; + virtual int32_t RegisterGroupCallBack(const sptr &observer) = 0; + virtual int32_t UnregisterGroupCallBack(const sptr &observer) = 0; + public: enum { REPORT_EVENT = 1, @@ -115,7 +120,9 @@ public: QUERY_CURRENT_EVENTS = 6, QUERY_BUNDLE_GROUP = 7, SET_BUNDLE_GROUP = 8, - QUERY_FORM_STATS = 9 + QUERY_FORM_STATS = 9, + REGISTER_GROUP_CALLBACK = 10, + UNREGISTER_GROUP_CALLBACK = 11 }; public: DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveService"); diff --git a/services/common/include/remote_deatch_recipient.h b/services/common/include/remote_deatch_recipient.h new file mode 100644 index 0000000000000000000000000000000000000000..3398e220ba9b0a5cd1eb605c010fd9dfc9c33f7f --- /dev/null +++ b/services/common/include/remote_deatch_recipient.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef REMOTE_DEATH_RECIPIENT_H +#define REMOTE_DEATH_RECIPIENT_H + +#include + +#include "iremote_object.h" + +namespace OHOS { +namespace DeviceUsageStats { +class RemoteDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit RemoteDeathRecipient(std::function &)> callback) + { + callback_ = callback; + } + + ~RemoteDeathRecipient() + { + callback_ = nullptr; + } + + void OnRemoteDied(const wptr &object) + { + if (callback_ != nullptr) { + callback_(object); + } + } + +private: + std::function &)> callback_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // REMOTE_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp index 15dcdc5e2513361564e75f65eea31a54b1e2f95a..aa822d24929bb609b3feb08b381721ac6ca23da4 100644 --- a/services/common/src/bundle_active_core.cpp +++ b/services/common/src/bundle_active_core.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ #include "bundle_active_core.h" - +#include "accesstoken_kit.h" #include "time_service_client.h" #include "bundle_active_event.h" @@ -164,7 +164,7 @@ void BundleActiveCore::InitBundleGroupController() } if (bundleGroupController_ != nullptr && bundleGroupHandler_ != nullptr) { bundleGroupHandler_->Init(bundleGroupController_); - bundleGroupController_->SetHandlerAndCreateUserHistory(bundleGroupHandler_, realTimeShot_); + bundleGroupController_->SetHandlerAndCreateUserHistory(bundleGroupHandler_, realTimeShot_, shared_from_this()); BUNDLE_ACTIVE_LOGI("Init Set group controller and handler done"); } else { return; @@ -543,17 +543,17 @@ int32_t BundleActiveCore::QueryFormStatistics(int32_t maxNum, std::vector timer = MiscServices::TimeServiceClient::GetInstance(); int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); - bundleGroupController_->SetBundleGroup(bundleName, userId, newGroup, newReason, bootBasedTimeStamp, false); + return bundleGroupController_->SetBundleGroup(bundleName, userId, newGroup, newReason, bootBasedTimeStamp, false); } -int32_t BundleActiveCore::QueryPackageGroup(const int32_t userId, const std::string bundleName) +int32_t BundleActiveCore::QueryPackageGroup(const std::string bundleName, const int32_t userId) { - return bundleGroupController_->QueryPackageGroup(userId, bundleName); + return bundleGroupController_->QueryPackageGroup(bundleName, userId); } int32_t BundleActiveCore::IsBundleIdle(const std::string& bundleName, const int32_t userId) @@ -596,6 +596,116 @@ int64_t BundleActiveCore::GetSystemTimeMs() } return static_cast(tarDate); } + +void BundleActiveCore::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo) +{ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter OnBundleGroupChanged!,groupChangeObservers_ number is %{public}d ",groupChangeObservers_.size()); + std::lock_guard lock(callbackMutex_); + for (const auto &item : groupChangeObservers_) { + auto observer = item.second; + if (observer) { + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack will OnBundleGroupChanged!,oldGroup is %{public}d ",callbackInfo.GetOldGroup()); + observer->OnBundleGroupChanged(callbackInfo); + } + } +} + +int32_t BundleActiveCore::RegisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, const sptr &observer) +{ + std::lock_guard lock(callbackMutex_); + if (!observer) { + BUNDLE_ACTIVE_LOGE("observer is null, return"); + return false; + } + auto item = groupChangeObservers_.find(tokenId); + if (item != groupChangeObservers_.end()) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack observer exist, return"); + return false; + } + groupChangeObservers_.emplace(tokenId, observer); + AddObserverDeathRecipient(observer); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack observers number is %{public}d", static_cast(groupChangeObservers_.size())); + return true; +} + +int32_t BundleActiveCore::UnregisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, const sptr &observer) +{ + BUNDLE_ACTIVE_LOGI("UnregisterGroupCallBack begin"); + std::lock_guard lock(callbackMutex_); + auto item = groupChangeObservers_.find(tokenId); + if (item == groupChangeObservers_.end()) { + BUNDLE_ACTIVE_LOGE("UnRegisterGroupCallBack observer is not exist, return"); + return false; + } + groupChangeObservers_.erase(tokenId); + RemoveObserverDeathRecipient(item->second); + BUNDLE_ACTIVE_LOGI("UnregisterGroupCallBack end"); + return true; +} + +void BundleActiveCore::AddObserverDeathRecipient(const sptr &observer) +{ + std::lock_guard lock(deathRecipientMutex_); + if (!observer || !(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("observer nullptr."); + return; + } + auto remoteObj = observer->AsObject(); + auto it = recipientMap_.find(observer->AsObject()); + if (it != recipientMap_.end()) { + BUNDLE_ACTIVE_LOGE("This death recipient has been added."); + return; + } else { + sptr deathRecipient = new (std::nothrow) RemoteDeathRecipient( + [this](const wptr &remote) { this->OnObserverDied(remote); }); + if (!deathRecipient) { + BUNDLE_ACTIVE_LOGE("create death recipient failed"); + return ; + } + observer->AsObject()->AddDeathRecipient(deathRecipient); + recipientMap_.emplace(observer->AsObject(), deathRecipient); + } +} +void BundleActiveCore::RemoveObserverDeathRecipient(const sptr &observer) +{ + std::lock_guard lock(deathRecipientMutex_); + if (!observer || !(observer->AsObject())) { + return ; + } + auto iter = recipientMap_.find(observer->AsObject()); + if (iter != recipientMap_.end()) { + iter->first->RemoveDeathRecipient(iter->second); + recipientMap_.erase(iter); + return ; + } +} + +void BundleActiveCore::OnObserverDied(const wptr &remote) +{ + if (remote == nullptr) { + BUNDLE_ACTIVE_LOGE("remote object is null."); + return; + } + + bundleGroupHandler_->PostSyncTask([this, &remote]() { this->OnObserverDiedInner(remote); }); +} + +void BundleActiveCore::OnObserverDiedInner(const wptr &remote) +{ + std::lock_guard lock(deathRecipientMutex_); + sptr objectProxy = remote.promote(); + if (!objectProxy) { + BUNDLE_ACTIVE_LOGE("get remote object failed"); + return; + } + for (const auto& item : groupChangeObservers_) { + if((item.second)->AsObject() == objectProxy){ + groupChangeObservers_.erase(item.first); + break; + } + } + recipientMap_.erase(objectProxy); +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_service.cpp b/services/common/src/bundle_active_service.cpp index d21188902487a5e8348f8fd939bb14852909e792..8134c2ceefabcb5e1b8f5be9b41ac3a69ef1727f 100644 --- a/services/common/src/bundle_active_service.cpp +++ b/services/common/src/bundle_active_service.cpp @@ -32,7 +32,6 @@ static const int32_t PERIOD_YEARLY_JS = 4; static const int32_t PERIOD_BEST_SERVICE = 4; static const int32_t DELAY_TIME = 2000; static const std::string PERMITTED_PROCESS_NAME = "foundation"; -static const int32_t MAXNUM_UP_LIMIT = 1000; const std::string NEEDED_PERMISSION = "ohos.permission.BUNDLE_ACTIVE_INFO"; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); @@ -48,10 +47,6 @@ BundleActiveService::~BundleActiveService() void BundleActiveService::OnStart() { BUNDLE_ACTIVE_LOGI("OnStart() called"); - if (ready_) { - BUNDLE_ACTIVE_LOGI("service is ready. nothing to do."); - return; - } runner_ = AppExecFwk::EventRunner::Create("device_usage_stats_init_handler"); if (runner_ == nullptr) { BUNDLE_ACTIVE_LOGI("BundleActiveService runner create failed!"); @@ -101,8 +96,8 @@ void BundleActiveService::InitNecessaryState() handler_->PostTask(task, DELAY_TIME); return; } + InitService(); - ready_ = true; } void BundleActiveService::InitService() @@ -180,6 +175,7 @@ bool BundleActiveService::SubscribeAppState() int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_.get()); if (err != 0) { BUNDLE_ACTIVE_LOGE("RegisterApplicationStateObserver failed. err:%{public}d", err); + appStateObserver_ = nullptr; return false; } BUNDLE_ACTIVE_LOGI("RegisterApplicationStateObserver success."); @@ -205,10 +201,11 @@ void BundleActiveService::OnStop() if (shutdownCallback_ != nullptr) { auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); powerManagerClient.UnRegisterShutdownCallback(shutdownCallback_); + delete shutdownCallback_; + shutdownCallback_ = nullptr; return; } BUNDLE_ACTIVE_LOGI("[Server] OnStop"); - ready_ = false; } int32_t BundleActiveService::ReportEvent(BundleActiveEvent& event, const int32_t userId) @@ -322,9 +319,29 @@ std::vector BundleActiveService::QueryEvents(const int64_t be return result; } -void BundleActiveService::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) +bool BundleActiveService::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t& errCode, int32_t userId) { - bundleActiveCore_->SetBundleGroup(bundleName, newGroup, userId); + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter service,4--------------------"); + int32_t result = -1; + // get uid + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + BUNDLE_ACTIVE_LOGI("SetBundleGroup UID is %{public}d", callingUid); + if (userId == -1) { + OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); + if (ret != ERR_OK) { + errCode = -1; + return false; + } + } + if (userId != -1) { + BUNDLE_ACTIVE_LOGI("SetBundleGroup userid is %{public}d", userId); + if (CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode) || + AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { + result = bundleActiveCore_->SetBundleGroup(bundleName, newGroup, userId); + } + } + return result == 0 ? false : true; } @@ -388,31 +405,63 @@ std::vector BundleActiveService::QueryCurrentEvents(const int return result; } -int32_t BundleActiveService::QueryPackageGroup() +int32_t BundleActiveService::QueryPackageGroup(const std::string& bundleName, int32_t userId) { - BUNDLE_ACTIVE_LOGI("QueryPackageGroup stats called"); // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGI("QueryPackageGroup UID is %{public}d", callingUid); - // get userid - int32_t userId = -1; + + int32_t errCode = 0; int32_t result = -1; - OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); - BUNDLE_ACTIVE_LOGI("QueryPackageGroup user id is %{public}d", userId); - if (ret == ERR_OK && userId != -1) { - if (!GetBundleMgrProxy()) { - BUNDLE_ACTIVE_LOGE("get bundle manager proxy failed!"); + if(userId == -1){ + OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); + if (ret != ERR_OK) { + errCode = -1; return result; } - std::string bundleName = ""; - // get bundle name - sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); - BUNDLE_ACTIVE_LOGI("QueryPackageGroup bundlename is %{public}s", bundleName.c_str()); - if (!bundleName.empty()) { - result = bundleActiveCore_->QueryPackageGroup(userId, bundleName); + } + if(userId != -1){ + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + if (CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode) || + AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { + result = bundleActiveCore_->QueryPackageGroup(bundleName, userId); } } - BUNDLE_ACTIVE_LOGI("QueryPackageGroup result is %{public}d", result); + return result; +} + +int32_t BundleActiveService::RegisterGroupCallBack(const sptr &observer) +{ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack enter bundleService"); + int result = false; + if (!bundleActiveCore_) { + return result; + } + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + int32_t errCode = 0; + if (CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode) || + AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { + result = bundleActiveCore_->RegisterGroupCallBack(tokenId, observer); + } + return result; +} + +int32_t BundleActiveService::UnregisterGroupCallBack(const sptr &observer) +{ + int32_t result = false; + if (!bundleActiveCore_ ) { + return result; + } + + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + int32_t errCode = 0; + if (CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode) || + AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { + result = bundleActiveCore_->UnregisterGroupCallBack(tokenId, observer); + } + return result; } @@ -453,20 +502,25 @@ bool BundleActiveService::CheckBundleIsSystemAppAndHasPermission(const int32_t u OHOS::Security::AccessToken::AccessTokenID tokenId, int32_t& errCode) { if (!GetBundleMgrProxy()) { - BUNDLE_ACTIVE_LOGE("Get bundle manager proxy failed!"); + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack Get bundle manager proxy failed!"); return false; } std::string bundleName = ""; sptrBundleMgr_->GetBundleNameForUid(uid, bundleName); + bool bundleIsSystemApp = sptrBundleMgr_->CheckIsSystemAppByUid(uid); int32_t bundleHasPermission = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, NEEDED_PERMISSION); - if (bundleHasPermission != 0) { + if (!bundleIsSystemApp) { + errCode = BUNDLE_ACTIVE_FAIL; + BUNDLE_ACTIVE_LOGE("%{public}s is not system app", bundleName.c_str()); + return false; + } else if (bundleHasPermission != 0) { errCode = bundleHasPermission; BUNDLE_ACTIVE_LOGE("%{public}s hasn't permission", bundleName.c_str()); return false; } else { - BUNDLE_ACTIVE_LOGI(" %{public}s has permission %{public}d", - bundleName.c_str(), bundleHasPermission); + BUNDLE_ACTIVE_LOGI("%{public}s is system app %{public}d, has permission %{public}d", + bundleName.c_str(), bundleIsSystemApp, bundleHasPermission); return true; } } @@ -474,15 +528,10 @@ bool BundleActiveService::CheckBundleIsSystemAppAndHasPermission(const int32_t u int32_t BundleActiveService::QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId) { - int32_t errCode = 0; - if (maxNum > MAXNUM_UP_LIMIT || maxNum <= 0) { - BUNDLE_ACTIVE_LOGE("MaxNum is Invalid!"); - errCode = -1; - return errCode; - } int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGI("QueryFormStatistics UID is %{public}d", callingUid); - // get userid when userId is -1 + + int32_t errCode = 0; if (userId == -1) { OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK) { diff --git a/services/common/src/bundle_active_stub.cpp b/services/common/src/bundle_active_stub.cpp index ad5037cd8e4eb7371c9c42f8a929d51185d407fe..dc215ba93d17155ca59225da0031e4ca59863c45 100644 --- a/services/common/src/bundle_active_stub.cpp +++ b/services/common/src/bundle_active_stub.cpp @@ -84,9 +84,10 @@ int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Me case SET_BUNDLE_GROUP: { std::string bundleName = data.ReadString(); int32_t newGroup = data.ReadInt32(); + int32_t errCode = data.ReadInt32(); int32_t userId = data.ReadInt32(); - SetBundleGroup(bundleName, newGroup, userId); - return 0; + int32_t result = SetBundleGroup(bundleName, newGroup, errCode, userId); + return reply.WriteInt32(result); } case QUERY_CURRENT_USAGE_STATS: { std::vector result; @@ -122,8 +123,9 @@ int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Me return size == 0; } case QUERY_BUNDLE_GROUP: { - int32_t result = -1; - result = QueryPackageGroup(); + std::string bundleName = data.ReadString(); + int32_t userId = data.ReadInt32(); + int32_t result = QueryPackageGroup(bundleName, userId); return reply.WriteInt32(result); } case QUERY_FORM_STATS: { @@ -142,6 +144,25 @@ int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Me } return size == 0; } + case REGISTER_GROUP_CALLBACK: { + auto observer = iface_cast(data.ReadRemoteObject()); + if (!observer) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack observer is null, return"); + return false; + } + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack observer is ok"); + int32_t result = RegisterGroupCallBack(observer); + return reply.WriteInt32(result); + } + case UNREGISTER_GROUP_CALLBACK: { + auto observer = iface_cast(data.ReadRemoteObject()); + if(!observer){ + BUNDLE_ACTIVE_LOGE("unRegisterGroupCallBack observer is null, return"); + return false; + } + int32_t result = UnregisterGroupCallBack(observer); + return reply.WriteInt32(result); + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/services/packagegroup/include/bundle_active_group_controller.h b/services/packagegroup/include/bundle_active_group_controller.h index 0f534cdf13728234520493df19d02132858464eb..e292d93ac02b622c6c2bbb3bd7b564cf67b33851 100644 --- a/services/packagegroup/include/bundle_active_group_controller.h +++ b/services/packagegroup/include/bundle_active_group_controller.h @@ -32,7 +32,6 @@ namespace DeviceUsageStats { using namespace DeviceUsageStatsGroupConst; class BundleActiveGroupHandler; - class BundleActiveGroupController { public: using PowerMgrClient = OHOS::PowerMgr::PowerMgrClient; @@ -55,7 +54,7 @@ public: ~BundleActiveGroupController() {} std::shared_ptr bundleUserHistory_; void SetHandlerAndCreateUserHistory(const std::shared_ptr& groupHandler, - const int64_t bootFromTimeStamp); + const int64_t bootFromTimeStamp, const std::shared_ptr& bundleActiveCore); void ReportEvent(const BundleActiveEvent& event, const int64_t bootBasedTimeStamp, const int32_t userId); void CheckAndUpdateGroup(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp); bool CheckEachBundleState(const int32_t userId); @@ -64,14 +63,14 @@ public: void OnUserRemoved(const int32_t userId); void OnBundleUninstalled(const int32_t userId, const std::string bundleName); void OnScreenChanged(const bool& isScreenOn, const int64_t bootFromTimeStamp); - void SetBundleGroup(const std::string& bundleName, const int32_t userId, int32_t newGroup, uint32_t reason, - const int64_t bootBasedTimeStamp, const bool& resetTimeout); + int32_t SetBundleGroup(const std::string& bundleName, const int32_t userId, int32_t newGroup, uint32_t reason, + const int64_t bootBasedTimeStamp, const bool resetTimeout); void RestoreToDatabase(const int32_t userId); void RestoreDurationToDatabase(); bool IsBundleInstalled(const std::string& bundleName, const int32_t userId); bool IsScreenOn(); int32_t IsBundleIdle(const std::string& bundleName, const int32_t userId); - int32_t QueryPackageGroup(const int32_t userId, const std::string& bundleName); + int32_t QueryPackageGroup(const std::string& bundleName, const int32_t userId); void ShutDown(const int64_t bootBasedTimeStamp, const int32_t userId); void OnUserSwitched(const int32_t userId, const int32_t currentUsedUser); diff --git a/services/packagegroup/include/bundle_active_package_history.h b/services/packagegroup/include/bundle_active_package_history.h index ac4b4503443205b01dc5f390e67db1420d0beea6..30b785b37457eb84077e84a6cd01b456d4ede379 100644 --- a/services/packagegroup/include/bundle_active_package_history.h +++ b/services/packagegroup/include/bundle_active_package_history.h @@ -22,10 +22,10 @@ namespace OHOS { namespace DeviceUsageStats { class BundleActivePackageHistory { public: - int64_t lastBootFromUsedTimeStamp_; - int64_t lastScreenUsedTimeStamp_; - int64_t lastGroupCalculatedTimeStamp_; - int32_t lastCalculatedGroup_; + int64_t lastBootFromUsedTimeStamp_;//开机使用时间的时间戳 + int64_t lastScreenUsedTimeStamp_;//最后一次亮屏时间戳 + int64_t lastGroupCalculatedTimeStamp_;//待使用字段 + int32_t lastCalculatedGroup_;//待使用字段 int32_t currentGroup_; uint32_t reasonInGroup_; int64_t bundleAliveTimeoutTimeStamp_; diff --git a/services/packagegroup/include/bundle_active_user_history.h b/services/packagegroup/include/bundle_active_user_history.h index 7279324e89387bfa9e657d1b4424b2e2704f6c56..4093a1ef81171e3d60c7ae9d47e1365afdb8b829 100644 --- a/services/packagegroup/include/bundle_active_user_history.h +++ b/services/packagegroup/include/bundle_active_user_history.h @@ -27,6 +27,7 @@ namespace OHOS { namespace DeviceUsageStats { using namespace DeviceUsageStatsGroupConst; +class BundleActiveCore; class BundleActiveUserHistory { public: @@ -36,11 +37,12 @@ public: int64_t screenOnTimeStamp_; int64_t ScreenOnDuration_; BundleActiveUsageDatabase database_; - BundleActiveUserHistory(const int64_t bootBasedTimeStamp); + BundleActiveUserHistory(const int64_t bootBasedTimeStamp, + const std::shared_ptr& bundleActiveCore); std::shared_ptr GetUsageHistoryForBundle(const std::string& bundleName, - const int32_t userId, const int64_t bootBasedTimeStamp, const bool& create); + const int32_t userId, const int64_t bootBasedTimeStamp, const bool create); std::shared_ptr>> GetUserHistory( - const int32_t userId, const bool& create); + const int32_t userId, const bool create); std::shared_ptr GetUsageHistoryInUserHistory(std::shared_ptr>> oneUserHistory, std::string bundleName, int64_t bootBasedTimeStamp, bool create); @@ -48,8 +50,8 @@ public: int64_t GetScreenOnTimeStamp(int64_t bootBasedTimeStamp); void ReportUsage(std::shared_ptr oneBundleUsageHistory, const std::string& bundleName, const int32_t newGroup, const uint32_t groupReason, const int64_t bootBasedTimeStamp, - const int64_t timeUntilNextCheck); - void SetBundleGroup(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, + const int64_t timeUntilNextCheck, const int32_t userId); + int32_t SetBundleGroup(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason, const bool& resetTimeout); int32_t GetLevelIndex(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const std::vector screenTimeLeve, const std::vector bootFromTimeLevel); @@ -61,7 +63,9 @@ public: void OnBundleUninstalled(const int32_t userId, const std::string bundleName); private: + std::mutex setGroupMutex_; bool isScreenOn_; + std::weak_ptr bundleActiveCore_; }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packagegroup/src/bundle_active_group_controller.cpp b/services/packagegroup/src/bundle_active_group_controller.cpp index 234086632e7be3e9c5ca607d28485437ed6ad1d3..a6f692ab9c8980c452857c04cf3ff164fe3c7244 100644 --- a/services/packagegroup/src/bundle_active_group_controller.cpp +++ b/services/packagegroup/src/bundle_active_group_controller.cpp @@ -81,12 +81,13 @@ void BundleActiveGroupController::OnScreenChanged(const bool& isScreenOn, const } void BundleActiveGroupController::SetHandlerAndCreateUserHistory( - const std::shared_ptr& groupHandler, const int64_t bootFromTimeStamp) + const std::shared_ptr& groupHandler, const int64_t bootFromTimeStamp, + const std::shared_ptr& bundleActiveCore) { if (bundleUserHistory_ == nullptr) { BUNDLE_ACTIVE_LOGI("SetHandlerAndCreateUserHistory bundleUserHistory_ is null, " "called constructor, bootstamp is %{public}lld", (long long)bootFromTimeStamp); - bundleUserHistory_ = std::make_shared(bootFromTimeStamp); + bundleUserHistory_ = std::make_shared(bootFromTimeStamp, bundleActiveCore); } OnScreenChanged(IsScreenOn(), bootFromTimeStamp); activeGroupHandler_ = groupHandler; @@ -242,17 +243,17 @@ void BundleActiveGroupController::ReportEvent(const BundleActiveEvent& event, co switch (eventId) { case BundleActiveEvent::NOTIFICATION_SEEN: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_DAILY, - eventReason, 0, bootBasedTimeStamp + timeoutForNotifySeen_); + eventReason, 0, bootBasedTimeStamp + timeoutForNotifySeen_, userId); timeUntilNextCheck = timeoutForNotifySeen_; break; case BundleActiveEvent::SYSTEM_INTERACTIVE: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, - eventReason, 0, bootBasedTimeStamp + timeoutForSystemInteraction_); + eventReason, 0, bootBasedTimeStamp + timeoutForSystemInteraction_, userId); timeUntilNextCheck = timeoutForSystemInteraction_; break; default: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, - eventReason, bootBasedTimeStamp, bootBasedTimeStamp + timeoutForDirectlyUse_); + eventReason, bootBasedTimeStamp, bootBasedTimeStamp + timeoutForDirectlyUse_, userId); timeUntilNextCheck = timeoutForDirectlyUse_; break; } @@ -298,6 +299,7 @@ void BundleActiveGroupController::CheckAndUpdateGroup(const std::string& bundleN if (newGroup >= ACTIVE_GROUP_ALIVE && oneBundleHistory->bundleAliveTimeoutTimeStamp_ > bootBasedTimeStampAdjusted) { newGroup = ACTIVE_GROUP_ALIVE; + groupReason = oneBundleHistory->reasonInGroup_; groupReason = GROUP_CONTROL_REASON_USAGE | GROUP_EVENT_REASON_ALIVE_NOT_TIMEOUT; notTimeout = true; } else if (newGroup >= ACTIVE_GROUP_DAILY && oneBundleHistory->bundleDailyTimeoutTimeStamp_ > @@ -312,36 +314,35 @@ void BundleActiveGroupController::CheckAndUpdateGroup(const std::string& bundleN } } -void BundleActiveGroupController::SetBundleGroup(const std::string& bundleName, const int32_t userId, int32_t newGroup, - uint32_t reason, const int64_t bootBasedTimeStamp, const bool& resetTimeout) +int32_t BundleActiveGroupController::SetBundleGroup(const std::string& bundleName, const int32_t userId, int32_t newGroup, + uint32_t reason, const int64_t bootBasedTimeStamp, const bool resetTimeout) { + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter controller,5--------------------"); std::lock_guard lock(mutex_); - if (IsBundleInstalled(bundleName, userId) == false) { - return; + if (!IsBundleInstalled(bundleName, userId)) { + return false; } auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle(bundleName, userId, bootBasedTimeStamp, true); - if (oneBundleHistory->currentGroup_ < ACTIVE_GROUP_ALIVE) { - return; + if (!oneBundleHistory || (oneBundleHistory->currentGroup_ < ACTIVE_GROUP_ALIVE)) { + return false; } - int64_t bootBasedTimeStampAdjusted = bundleUserHistory_->GetBootBasedTimeStamp(bootBasedTimeStamp); - if (newGroup > ACTIVE_GROUP_ALIVE && oneBundleHistory->bundleAliveTimeoutTimeStamp_ > - bootBasedTimeStampAdjusted) { - BUNDLE_ACTIVE_LOGI("%{public}s should be decreased, but time out in alive is not expire! now is %{public}lld," - "timeout is %{public}lld", - bundleName.c_str(), - (long long)bootBasedTimeStampAdjusted, (long long)oneBundleHistory->bundleAliveTimeoutTimeStamp_); - newGroup = ACTIVE_GROUP_ALIVE; - reason = oneBundleHistory->reasonInGroup_; - } else if (newGroup > ACTIVE_GROUP_DAILY && oneBundleHistory->bundleDailyTimeoutTimeStamp_ > - bootBasedTimeStampAdjusted) { - newGroup = ACTIVE_GROUP_DAILY; - if (oneBundleHistory->currentGroup_ != newGroup) { - reason = GROUP_CONTROL_REASON_USAGE | GROUP_CONTROL_REASON_TIMEOUT; - } else { + if (reason != GROUP_CONTROL_REASON_FORCED) { + int64_t bootBasedTimeStampAdjusted = bundleUserHistory_->GetBootBasedTimeStamp(bootBasedTimeStamp); + if (newGroup > ACTIVE_GROUP_ALIVE && oneBundleHistory->bundleAliveTimeoutTimeStamp_ > bootBasedTimeStampAdjusted) { + BUNDLE_ACTIVE_LOGI("%{public}s should be decreased, but time out in alive is not expire! now is %{public}lld," + "timeout is %{public}lld", bundleName.c_str(), (long long)bootBasedTimeStampAdjusted, (long long)oneBundleHistory->bundleAliveTimeoutTimeStamp_); + newGroup = ACTIVE_GROUP_ALIVE; reason = oneBundleHistory->reasonInGroup_; + } else if (newGroup > ACTIVE_GROUP_DAILY && oneBundleHistory->bundleDailyTimeoutTimeStamp_ > bootBasedTimeStampAdjusted) { + newGroup = ACTIVE_GROUP_DAILY; + if (oneBundleHistory->currentGroup_ != newGroup) { + reason = GROUP_CONTROL_REASON_USAGE | GROUP_CONTROL_REASON_TIMEOUT; + } else { + reason = oneBundleHistory->reasonInGroup_; + } } } - bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, reason, false); + return bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, reason, false); } int32_t BundleActiveGroupController::IsBundleIdle(const std::string& bundleName, const int32_t userId) @@ -364,21 +365,22 @@ int32_t BundleActiveGroupController::IsBundleIdle(const std::string& bundleName, } } -int32_t BundleActiveGroupController::QueryPackageGroup(const int32_t userId, const std::string& bundleName) +int32_t BundleActiveGroupController::QueryPackageGroup(const std::string& bundleName, const int32_t userId) { BUNDLE_ACTIVE_LOGI("QueryPackageGroup called"); sptr timer = MiscServices::TimeServiceClient::GetInstance(); - if (IsBundleInstalled(bundleName, userId) == false) { + if (!IsBundleInstalled(bundleName, userId)) { + BUNDLE_ACTIVE_LOGI("QueryPackageGroup is not bundleInstalled"); return -1; } + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle( bundleName, userId, bootBasedTimeStamp, false); - if (oneBundleHistory == nullptr) { + if (!oneBundleHistory) { return -1; - } else { - return oneBundleHistory->currentGroup_; } + return oneBundleHistory->currentGroup_; } bool BundleActiveGroupController::IsBundleInstalled(const std::string& bundleName, const int32_t userId) diff --git a/services/packagegroup/src/bundle_active_user_history.cpp b/services/packagegroup/src/bundle_active_user_history.cpp index 42175f3334adf2ab90fa5f639c72761ea113b8d3..4e801067e833518bcabe0e0abbd3a2f757feb3e8 100644 --- a/services/packagegroup/src/bundle_active_user_history.cpp +++ b/services/packagegroup/src/bundle_active_user_history.cpp @@ -16,6 +16,8 @@ #include "bundle_active_user_history.h" #include "bundle_active_group_common.h" #include "bundle_active_constant.h" +#include "bundle_active_core.h" +#include "bundle_active_group_callback_info.h" namespace OHOS { namespace DeviceUsageStats { @@ -56,7 +58,8 @@ void BundleActiveUserHistory::OnBundleUninstalled(const int32_t userId, const st database_.OnPackageUninstalled(userId, bundleName); } -BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStamp) +BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStamp, + const std::shared_ptr& bundleActiveCore) { bootBasedTimeStamp_ = bootBasedTimeStamp; screenOnTimeStamp_ = bootBasedTimeStamp; @@ -65,6 +68,9 @@ BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStam bootBasedDuration_ = bootAndScreenOnDuraton.first; ScreenOnDuration_ = bootAndScreenOnDuraton.second; isScreenOn_ = false; + if (bundleActiveCore) { + bundleActiveCore_ = bundleActiveCore; + } } int32_t BundleActiveUserHistory::GetLevelIndex(const string& bundleName, const int32_t userId, @@ -107,13 +113,13 @@ int64_t BundleActiveUserHistory::GetScreenOnTimeStamp(int64_t bootBasedTimeStamp } shared_ptr>> BundleActiveUserHistory::GetUserHistory( - const int32_t userId, const bool& create) + const int32_t userId, const bool create) { auto it = userHistory_.find(userId); - if (it == userHistory_.end() && create) { + if ((it == userHistory_.end()) && create) { shared_ptr>> usageHistoryInserted = database_.GetBundleHistoryData(userId); - if (usageHistoryInserted == nullptr) { + if (!usageHistoryInserted) { BUNDLE_ACTIVE_LOGI("GetUserHistory READ FROM DATABASE FAILD"); usageHistoryInserted = make_shared>>(); @@ -126,13 +132,13 @@ shared_ptr>> BundleActiveUser shared_ptr BundleActiveUserHistory::GetUsageHistoryInUserHistory( shared_ptr>> oneUserHistory, - string bundleName, int64_t bootBasedTimeStamp, bool create) + string bundleName, int64_t bootBasedTimeStamp, const bool create) { - if (oneUserHistory == nullptr) { + if (!oneUserHistory) { return nullptr; } auto it = oneUserHistory->find(bundleName); - if (it == oneUserHistory->end() && create) { + if ((it == oneUserHistory->end()) && create) { shared_ptr usageHistoryInserted = make_shared(); usageHistoryInserted->lastBootFromUsedTimeStamp_ = GetBootBasedTimeStamp(bootBasedTimeStamp); @@ -147,14 +153,14 @@ shared_ptr BundleActiveUserHistory::GetUsageHistoryI } shared_ptr BundleActiveUserHistory::GetUsageHistoryForBundle( - const string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const bool& create) + const string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const bool create) { auto oneUserHistory = GetUserHistory(userId, create); - if (oneUserHistory == nullptr) { + if (!oneUserHistory) { return nullptr; } auto oneBundleHistory = GetUsageHistoryInUserHistory(oneUserHistory, bundleName, bootBasedTimeStamp, create); - if (oneBundleHistory == nullptr) { + if (!oneBundleHistory) { return nullptr; } return oneBundleHistory; @@ -162,7 +168,7 @@ shared_ptr BundleActiveUserHistory::GetUsageHistoryF void BundleActiveUserHistory::ReportUsage(shared_ptr oneBundleUsageHistory, const string& bundleName, const int32_t newGroup, const uint32_t groupReason, const int64_t bootBasedTimeStamp, - const int64_t timeUntilNextCheck) + const int64_t timeUntilNextCheck, const int32_t userId) { if (timeUntilNextCheck > bootBasedTimeStamp) { int64_t nextCheckTimeStamp = bootBasedDuration_ + (timeUntilNextCheck - bootBasedTimeStamp_); @@ -181,39 +187,50 @@ void BundleActiveUserHistory::ReportUsage(shared_ptr (bootBasedTimeStamp - bootBasedTimeStamp_); oneBundleUsageHistory->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp); } + int32_t oldGroup = oneBundleUsageHistory->currentGroup_; if (oneBundleUsageHistory->currentGroup_ > newGroup) { oneBundleUsageHistory->currentGroup_ = newGroup; } oneBundleUsageHistory->reasonInGroup_ = GROUP_CONTROL_REASON_USAGE | groupReason; oneBundleUsageHistory->isChanged_ = true; + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack will ReportUsage"); + BundleActiveGroupCallbackInfo callbackInfo(userId, oldGroup, newGroup, oneBundleUsageHistory->reasonInGroup_, bundleName); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack BundleActiveGroupCallbackInfo build success"); + if (!bundleActiveCore_.expired()) { + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack will callback!"); + bundleActiveCore_.lock()->OnBundleGroupChanged(callbackInfo); + } } -void BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int32_t userId, +int32_t BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason, const bool& resetTimeout) { + BUNDLE_ACTIVE_LOGE("SetBundleGroup enter BundleActiveUserHistory,6--------------------"); + std::lock_guard lock(setGroupMutex_); BUNDLE_ACTIVE_LOGI("set %{public}s to group %{public}d, reason is %{public}d, userId is %{public}d", bundleName.c_str(), newGroup, groupReason, userId); shared_ptr>> userBundleHistory = GetUserHistory(userId, false); - if (userBundleHistory == nullptr) { - return; + if (!userBundleHistory) { + return false; } shared_ptr oneBundleHistory = GetUsageHistoryInUserHistory(userBundleHistory, bundleName, bootBasedTimeStamp, false); - if (oneBundleHistory == nullptr) { - return; + if (!oneBundleHistory) { + return false; } if (oneBundleHistory->currentGroup_ == newGroup && oneBundleHistory->reasonInGroup_ == groupReason) { BUNDLE_ACTIVE_LOGI("%{public}s group and reason is same as before, not update", bundleName.c_str()); - return; + return false; } + int32_t oldGroup = oneBundleHistory->currentGroup_; oneBundleHistory->currentGroup_ = newGroup; oneBundleHistory->reasonInGroup_ = groupReason; - int64_t setTimeStamp = GetBootBasedTimeStamp(bootBasedTimeStamp); - if (resetTimeout) { - oneBundleHistory->bundleAliveTimeoutTimeStamp_ = setTimeStamp; - oneBundleHistory->bundleDailyTimeoutTimeStamp_ = setTimeStamp; + oneBundleHistory->isChanged_ = true; + BundleActiveGroupCallbackInfo callbackInfo(userId, oldGroup, newGroup, oneBundleHistory->reasonInGroup_, bundleName); + if (!bundleActiveCore_.expired()) { + bundleActiveCore_.lock()->OnBundleGroupChanged(callbackInfo); } - oneBundleHistory->isChanged_ = true; + return true; } void BundleActiveUserHistory::UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t bootBasedTimeStamp, diff --git a/test/unittest/device_usage_statistics_test.cpp b/test/unittest/device_usage_statistics_test.cpp index 9a4eca3ef85d3f2f0fb083a593e3656a9149f46d..7e210ab762b337152e1054d5cbdd9d838d1ee6ed 100644 --- a/test/unittest/device_usage_statistics_test.cpp +++ b/test/unittest/device_usage_statistics_test.cpp @@ -25,6 +25,7 @@ #include "bundle_active_client.h" #include "bundle_active_event.h" +#include "bundle_active_group_callback_stub.h" using namespace testing::ext; @@ -39,6 +40,7 @@ static std::string DEFAULT_ABILITYID = "1234"; static std::string DEFAULT_ABILITYNAME = "testability"; static int32_t DEFAULT_USERID = 0; static int64_t LARGE_NUM = 20000000000000; +static int32_t DEFAULT_GROUP = 10; class DeviceUsageStatisticsTest : public testing::Test { public: @@ -154,11 +156,11 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_IsBundleIdle_001, * @tc.type: FUNC * @tc.require: */ -HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryPackageGroup_001, Function | MediumTest | Level0) -{ - int32_t result = BundleActiveClient::GetInstance().QueryPackageGroup(); - EXPECT_EQ(result, -1); -} +// HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryPackageGroup_001, Function | MediumTest | Level0) +// { +// int32_t result = BundleActiveClient::GetInstance().QueryPackageGroup(); +// EXPECT_EQ(result, -1); +// } /* * @tc.name: DeviceUsageStatisticsTest_QueryFormStatistics_001 @@ -177,6 +179,23 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryFormStatistic EXPECT_EQ(errCode, 0); EXPECT_EQ(results.size(), 0); } + +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_SetBundleGroup_001, Function | MediumTest | Level0) +{ + bool result = BundleActiveClient::GetInstance().SetBundleGroup(DEFAULT_BUNDLENAME, DEFAULT_GROUP, DEFAULT_USERID); + EXPECT_EQ(result, true); +} + +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_RegisterGroupCallBack_001, Function | MediumTest | Level0) +{ + //sptr observer(new (std::nothrow) BundleGroupCallbackInstance()); + auto observer=std::make_shared(); + if(!observer){ + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack construct observer!------------------------------"); + } + bool result = BundleActiveClient::GetInstance().RegisterGroupCallBack(observer.get()); + EXPECT_EQ(result, true); +} } // namespace DeviceUsageStats } // namespace OHOS