diff --git a/BUILD.gn b/BUILD.gn index 4eea17eb3e3502218d0a179a03fa6996ede6d872..90d85f3f8014da169db6263a3f46df5fe8272f6b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -31,6 +31,9 @@ config("usagestatsinner_public_config") { ohos_shared_library("usagestatsinner") { sources = [ "interfaces/innerkits/src/bundle_active_client.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", "interfaces/innerkits/src/bundle_active_proxy.cpp", "services/packageusage/src/bundle_active_event.cpp", "services/packageusage/src/bundle_active_package_stats.cpp", @@ -58,6 +61,7 @@ ohos_prebuilt_etc("device_usage_statistics_service_init") { ohos_shared_library("bundlestate") { sources = [ + "frameworks/src/bundle_active_group_observer.cpp", "frameworks/src/bundle_state_common.cpp", "frameworks/src/bundle_state_init.cpp", "frameworks/src/bundle_state_query.cpp", @@ -67,6 +71,7 @@ ohos_shared_library("bundlestate") { "services/common/include", "interfaces/innerkits/include", "services/packageusage/include", + "services/packagegroup/include", ] deps = [ @@ -90,6 +95,8 @@ ohos_shared_library("bundlestate") { ohos_shared_library("usagestatservice") { cflags_cc = [] sources = [ + "interfaces/innerkits/src/bundle_active_group_callback_info.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp", "services/common/src/bundle_active_account_helper.cpp", "services/common/src/bundle_active_app_state_obsever.cpp", "services/common/src/bundle_active_binary_search.cpp", @@ -98,6 +105,9 @@ ohos_shared_library("usagestatservice") { "services/common/src/bundle_active_debug_mode.cpp", "services/common/src/bundle_active_log.cpp", "services/common/src/bundle_active_open_callback.cpp", + "services/common/src/bundle_active_power_state_callback_proxy.cpp", + "services/common/src/bundle_active_power_state_callback_service.cpp", + "services/common/src/bundle_active_power_state_callback_stub.cpp", "services/common/src/bundle_active_service.cpp", "services/common/src/bundle_active_shutdown_callback_proxy.cpp", "services/common/src/bundle_active_shutdown_callback_service.cpp", @@ -125,9 +135,11 @@ ohos_shared_library("usagestatservice") { "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", @@ -139,9 +151,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 f28be986a2664edae4fb546d7b98beeabcd843b9..b0efeabb09a11cdbf6214cb6c5a5bdd6e6e423af 100644 --- a/README.md +++ b/README.md @@ -97,4 +97,4 @@ resource_schedule_service appexecfwk_standard -native_appdatamgr \ No newline at end of file +relational_store \ No newline at end of file diff --git a/frameworks/src/bundle_active_group_observer.cpp b/frameworks/src/bundle_active_group_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8de846dc2b0bf0daacbe74b9c4eec4e5968f840e --- /dev/null +++ b/frameworks/src/bundle_active_group_observer.cpp @@ -0,0 +1,381 @@ +/* + * 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_state_inner_errors.h" +#include "bundle_active_group_callback_info.h" + +#include "bundle_active_group_observer.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 oldGroup=%{public}d, newGroup=%{public}d, userId=%{public}d, " + "changeReason=%{public}d, bundleName=%{public}s", + commonEventDataWorkerData->oldGroup, commonEventDataWorkerData->newGroup, commonEventDataWorkerData->userId, + commonEventDataWorkerData->changeReason, 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; + 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)); + delete callbackReceiveDataWorkerData; + callbackReceiveDataWorkerData = nullptr; + delete work; + work = nullptr; +} + +/* +* observer callback 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; + } +} + +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) +{ + 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"); + + // arg[0] : callback + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + BundleActiveGroupObserverInfo bundleActiveGroupObserverInfo; + if (valuetype != napi_function || !GetBundleGroupChangeCallback(env, argv[0], bundleActiveGroupObserverInfo)) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack bundleActiveGroupObserverInfo parse failed"); + params.errorCode = ERR_OBSERVER_CALLBACK_IS_INVALID; + } else { + 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) +{ + RegisterCallbackInfo params; + 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; + AsyncRegisterCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncRegisterCallbackInfo(env); + if (!asyncCallbackInfo) { + 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) { + 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) { + AsyncRegisterCallbackInfo *asyncCallbackInfo = (AsyncRegisterCallbackInfo *)data; + if (asyncCallbackInfo) { + asyncCallbackInfo->errorCode = + BundleActiveClient::GetInstance().RegisterGroupCallBack(asyncCallbackInfo->observer); + } else { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncRegisterCallbackInfo *asyncCallbackInfo = (AsyncRegisterCallbackInfo *)data; + if (asyncCallbackInfo) { + napi_value result = nullptr; + asyncCallbackInfo->state = (asyncCallbackInfo->errorCode == ERR_OK) ? true : false; + 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) +{ + 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) +{ + UnRegisterCallbackInfo params; + ParseUnRegisterGroupCallBackParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + if (!registerObserver) { + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack observer is not exist"); + params.errorCode = ERR_REGISTER_OBSERVER_IS_NULL; + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncUnRegisterCallbackInfo *asyncCallbackInfo = + new (std::nothrow) AsyncUnRegisterCallbackInfo(env); + if (!asyncCallbackInfo) { + 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) { + 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); + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack will Async"); + 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) { + AsyncUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncUnRegisterCallbackInfo *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->errorCode = + BundleActiveClient::GetInstance().UnregisterGroupCallBack(asyncCallbackInfo->observer); + } else { + BUNDLE_ACTIVE_LOGE("UnRegisterGroupCallBack, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncUnRegisterCallbackInfo *asyncCallbackInfo = (AsyncUnRegisterCallbackInfo *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + asyncCallbackInfo->state = (asyncCallbackInfo->errorCode == ERR_OK) ? true : false; + 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)); + registerObserver = nullptr; + if (callbackPtr->isCallback) { + callbackPtr.release(); + return BundleStateCommon::NapiGetNull(env); + } else { + callbackPtr.release(); + return promise; + } +} +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/src/bundle_state_common.cpp b/frameworks/src/bundle_state_common.cpp index ae6a6d52bb30833861798993a034fd65150da467..dcefc9718700a24ca6d61b1a74c57e7330744866 100644 --- a/frameworks/src/bundle_state_common.cpp +++ b/frameworks/src/bundle_state_common.cpp @@ -16,7 +16,7 @@ #include "securec.h" #include "bundle_active_log.h" -#include "bundle_state_data.h" +#include "bundle_state_inner_errors.h" #include "bundle_state_common.h" namespace OHOS { @@ -67,7 +67,13 @@ void BundleStateCommon::SetCallbackInfo( napi_value resultout = nullptr; napi_get_reference_value(env, callbackIn, &callback); napi_value results[ARGS_TWO] = {nullptr}; - results[PARAM_FIRST] = GetErrorValue(env, errorCode); + if (errorCode == -1) { + results[PARAM_FIRST] = GetErrorValue(env, ERR_SERVICE_FAILED); + } else if (errorCode == 1) { + results[PARAM_FIRST] = GetErrorValue(env, ERR_REPEAT_OPERATION); + } else { + results[PARAM_FIRST] = GetErrorValue(env, errorCode); + } results[PARAM_SECOND] = result; NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM_FIRST], &resultout)); @@ -128,6 +134,58 @@ void BundleStateCommon::GetBundleStateInfoByIntervalForResult( } } +void BundleStateCommon::GetBundleActiveEventStatsForResult(napi_env env, + const std::vector &eventStats, napi_value result) +{ + int32_t index = 0; + for (const auto &item : eventStats) { + napi_value eventStatsObject = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &eventStatsObject)); + + napi_value name = nullptr; + NAPI_CALL_RETURN_VOID( + env, napi_create_string_utf8(env, item.name_.c_str(), NAPI_AUTO_LENGTH, &name)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "name", name)); + + napi_value eventId = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item.eventId_, &eventId)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "eventId", eventId)); + + napi_value count = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item.count_, &count)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "count", count)); + + NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, eventStatsObject)); + index++; + } +} + +void BundleStateCommon::GetBundleActiveNotificationNumberForResult(napi_env env, + const std::vector &eventStats, napi_value result) +{ + int32_t index = 0; + for (const auto &item : eventStats) { + napi_value eventStatsObject = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &eventStatsObject)); + + napi_value name = nullptr; + NAPI_CALL_RETURN_VOID( + env, napi_create_string_utf8(env, item.name_.c_str(), NAPI_AUTO_LENGTH, &name)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "name", name)); + + napi_value eventId = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item.eventId_, &eventId)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "eventId", eventId)); + + napi_value count = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item.count_, &count)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, eventStatsObject, "count", count)); + + NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, eventStatsObject)); + index++; + } +} + void BundleStateCommon::GetBundleStateInfoForResult(napi_env env, const std::shared_ptr> &packageStats, napi_value result) { @@ -248,10 +306,19 @@ void BundleStateCommon::GetModuleRecordForResult(napi_env env, void BundleStateCommon::SetPromiseInfo(const napi_env &env, const napi_deferred &deferred, const napi_value &result, const int32_t &errorCode) { - if (errorCode == ERR_OK) { - napi_resolve_deferred(env, deferred, result); - } else { - napi_reject_deferred(env, deferred, GetErrorValue(env, errorCode)); + switch (errorCode) { + case ERR_OK: + napi_resolve_deferred(env, deferred, result); + break; + case -1: + napi_reject_deferred(env, deferred, GetErrorValue(env, ERR_SERVICE_FAILED)); + break; + case 1: + napi_reject_deferred(env, deferred, GetErrorValue(env, ERR_REPEAT_OPERATION)); + break; + default: + napi_reject_deferred(env, deferred, GetErrorValue(env, errorCode)); + break; } } @@ -394,6 +461,27 @@ void BundleStateCommon::MergePackageStats(BundleActivePackageStats &left, const left.totalContiniousTaskUsedTime_ += right.totalContiniousTaskUsedTime_; left.bundleStartedCount_ += right.bundleStartedCount_; } + +std::unique_ptr BundleStateCommon::HandleEventStatsInfo( + AsyncCallbackInfoEventStats *asyncCallbackInfo, EventStatesParamsInfo ¶ms) +{ + if (!asyncCallbackInfo) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; + return nullptr; + } + if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) != EOK) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + return nullptr; + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->beginTime = params.beginTime; + callbackPtr->endTime = params.endTime; + BUNDLE_ACTIVE_LOGI("CallbackPtr->beginTime: %{public}lld, callbackPtr->endTime: %{public}lld", + (long long)callbackPtr->beginTime, (long long)callbackPtr->endTime); + return callbackPtr; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/frameworks/src/bundle_state_init.cpp b/frameworks/src/bundle_state_init.cpp index 56e36f89b19d0ca4be68425304fcf744fb134228..99dddd2fc59cfb91799c180d69570b240e069d73 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 { @@ -23,7 +24,7 @@ EXTERN_C_START static const uint8_t ARG_FIRST = 1; -napi_ref intervalTypeConstructor_ = nullptr; +napi_ref typeConstructor_ = nullptr; /* * Module export function @@ -40,12 +41,18 @@ 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), + DECLARE_NAPI_FUNCTION("queryBundleActiveEventStates", QueryBundleActiveEventStates), + DECLARE_NAPI_FUNCTION("queryAppNotificationNumber", QueryAppNotificationNumber) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); InitIntervalType(env, exports); + InitGroupType(env, exports); return exports; } @@ -78,14 +85,54 @@ napi_value InitIntervalType(napi_env env, napi_value exports) }; napi_value result = nullptr; - napi_define_class(env, "IntervalType", NAPI_AUTO_LENGTH, EnumIntervalTypeConstructor, + napi_define_class(env, "IntervalType", NAPI_AUTO_LENGTH, EnumTypeConstructor, nullptr, sizeof(desc) / sizeof(*desc), desc, &result); - napi_create_reference(env, result, refCount, &intervalTypeConstructor_); + napi_create_reference(env, result, refCount, &typeConstructor_); napi_set_named_property(env, exports, "IntervalType", result); return exports; } -napi_value EnumIntervalTypeConstructor(napi_env env, napi_callback_info info) +napi_value InitGroupType(napi_env env, napi_value exports) +{ + napi_value active_group_alive; + napi_value active_group_daily; + napi_value active_group_fixed; + napi_value active_group_rare; + napi_value active_group_limit; + napi_value active_group_never; + int32_t refCount = 1; + + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_ALIVE), + &active_group_alive); + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_DAILY), + &active_group_daily); + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_FIXED), + &active_group_fixed); + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_RARE), + &active_group_rare); + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_LIMIT), + &active_group_limit); + napi_create_uint32(env, static_cast(BundleStateCondition::GroupType::ACTIVE_GROUP_NEVER), + &active_group_never); + + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_ALIVE", active_group_alive), + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_DAILY", active_group_daily), + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_FIXED", active_group_fixed), + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_RARE", active_group_rare), + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_LIMIT", active_group_limit), + DECLARE_NAPI_STATIC_PROPERTY("ACTIVE_GROUP_NEVER", active_group_never), + }; + + napi_value result = nullptr; + napi_define_class(env, "GroupType", NAPI_AUTO_LENGTH, EnumTypeConstructor, + nullptr, sizeof(desc) / sizeof(*desc), desc, &result); + napi_create_reference(env, result, refCount, &typeConstructor_); + napi_set_named_property(env, exports, "GroupType", result); + return exports; +} + +napi_value EnumTypeConstructor(napi_env env, napi_callback_info info) { size_t argc = 0; napi_value args[ARG_FIRST] = {0}; diff --git a/frameworks/src/bundle_state_query.cpp b/frameworks/src/bundle_state_query.cpp index 7b840ef2e1889b1c220f3b79fb1a8df34223bee5..d0f35edbcf8e0fb6ac488c8990ed68af35c99334 100644 --- a/frameworks/src/bundle_state_query.cpp +++ b/frameworks/src/bundle_state_query.cpp @@ -19,6 +19,7 @@ #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 { @@ -26,11 +27,14 @@ 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_MIDDLE_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 +43,9 @@ 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 {10, 20, 30, 40, 50, 60}; +const uint32_t EVENT_STATES_MIN_PARAMS = 2; +const uint32_t EVENT_STATES_PARAMS = 3; napi_value ParseModuleRecordsParameters(const napi_env &env, const napi_callback_info &info, ModuleRecordParamsInfo ¶ms) @@ -245,16 +252,41 @@ napi_value ParsePriorityGroupParameters(const napi_env &env, const napi_callback size_t argc = PRIORITY_GROUP_PARAMS; napi_value argv[PRIORITY_GROUP_PARAMS] = {nullptr}; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); - NAPI_ASSERT(env, argc == PRIORITY_GROUP_MIN_PARAMS || argc == PRIORITY_GROUP_PARAMS, - "Invalid number of parameters"); - - // argv[0]: callback - if (argc == PRIORITY_GROUP_PARAMS) { + NAPI_ASSERT(env, argc == PRIORITY_GROUP_MIN_PARAMS || argc == PRIORITY_GROUP_MIDDLE_PARAMS || + argc == PRIORITY_GROUP_PARAMS, "Invalid number of parameters"); + std::string result = ""; + params.bundleName = ""; + if (argc == PRIORITY_GROUP_MIDDLE_PARAMS) { napi_valuetype valuetype = napi_undefined; NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); - NAPI_ASSERT(env, valuetype == napi_function, "ParsePriorityGroupParameters invalid parameter type. " - "Function expected."); - napi_create_reference(env, argv[0], 1, ¶ms.callback); + if (valuetype == napi_function) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParsePriorityGroupParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[0], 1, ¶ms.callback); + } else { + 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; + } + } + } else if (argc == PRIORITY_GROUP_PARAMS) { + // argv[0] : bundleName + 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; + } + // argv[1]: callback + if (argc == PRIORITY_GROUP_PARAMS) { + napi_valuetype valuetype = napi_undefined; + 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[1], 1, ¶ms.callback); + } } return BundleStateCommon::NapiGetNull(env); } @@ -263,6 +295,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); @@ -277,6 +312,9 @@ napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGI("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 +323,19 @@ 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) { + if (asyncCallbackInfo) { + if (asyncCallbackInfo->priorityGroup == -1) { + asyncCallbackInfo->errorCode = ERR_SERVICE_FAILED; + } napi_value result = nullptr; napi_create_int32(env, asyncCallbackInfo->priorityGroup, &result); BundleStateCommon::GetCallbackPromiseResult(env, *asyncCallbackInfo, result); @@ -413,7 +455,6 @@ napi_value QueryCurrentBundleActiveStates(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(); @@ -724,6 +765,268 @@ napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) return promise; } } + +napi_value ParseAppUsageBundleGroupInfoParameters(const napi_env &env, const napi_callback_info &info, + ParamsBundleGroupInfo ¶ms) +{ + BUNDLE_ACTIVE_LOGD("enter ParseAppUsageBundleGroupInfoParameters"); + 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, newGroup type is invalid."); + params.errorCode = ERR_USAGE_STATS_GROUP_INVALID; + } + bool flag = false; + if (params.errorCode == ERR_OK) { + 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_LOGI("enter SetBundleGroup"); + ParamsBundleGroupInfo params; + ParseAppUsageBundleGroupInfoParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncCallbackInfoSetBundleGroup *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoSetBundleGroup(env); + if (!asyncCallbackInfo) { + 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) { + 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; + BUNDLE_ACTIVE_LOGI("SetBundleGroup, bundleName is %{public}s, newGroup is %{public}d", + callbackPtr->bundleName.c_str(), callbackPtr->newGroup); + 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) { + AsyncCallbackInfoSetBundleGroup *asyncCallbackInfo = (AsyncCallbackInfoSetBundleGroup *)data; + if (asyncCallbackInfo) { + asyncCallbackInfo->errorCode = BundleActiveClient::GetInstance().SetBundleGroup( + asyncCallbackInfo->bundleName, asyncCallbackInfo->newGroup, asyncCallbackInfo->errorCode); + } else { + BUNDLE_ACTIVE_LOGE("SetBundleGroup, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoSetBundleGroup *asyncCallbackInfo = (AsyncCallbackInfoSetBundleGroup *)data; + if (asyncCallbackInfo) { + napi_value result = nullptr; + asyncCallbackInfo->state = (asyncCallbackInfo->errorCode == ERR_OK) ? true : false; + 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 ParseEventStatesParameters(const napi_env &env, const napi_callback_info &info, + EventStatesParamsInfo ¶ms) +{ + size_t argc = EVENT_STATES_PARAMS; + napi_value argv[EVENT_STATES_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == EVENT_STATES_MIN_PARAMS || argc == EVENT_STATES_PARAMS, + "Invalid number of parameters"); + + // argv[0] : beginTime + if ((params.errorCode == ERR_OK) + && ((BundleStateCommon::GetInt64NumberValue(env, argv[0], params.beginTime) == nullptr) + || (params.beginTime < TIME_NUMBER_MIN))) { + BUNDLE_ACTIVE_LOGE("ParseEventStatesParameters failed, beginTime is invalid."); + params.errorCode = ERR_USAGE_STATS_BEGIN_TIME_INVALID; + } + + // argv[1] : endTime + if ((params.errorCode == ERR_OK) + && ((BundleStateCommon::GetInt64NumberValue(env, argv[1], params.endTime) == nullptr) + || (params.endTime < TIME_NUMBER_MIN))) { + BUNDLE_ACTIVE_LOGE("ParseEventStatesParameters failed, endTime is invalid."); + params.errorCode = ERR_USAGE_STATS_END_TIME_INVALID; + } + if ((params.errorCode == ERR_OK) && (params.endTime <= params.beginTime)) { + BUNDLE_ACTIVE_LOGE("ParseEventStatesParameters endTime(%{public}lld) <= beginTime(%{public}lld)", + (long long)params.endTime, (long long)params.beginTime); + params.errorCode = ERR_USAGE_STATS_TIME_INTERVAL; + } + + // argv[SECOND_ARG]: callback + if (argc == EVENT_STATES_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[SECOND_ARG], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseEventStatesParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[SECOND_ARG], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value QueryBundleActiveEventStates(napi_env env, napi_callback_info info) +{ + EventStatesParamsInfo params; + ParseEventStatesParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncCallbackInfoEventStats *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoEventStats(env); + std::unique_ptr callbackPtr = + BundleStateCommon::HandleEventStatsInfo(asyncCallbackInfo, params); + if (!callbackPtr) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "QueryBundleActiveEventStates", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoEventStats *asyncCallbackInfo = (AsyncCallbackInfoEventStats *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->errorCode = BundleActiveClient::GetInstance() + .QueryEventStats(asyncCallbackInfo->beginTime, + asyncCallbackInfo->endTime, asyncCallbackInfo->eventStats); + } else { + BUNDLE_ACTIVE_LOGE("QueryBundleActiveEventStates, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoEventStats *asyncCallbackInfo = (AsyncCallbackInfoEventStats *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleActiveEventStatsForResult(env, asyncCallbackInfo->eventStats, 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 QueryAppNotificationNumber(napi_env env, napi_callback_info info) +{ + EventStatesParamsInfo params; + ParseEventStatesParameters(env, info, params); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + napi_value promise = nullptr; + AsyncCallbackInfoEventStats *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoEventStats(env); + std::unique_ptr callbackPtr = + BundleStateCommon::HandleEventStatsInfo(asyncCallbackInfo, params); + if (!callbackPtr) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "QueryAppNotificationNumber", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoEventStats *asyncCallbackInfo = (AsyncCallbackInfoEventStats *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->errorCode = BundleActiveClient::GetInstance() + .QueryAppNotificationNumber(asyncCallbackInfo->beginTime, + asyncCallbackInfo->endTime, asyncCallbackInfo->eventStats); + } else { + BUNDLE_ACTIVE_LOGE("QueryAppNotificationNumber, asyncCallbackInfo == nullptr"); + } + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoEventStats *asyncCallbackInfo = (AsyncCallbackInfoEventStats *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleActiveNotificationNumberForResult(env, + asyncCallbackInfo->eventStats, 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; + } +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/init/device_usage_statistics_service.cfg b/init/device_usage_statistics_service.cfg index 193ac5da3de3bfd67ba68bfb10797288be375ad5..fe224844abef7213d1e3c861f79fc4e64892623f 100644 --- a/init/device_usage_statistics_service.cfg +++ b/init/device_usage_statistics_service.cfg @@ -2,6 +2,7 @@ "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" ] } @@ -9,9 +10,10 @@ "services" : [{ "name" : "device_usage_stats_service", "path" : ["/system/bin/sa_main", "/system/profile/device_usage_stats_service.xml"], - "uid" : "system", - "gid" : ["system", "shell"], - "secon" : "u:r:device_usage_stats_service:s0" + "uid" : "device_usage_stats", + "gid" : ["device_usage_stats", "shell"], + "secon" : "u:r:device_usage_stats_service:s0", + "apl" : "system_basic" } ] } \ 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..c7668f2e174f83f45ab54887bea7bd11b56ce94b 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -19,6 +19,7 @@ #include "ibundle_active_service.h" #include "bundle_active_package_stats.h" #include "bundle_active_event.h" +#include "bundle_active_event_stats.h" #include "bundle_active_package_stats.h" #include "bundle_active_module_record.h" @@ -57,8 +58,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); + int32_t 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,17 +76,48 @@ 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(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, - * if other SAs call this API, they should explicit define userId + * if other SAs call this API, they should explicit define userId. * return: errorcode. */ 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: QueryEventStats, query all from event stats in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId = -1); + + /* + * function: QueryAppNotificationNumber, query all app notification number in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId = -1); + /* * 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..a3b29e726bab2dff25e310c2ac988861b7dc26a2 --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_proxy.h @@ -0,0 +1,42 @@ +/* + * 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: + explicit BundleActiveGroupCallbackProxy(const sptr& impl); + virtual ~BundleActiveGroupCallbackProxy() override; + DISALLOW_COPY_AND_MOVE(BundleActiveGroupCallbackProxy); + /* + * function: OnBundleGroupChanged, bundleGroupChanged callback, IPC proxy, send message to stub. + * parameters: bundleActiveGroupCallbackInfo + * return: void. + */ + 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..a748c873c32cb52a99522df01199cbdcc187e64e --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_stub.h @@ -0,0 +1,47 @@ +/* + * 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; + /* + * function: OnRemoteRequest, handle message from proxy. + * parameters: code, data, reply, option + * return: errorcode. + */ + virtual int OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + /* + * function: OnBundleGroupChanged, bundleGroupChanged callback, handle message from proxy. + * parameters: bundleActiveGroupCallbackInfo + * return: void. + */ + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) override; +private: + 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..a0b90b397062d4ae317c99858be4e47d09ecba20 100644 --- a/interfaces/innerkits/include/bundle_active_proxy.h +++ b/interfaces/innerkits/include/bundle_active_proxy.h @@ -18,9 +18,10 @@ #include "ibundle_active_service.h" #include "bundle_active_event.h" -#include "bundle_active_package_stats.h" +#include "bundle_active_event_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 +57,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; + int32_t 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,28 +75,58 @@ public: * function: QueryPackageGroup, query bundle priority group calling bundle. * return: the priority group of calling bundle. */ - int32_t QueryPackageGroup() override; + int32_t QueryPackageGroup(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, - * if other SAs call this API, they should explicit define userId + * if other SAs call this API, they should explicit define userId. * return: errorcode. */ int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId = -1) override; /* + * function: QueryEventStats, query all from event stats in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) override; + /* + * function: QueryAppNotificationNumber, query all app notification number in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) override; + /* * function: BundleActiveProxy, default constructor. * parameters: impl */ explicit BundleActiveProxy(const sptr& impl) : IRemoteProxy(impl) {} /* + * function: RegisterGroupCallBack, register the observer to groupObservers. + * parameters: observer + * return: result of RegisterGroupCallBack, true or false. + */ + int32_t RegisterGroupCallBack(const sptr &observer) override; + /* + * function: UnregisterGroupCallBack, remove the observer from groupObservers. + * parameters: observer + * return: result of UnregisterGroupCallBack, true or false. + */ + int32_t UnregisterGroupCallBack(const sptr &observer) override; + /* * function: ~BundleActiveProxy, default destructor. */ virtual ~BundleActiveProxy() {} private: static inline BrokerDelegator delegator_; + int32_t IPCCommunication(int64_t beginTime, int64_t endTime, std::vector& eventStats, + int32_t userId, int32_t communicationFlag); }; } // namespace DeviceUsageStats } // namespace OHOS 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..25bc8139108c1e7b93e6f43d4e715071cdf24a74 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -38,7 +38,7 @@ bool BundleActiveClient::GetBundleActiveProxy() sptr object = samgr->GetSystemAbility(DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID); if (!object) { - BUNDLE_ACTIVE_LOGE("Failed to get SystemAbility[1920] ."); + BUNDLE_ACTIVE_LOGE("Failed to get SystemAbility[1907] ."); return false; } @@ -85,13 +85,13 @@ 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) +int32_t BundleActiveClient::SetBundleGroup(std::string bundleName, const int32_t newGroup, + int32_t errCode, int32_t userId) { if (!GetBundleActiveProxy()) { - return; + return -1; } - bundleActiveProxy_->SetBundleGroup(bundleName, newGroup, userId); - return; + return bundleActiveProxy_->SetBundleGroup(bundleName, newGroup, errCode, userId); } std::vector BundleActiveClient::QueryCurrentPackageStats(const int32_t intervalType, @@ -111,12 +111,13 @@ std::vector BundleActiveClient::QueryCurrentEvents(const int6 return bundleActiveProxy_->QueryCurrentEvents(beginTime, endTime); } -int32_t BundleActiveClient::QueryPackageGroup() +int32_t BundleActiveClient::QueryPackageGroup(std::string& bundleName, const int32_t userId) { if (!GetBundleActiveProxy()) { return -1; } - return bundleActiveProxy_->QueryPackageGroup(); + int32_t result = bundleActiveProxy_->QueryPackageGroup(bundleName, userId); + return result; } int32_t BundleActiveClient::QueryFormStatistics(int32_t maxNum, std::vector& results, @@ -132,6 +133,42 @@ 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::QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + if (!GetBundleActiveProxy()) { + return -1; + } + return bundleActiveProxy_->QueryEventStats(beginTime, endTime, eventStats, userId); +} + +int32_t BundleActiveClient::QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + if (!GetBundleActiveProxy()) { + return -1; + } + return bundleActiveProxy_->QueryAppNotificationNumber(beginTime, endTime, eventStats, userId); +} + 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..768d8093614a77445cdb2d432cc38cf8d7a15972 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp @@ -0,0 +1,52 @@ +/* + * 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..7b8ebce88690908661e287ffb5b0530e0cda6897 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_stub.cpp @@ -0,0 +1,54 @@ +/* + * 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 { +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_LOGI("RegisterGroupCallBack OnRemoteRequest cannot get power mgr service"); + return -1; + } + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack BundleActiveGroupCallbackStub will switch"); + switch (code) { + case static_cast(IBundleActiveGroupCallback::message::ON_BUNDLE_GROUP_CHANGED): { + std::shared_ptr groupInfo( + data.ReadParcelable()); + if (!groupInfo) { + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack ReadParcelable failed"); + return -1; + } + OnBundleGroupChanged(*(groupInfo.get())); + groupInfo = nullptr; + 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..1392c7d3e063d0e6c3660f1bb633bb77968e8690 100644 --- a/interfaces/innerkits/src/bundle_active_proxy.cpp +++ b/interfaces/innerkits/src/bundle_active_proxy.cpp @@ -116,18 +116,23 @@ std::vector BundleActiveProxy::QueryEvents(const int64_t begi return result; } -void BundleActiveProxy::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) +int32_t BundleActiveProxy::SetBundleGroup(const std::string& bundleName, int32_t newGroup, + int32_t errCode, int32_t userId) { + BUNDLE_ACTIVE_LOGI("SetBundleGroup enter bundleActiveProxy"); MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - return; + return -1; } 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 +198,20 @@ std::vector BundleActiveProxy::QueryCurrentEvents(const int64 return result; } -int32_t BundleActiveProxy::QueryPackageGroup() +int32_t BundleActiveProxy::QueryPackageGroup(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; + int32_t result = reply.ReadInt32(); + return result; } int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector& results, @@ -242,6 +249,98 @@ int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector &observer) +{ + 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; + } + 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 reply.ReadInt32(); +} + +int32_t BundleActiveProxy::UnregisterGroupCallBack(const sptr &observer) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGE("observer null"); + return false; + } + 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 reply.ReadInt32(); +} + +int32_t BundleActiveProxy::QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + int32_t errCode = IPCCommunication(beginTime, endTime, eventStats, userId, QUERY_EVENT_STATS); + for (const auto& singleEvent : eventStats) { + BUNDLE_ACTIVE_LOGI("name is %{public}s, eventId is %{public}d, count is %{public}d", + singleEvent.name_.c_str(), singleEvent.eventId_, singleEvent.count_); + } + return errCode; +} + +int32_t BundleActiveProxy::QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + int32_t errCode = IPCCommunication(beginTime, endTime, eventStats, userId, QUERY_APP_NOTIFICATION_NUMBER); + for (const auto& singleEvent : eventStats) { + BUNDLE_ACTIVE_LOGI("name is %{public}s, eventId is %{public}d, count is %{public}d", + singleEvent.name_.c_str(), singleEvent.eventId_, singleEvent.count_); + } + return errCode; +} + +int32_t BundleActiveProxy::IPCCommunication(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId, int32_t communicationFlag) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return -1; + } + data.WriteInt64(beginTime); + data.WriteInt64(endTime); + data.WriteInt32(userId); + Remote() -> SendRequest(communicationFlag, data, reply, option); + int32_t errCode = reply.ReadInt32(); + int32_t size = reply.ReadInt32(); + std::shared_ptr tmp; + for (int32_t i = 0; i < size; i++) { + tmp = tmp->UnMarshalling(reply); + if (!tmp) { + continue; + } + eventStats.emplace_back(*tmp); + } + return errCode; +} } // 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..265e869506739754977a864cdc48021b3858c804 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, @@ -174,6 +174,27 @@ declare namespace bundleState { formRecords: Array; } + /** + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + */ + interface BundleActiveEventState { + /** + * the bundle name or system event name. + */ + name?: string; + + /** + * the event id. + */ + eventId: number; + + /** + * the the event occurrence number. + */ + count: number; + } + /** * @since 7 * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App @@ -204,6 +225,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 + */ + userId?: 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. @@ -218,19 +265,6 @@ declare namespace bundleState { function isIdleState(bundleName: string, callback: AsyncCallback): void; function isIdleState(bundleName: string): Promise; - /** - * Queries the usage priority group of the calling application. - * - *

The priority defined in a priority group restricts the resource usage of an application, - * for example, restricting the running of background tasks.

- * - * @since 7 - * @syscap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup - * @return Returns the usage priority group of the calling application. - */ - function queryAppUsagePriorityGroup(callback: AsyncCallback): void; - function queryAppUsagePriorityGroup(): Promise; - /** * @since 7 * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App @@ -343,6 +377,115 @@ declare namespace bundleState { */ function getRecentlyUsedModules(maxNum?: number, callback: AsyncCallback>): void; function getRecentlyUsedModules(maxNum?: number): Promise>; + + /** + * Queries the usage priority group of the calling application. + * + *

The priority defined in a priority group restricts the resource usage of an application, + * for example, restricting the running of background tasks.

+ * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup + * @return Returns the usage priority group of the calling application. + */ + function queryAppUsagePriorityGroup(bundleName? : string, callback: AsyncCallback): void; + function queryAppUsagePriorityGroup(bundleName? : string): Promise; + + /** + * Declares group type. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + */ + export enum GroupType { + /** + * Indicates the alive group. + */ + ACTIVE_GROUP_ALIVE = 10, + + /** + * Indicates the daily group. + */ + ACTIVE_GROUP_DAILY = 20, + + /** + * Indicates the fixed group. + */ + ACTIVE_GROUP_FIXED = 30, + + /** + * Indicates the rare group. + */ + ACTIVE_GROUP_RARE = 40, + + /** + * Indicates the limit group. + */ + ACTIVE_GROUP_LIMIT = 50, + + /** + * Indicates the never group. + */ + ACTIVE_GROUP_NEVER = 60 + } + + /** + * set bundle group by bundleName and number. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @return Returns the result of setBundleGroup, true of false. + */ + function setBundleGroup(bundleName: string, newGroup: GroupType, callback: AsyncCallback): void; + function setBundleGroup(bundleName: string, newGroup: GroupType): Promise; + + /** + * register callback to service. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @return Returns BundleActiveGroupCallbackInfo when the group of bundle changed. the result of AsyncCallback is true or false. + */ + function registerGroupCallBack(callback: Callback, callback: AsyncCallback): void; + function registerGroupCallBack(callback: Callback): Promise; + + /** + * unRegister callback from service. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @return Returns the result of unRegisterGroupCallBack, true of false. + */ + function unRegisterGroupCallBack(callback: AsyncCallback): void; + function unRegisterGroupCallBack(): Promise; + + /* + * Queries system event states data within a specified period identified by the start and end time. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @param begin Indicates the start time of the query period, in milliseconds. + * @param end Indicates the end time of the query period, in milliseconds. + * @return Returns the {@link BundleActiveEventState} object Array containing the event states data. + */ + function queryBundleActiveEventStates(begin: number, end: number, callback: AsyncCallback>): void; + function queryBundleActiveEventStates(begin: number, end: number): Promise>; + + /** + * Queries app notification number within a specified period identified by the start and end time. + * + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @param begin Indicates the start time of the query period, in milliseconds. + * @param end Indicates the end time of the query period, in milliseconds. + * @return Returns the {@link BundleActiveEventState} object Array containing the event states data. + */ + function queryAppNotificationNumber(begin: number, end: number, callback: AsyncCallback>): void; + function queryAppNotificationNumber(begin: number, end: number): 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..3e7cd4fa8f1b687f3ab35ef40e62d1deec1f9161 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_active_group_observer.h @@ -0,0 +1,58 @@ +/* + * 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; +}; + +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_common.h b/interfaces/kits/bundlestats/napi/include/bundle_state_common.h index f2a172aa2f08fce36dc6f07cab6252226d040f19..a0f551216710e83afa8c18789fff4c379132f29e 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_common.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_common.h @@ -50,6 +50,12 @@ public: static void GetBundleStateInfoByIntervalForResult( napi_env env, const std::vector &packageStats, napi_value result); + static void GetBundleActiveEventStatsForResult(napi_env env, + const std::vector &eventStats, napi_value result); + + static void GetBundleActiveNotificationNumberForResult(napi_env env, + const std::vector &eventStats, napi_value result); + static void GetBundleStateInfoForResult(napi_env env, const std::shared_ptr> &packageStats, napi_value result); @@ -74,6 +80,9 @@ public: int64_t &beginTime, int64_t &endTime, int32_t &errCode); static void MergePackageStats(BundleActivePackageStats &left, const BundleActivePackageStats &right); + + static std::unique_ptr HandleEventStatsInfo( + AsyncCallbackInfoEventStats *asyncCallbackInfo, EventStatesParamsInfo ¶ms); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_condition.h b/interfaces/kits/bundlestats/napi/include/bundle_state_condition.h index eb4dc7aee7ccb83f126ca1375943e8776af288ef..d051d6a16e7955dacea35afa18f063fc58d3e32e 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_condition.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_condition.h @@ -30,6 +30,15 @@ public: BY_MONTHLY, BY_ANNUALLY, }; + + enum GroupType { + ACTIVE_GROUP_ALIVE = 10, + ACTIVE_GROUP_DAILY = 20, + ACTIVE_GROUP_FIXED = 30, + ACTIVE_GROUP_RARE = 40, + ACTIVE_GROUP_LIMIT = 50, + ACTIVE_GROUP_NEVER = 60, + }; }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_data.h b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h index b27b51d8a639e7ccc8e6501b1caca69cced3f1f1..6856cf08635cb38c41cdbd9f9226e3db2c0e5721 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_data.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h @@ -23,7 +23,9 @@ #include "napi/native_node_api.h" #include "bundle_active_event.h" +#include "bundle_active_event_stats.h" #include "bundle_active_package_stats.h" +#include "bundle_active_group_observer.h" namespace OHOS { namespace DeviceUsageStats { @@ -42,6 +44,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,6 +58,16 @@ struct AsyncWorkData { int32_t errorCode = 0; }; +struct CallbackReceiveDataWorker { + napi_env env = nullptr; + napi_ref ref = nullptr; + int32_t oldGroup = 0; + int32_t newGroup = 0; + int32_t userId = -1; + uint32_t changeReason = 0; + std::string bundleName; +}; + struct AsyncCallbackInfoIsIdleState : public AsyncWorkData { explicit AsyncCallbackInfoIsIdleState(napi_env env) : AsyncWorkData(env) {} std::string bundleName = ""; @@ -62,7 +76,8 @@ struct AsyncCallbackInfoIsIdleState : public AsyncWorkData { struct AsyncCallbackInfoPriorityGroup : public AsyncWorkData { explicit AsyncCallbackInfoPriorityGroup(napi_env env) : AsyncWorkData(env) {} - int32_t priorityGroup = 60; + std::string bundleName = ""; + int32_t priorityGroup = -1; }; struct AsyncCallbackInfoStates : public AsyncWorkData { @@ -80,12 +95,25 @@ struct AsyncCallbackInfoAppUsageByInterval : public AsyncWorkData { std::vector packageStats; }; +struct AsyncCallbackInfoEventStats : public AsyncWorkData { + explicit AsyncCallbackInfoEventStats(napi_env env) : AsyncWorkData(env) {} + int64_t beginTime = -1; + int64_t endTime = -1; + std::vector eventStats; +}; + struct AsyncCallbackInfoAppUsage : public AsyncWorkData { explicit AsyncCallbackInfoAppUsage(napi_env env) : AsyncWorkData(env) {} int64_t beginTime = -1; int64_t endTime = -1; std::shared_ptr> packageStats; }; +struct AsyncCallbackInfoSetBundleGroup : public AsyncWorkData { + explicit AsyncCallbackInfoSetBundleGroup(napi_env env) : AsyncWorkData(env) {} + int32_t newGroup = -1;; + std::string bundleName = ""; + bool state = true; +}; struct AsyncCallbackInfoModuleRecord : public AsyncWorkData { explicit AsyncCallbackInfoModuleRecord(napi_env env) : AsyncWorkData(env) {} @@ -93,6 +121,18 @@ struct AsyncCallbackInfoModuleRecord : public AsyncWorkData { std::vector moduleRecords; }; +struct AsyncUnRegisterCallbackInfo : public AsyncWorkData { + explicit AsyncUnRegisterCallbackInfo(napi_env env) : AsyncWorkData(env) {} + sptr observer = nullptr; + bool state = true; +}; + +struct AsyncRegisterCallbackInfo : public AsyncWorkData { + explicit AsyncRegisterCallbackInfo(napi_env env) : AsyncWorkData(env) {} + sptr observer = nullptr; + bool state = true; +}; + struct IsIdleStateParamsInfo { std::string bundleName = ""; napi_ref callback = nullptr; @@ -100,6 +140,7 @@ struct IsIdleStateParamsInfo { }; struct PriorityGroupParamsInfo { + std::string bundleName; napi_ref callback = nullptr; int32_t errorCode = 0; }; @@ -131,6 +172,30 @@ struct ModuleRecordParamsInfo { napi_ref callback = nullptr; int32_t errorCode = 0; }; + +struct ParamsBundleGroupInfo { + std::string bundleName = ""; + int32_t newGroup = -1; + 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; +}; + +struct EventStatesParamsInfo { + int64_t beginTime = -1; + int64_t endTime = -1; + 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_init.h b/interfaces/kits/bundlestats/napi/include/bundle_state_init.h index 7ac5260b0e8a45035b36464000ebeabc005e3012..8e65667bcfce6f98b9cc62e4a618ef0c9968bb8d 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_init.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_init.h @@ -28,7 +28,8 @@ extern "C" { __attribute__((constructor)) void RegisterModule(void); static napi_value BundleStateInit(napi_env env, napi_value exports); static napi_value InitIntervalType(napi_env env, napi_value exports); -static napi_value EnumIntervalTypeConstructor(napi_env env, napi_callback_info info); +static napi_value InitGroupType(napi_env env, napi_value exports); +static napi_value EnumTypeConstructor(napi_env env, napi_callback_info info); #ifdef __cplusplus } 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..7d54aa3fb3b90dc1c3c78e56d3c863543f54a3f5 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_inner_errors.h @@ -49,7 +49,14 @@ 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, + ERR_EVENT_TYPE, + ERR_EVENT_TYPE_NUMBER, + ERR_SERVICE_FAILED, + ERR_REPEAT_OPERATION, + ERR_REGISTER_OBSERVER_IS_NULL, + ERR_OBSERVER_CALLBACK_IS_INVALID, }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_query.h b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h index 0a0492aaa541cfe9d4e674c5668a6ad8513e28e5..ab87f75a5c06bb2feb1bf22d702c8da7aaebc352 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_query.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h @@ -28,6 +28,9 @@ 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); + napi_value QueryBundleActiveEventStates(napi_env env, napi_callback_info info); + napi_value QueryAppNotificationNumber(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..9ecd0abdff79a12004ff4d6b822fed244d23f135 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 @@ -94,17 +94,19 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest003 - * @tc.desc: test queryAppUsagePriorityGroup promise. + * @tc.desc: test queryBundleActiveStates promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ it("DeviceUsageStatisticsJsTest003", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest003---------------------------'); - bundleState.queryAppUsagePriorityGroup().then( res => { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise success.'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryBundleActiveStates(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryBundleActiveStates promise success.'); expect(true).assertEqual(true); - }).catch( err => { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); + }).catch((err) => { + console.info('BUNDLE_ACTIVE queryBundleActiveStates promise failure.'); expect(false).assertEqual(true); }); @@ -115,18 +117,20 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest004 - * @tc.desc: test queryAppUsagePriorityGroup callback. + * @tc.desc: test queryBundleActiveStates callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ it("DeviceUsageStatisticsJsTest004", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest004---------------------------'); - bundleState.queryAppUsagePriorityGroup((err, res) => { + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryBundleActiveStates(beginTime, endTime, (err, res) => { if (err) { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failure.'); + console.info('BUNDLE_ACTIVE queryBundleActiveStates callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); + console.info('BUNDLE_ACTIVE queryBundleActiveStates callback success.'); expect(true).assertEqual(true); } }); @@ -138,7 +142,7 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest005 - * @tc.desc: test queryBundleActiveStates promise. + * @tc.desc: test queryBundleStateInfos promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ @@ -146,11 +150,11 @@ describe("DeviceUsageStatisticsJsTest", function () { console.info('----------------------DeviceUsageStatisticsJsTest005---------------------------'); let beginTime = 0; let endTime = 20000000000000; - bundleState.queryBundleActiveStates(beginTime, endTime).then((res) => { - console.info('BUNDLE_ACTIVE queryBundleActiveStates promise success.'); + bundleState.queryBundleStateInfos(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryBundleStateInfos promise success.'); expect(true).assertEqual(true); }).catch((err) => { - console.info('BUNDLE_ACTIVE queryBundleActiveStates promise failure.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfos promise failure.'); expect(false).assertEqual(true); }); @@ -161,7 +165,7 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest006 - * @tc.desc: test queryBundleActiveStates callback. + * @tc.desc: test queryBundleStateInfos callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ @@ -169,12 +173,12 @@ describe("DeviceUsageStatisticsJsTest", function () { console.info('----------------------DeviceUsageStatisticsJsTest006---------------------------'); let beginTime = 0; let endTime = 20000000000000; - bundleState.queryBundleActiveStates(beginTime, endTime, (err, res) => { + bundleState.queryBundleStateInfos(beginTime, endTime, (err, res) => { if (err) { - console.info('BUNDLE_ACTIVE queryBundleActiveStates callback failure.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfos callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE queryBundleActiveStates callback success.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfos callback success.'); expect(true).assertEqual(true); } }); @@ -186,7 +190,7 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest007 - * @tc.desc: test queryBundleStateInfos promise. + * @tc.desc: test queryCurrentBundleActiveStates promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ @@ -194,11 +198,11 @@ describe("DeviceUsageStatisticsJsTest", function () { console.info('----------------------DeviceUsageStatisticsJsTest007---------------------------'); let beginTime = 0; let endTime = 20000000000000; - bundleState.queryBundleStateInfos(beginTime, endTime).then((res) => { - console.info('BUNDLE_ACTIVE queryBundleStateInfos promise success.'); + bundleState.queryCurrentBundleActiveStates(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise success.'); expect(true).assertEqual(true); }).catch((err) => { - console.info('BUNDLE_ACTIVE queryBundleStateInfos promise failure.'); + console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise failure.'); expect(false).assertEqual(true); }); @@ -209,7 +213,7 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest008 - * @tc.desc: test queryBundleStateInfos callback. + * @tc.desc: test queryCurrentBundleActiveStates callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ @@ -217,12 +221,12 @@ describe("DeviceUsageStatisticsJsTest", function () { console.info('----------------------DeviceUsageStatisticsJsTest008---------------------------'); let beginTime = 0; let endTime = 20000000000000; - bundleState.queryBundleStateInfos(beginTime, endTime, (err, res) => { + bundleState.queryCurrentBundleActiveStates(beginTime, endTime, (err, res) => { if (err) { - console.info('BUNDLE_ACTIVE queryBundleStateInfos callback failure.'); + console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE queryBundleStateInfos callback success.'); + console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback success.'); expect(true).assertEqual(true); } }); @@ -234,19 +238,20 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest009 - * @tc.desc: test queryCurrentBundleActiveStates promise. + * @tc.desc: test queryBundleStateInfoByInterval promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ it("DeviceUsageStatisticsJsTest009", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest009---------------------------'); + let intervalType = 0; let beginTime = 0; let endTime = 20000000000000; - bundleState.queryCurrentBundleActiveStates(beginTime, endTime).then((res) => { - console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise success.'); + bundleState.queryBundleStateInfoByInterval(intervalType, beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise success.'); expect(true).assertEqual(true); }).catch((err) => { - console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise failure.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise failure.'); expect(false).assertEqual(true); }); @@ -257,20 +262,21 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest010 - * @tc.desc: test queryCurrentBundleActiveStates callback. + * @tc.desc: test queryBundleStateInfoByInterval callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ it("DeviceUsageStatisticsJsTest010", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest010---------------------------'); + let intervalType = 0; let beginTime = 0; let endTime = 20000000000000; - bundleState.queryCurrentBundleActiveStates(beginTime, endTime, (err, res) => { + bundleState.queryBundleStateInfoByInterval(intervalType, beginTime, endTime, (err, res) => { if (err) { - console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback failure.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback success.'); + console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback success.'); expect(true).assertEqual(true); } }); @@ -282,21 +288,21 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest011 - * @tc.desc: test queryBundleStateInfoByInterval promise. + * @tc.desc: test getRecentlyUsedModules callback. * @tc.type: FUNC - * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 + * @tc.require: SR000GU2UE AR0003GU3EQ */ it("DeviceUsageStatisticsJsTest011", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest011---------------------------'); - let intervalType = 0; - let beginTime = 0; - let endTime = 20000000000000; - bundleState.queryBundleStateInfoByInterval(intervalType, beginTime, endTime).then((res) => { - console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise success.'); - expect(true).assertEqual(true); - }).catch((err) => { - console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise failure.'); - expect(false).assertEqual(true); + let maxNum = 1; + bundleState.getRecentlyUsedModules(maxNum, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback failure.'); + expect(false).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback success.'); + expect(true).assertEqual(true); + } }); setTimeout(()=>{ @@ -306,21 +312,63 @@ describe("DeviceUsageStatisticsJsTest", function () { /* * @tc.name: DeviceUsageStatisticsJsTest012 - * @tc.desc: test queryBundleStateInfoByInterval callback. + * @tc.desc: test getRecentlyUsedModules promise. * @tc.type: FUNC - * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G + * @tc.require: SR000GU2UE AR0003GU3EQ */ it("DeviceUsageStatisticsJsTest012", 0, async function (done) { console.info('----------------------DeviceUsageStatisticsJsTest012---------------------------'); - let intervalType = 0; - let beginTime = 0; - let endTime = 20000000000000; - bundleState.queryBundleStateInfoByInterval(intervalType, beginTime, endTime, (err, res) => { + let maxNum = 1; + bundleState.getRecentlyUsedModules(maxNum).then((res) => { + console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise success.'); + expect(true).assertEqual(true); + }).catch((err) => { + console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest013 + * @tc.desc: test queryAppUsagePriorityGroup promise. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest013", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest013---------------------------'); + let bundleName = 'com.example.deviceUsageStatistics'; + bundleState.queryAppUsagePriorityGroup(bundleName).then( res => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise success.'); + expect(true).assertEqual(true); + }).catch( err => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest014 + * @tc.desc: test queryAppUsagePriorityGroup callback. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest014", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest014---------------------------'); + let bundleName = 'com.example.deviceUsageStatistics'; + bundleState.queryAppUsagePriorityGroup(bundleName, (err, res) => { if (err) { - console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback failure.'); + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback success.'); + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); expect(true).assertEqual(true); } }); @@ -331,20 +379,40 @@ describe("DeviceUsageStatisticsJsTest", function () { }) /* - * @tc.name: DeviceUsageStatisticsJsTest013 - * @tc.desc: test getRecentlyUsedModules callback. + * @tc.name: DeviceUsageStatisticsJsTest015 + * @tc.desc: test queryAppUsagePriorityGroup promise, with no param. * @tc.type: FUNC - * @tc.require: SR000GU2UE AR0003GU3EQ + * @tc.require: SR000H0HAQ AR000H0ROE */ - it("DeviceUsageStatisticsJsTest013", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest013---------------------------'); - let maxNum = 1; - bundleState.getRecentlyUsedModules(maxNum, (err, res) => { + it("DeviceUsageStatisticsJsTest015", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest015---------------------------'); + bundleState.queryAppUsagePriorityGroup().then( res => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise success.'); + expect(true).assertEqual(true); + }).catch( err => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest016 + * @tc.desc: test queryAppUsagePriorityGroup callback, with no param. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest016", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest016---------------------------'); + bundleState.queryAppUsagePriorityGroup((err, res) => { if (err) { - console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback failure.'); + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failure.'); expect(false).assertEqual(true); } else { - console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback success.'); + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); expect(true).assertEqual(true); } }); @@ -355,19 +423,172 @@ describe("DeviceUsageStatisticsJsTest", function () { }) /* - * @tc.name: DeviceUsageStatisticsJsTest014 - * @tc.desc: test getRecentlyUsedModules promise. + * @tc.name: DeviceUsageStatisticsJsTest017 + * @tc.desc: test setBundleGroup promise. * @tc.type: FUNC - * @tc.require: SR000GU2UE AR0003GU3EQ + * @tc.require: SR000H0HAQ AR000H0ROE */ - it("DeviceUsageStatisticsJsTest014", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest014---------------------------'); - let maxNum = 1; - bundleState.getRecentlyUsedModules(maxNum).then((res) => { - console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise success.'); + it("DeviceUsageStatisticsJsTest017", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest017---------------------------'); + let bundleName = 'com.example.deviceUsageStatistics'; + let newGroup = 30; + bundleState.setBundleGroup(bundleName, newGroup).then( res => { + console.info('BUNDLE_ACTIVE setBundleGroup promise success.'); + expect(true).assertEqual(true); + }).catch( err => { + console.info('BUNDLE_ACTIVE setBundleGroup promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest018 + * @tc.desc: test setBundleGroup callback. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest018", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest018---------------------------'); + let bundleName = 'com.example.deviceUsageStatistics'; + let newGroup = 30; + bundleState.setBundleGroup(bundleName, newGroup, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE setBundleGroup callback failure.'); + expect(true).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE setBundleGroup callback success.'); + expect(false).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest019 + * @tc.desc: test registerGroupCallBack promise. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest019", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest019---------------------------'); + let onBundleGroupChanged = (err,res) =>{ + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.'); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack oldGroup is : ' + res.oldGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack newGroup is : ' + res.newGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack changeReason is : ' + res.newGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack bundleName is : ' + res.bundleName); + }; + bundleState.registerGroupCallBack(onBundleGroupChanged).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: DeviceUsageStatisticsJsTest020 + * @tc.desc: test registerGroupCallBack callback. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest020", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest020---------------------------'); + let onBundleGroupChanged = (err,res) =>{ + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.'); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack oldGroup is : ' + res.oldGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack newGroup is : ' + res.newGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack changeReason is : ' + res.newGroup); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack bundleName is : ' + res.bundleName); + }; + bundleState.registerGroupCallBack(onBundleGroupChanged, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback failure.'); + expect(true).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback success.'); + expect(false).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest021 + * @tc.desc: test unRegisterGroupCallBack promise. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest021", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest021---------------------------'); + bundleState.unRegisterGroupCallBack().then( res => { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack promise success.'); + expect(true).assertEqual(true); + }).catch( err => { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest022 + * @tc.desc: test unRegisterGroupCallBack callback. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest022", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest022---------------------------'); + bundleState.unRegisterGroupCallBack((err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack callback failure.'); + expect(true).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack callback success.'); + expect(false).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest020 + * @tc.desc: test queryBundleActiveEventStates promise. + * @tc.type: FUNC + * @tc.require: SR000H0H9H AR000H0ROG + */ + it("DeviceUsageStatisticsJsTest020", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest020---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryBundleActiveEventStates(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates promise success.'); expect(true).assertEqual(true); }).catch((err) => { - console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise failure.'); + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates promise failure.'); expect(false).assertEqual(true); }); @@ -375,5 +596,78 @@ describe("DeviceUsageStatisticsJsTest", function () { done(); }, 500); }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest021 + * @tc.desc: test queryBundleActiveEventStates callback. + * @tc.type: FUNC + * @tc.require: SR000H0H9H AR000H0ROG + */ + it("DeviceUsageStatisticsJsTest021", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest021---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryBundleActiveEventStates(beginTime, endTime, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates callback failure.'); + expect(false).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates callback success.'); + expect(true).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest022 + * @tc.desc: test queryAppNotificationNumber promise. + * @tc.type: FUNC + * @tc.require: SR000H0H7D AR000H0RR6 + */ + it("DeviceUsageStatisticsJsTest022", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest022---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryAppNotificationNumber(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber promise success.'); + expect(true).assertEqual(true); + }).catch((err) => { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber promise failure.'); + expect(false).assertEqual(true); + }); + + setTimeout(()=>{ + done(); + }, 500); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest023 + * @tc.desc: test queryAppNotificationNumber callback. + * @tc.type: FUNC + * @tc.require: SR000H0H7D AR000H0RR6 + */ + it("DeviceUsageStatisticsJsTest023", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest023---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryAppNotificationNumber(beginTime, endTime, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber callback failure.'); + expect(false).assertEqual(true); + } else { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber callback success.'); + expect(true).assertEqual(true); + } + }); + + setTimeout(()=>{ + done(); + }, 500); + }) }) diff --git a/services/common/include/bundle_active_common_event_subscriber.h b/services/common/include/bundle_active_common_event_subscriber.h index 5ffc4030da50b5a03a1a85fb6c7a1a3c73641131..def3de908c2c2755bc2e67cf38bda7ed79557d45 100644 --- a/services/common/include/bundle_active_common_event_subscriber.h +++ b/services/common/include/bundle_active_common_event_subscriber.h @@ -46,6 +46,7 @@ public: bundleActiveReportHandler_(bundleActiveReportHandler) {} ~BundleActiveCommonEventSubscriber() = default; void OnReceiveEvent(const CommonEventData &data) override; + void HandleLockEvent(const std::string& action, const int32_t userId); private: std::mutex mutex_; diff --git a/services/common/include/bundle_active_constant.h b/services/common/include/bundle_active_constant.h index e20b850c7dc002c4d37d6f91fcad0ac0c537ba1e..8cd7ba58b7f79ca8338b827ae4a8ed966a374150 100644 --- a/services/common/include/bundle_active_constant.h +++ b/services/common/include/bundle_active_constant.h @@ -69,6 +69,8 @@ const int32_t FORM_DIMENSION_COLUMN_INDEX = 4; const int32_t FORM_ID_COLUMN_INDEX = 5; const int32_t FORM_COUNT_COLUMN_INDEX = 6; const int32_t FORM_LAST_TIME_COLUMN_INDEX = 7; +const int32_t QUERY_CONDITION_VALID = 0; +const int32_t QUERY_CONDITION_INVALID = -1; const int64_t TWO_SECONDS = 2 * 1000LL; const int64_t THIRTY_MINUTE = 30 * 60 * 1000LL; const int64_t SIX_DAY_IN_MILLIS_MAX_DEBUG = 6 * 1 * 10 * 60 * 1000LL; @@ -121,12 +123,18 @@ 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/system_ce/bundle_usage/"; +const std::string BUNDLE_ACTIVE_DATABASE_DIR = "/data/service/el1/public/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"; +const std::string COMMON_EVENT_UNLOCK_SCREEN = "common.event.UNLOCK_SCREEN"; +const std::string COMMON_EVENT_LOCK_SCREEN = "common.event.LOCK_SCREEN"; const std::string DATABASE_TYPE[] = {"daily", "weekly", "monthly", "yearly", "event", "usageGroup"}; const std::string SUFFIX_TYPE[] = {".db", ".db-shm", ".db-wal"}; +const std::string OPERATION_SYSTEM_LOCK = "SYSTEM_LOCK"; +const std::string OPERATION_SYSTEM_UNLOCK = "SYSTEM_UNLOCK"; +const std::string OPERATION_SYSTEM_SLEEP = "SYSTEM_SLEEP"; +const std::string OPERATION_SYSTEM_WAKEUP = "SYSTEM_WAKEUP"; } // namespace DeviceUsageStats } // namespace OHOS #endif // BUNDLE_ACTIVE_CONSTANT_H diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h index 3c861ce114a3dc465d943d84b8c1a01a188a2cd9..4f61f0582506f96da6dedd91c163aa31faf3dd1f 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_death_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,8 @@ public: class BundleActiveReportHandler; -class BundleActiveCore : public BundleActiveStatsUpdateListener { +class BundleActiveCore : public BundleActiveStatsUpdateListener, + public std::enable_shared_from_this { public: BundleActiveCore(); virtual ~BundleActiveCore(); @@ -54,7 +60,7 @@ public: * function: ReportEvent, used to report ability fourground/background/destroy event. * parameters: event, userId */ - int32_t ReportEvent(BundleActiveEvent& event, const int32_t userId); + int32_t ReportEvent(BundleActiveEvent& event, int32_t userId); /* * function: ReportEventToAllUserId, report flush to disk, end_of_day event to service. * parameters: event @@ -112,6 +118,10 @@ public: */ void ShutDown(); /* + * function: PreservePowerStateInfo, called when device change power state, preserve power state info. + */ + void PreservePowerStateInfo(const int32_t eventId); + /* * function: QueryPackageStats, query the package stat for calling user. * parameters: userId, intervalType, beginTime, endTime, bundleName * return: vector of BundleActivePackageStats @@ -124,8 +134,25 @@ 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); + /* + * function: QueryEventStats, query all from event stats in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId); + + /* + * function: QueryAppNotificationNumber, query all app notification number in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId); // get the wall time and check if the wall time is changed. int64_t CheckTimeChangeAndGetWallTime(int32_t userId = 0); // convert event timestamp from boot based time to wall time. @@ -138,16 +165,35 @@ 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(); + /* + * function: RegisterGroupCallBack, register the observer to groupObservers. + * parameters: observer + * return: result of RegisterGroupCallBack, true or false. + */ + int32_t RegisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, + const sptr &observer); + /* + * function: UnregisterGroupCallBack, remove the observer from groupObservers. + * parameters: observer + * return: result of UnregisterGroupCallBack, true or false. + */ + 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 +205,15 @@ 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_; + void ObtainSystemEventName(BundleActiveEvent& event); 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_power_state_callback_proxy.h b/services/common/include/bundle_active_power_state_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..c0a158a610d66fd98b7366a661a0cf851d5b4a8d --- /dev/null +++ b/services/common/include/bundle_active_power_state_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_POWER_STATE_CALLBACK_PROXY_H +#define BUNDLE_ACTIVE_POWER_STATE_CALLBACK_PROXY_H + +#include "ibundle_active_service.h" +#include "ipower_state_callback.h" +#include "nocopyable.h" + +namespace OHOS { +namespace DeviceUsageStats { +using IPowerStateCallback = OHOS::PowerMgr::IPowerStateCallback; +class BundleActivePowerStateCallbackProxy : public IRemoteProxy { +public: + explicit BundleActivePowerStateCallbackProxy(const sptr& impl) + : IRemoteProxy(impl) {} + ~BundleActivePowerStateCallbackProxy() = default; + DISALLOW_COPY_AND_MOVE(BundleActivePowerStateCallbackProxy); + void OnPowerStateChanged(PowerMgr::PowerState state) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_POWER_STATE_CALLBACK_PROXY_H + diff --git a/services/common/include/bundle_active_power_state_callback_service.h b/services/common/include/bundle_active_power_state_callback_service.h new file mode 100644 index 0000000000000000000000000000000000000000..7cca1ea5e8f845d3d0cf5e4c3eceae27bef49c54 --- /dev/null +++ b/services/common/include/bundle_active_power_state_callback_service.h @@ -0,0 +1,36 @@ + /* + * 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_POWER_STATE_CALLBACK_SERVICE_H +#define BUNDLE_ACTIVE_POWER_STATE_CALLBACK_SERVICE_H + +#include "bundle_active_power_state_callback_stub.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace DeviceUsageStats { +using OHOS::PowerMgr::PowerState; +class BundleActivePowerStateCallbackService : public BundleActivePowerStateCallbackStub { +public: + BundleActivePowerStateCallbackService(std::shared_ptr bundleActiveCore); + virtual ~BundleActivePowerStateCallbackService() {} + void OnPowerStateChanged(PowerState state) override; +private: + std::shared_ptr bundleActiveCore_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_POWER_STATE_CALLBACK_SERVICE_H + diff --git a/services/common/include/bundle_active_power_state_callback_stub.h b/services/common/include/bundle_active_power_state_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..93ec067c8636cb01992f33b91860898e2e610544 --- /dev/null +++ b/services/common/include/bundle_active_power_state_callback_stub.h @@ -0,0 +1,40 @@ +/* + * 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_POWER_STATE_CALLBACK_STUB_H +#define BUNDLE_ACTIVE_POWER_STATE_CALLBACK_STUB_H + +#include "ipower_state_callback.h" +#include "nocopyable.h" + +#include "ibundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +using IPowerStateCallback = OHOS::PowerMgr::IPowerStateCallback; +using PowerState = OHOS::PowerMgr::PowerState; +class BundleActivePowerStateCallbackStub : public IRemoteStub { +public: + DISALLOW_COPY_AND_MOVE(BundleActivePowerStateCallbackStub); + BundleActivePowerStateCallbackStub() = default; + virtual ~BundleActivePowerStateCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, MessageOption &option) override; +private: + void PowerStateStub(PowerState state); +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_POWER_STATE_CALLBACK_STUB_H + diff --git a/services/common/include/bundle_active_service.h b/services/common/include/bundle_active_service.h index e8921a47ed0ed02e28fe2e4b927f54cd366407a9..954a28bac8ff99909618a85869607f94f85feced 100644 --- a/services/common/include/bundle_active_service.h +++ b/services/common/include/bundle_active_service.h @@ -24,6 +24,7 @@ #include "bundle_active_core.h" #include "bundle_active_report_handler.h" #include "bundle_active_shutdown_callback_service.h" +#include "bundle_active_power_state_callback_service.h" #include "bundle_active_app_state_observer.h" #include "bundle_active_continuous_task_observer.h" #include "bundle_active_account_helper.h" @@ -35,7 +36,6 @@ class BundleActiveService : public SystemAbility, public BundleActiveStub, DISALLOW_COPY_AND_MOVE(BundleActiveService); DECLARE_SYSTEM_ABILITY(BundleActiveService); DECLARE_DELAYED_SINGLETON(BundleActiveService); - public: using IBundleMgr = OHOS::AppExecFwk::IBundleMgr; using BundleInfo = OHOS::AppExecFwk::BundleInfo; @@ -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; + int32_t 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,20 +93,50 @@ public: * function: QueryPackageGroup, query bundle priority group calling bundle. * return: the priority group of calling bundle. */ - int32_t QueryPackageGroup() override; + int32_t QueryPackageGroup(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, - * if other SAs call this API, they should explicit define userId + * if other SAs call this API, they should explicit define userId. * return: errorcode. */ int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId = -1) override; /* + * function: QueryEventStats, query all from event stats in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) override; + /* + * function: QueryAppNotificationNumber, query all app notification number in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) override; + /* * function: BundleActiveService, default constructor. * parameters: systemAbilityId, runOnCreate */ BundleActiveService(const int32_t systemAbilityId, bool runOnCreate); + /* + * function: RegisterGroupCallBack, register the observer to groupObservers. + * parameters: observer + * return: result of RegisterGroupCallBack, true or false. + */ + int32_t RegisterGroupCallBack(const sptr &observer) override; + /* + * function: UnregisterGroupCallBack, remove the observer from groupObservers. + * parameters: observer + * return: result of UnregisterGroupCallBack, true or false. + */ + int32_t UnregisterGroupCallBack(const sptr &observer) override; + +protected: /** * @brief The OnStart callback. */ @@ -123,6 +153,7 @@ private: std::shared_ptr continuousTaskObserver_; sptr sptrBundleMgr_; sptr shutdownCallback_; + sptr powerStateCallback_; std::shared_ptr runner_; std::shared_ptr handler_; bool ready_ {false}; diff --git a/services/common/include/bundle_active_usage_database.h b/services/common/include/bundle_active_usage_database.h index f26373cbbc4d5b873831444f2c66e2c494dacae3..e544d6c8b01d2d9839b9729a6a5c41aa483a6f04 100644 --- a/services/common/include/bundle_active_usage_database.h +++ b/services/common/include/bundle_active_usage_database.h @@ -41,7 +41,8 @@ public: ~BundleActiveUsageDatabase(); void InitDatabaseTableInfo(int64_t currentTime); void InitUsageGroupDatabase(const int32_t databaseType, const bool forModuleRecords); - void UpdateUsageData(int32_t databaseType, BundleActivePeriodStats &stats); + void UpdateBundleUsageData(int32_t databaseType, BundleActivePeriodStats &stats); + void UpdateEventData(int32_t databaseType, BundleActivePeriodStats &stats); std::shared_ptr GetCurrentUsageData(int32_t databaseType, int32_t userId); void RenewTableTime(int64_t timeDiffMillis); int32_t GetOptimalIntervalType(int64_t beginTime, int64_t endTime); @@ -67,6 +68,10 @@ public: std::shared_ptr>& moduleRecords); void LoadFormData(const int32_t userId, std::map>& moduleRecords); + void QueryEventStats(int32_t eventId, int64_t beginTime, int64_t endTime, + std::map& eventStats, int32_t userId); + void QueryAppNotificationNumber(int32_t eventId, int64_t beginTime, int64_t endTime, + std::map& notificationEventStats, int32_t userId); private: void CheckDatabaseVersion(); @@ -102,6 +107,8 @@ private: void UpdateFormData(const int32_t userId, const std::string bundleName, const std::string moduleName, const BundleActiveFormRecord& formRecord, std::shared_ptr rdbStore); + int32_t JudgeQueryCondition(const int64_t beginTime, const int64_t endTime, const int64_t eventTableTime); + std::string GetSystemEventName(const int32_t userId); private: std::vector databaseFiles_; diff --git a/services/common/include/ibundle_active_service.h b/services/common/include/ibundle_active_service.h index 63d332c2bac2a7d65d779fb9dccf9ecdce54b91f..eff21f7fec82534d0480ce2f20a1df0ecf7eba59 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" @@ -40,6 +42,7 @@ namespace OHOS { namespace DeviceUsageStats { class BundleActivePackageStats; class BundleActiveEvent; +class BundleActiveEventStats; class BundleActiveModuleRecord; class IBundleActiveService : public IRemoteBroker { @@ -90,21 +93,42 @@ 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(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 int32_t 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, - * if other SAs call this API, they should explicit define userId + * if other SAs call this API, they should explicit define userId. * return: errorcode. */ 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; + + /* + * function: QueryEventStats, query all from event stats in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + virtual int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) = 0; + + /* + * function: QueryAppNotificationNumber, query all app notification number in specific time span for calling user. + * parameters: beginTime, endTime, eventStats, userId, default userId is -1 for JS API, + * if other SAs call this API, they should explicit define userId. + * return: errorcode. + */ + virtual int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) = 0; public: enum { REPORT_EVENT = 1, @@ -115,7 +139,11 @@ 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, + QUERY_EVENT_STATS = 12, + QUERY_APP_NOTIFICATION_NUMBER = 13 }; public: DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveService"); diff --git a/services/common/include/remote_death_recipient.h b/services/common/include/remote_death_recipient.h new file mode 100644 index 0000000000000000000000000000000000000000..3398e220ba9b0a5cd1eb605c010fd9dfc9c33f7f --- /dev/null +++ b/services/common/include/remote_death_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..b6b5dad0c4726a1dacd4a4bb998d798e8133387b 100644 --- a/services/common/src/bundle_active_core.cpp +++ b/services/common/src/bundle_active_core.cpp @@ -13,10 +13,11 @@ * limitations under the License. */ #include "bundle_active_core.h" - +#include "accesstoken_kit.h" #include "time_service_client.h" #include "bundle_active_event.h" +#include "bundle_active_event_stats.h" #include "bundle_active_report_handler.h" #include "bundle_active_group_common.h" #include "bundle_active_constant.h" @@ -111,7 +112,33 @@ void BundleActiveCommonEventSubscriber::OnReceiveEvent(const CommonEventData &da handlerobjToPtr); bundleActiveReportHandler_.lock()->SendEvent(event); } + } else if (action == COMMON_EVENT_UNLOCK_SCREEN || action == COMMON_EVENT_LOCK_SCREEN) { + int32_t userId = data.GetWant().GetIntParam("userId", 0); + BUNDLE_ACTIVE_LOGI("action is %{public}s, userID is %{public}d", action.c_str(), userId); + HandleLockEvent(action, userId); + } +} + +void BundleActiveCommonEventSubscriber::HandleLockEvent(const std::string& action, const int32_t userId) +{ + if (bundleActiveReportHandler_.expired()) { + return; + } + BundleActiveReportHandlerObject tmpHandlerObject(-1, ""); + BundleActiveEvent newEvent; + tmpHandlerObject.event_ = newEvent; + if (action == COMMON_EVENT_UNLOCK_SCREEN) { + tmpHandlerObject.event_.eventId_ = BundleActiveEvent::SYSTEM_UNLOCK; + } else { + tmpHandlerObject.event_.eventId_ = BundleActiveEvent::SYSTEM_LOCK; } + tmpHandlerObject.userId_ = userId; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs(); + auto handlerobjToPtr = std::make_shared(tmpHandlerObject); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_REPORT_EVENT, + handlerobjToPtr); + bundleActiveReportHandler_.lock()->SendEvent(event); } void BundleActiveCore::RegisterSubscriber() @@ -124,6 +151,8 @@ void BundleActiveCore::RegisterSubscriber() matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED); + matchingSkills.AddEvent(COMMON_EVENT_UNLOCK_SCREEN); + matchingSkills.AddEvent(COMMON_EVENT_LOCK_SCREEN); CommonEventSubscribeInfo subscriberInfo(matchingSkills); commonEventSubscriber_ = std::make_shared(subscriberInfo, bundleGroupController_, handler_); @@ -164,7 +193,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; @@ -293,6 +322,28 @@ void BundleActiveCore::RestoreToDatabaseLocked(const int32_t userId) } } +void BundleActiveCore::PreservePowerStateInfo(const int32_t eventId) +{ + if (!handler_.expired()) { + int32_t userId = -1; + std::vector currentActiveUser; + BundleActiveCore::GetAllActiveUser(currentActiveUser); + if (currentActiveUser.size() == 1) { + userId = currentActiveUser.front(); + } + BundleActiveReportHandlerObject tmpHandlerObject(userId, ""); + BundleActiveEvent newEvent; + tmpHandlerObject.event_ = newEvent; + tmpHandlerObject.event_.eventId_ = eventId; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs(); + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpHandlerObject); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_REPORT_EVENT, handlerobjToPtr); + handler_.lock()->SendEvent(event); + } +} + void BundleActiveCore::ShutDown() { std::lock_guard lock(mutex_); @@ -410,9 +461,10 @@ void BundleActiveCore::OnUserSwitched(const int32_t userId) OnStatsChanged(userId); } -int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, const int32_t userId) +int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, int32_t userId) { BUNDLE_ACTIVE_LOGI("FLUSH interval is %{public}lld, debug is %{public}d", (long long)flushInterval_, debugCore_); + ObtainSystemEventName(event); event.PrintEvent(debugCore_); std::lock_guard lock(mutex_); if (userId == 0 || userId == -1) { @@ -422,7 +474,6 @@ int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, const int32_t us currentUsedUser_ = userId; BUNDLE_ACTIVE_LOGI("last used id change to %{public}d", currentUsedUser_); } - sptr timer = MiscServices::TimeServiceClient::GetInstance(); int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); if (event.bundleName_ == LAUNCHER_BUNDLE_NAME) { @@ -430,7 +481,6 @@ int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, const int32_t us bundleGroupController_->ReportEvent(event, bootBasedTimeStamp, userId); return 0; } - BUNDLE_ACTIVE_LOGI("report event called, bundle name %{public}s time %{public}lld userId %{public}d, " "eventid %{public}d, in lock range", event.bundleName_.c_str(), (long long)event.timeStamp_, userId, event.eventId_); @@ -455,6 +505,26 @@ int32_t BundleActiveCore::ReportEvent(BundleActiveEvent& event, const int32_t us return 0; } +void BundleActiveCore::ObtainSystemEventName(BundleActiveEvent& event) +{ + switch (event.eventId_) { + case BundleActiveEvent::SYSTEM_LOCK: + event.bundleName_ = OPERATION_SYSTEM_LOCK; + break; + case BundleActiveEvent::SYSTEM_UNLOCK: + event.bundleName_ = OPERATION_SYSTEM_UNLOCK; + break; + case BundleActiveEvent::SYSTEM_SLEEP: + event.bundleName_ = OPERATION_SYSTEM_SLEEP; + break; + case BundleActiveEvent::SYSTEM_WAKEUP: + event.bundleName_ = OPERATION_SYSTEM_WAKEUP; + break; + default: + break; + } +} + int32_t BundleActiveCore::ReportEventToAllUserId(BundleActiveEvent& event) { BUNDLE_ACTIVE_LOGI("ReportEventToAllUserId called"); @@ -543,17 +613,49 @@ int32_t BundleActiveCore::QueryFormStatistics(int32_t maxNum, std::vector& eventStats, int32_t userId) +{ + std::lock_guard lock(mutex_); + int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); + if (timeNow == -1) { + return -1; + } + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_); + if (!service) { + return -1; + } + int32_t errCode = service->QueryEventStats(beginTime, endTime, eventStats, userId); + return errCode; +} + +int32_t BundleActiveCore::QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + std::lock_guard lock(mutex_); + int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); + if (timeNow == -1) { + return -1; + } + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(userId, timeNow, debugCore_); + if (!service) { + return -1; + } + int32_t errCode = service->QueryAppNotificationNumber(beginTime, endTime, eventStats, userId); + return errCode; +} + +int32_t BundleActiveCore::SetBundleGroup(const std::string& bundleName, const int32_t newGroup, const int32_t userId) { int32_t newReason = GROUP_CONTROL_REASON_FORCED; sptr 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); } -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 +698,115 @@ int64_t BundleActiveCore::GetSystemTimeMs() } return static_cast(tarDate); } + +void BundleActiveCore::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo) +{ + 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, newGroup is %{public}d", + callbackInfo.GetOldGroup(), callbackInfo.GetNewGroup()); + observer->OnBundleGroupChanged(callbackInfo); + } + } +} + +int32_t BundleActiveCore::RegisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, + const sptr &observer) +{ + std::lock_guard lock(callbackMutex_); + if (!observer) { + return -1; + } + auto item = groupChangeObservers_.find(tokenId); + if (item != groupChangeObservers_.end()) { + return 1; + } + groupChangeObservers_.emplace(tokenId, observer); + AddObserverDeathRecipient(observer); + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack number is %{public}d", static_cast(groupChangeObservers_.size())); + return 0; +} + +int32_t BundleActiveCore::UnregisterGroupCallBack(const AccessToken::AccessTokenID& tokenId, + const sptr &observer) +{ + std::lock_guard lock(callbackMutex_); + auto item = groupChangeObservers_.find(tokenId); + if (item == groupChangeObservers_.end()) { + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack observer is not exist, return"); + return 1; + } + RemoveObserverDeathRecipient(item->second); + groupChangeObservers_.erase(tokenId); + return 0; +} + +void BundleActiveCore::AddObserverDeathRecipient(const sptr &observer) +{ + std::lock_guard lock(deathRecipientMutex_); + if (!observer || !(observer->AsObject())) { + BUNDLE_ACTIVE_LOGI("observer nullptr."); + return; + } + auto remoteObj = observer->AsObject(); + auto it = recipientMap_.find(observer->AsObject()); + if (it != recipientMap_.end()) { + BUNDLE_ACTIVE_LOGI("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_LOGI("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 (remote == nullptr || !objectProxy) { + BUNDLE_ACTIVE_LOGE("get remote object failed"); + return; + } + for (const auto& item : groupChangeObservers_) { + if ((item.second) && ((item.second)->AsObject()) && ((item.second)->AsObject() == objectProxy)) { + groupChangeObservers_.erase(item.first); + break; + } + } + recipientMap_.erase(objectProxy); +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_power_state_callback_proxy.cpp b/services/common/src/bundle_active_power_state_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..356183f8434feb840eb0c85de2d71c407ba0f6c5 --- /dev/null +++ b/services/common/src/bundle_active_power_state_callback_proxy.cpp @@ -0,0 +1,41 @@ +/* + * 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_power_state_callback_proxy.h" +#include "power_state_machine_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +void BundleActivePowerStateCallbackProxy::OnPowerStateChanged(PowerMgr::PowerState state) +{ + sptr remote = Remote(); + if (remote == nullptr) { + return; + } + MessageParcel data; + data.WriteInt32((int32_t)state); + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(BundleActivePowerStateCallbackProxy::GetDescriptor())) { + return; + } + int32_t ret = remote->SendRequest(IPowerStateCallback::POWER_STATE_CHANGED, data, reply, option); + if (ret != ERR_OK) { + BUNDLE_ACTIVE_LOGE("BundleActivePowerStateCallbackProxy::PowerStateCallback failed!"); + } +} +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/services/common/src/bundle_active_power_state_callback_service.cpp b/services/common/src/bundle_active_power_state_callback_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fcbdb3709b13cbf0c366081c36f5c90e14f6840a --- /dev/null +++ b/services/common/src/bundle_active_power_state_callback_service.cpp @@ -0,0 +1,45 @@ +/* + * 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_power_state_callback_service.h" +#include "power_state_machine_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +using OHOS::PowerMgr::PowerState; +BundleActivePowerStateCallbackService::BundleActivePowerStateCallbackService( + std::shared_ptr bundleActiveCore) +{ + if (bundleActiveCore != nullptr) { + bundleActiveCore_ = bundleActiveCore; + } +} + +void BundleActivePowerStateCallbackService::OnPowerStateChanged(PowerState state) +{ + int32_t eventId; + BUNDLE_ACTIVE_LOGD("BundleActDvePowerStateCallbackService::OnPowerStateChanged power state is %{public}u", state); + if (state == PowerState::AWAKE) { + eventId = BundleActiveEvent::SYSTEM_WAKEUP; + } else if (state == PowerState::SLEEP) { + eventId = BundleActiveEvent::SYSTEM_SLEEP; + } else { + return; + } + bundleActiveCore_->PreservePowerStateInfo(eventId); +} +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/services/common/src/bundle_active_power_state_callback_stub.cpp b/services/common/src/bundle_active_power_state_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ec2ff17d6e6023fdb831ce91634e797685f33a2 --- /dev/null +++ b/services/common/src/bundle_active_power_state_callback_stub.cpp @@ -0,0 +1,47 @@ +/* + * 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_power_state_callback_stub.h" +#include "bundle_active_event.h" + +namespace OHOS { +namespace DeviceUsageStats { +int32_t BundleActivePowerStateCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) +{ + std::u16string descriptor = BundleActivePowerStateCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + PowerMgr::PowerState state = (PowerMgr::PowerState)data.ReadInt32(); + if (descriptor != remoteDescriptor) { + BUNDLE_ACTIVE_LOGE("BundleActivePowerStateCallbackStub::OnRemoteRequest cannot get power mgr service"); + return -1; + } + switch (code) { + case IPowerStateCallback::POWER_STATE_CHANGED: { + PowerStateStub(state); + return ERR_OK; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} + +void BundleActivePowerStateCallbackStub::PowerStateStub(PowerMgr::PowerState state) +{ + OnPowerStateChanged(state); +} +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/services/common/src/bundle_active_service.cpp b/services/common/src/bundle_active_service.cpp index 08754af6078d8f34f2d93c92fe20be67e5715de9..fd6e68ac3003f065c16ea88768259a121c944475 100644 --- a/services/common/src/bundle_active_service.cpp +++ b/services/common/src/bundle_active_service.cpp @@ -62,15 +62,8 @@ void BundleActiveService::OnStart() BUNDLE_ACTIVE_LOGI("BundleActiveService handler create failed!"); return; } - - InitNecessaryState(); - int32_t ret = Publish(DelayedSingleton::GetInstance().get()); - if (!ret) { - BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1907] FAIL."); - return; - } - BUNDLE_ACTIVE_LOGI("[Server] OnStart, Register SystemAbility[1907] SUCCESS."); - return; + auto registerTask = [this]() { this->InitNecessaryState(); }; + handler_->PostSyncTask(registerTask); } void BundleActiveService::InitNecessaryState() @@ -103,6 +96,12 @@ void BundleActiveService::InitNecessaryState() } InitService(); ready_ = true; + int32_t ret = Publish(DelayedSingleton::GetInstance().get()); + if (!ret) { + BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1907] FAIL."); + return; + } + BUNDLE_ACTIVE_LOGI("[Server] OnStart, Register SystemAbility[1907] SUCCESS."); } void BundleActiveService::InitService() @@ -131,10 +130,14 @@ void BundleActiveService::InitService() return; } shutdownCallback_ = new (std::nothrow) BundleActiveShutdownCallbackService(bundleActiveCore_); + powerStateCallback_ = new (std::nothrow) BundleActivePowerStateCallbackService(bundleActiveCore_); auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); if (shutdownCallback_) { powerManagerClient.RegisterShutdownCallback(shutdownCallback_); } + if (powerStateCallback_) { + powerManagerClient.RegisterPowerStateCallback(powerStateCallback_); + } InitAppStateSubscriber(reportHandler_); InitContinuousSubscriber(reportHandler_); bundleActiveCore_->InitBundleGroupController(); @@ -205,6 +208,7 @@ void BundleActiveService::OnStop() if (shutdownCallback_ != nullptr) { auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); powerManagerClient.UnRegisterShutdownCallback(shutdownCallback_); + powerManagerClient.UnRegisterPowerStateCallback(powerStateCallback_); return; } BUNDLE_ACTIVE_LOGI("[Server] OnStop"); @@ -322,9 +326,28 @@ std::vector BundleActiveService::QueryEvents(const int64_t be return result; } -void BundleActiveService::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) +int32_t BundleActiveService::SetBundleGroup(const std::string& bundleName, int32_t newGroup, int32_t errCode, + int32_t userId) { - bundleActiveCore_->SetBundleGroup(bundleName, newGroup, userId); + bool result = -1; + // get uid + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + if (userId == -1) { + OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); + if (ret != ERR_OK) { + errCode = -1; + return result; + } + } + 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; } @@ -388,31 +411,72 @@ std::vector BundleActiveService::QueryCurrentEvents(const int return result; } -int32_t BundleActiveService::QueryPackageGroup() +int32_t BundleActiveService::QueryPackageGroup(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; + BUNDLE_ACTIVE_LOGD("QueryPackageGroup UID is %{public}d", callingUid); + 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) { + if (bundleName.empty()) { + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("get bundle manager proxy failed!"); + return result; + } + std::string g_bundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, g_bundleName); + bundleName = g_bundleName; + result = bundleActiveCore_->QueryPackageGroup(bundleName, userId); + } else { + 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) +{ + int result = -1; + 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 = -1; + 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,25 +517,20 @@ 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 (!bundleIsSystemApp) { - errCode = BUNDLE_ACTIVE_FAIL; - BUNDLE_ACTIVE_LOGE("%{public}s is not system app", bundleName.c_str()); - return false; - } else if (bundleHasPermission != 0) { + if (bundleHasPermission != 0) { errCode = bundleHasPermission; - BUNDLE_ACTIVE_LOGE("%{public}s hasn't permission", bundleName.c_str()); + BUNDLE_ACTIVE_LOGE("UnRegisterGroupCallBack %{public}s hasn't permission", bundleName.c_str()); return false; } else { - BUNDLE_ACTIVE_LOGI(" %{public}s is system app %{public}d, has permission %{public}d", - bundleName.c_str(), bundleIsSystemApp, bundleHasPermission); + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack %{public}s has permission %{public}d", + bundleName.c_str(), bundleHasPermission); return true; } } @@ -511,6 +570,60 @@ int32_t BundleActiveService::QueryFormStatistics(int32_t maxNum, std::vector& eventStats, int32_t userId) +{ + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("QueryEventStats 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) { + errCode = -1; + return errCode; + } + } + if (userId != -1) { + BUNDLE_ACTIVE_LOGI("QueryEventStats userid is %{public}d", userId); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + if ((CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode)) || + (AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == + AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE)) { + errCode = bundleActiveCore_->QueryEventStats(beginTime, endTime, eventStats, userId); + } + } + BUNDLE_ACTIVE_LOGI("QueryEventStats result size is %{public}zu", eventStats.size()); + return errCode; +} + +int32_t BundleActiveService::QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("QueryAppNotificationNumber 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) { + errCode = -1; + return errCode; + } + } + if (userId != -1) { + BUNDLE_ACTIVE_LOGI("QueryAppNotificationNumber userid is %{public}d", userId); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + if ((CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode)) || + (AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == + AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE)) { + errCode = bundleActiveCore_->QueryAppNotificationNumber(beginTime, endTime, eventStats, userId); + } + } + BUNDLE_ACTIVE_LOGI("QueryAppNotificationNumber result size is %{public}zu", eventStats.size()); + return errCode; +} + void BundleActiveService::QueryModuleRecordInfos(BundleActiveModuleRecord& moduleRecord) { if (!GetBundleMgrProxy()) { diff --git a/services/common/src/bundle_active_stub.cpp b/services/common/src/bundle_active_stub.cpp index ad5037cd8e4eb7371c9c42f8a929d51185d407fe..25fe267908e9313fab795bb4ead5180280ad35ec 100644 --- a/services/common/src/bundle_active_stub.cpp +++ b/services/common/src/bundle_active_stub.cpp @@ -16,6 +16,7 @@ #include "bundle_active_stub.h" #include "bundle_active_package_stats.h" #include "bundle_active_event.h" +#include "bundle_active_event_stats.h" #include "bundle_active_module_record.h" namespace OHOS { @@ -84,9 +85,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 +124,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 +145,59 @@ 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); + } + case QUERY_EVENT_STATS: { + std::vector result; + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + int32_t userId = data.ReadInt32(); + int32_t errCode = QueryEventStats(beginTime, endTime, result, userId); + int32_t size = static_cast(result.size()); + reply.WriteInt32(errCode); + reply.WriteInt32(size); + for (int32_t i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (!tmp) { + return 1; + } + } + return size == 0; + } + case QUERY_APP_NOTIFICATION_NUMBER: { + std::vector result; + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + int32_t userId = data.ReadInt32(); + int32_t errCode = QueryAppNotificationNumber(beginTime, endTime, result, userId); + int32_t size = static_cast(result.size()); + reply.WriteInt32(errCode); + reply.WriteInt32(size); + for (int32_t i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (!tmp) { + return 1; + } + } + return size == 0; + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/services/common/src/bundle_active_usage_database.cpp b/services/common/src/bundle_active_usage_database.cpp index 2195f2e220a440c994366841a66c1d19a2536098..a809cb9f2b572edae1cb139985c77c45a01acb06 100644 --- a/services/common/src/bundle_active_usage_database.cpp +++ b/services/common/src/bundle_active_usage_database.cpp @@ -1167,7 +1167,20 @@ void BundleActiveUsageDatabase::RenewTableTime(int64_t changedTime) } } -void BundleActiveUsageDatabase::UpdateUsageData(int32_t databaseType, BundleActivePeriodStats &stats) +void BundleActiveUsageDatabase::UpdateEventData(int32_t databaseType, BundleActivePeriodStats &stats) +{ + lock_guard lock(databaseMutex_); + CheckDatabaseFile(databaseType); + if (databaseType != DAILY_DATABASE_INDEX) { + return; + } + if (stats.events_.Size() != 0) { + CheckDatabaseFile(EVENT_DATABASE_INDEX); + FlushEventInfo(EVENT_DATABASE_INDEX, stats); + } +} + +void BundleActiveUsageDatabase::UpdateBundleUsageData(int32_t databaseType, BundleActivePeriodStats &stats) { lock_guard lock(databaseMutex_); if (databaseType < 0 || databaseType >= EVENT_DATABASE_INDEX) { @@ -1175,12 +1188,6 @@ void BundleActiveUsageDatabase::UpdateUsageData(int32_t databaseType, BundleActi return; } CheckDatabaseFile(databaseType); - if (databaseType == DAILY_DATABASE_INDEX) { - if (stats.events_.Size() != 0) { - CheckDatabaseFile(EVENT_DATABASE_INDEX); - FlushEventInfo(EVENT_DATABASE_INDEX, stats); - } - } int32_t packageTableIndex = BundleActiveBinarySearch::GetInstance()->BinarySearch( sortedTableArray_.at(databaseType), stats.beginTime_); if (packageTableIndex < 0) { @@ -1297,19 +1304,8 @@ vector BundleActiveUsageDatabase::QueryDatabaseEvents(int64_t { lock_guard lock(databaseMutex_); vector databaseEvents; - if (eventTableName_ == UNKNOWN_TABLE_NAME) { - BUNDLE_ACTIVE_LOGE("eventTable does not exist"); - return databaseEvents; - } - if (endTime <= beginTime) { - BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)", - (long long)endTime, (long long)beginTime); - return databaseEvents; - } int64_t eventTableTime = ParseStartTime(eventTableName_); - if (endTime < eventTableTime) { - BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= eventTableTime(%{public}lld)", - (long long)endTime, (long long)eventTableTime); + if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) { return databaseEvents; } vector queryCondition; @@ -1597,6 +1593,131 @@ void BundleActiveUsageDatabase::LoadFormData(const int32_t userId, std::map& eventStats, int32_t userId) +{ + lock_guard lock(databaseMutex_); + int64_t eventTableTime = ParseStartTime(eventTableName_); + if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) { + return; + } + vector queryCondition; + int64_t diff = beginTime - eventTableTime; + if (diff >= 0) { + queryCondition.push_back(to_string(diff)); + } else { + queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN)); + } + queryCondition.push_back(to_string(endTime - eventTableTime)); + queryCondition.push_back(to_string(userId)); + queryCondition.push_back(to_string(eventId)); + string queryEventSql = "select * from " + eventTableName_ + + " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?"; + unique_ptr bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX, + queryEventSql, queryCondition); + if (bundleActiveResult == nullptr) { + return; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + if (tableRowNumber == 0) { + return; + } + BundleActiveEventStats event; + event.name_= GetSystemEventName(eventId); + event.count_ = tableRowNumber; + event.eventId_ = eventId; + eventStats.insert(std::pair(event.name_, event)); +} + +std::string BundleActiveUsageDatabase::GetSystemEventName(const int32_t userId) +{ + std::string systemEventName = ""; + switch (userId) { + case BundleActiveEvent::SYSTEM_LOCK: + systemEventName = OPERATION_SYSTEM_LOCK; + break; + case BundleActiveEvent::SYSTEM_UNLOCK: + systemEventName = OPERATION_SYSTEM_UNLOCK; + break; + case BundleActiveEvent::SYSTEM_SLEEP: + systemEventName = OPERATION_SYSTEM_SLEEP; + break; + case BundleActiveEvent::SYSTEM_WAKEUP: + systemEventName = OPERATION_SYSTEM_WAKEUP; + break; + default: + break; + } + return systemEventName; +} + +void BundleActiveUsageDatabase::QueryAppNotificationNumber(int32_t eventId, int64_t beginTime, + int64_t endTime, std::map& notificationEventStats, int32_t userId) +{ + lock_guard lock(databaseMutex_); + int64_t eventTableTime = ParseStartTime(eventTableName_); + if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) { + return; + } + vector queryCondition; + int64_t diff = beginTime - eventTableTime; + if (diff >= 0) { + queryCondition.push_back(to_string(diff)); + } else { + queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN)); + } + queryCondition.push_back(to_string(endTime - eventTableTime)); + queryCondition.push_back(to_string(userId)); + queryCondition.push_back(to_string(eventId)); + string queryEventSql = "select * from " + eventTableName_ + + " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?"; + unique_ptr bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX, + queryEventSql, queryCondition); + if (bundleActiveResult == nullptr) { + return; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + if (tableRowNumber == 0) { + return; + } + BundleActiveEventStats event; + std::map::iterator iter; + for (int32_t i = 0; i < tableRowNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.name_); + bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_); + iter = notificationEventStats.find(event.name_); + if (iter != notificationEventStats.end()) { + iter->second.count_++; + } else { + event.count_ = 1; + notificationEventStats.insert(std::pair(event.name_, event)); + } + } +} + +int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime, + const int64_t endTime, const int64_t eventTableTime) +{ + if (eventTableName_ == UNKNOWN_TABLE_NAME) { + BUNDLE_ACTIVE_LOGE("eventTable does not exist"); + return QUERY_CONDITION_INVALID; + } + if (endTime <= beginTime) { + BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)", + (long long)endTime, (long long)beginTime); + return QUERY_CONDITION_INVALID; + } + if (endTime < eventTableTime) { + BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= eventTableTime(%{public}lld)", + (long long)endTime, (long long)eventTableTime); + return QUERY_CONDITION_INVALID; + } + return QUERY_CONDITION_VALID; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packagegroup/include/bundle_active_group_controller.h b/services/packagegroup/include/bundle_active_group_controller.h index 0f534cdf13728234520493df19d02132858464eb..6cfa429189b9ddd7f6be169c5c849a588f2284f2 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); 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_user_history.h b/services/packagegroup/include/bundle_active_user_history.h index 7279324e89387bfa9e657d1b4424b2e2704f6c56..b6617019d68261668410cb7a938b58a2c6ae9c93 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,9 +50,9 @@ 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, - int32_t newGroup, uint32_t groupReason, const bool& resetTimeout); + 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); int32_t GetLevelIndex(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const std::vector screenTimeLeve, const std::vector bootFromTimeLevel); void WriteDeviceDuration(); @@ -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 119dd4750e043e48a840d64159095d2afbb9a115..94f22724fbb60244fc7c884d838cbe7d041993e2 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; @@ -217,12 +218,12 @@ uint32_t BundleActiveGroupController::EventToGroupReason(const int32_t eventId) void BundleActiveGroupController::ReportEvent(const BundleActiveEvent& event, const int64_t bootBasedTimeStamp, const int32_t userId) { - BUNDLE_ACTIVE_LOGI("ReportEvent called"); if (bundleGroupEnable_ == false) { return; } std::lock_guard lock(mutex_); if (IsBundleInstalled(event.bundleName_, userId) == false) { + BUNDLE_ACTIVE_LOGE("Report an uninstalled package event, return!"); return; } int32_t eventId = event.eventId_; @@ -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; } @@ -280,6 +281,7 @@ void BundleActiveGroupController::CheckAndUpdateGroup(const std::string& bundleN uint32_t groupReason = oneBundleHistory->reasonInGroup_; uint32_t oldGroupControlReason = groupReason & GROUP_CONTROL_REASON_MASK; if (oldGroupControlReason == GROUP_CONTROL_REASON_FORCED) { + BUNDLE_ACTIVE_LOGI("%{public}s is forced set, return", bundleName.c_str()); return; } int32_t oldGroup = oneBundleHistory->currentGroup_; @@ -298,7 +300,6 @@ 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_ > @@ -309,40 +310,22 @@ void BundleActiveGroupController::CheckAndUpdateGroup(const std::string& bundleN } if (oldGroup < newGroup || notTimeout) { BUNDLE_ACTIVE_LOGI("CheckAndUpdateGroup called SetBundleGroup"); - bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, groupReason, false); + bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, groupReason); } } -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) { std::lock_guard lock(mutex_); - if (IsBundleInstalled(bundleName, userId) == false) { - return; + if (!IsBundleInstalled(bundleName, userId)) { + return -1; } auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle(bundleName, userId, bootBasedTimeStamp, true); - if (oneBundleHistory->currentGroup_ < ACTIVE_GROUP_ALIVE) { - return; - } - 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_; - } + if (!oneBundleHistory) { + return -1; } - bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, reason, false); + return bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, reason); } int32_t BundleActiveGroupController::IsBundleIdle(const std::string& bundleName, const int32_t userId) @@ -365,21 +348,25 @@ 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"); + if (bundleName.empty()) { + BUNDLE_ACTIVE_LOGE("bundleName can not get by userId"); + return -1; + } 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_; } + BUNDLE_ACTIVE_LOGI("QueryPackageGroup group is %{public}d", 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..bf6bb1713b6a1919ba744cc7c698b122bb4cb9fa 100644 --- a/services/packagegroup/src/bundle_active_user_history.cpp +++ b/services/packagegroup/src/bundle_active_user_history.cpp @@ -12,10 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include "bundle_active_core.h" +#include "bundle_active_group_callback_info.h" #include "bundle_active_user_history.h" -#include "bundle_active_group_common.h" -#include "bundle_active_constant.h" namespace OHOS { namespace DeviceUsageStats { @@ -56,7 +55,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 +65,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 +110,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 +129,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 +150,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,8 +165,11 @@ 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 ((oneBundleUsageHistory->reasonInGroup_ & GROUP_CONTROL_REASON_MASK) == GROUP_CONTROL_REASON_FORCED) { + return; + } if (timeUntilNextCheck > bootBasedTimeStamp) { int64_t nextCheckTimeStamp = bootBasedDuration_ + (timeUntilNextCheck - bootBasedTimeStamp_); if (newGroup == ACTIVE_GROUP_ALIVE) { @@ -181,39 +187,58 @@ 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"); + bool isGroupChanged = (oldGroup == newGroup) ? true : false; + if (!isGroupChanged) { + 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, - const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason, const bool& resetTimeout) +int32_t BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int32_t userId, + const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason) { + 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 -1; } shared_ptr oneBundleHistory = GetUsageHistoryInUserHistory(userBundleHistory, bundleName, bootBasedTimeStamp, false); - if (oneBundleHistory == nullptr) { - return; + if (!oneBundleHistory) { + return -1; } 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 1; } + 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; + BUNDLE_ACTIVE_LOGI("SetBundleGroup set success"); + bool isGroupChanged = (oldGroup == newGroup) ? true : false; + if (!isGroupChanged) { + BundleActiveGroupCallbackInfo callbackInfo( + userId, oldGroup, newGroup, oneBundleHistory->reasonInGroup_, bundleName); + if (!bundleActiveCore_.expired()) { + bundleActiveCore_.lock()->OnBundleGroupChanged(callbackInfo); + } + } + return 0; } void BundleActiveUserHistory::UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t bootBasedTimeStamp, diff --git a/services/packageusage/include/bundle_active_event.h b/services/packageusage/include/bundle_active_event.h index 57ce14b3f4bd67edff2c70454bba1585bb6d91ca..e92dda6ed8befb8495ff63fcda45dd46eaa88f78 100644 --- a/services/packageusage/include/bundle_active_event.h +++ b/services/packageusage/include/bundle_active_event.h @@ -38,11 +38,15 @@ public: static const int32_t FLUSH = 12; static const int32_t SCREEN_INTERACTIVE = 13; static const int32_t SCREEN_NON_INTERACTIVE = 14; - static const int32_t KEYGUARD_SHOWN = 15; - static const int32_t KEYGUARD_HIDDEN = 16; - static const int32_t NOTIFICATION_SEEN = 17; - static const int32_t FORM_IS_CLICKED = 18; - static const int32_t FORM_IS_REMOVED = 19; + static const int32_t FORM_IS_CLICKED = 15; + static const int32_t FORM_IS_REMOVED = 16; + static const int32_t KEYGUARD_SHOWN = 17; + static const int32_t KEYGUARD_HIDDEN = 18; + static const int32_t NOTIFICATION_SEEN = 19; + static const int32_t SYSTEM_LOCK = 20; + static const int32_t SYSTEM_UNLOCK = 21; + static const int32_t SYSTEM_SLEEP = 22; + static const int32_t SYSTEM_WAKEUP = 23; inline static const std::string DEVICE_EVENT_PACKAGE_NAME = "openharmony"; std::string bundleName_; std::string continuousTaskAbilityName_; @@ -71,6 +75,11 @@ public: */ BundleActiveEvent(int32_t eventId, int64_t timeStamp); /* + * function: BundleActiveEvent, constructor using event Id, time stamp. + * parameters: eventId, bundleName. + */ + BundleActiveEvent(const int32_t eventId, const std::string bundleName); + /* * function: BundleActiveEvent, constructor of continuous task event. * parameters: bundleName, continuousTaskAbilityName */ @@ -111,6 +120,12 @@ public: * return: string of bundlename, timestamp, eventid. */ std::string ToString(); + /** + * @brief get if the event is reported by bundle usage. + * + * @return return true if event reported by bundle usage. + */ + static bool IsBundleEvent(const int32_t eventId); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_event_stats.h b/services/packageusage/include/bundle_active_event_stats.h index 34ee080bca180e31451e89f6793956531dd94c4d..59360b761b572cb84b8d56535df04df314b340e3 100644 --- a/services/packageusage/include/bundle_active_event_stats.h +++ b/services/packageusage/include/bundle_active_event_stats.h @@ -20,7 +20,7 @@ namespace OHOS { namespace DeviceUsageStats { -class BundleActiveEventStats { +class BundleActiveEventStats : public Parcelable { public: int32_t eventId_; int64_t beginTimeStamp_; @@ -28,6 +28,8 @@ public: int64_t lastEventTime_; int64_t totalTime_; int32_t count_; + std::string name_; + /* * function: BundleActiveEventStats, default constructor. */ @@ -72,6 +74,20 @@ public: * parameters: right */ void add(const BundleActiveEventStats& right); + + /* + * function: Marshalling, mashalling event stats object to parcel. + * parameters: parcel + * return: result of mashalling, true means successful, flase means failed. + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /* + * function: UnMarshalling, Unmashalling event stats object from parcel. + * parameters: parcel + * return: point to a BundleActiveEventStats. + */ + std::shared_ptr UnMarshalling(Parcel &parcel); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_user_service.h b/services/packageusage/include/bundle_active_user_service.h index cb56fc9a73fd146c67cf7337f3815f2a28c91759..c412f61a75d8c0620f60f72c5f8ecd3339bb6470 100644 --- a/services/packageusage/include/bundle_active_user_service.h +++ b/services/packageusage/include/bundle_active_user_service.h @@ -71,6 +71,10 @@ public: std::vector QueryEvents(const int64_t beginTime, const int64_t endTime, const int32_t userId, const std::string& bundleName); int32_t QueryFormStatistics(int32_t maxNum, std::vector& results); + int32_t QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId); + int32_t QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId); void LoadActiveStats(const int64_t timeStamp, const bool& force, const bool& timeChanged); void LoadModuleAndFormStats(); @@ -90,6 +94,10 @@ private: void PrintInMemPackageStats(const int32_t idx, const bool debug); void PrintInMemEventStats(const bool debug); void PrintInMemFormStats(const bool debug, const bool printform); + void GetCachedSystemEvents(std::shared_ptr currentStats, int64_t beginTime, + int64_t endTime, std::map& systemEventStats); + void GetCachedNotificationEvents(std::shared_ptr currentStats, int64_t beginTime, + int64_t endTime, std::map& notificationEventStats); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_event.cpp b/services/packageusage/src/bundle_active_event.cpp index a96c4cf0a6a175d91e61153dfd72091b730c5a3f..e005984cc546979bd874623730de25e8d263c1e0 100644 --- a/services/packageusage/src/bundle_active_event.cpp +++ b/services/packageusage/src/bundle_active_event.cpp @@ -59,6 +59,20 @@ BundleActiveEvent::BundleActiveEvent(int32_t eventId, int64_t timeStamp) eventId_ = eventId; } +BundleActiveEvent::BundleActiveEvent(const int32_t eventId, const std::string bundleName) +{ + bundleName_ = bundleName; + continuousTaskAbilityName_.clear(); + abilityName_.clear(); + abilityId_.clear(); + moduleName_.clear(); + formName_.clear(); + formDimension_ = 0; + formId_ = 0; + timeStamp_ = 0; + eventId_ = eventId; +} + BundleActiveEvent::BundleActiveEvent(const std::string bundleName, const std::string continuousTaskAbilityName) { bundleName_ = bundleName; @@ -169,6 +183,19 @@ std::string BundleActiveEvent::ToString() return "bundle name is " + this->bundleName_ + ", event is " + std::to_string(this->eventId_) + ", timestamp is " + std::to_string(this->timeStamp_) + "\n"; } + +bool BundleActiveEvent::IsBundleEvent(const int32_t eventId) +{ + if (eventId == ABILITY_BACKGROUND || + eventId == ABILITY_FOREGROUND || + eventId == ABILITY_STOP || + eventId == LONG_TIME_TASK_STARTTED || + eventId == LONG_TIME_TASK_ENDED || + eventId == END_OF_THE_DAY) { + return true; + } + return false; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_event_stats.cpp b/services/packageusage/src/bundle_active_event_stats.cpp index a433446a259532faa74f1c17f4b59d513c14ba30..739019ed9d22f32d952c630ee17ab86310a4932c 100644 --- a/services/packageusage/src/bundle_active_event_stats.cpp +++ b/services/packageusage/src/bundle_active_event_stats.cpp @@ -25,6 +25,7 @@ BundleActiveEventStats::BundleActiveEventStats() lastEventTime_ = 0; totalTime_ = 0; count_ = 0; + name_.clear(); } BundleActiveEventStats::BundleActiveEventStats(const BundleActiveEventStats& orig) @@ -35,6 +36,7 @@ BundleActiveEventStats::BundleActiveEventStats(const BundleActiveEventStats& ori lastEventTime_ = orig.lastEventTime_; totalTime_ = orig.totalTime_; count_ = orig.count_; + name_ = orig.name_; } int32_t BundleActiveEventStats::GetEventId() @@ -81,6 +83,33 @@ void BundleActiveEventStats::add(const BundleActiveEventStats& right) totalTime_ += right.totalTime_; count_ += right.count_; } + +bool BundleActiveEventStats::Marshalling(Parcel &parcel) const +{ + if (parcel.WriteInt32(eventId_) && + parcel.WriteInt64(beginTimeStamp_) && + parcel.WriteInt64(endTimeStamp_) && + parcel.WriteInt64(lastEventTime_) && + parcel.WriteInt64(totalTime_) && + parcel.WriteInt32(count_) && + parcel.WriteString(name_)) { + return true; + } + return false; +} + +std::shared_ptr BundleActiveEventStats::UnMarshalling(Parcel &parcel) +{ + std::shared_ptr result = std::make_shared(); + result->eventId_ = parcel.ReadInt32(); + result->beginTimeStamp_ = parcel.ReadInt64(); + result->endTimeStamp_ = parcel.ReadInt64(); + result->lastEventTime_ = parcel.ReadInt64(); + result->totalTime_ = parcel.ReadInt64(); + result->count_ = parcel.ReadInt32(); + result->name_ = parcel.ReadString(); + return result; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_period_stats.cpp b/services/packageusage/src/bundle_active_period_stats.cpp index d223d62b91bda2bb7608ce32d190ca5e2780d7d3..c8b6994ace7efeb4b80072d719a531289554ccf5 100644 --- a/services/packageusage/src/bundle_active_period_stats.cpp +++ b/services/packageusage/src/bundle_active_period_stats.cpp @@ -53,7 +53,7 @@ void BundleActivePeriodStats::Update(const std::string bundleName, const std::st tmpUsageStats->Update("", timeStamp, eventId, abilityId); } } - } else { + } else if (BundleActiveEvent::IsBundleEvent(eventId)) { auto usageStats = GetOrCreateUsageStats(bundleName); usageStats->Update(longTimeTaskName, timeStamp, eventId, abilityId); } diff --git a/services/packageusage/src/bundle_active_user_service.cpp b/services/packageusage/src/bundle_active_user_service.cpp index c79f1d62e4a6a98de00d1354296fd4499ef8702b..7f091db16bfbbaf5d451a4e04d43ef7b8839d6b9 100644 --- a/services/packageusage/src/bundle_active_user_service.cpp +++ b/services/packageusage/src/bundle_active_user_service.cpp @@ -173,10 +173,12 @@ void BundleActiveUserService::RestoreStats(bool forced) BUNDLE_ACTIVE_LOGI("RestoreStats() stat changed is true"); for (uint32_t i = 0; i < currentStats_.size(); i++) { if (currentStats_[i]) { - if (currentStats_[i]->bundleStats_.empty() && currentStats_[i]->events_.events_.empty()) { - continue; + if (!currentStats_[i]->bundleStats_.empty()) { + database_.UpdateBundleUsageData(i, *(currentStats_[i])); + } + if (!currentStats_[i]->events_.events_.empty() && i == BundleActivePeriodStats::PERIOD_DAILY) { + database_.UpdateEventData(i, *(currentStats_[i])); } - database_.UpdateUsageData(i, *(currentStats_[i])); } } if (!moduleRecords_.empty()) { @@ -410,6 +412,117 @@ int32_t BundleActiveUserService::QueryFormStatistics(int32_t maxNum, std::vector return 0; } +int32_t BundleActiveUserService::QueryEventStats(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + BUNDLE_ACTIVE_LOGI("QueryEventStats called"); + auto currentStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; + if (currentStats == nullptr) { + BUNDLE_ACTIVE_LOGE("current interval stat is null!"); + return BUNDLE_ACTIVE_FAIL; + } + if (beginTime >= currentStats->endTime_) { + return BUNDLE_ACTIVE_FAIL; + } + std::map systemEventStats; + database_.QueryEventStats(BundleActiveEvent::SYSTEM_LOCK, beginTime, endTime, systemEventStats, userId); + database_.QueryEventStats(BundleActiveEvent::SYSTEM_UNLOCK, beginTime, endTime, systemEventStats, userId); + database_.QueryEventStats(BundleActiveEvent::SYSTEM_SLEEP, beginTime, endTime, systemEventStats, userId); + database_.QueryEventStats(BundleActiveEvent::SYSTEM_WAKEUP, beginTime, endTime, systemEventStats, userId); + BUNDLE_ACTIVE_LOGI("Query eventStats data in db result size is %{public}zu", systemEventStats.size()); + PrintInMemEventStats(debugUserService_); + // if we need a in-memory stats, combine current stats with result from database. + if (currentStats->endTime_ != 0 && endTime > currentStats->beginTime_) { + BUNDLE_ACTIVE_LOGI("QueryEventStats need in memory stats"); + GetCachedSystemEvents(currentStats, beginTime, endTime, systemEventStats); + } + std::map::iterator iter; + for (iter = systemEventStats.begin(); iter != systemEventStats.end(); iter++) { + eventStats.push_back(iter->second); + } + return BUNDLE_ACTIVE_SUCCESS; +} + +void BundleActiveUserService::GetCachedSystemEvents(std::shared_ptr currentStats, + int64_t beginTime, int64_t endTime, std::map& systemEventStats) +{ + int32_t eventBeginIdx = currentStats->events_.FindBestIndex(beginTime); + int32_t eventSize = currentStats->events_.Size(); + BundleActiveEventStats singleEventStats; + std::map::iterator iter; + for (int32_t i = eventBeginIdx; i < eventSize; i++) { + if ((currentStats->events_.events_[i].timeStamp_ <= endTime) + && ((currentStats->events_.events_[i].eventId_== BundleActiveEvent::SYSTEM_LOCK) + || (currentStats->events_.events_[i].eventId_== BundleActiveEvent::SYSTEM_UNLOCK) + || (currentStats->events_.events_[i].eventId_== BundleActiveEvent::SYSTEM_SLEEP) + || (currentStats->events_.events_[i].eventId_== BundleActiveEvent::SYSTEM_WAKEUP))) { + singleEventStats.name_ = currentStats->events_.events_[i].bundleName_; + iter = systemEventStats.find(singleEventStats.name_); + if (iter != systemEventStats.end()) { + iter->second.count_++; + } else { + singleEventStats.eventId_ = currentStats->events_.events_[i].eventId_; + singleEventStats.count_ = 1; + systemEventStats.insert(std::pair( + singleEventStats.name_, singleEventStats)); + } + } + } +} + +int32_t BundleActiveUserService::QueryAppNotificationNumber(int64_t beginTime, int64_t endTime, + std::vector& eventStats, int32_t userId) +{ + BUNDLE_ACTIVE_LOGI("QueryAppNotificationNumber called"); + auto currentStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; + if (currentStats == nullptr) { + BUNDLE_ACTIVE_LOGE("current interval stat is null!"); + return BUNDLE_ACTIVE_FAIL; + } + if (beginTime >= currentStats->endTime_) { + return BUNDLE_ACTIVE_FAIL; + } + std::map notificationEventStats; + database_.QueryAppNotificationNumber(BundleActiveEvent::NOTIFICATION_SEEN, + beginTime, endTime, notificationEventStats, userId); + BUNDLE_ACTIVE_LOGI("Query eventStats data in db result size is %{public}zu", notificationEventStats.size()); + PrintInMemEventStats(debugUserService_); + // if we need a in-memory stats, combine current stats with result from database. + if (currentStats->endTime_ != 0 && endTime > currentStats->beginTime_) { + BUNDLE_ACTIVE_LOGI("QueryAppNotificationNumber need in memory stats"); + GetCachedNotificationEvents(currentStats, beginTime, endTime, notificationEventStats); + } + std::map::iterator iter; + for (iter = notificationEventStats.begin(); iter != notificationEventStats.end(); iter++) { + eventStats.push_back(iter->second); + } + return BUNDLE_ACTIVE_SUCCESS; +} + +void BundleActiveUserService::GetCachedNotificationEvents(std::shared_ptr currentStats, + int64_t beginTime, int64_t endTime, std::map& notificationEventStats) +{ + int32_t eventBeginIdx = currentStats->events_.FindBestIndex(beginTime); + int32_t eventSize = currentStats->events_.Size(); + std::map::iterator iter; + BundleActiveEventStats singleEventStats; + for (int32_t i = eventBeginIdx; i < eventSize; i++) { + if ((currentStats->events_.events_[i].timeStamp_ <= endTime) + && (currentStats->events_.events_[i].eventId_== BundleActiveEvent::NOTIFICATION_SEEN)) { + singleEventStats.name_ = currentStats->events_.events_[i].bundleName_; + iter = notificationEventStats.find(singleEventStats.name_); + if (iter != notificationEventStats.end()) { + iter->second.count_++; + } else { + singleEventStats.eventId_ = BundleActiveEvent::NOTIFICATION_SEEN; + singleEventStats.count_ = 1; + notificationEventStats.insert(std::pair( + singleEventStats.name_, singleEventStats)); + } + } + } +} + void BundleActiveUserService::PrintInMemPackageStats(const int32_t idx, const bool debug) { if (!debug) { diff --git a/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn b/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn index 9ee599a6c215f058849b038b2993ed3b799b1770..45aaa5019a8e1a11d6609bf3dc7d01ac13628942 100644 --- a/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn +++ b/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn @@ -54,9 +54,9 @@ ohos_fuzztest("BundleActiveOnRemoteRequestFuzzTest") { "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/test/fuzztest/bundleactiveonremoterequest_fuzzer/bundleactiveonremoterequest_fuzzer.cpp b/test/fuzztest/bundleactiveonremoterequest_fuzzer/bundleactiveonremoterequest_fuzzer.cpp index d2b6394ad5e28bec7bc7320504a9616106fe6151..e97c7e106f6d97042051d4ff07ba3d92d3e17086 100644 --- a/test/fuzztest/bundleactiveonremoterequest_fuzzer/bundleactiveonremoterequest_fuzzer.cpp +++ b/test/fuzztest/bundleactiveonremoterequest_fuzzer/bundleactiveonremoterequest_fuzzer.cpp @@ -26,24 +26,26 @@ namespace OHOS { namespace DeviceUsageStats { constexpr int32_t MIN_LEN = 4; constexpr int32_t MAX_CODE_TEST = 15; // current max code is 9 + static bool isInited = false; - void DoInit() + bool DoInit() { auto instance = DelayedSingleton::GetInstance(); if (!instance->runner_) { instance->runner_ = AppExecFwk::EventRunner::Create("device_usage_stats_init_handler"); } if (!instance->runner_) { - return; + return false; } if (!instance->handler_) { instance->handler_ = std::make_shared(instance->runner_); } if (!instance->handler_) { - return; + return false; } instance->InitNecessaryState(); + return true; } int32_t OnRemoteRequest(uint32_t code, MessageParcel& data) @@ -75,9 +77,12 @@ namespace DeviceUsageStats { dataMessageParcel.WriteBuffer(data + sizeof(uint32_t), size); dataMessageParcel.RewindRead(0); - DoInit(); - OnRemoteRequest(code, dataMessageParcel); - DelayedSingleton::GetInstance()->OnStop(); + if (!isInited) { + isInited = DoInit(); + } + if (isInited) { + OnRemoteRequest(code, dataMessageParcel); + } } } // namespace DeviceUsageStats } // namespace OHOS diff --git a/test/unittest/device_usage_statistics_test.cpp b/test/unittest/device_usage_statistics_test.cpp index 9a4eca3ef85d3f2f0fb083a593e3656a9149f46d..3b373a565ec97463ecafd59a792b259db145d79d 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; @@ -38,7 +39,12 @@ static int64_t DEFAULT_FORMID = 1; static std::string DEFAULT_ABILITYID = "1234"; static std::string DEFAULT_ABILITYNAME = "testability"; static int32_t DEFAULT_USERID = 0; +static int32_t COMMON_USERID = 100; +static int32_t DEFAULT_ERRCODE = 0; static int64_t LARGE_NUM = 20000000000000; +static int32_t DEFAULT_GROUP = 10; +static std::vector GROUP_TYPE {10, 20, 30, 40, 50}; +static std::shared_ptr observer = nullptr; class DeviceUsageStatisticsTest : public testing::Test { public: @@ -148,18 +154,6 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_IsBundleIdle_001, EXPECT_EQ(result, true); } -/* - * @tc.name: DeviceUsageStatisticsTest_QueryPackageGroup_001 - * @tc.desc: querypackagegroup - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryPackageGroup_001, Function | MediumTest | Level0) -{ - int32_t result = BundleActiveClient::GetInstance().QueryPackageGroup(); - EXPECT_EQ(result, -1); -} - /* * @tc.name: DeviceUsageStatisticsTest_QueryFormStatistics_001 * @tc.desc: QueryFormStatistics @@ -177,6 +171,98 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryFormStatistic EXPECT_EQ(errCode, 0); EXPECT_EQ(results.size(), 0); } + +/* + * @tc.name: DeviceUsageStatisticsTest_QueryPackageGroup_001 + * @tc.desc: querypackagegroup, no bundleName + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryPackageGroup_001, Function | MediumTest | Level0) +{ + int32_t result = BundleActiveClient::GetInstance().QueryPackageGroup(DEFAULT_BUNDLENAME, COMMON_USERID); + bool flag = false; + for (auto item = GROUP_TYPE.begin(); item != GROUP_TYPE.end(); item++) { + if (*item == result) { + flag = true; + break; + } + } + EXPECT_EQ(flag, true); +} + +/* + * @tc.name: DeviceUsageStatisticsTest_SetBundleGroup_001 + * @tc.desc: setbundlename + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_SetBundleGroup_001, Function | MediumTest | Level0) +{ + int32_t result = BundleActiveClient::GetInstance().SetBundleGroup(DEFAULT_BUNDLENAME, DEFAULT_GROUP, + DEFAULT_ERRCODE, COMMON_USERID); + EXPECT_EQ(result, DEFAULT_ERRCODE); +} + +/* + * @tc.name: DeviceUsageStatisticsTest_RegisterGroupCallBack_001 + * @tc.desc: registercallback + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_RegisterGroupCallBack_001, Function | MediumTest | Level0) +{ + observer=std::make_shared(); + if (!observer) { + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack construct observer!------------------------------"); + } + int32_t result = BundleActiveClient::GetInstance().RegisterGroupCallBack(observer.get()); + EXPECT_EQ(result, DEFAULT_ERRCODE); +} + +/* + * @tc.name: DeviceUsageStatisticsTest_UnRegisterGroupCallBack_001 + * @tc.desc: unregistercallback + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_UnRegisterGroupCallBack_001, + Function | MediumTest | Level0) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGI("observer has been delete"); + } + int32_t result = BundleActiveClient::GetInstance().UnregisterGroupCallBack(observer.get()); + observer = nullptr; + EXPECT_EQ(result, DEFAULT_ERRCODE); +} + +/* + * @tc.name: DeviceUsageStatisticsTest_QueryEventStats_001 + * @tc.desc: QueryEventStats + * @tc.type: FUNC + * @tc.require: SR000H0H9H AR000H0ROG + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryEventStats_001, Function | MediumTest | Level0) +{ + std::vector eventStats; + int32_t errCode = BundleActiveClient::GetInstance().QueryEventStats(0, LARGE_NUM, eventStats); + EXPECT_EQ(errCode, 0); +} + +/* + * @tc.name: DeviceUsageStatisticsTest_QueryAppNotificationNumber_001 + * @tc.desc: QueryAppNotificationNumber + * @tc.type: FUNC + * @tc.require: SR000H0H7D AR000H0RR6 + */ +HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryAppNotificationNumber_001, Function + | MediumTest | Level0) +{ + std::vector eventStats; + int32_t errCode = BundleActiveClient::GetInstance().QueryAppNotificationNumber(0, LARGE_NUM, eventStats); + EXPECT_EQ(errCode, 0); +} } // namespace DeviceUsageStats } // namespace OHOS