diff --git a/BUILD.gn b/BUILD.gn index 4eea17eb3e3502218d0a179a03fa6996ede6d872..2c759b844c5304ac0d9c7645f320f664354a8504 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", @@ -38,6 +41,7 @@ ohos_shared_library("usagestatsinner") { public_configs = [ ":usagestatsinner_public_config" ] public_deps = [ ":usagestatservice" ] external_deps = [ + "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "safwk:system_ability_fwk", @@ -58,6 +62,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 +72,7 @@ ohos_shared_library("bundlestate") { "services/common/include", "interfaces/innerkits/include", "services/packageusage/include", + "services/packagegroup/include", ] deps = [ @@ -75,6 +81,7 @@ ohos_shared_library("bundlestate") { ] external_deps = [ + "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "napi:ace_napi", @@ -90,6 +97,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 +107,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 +137,12 @@ ohos_shared_library("usagestatservice") { "services/common/include", "services/packageusage/include", "services/packagegroup/include", + "interfaces/innerkits/include", + "interfaces/kits/bundlestats/napi/include", ] external_deps = [ + "ability_base:configuration", "ability_base:want", "ability_runtime:app_manager", "ability_runtime:wantagent_innerkits", @@ -138,13 +153,12 @@ ohos_shared_library("usagestatservice") { "common_event_service:cesfwk_innerkits", "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", + "init:libbegetutil", "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", "time_native:time_service", "utils_base:utils", ] @@ -157,36 +171,3 @@ ohos_shared_library("usagestatservice") { part_name = "${device_usage_statistics_part_name}" subsystem_name = "resourceschedule" } - -ohos_executable("deviceusagestats") { - include_dirs = [ - "services/common/include", - "services/packageusage/include", - "services/packagegroup/include", - "interfaces/innerkits/include", - "utils/dump/include", - ] - - sources = [ - "utils/dump/src/bundle_active_shell_command.cpp", - "utils/dump/src/main.cpp", - "utils/dump/src/shell_command.cpp", - ] - - deps = [ ":usagestatsinner" ] - - configs = [] - - external_deps = [ - "ability_base:want", - "ability_runtime:wantagent_innerkits", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "safwk:system_ability_fwk", - "samgr_standard:samgr_proxy", - "utils_base:utils", - ] - - install_enable = true - part_name = "${device_usage_statistics_part_name}" -} diff --git a/README.md b/README.md index f28be986a2664edae4fb546d7b98beeabcd843b9..27262a6a75137c83aa85ca14dd89395460db56c6 100644 --- a/README.md +++ b/README.md @@ -40,37 +40,69 @@ Taking app usage interface as an example, the main exposed interfaces are as fol - - - - - - - - - - - -

API name

API description

+

API description

queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

-

Queries the event collection of all applications through time interval.

-

queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback<BundleActiveInfoResponse>): void

-

Uses the start and end time to query the application usage time statistics.

-

queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

-

Queries the event collection of the current application through the time interval.

-

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStateInfo>>): void

-

Queries application usage duration statistics by time interval.

-

queryAppUsagePriorityGroup(callback: AsyncCallback<number>): void

-

Queries (returns) the priority group used by the current caller application.

-

isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void

-

Judges whether the application of the specified bundle name is currently idle.

+

queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

+

Queries the event collection of all applications through time interval(callback).

+

queryBundleActiveStates(begin: number, end: number): Promise<Array<BundleActiveState>>

+

Queries the event collection of all applications through time interval(Promise).

+

queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback<BundleActiveInfoResponse>): void

+

Uses the start and end time to query the application usage time statistics(callback).

+

queryBundleStateInfos(begin: number, end: number): Promise<BundleActiveInfoResponse>

+

Uses the start and end time to query the application usage time statistics(Promise).

+

queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

+

Queries the event collection of the current application through the time interval(callback).

+

queryCurrentBundleActiveStates(begin: number, end: number): Promise<Array<BundleActiveState>>

+

Queries the event collection of the current application through the time interval(Promise).

+

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStateInfo>>): void

+

Queries application usage duration statistics by time interval(callback).

+

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number): Promise<Array<BundleStateInfo>>

+

Queries application usage duration statistics by time interval(Promise).

+

queryAppUsagePriorityGroup(callback: AsyncCallback<number>): void

+

Query the priority group of the application.

+

queryAppUsagePriorityGroup(): Promise<number>

+

Query the priority group of the application.

+

isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void

+

Judges whether the application of the specified bundle name is currently idle(callback).

+

isIdleState(bundleName: string): Promise<boolean>

+

Judges whether the application of the specified bundle name is currently idle(Promise).

+

queryBundleActiveEventStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void

+

Query the statistical information of system events (sleep, wake-up, unlock and screen lock) according to the start and end time(callback).

+

queryBundleActiveEventStates(begin: number, end: number): Promise<Array<BundleActiveEventState>>

+

Query the statistical information of system events (sleep, wake-up, unlock and screen lock) according to the start and end time(Promise).

+

queryAppNotificationNumber(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void

+

Query the application notification times according to the start and end time(callback).

+

queryAppNotificationNumber(begin: number, end: number): Promise<Array<BundleActiveEventState>>

+

Query the application notification times according to the start and end time(Promise).

+

getRecentlyUsedModules(maxNum?: number, callback: AsyncCallback<Array<BundleActiveModuleInfo>>): void

+

Query FA usage records. The maximum returned quantity does not exceed the value set by maxnum. FA usage records are sorted from near to far. The maximum maxnum is 1000. If the maxnum parameter is not filled in, the default maxnum is 1000(callback).

+

getRecentlyUsedModules(maxNum?: number): Promise<Array<BundleActiveModuleInfo>>

+

Query FA usage records. The maximum returned quantity does not exceed the value set by maxnum. FA usage records are sorted from near to far. The maximum maxnum is 1000. If the maxnum parameter is not filled in, the default maxnum is 1000(Promise).

+

queryAppUsagePriorityGroup(bundleName? : string, callback: AsyncCallback<number>): void

+

Query the group of the current application or the application of specified bundlename.

+

queryAppUsagePriorityGroup(bundleName? : string): Promise<number>

+

Query the group of the current application or the application of specified bundlename.

+

setBundleGroup(bundleName: string, newGroup: GroupType, callback: AsyncCallback<void>): void

+

Set the group of the specified application as the group provided by the parameter(callback).

+

setBundleGroup(bundleName: string, newGroup: GroupType): Promise<void>

+

Set the group of the specified application as the group provided by the parameter(Promise).

+

registerGroupCallBack(callback: Callback<BundleActiveGroupCallbackInfo>, callback: AsyncCallback<void>): void

+

Register callback for application group change(callback).

+

registerGroupCallBack(callback: Callback<BundleActiveGroupCallbackInfo>): Promise<void>

+

Register callback for application group change(Promise).

+

unRegisterGroupCallBack(callback: AsyncCallback<void>): void

+

Unregister the registered application group callback(callback).

+

unRegisterGroupCallBack(): Promise<void>

+

Unregister the registered application group callback(Promise).

+ + ### Usage Guidelines There are many interfaces for device usage statistics. Take app usage interface as an example to introduce the interface logic. @@ -84,8 +116,15 @@ There are many interfaces for device usage statistics. Take app usage interface >2. Query the usage duration of the application according to the start and end time; >3. Query the event collection of the current application according to the start and end time; >4. Query the usage duration of the application according to the type of interval (day, week, month, year) and the start and end time; ->5. Query the priority group of the caller application; +>5. Query the priority group of the application; >6. Judge whether the specified application is currently idle; +>7. Query the statistical information of system events (sleep, wake-up, unlock and screen lock) according to the start and end time; +>8. Query the application notification times according to the start and end time; +>9. Query FA usage records. The maximum returned quantity does not exceed the value set by maxnum. FA usage records are sorted from near to far. The maximum maxnum is 1000. If the maxnum parameter is not filled in, the default maxnum is 1000; +>10. Query the group of the current application or the application of specified bundlename; +>11. Set the group of the specified application as the group provided by the parameter; +>12. Register callback for application group change; +>13. Unregister the registered application group callback; ## Repositories Involved @@ -97,4 +136,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/README_zh.md b/README_zh.md index 4910fdf7a7e31e268df1b286d53afcb7863d70e8..9fabc001ff5343b00ce71ff5b4a494c671daf42f 100644 --- a/README_zh.md +++ b/README_zh.md @@ -37,37 +37,70 @@ - - + - - - - - - - - - -

接口名

接口描述

+

接口描述

queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

+

queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

+

通过指定起始和结束时间查询所有应用的事件集合(callback形式)。

+

queryBundleActiveStates(begin: number, end: number): Promise<Array<BundleActiveState>>

+

通过指定起始和结束时间查询所有应用的事件集合(Promise形式)。

+

queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback<BundleActiveInfoResponse>): void

+

通过指定起始和结束时间查询应用使用时长统计信息(callback形式)。

+

queryBundleStateInfos(begin: number, end: number): Promise<BundleActiveInfoResponse>

+

通过指定起始和结束时间查询应用使用时长统计信息(Promise形式)。

+

queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

+

通过指定起始和结束时间查询当前应用的事件集合(callback形式)。

+

queryCurrentBundleActiveStates(begin: number, end: number): Promise<Array<BundleActiveState>>

+

通过指定起始和结束时间查询当前应用的事件集合(Promise形式)。

+

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStateInfo>>): void

+

通过指定时间段间隔(天、周、月、年)查询应用使用时长统计信息(callback形式)。

+

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number): Promise<Array<BundleStateInfo>>

+

通过指定时间段间隔(天、周、月、年)查询应用使用时长统计信息(Promise形式)。

+

queryAppUsagePriorityGroup(callback: AsyncCallback<number>): void

+

查询当前应用的优先级分组(callback形式)。

+

queryAppUsagePriorityGroup(): Promise<number>

+

查询当前应用的优先级分组(Promise形式)。

+

isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void

+

判断指定Bundle Name的应用当前是否是空闲状态(callback形式)。

+

isIdleState(bundleName: string): Promise<boolean>

+

判断指定Bundle Name的应用当前是否是空闲状态(Promise形式)。

+

queryBundleActiveEventStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void

+

根据起止时间查询系统事件(休眠、唤醒、解锁、锁屏)统计信息(callback形式)。

+

queryBundleActiveEventStates(begin: number, end: number): Promise<Array<BundleActiveEventState>>

+

根据起止时间查询系统事件(休眠、唤醒、解锁、锁屏)统计信息(Promise形式)。

+

queryAppNotificationNumber(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveEventState>>): void

+

根据起止时间查询应用通知次数(callback形式)。

+

queryAppNotificationNumber(begin: number, end: number): Promise<Array<BundleActiveEventState>>

+

根据起止时间查询应用通知次数(Promise形式)。

+

getRecentlyUsedModules(maxNum?: number, callback: AsyncCallback<Array<BundleActiveModuleInfo>>): void

+

查询FA使用记录。返回数量最大不超过maxNum设置的值,FA使用记录由近及远排序,maxNum最大为1000,若不填写maxNum参数,则maxNum默认为1000(callback形式)。

+

getRecentlyUsedModules(maxNum?: number): Promise<Array<BundleActiveModuleInfo>>

+

查询FA使用记录。返回数量最大不超过maxNum设置的值,FA使用记录由近及远排序,maxNum最大为1000,若不填写maxNum参数,则maxNum默认为1000(Promise形式)。

+

queryAppUsagePriorityGroup(bundleName? : string, callback: AsyncCallback<number>): void

+

使用可选参数查询当前调用者应用的使用优先级群组(callback形式)。

+

queryAppUsagePriorityGroup(bundleName? : string): Promise<number>

+

使用可选参数查询当前调用者应用的使用优先级群组(Promise形式)。

+

setBundleGroup(bundleName: string, newGroup: GroupType, callback: AsyncCallback<void>): void

+

将指定应用的分组设置为参数提供的分组(callback形式)。

+

setBundleGroup(bundleName: string, newGroup: GroupType): Promise<void>

+

将指定应用的分组设置为参数提供的分组(Promise形式)。

+

registerGroupCallBack(callback: Callback<BundleActiveGroupCallbackInfo>, callback: AsyncCallback<void>): void

+

给应用分组变化注册回调(callback形式)。

+

registerGroupCallBack(callback: Callback<BundleActiveGroupCallbackInfo>): Promise<void>

+

给应用分组变化注册回调(Promise形式)。

+

unRegisterGroupCallBack(callback: AsyncCallback<void>): void

+

将已注册过的应用分组回调解除注册(callback形式)。

+

unRegisterGroupCallBack(): Promise<void>

+

将已注册过的应用分组回调解除注册(Promise形式)。

通过指定起始和结束时间查询所有应用的事件集合。

-

queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback<BundleActiveInfoResponse>): void

-

通过指定起始和结束时间查询应用使用时长统计信息。

-

queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback<Array<BundleActiveState>>): void

-

通过指定起始和结束时间查询当前应用的事件集合。

-

queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback<Array<BundleStateInfo>>): void

-

通过指定时间段间隔(天、周、月、年)查询应用使用时长统计信息。

-

queryAppUsagePriorityGroup(callback: AsyncCallback<number>): void

-

查询(返回)当前调用者应用的使用优先级群组。

-

isIdleState(bundleName: string, callback: AsyncCallback<boolean>): void

-

判断指定Bundle Name的应用当前是否是空闲状态。

+ ### 使用说明 设备使用信息统计接口众多,以应用使用详情(app usage)接口为例,介绍接口逻辑。 @@ -81,8 +114,15 @@ >2. 根据起止时间查询应用的使用时长; >3. 根据起止时间查询当前应用的事件集合; >4. 根据interval(日、周、月、年)类型和起止时间查询应用的使用时长; ->5. 查询调用者应用的优先级群组; +>5. 查询当前应用的优先级分组; >6. 判断指定应用当前是否是空闲状态; +>7. 根据起止时间查询系统事件(休眠、唤醒、解锁、锁屏)统计信息; +>8. 根据起止时间查询应用通知次数; +>9. 查询FA使用记录。返回数量最大不超过maxNum设置的值,FA使用记录由近及远排序,maxNum最大为1000,若不填写maxNum参数,则maxNum默认为1000; +>10. 查询当前应用或指定bundlename对应的应用的分组; +>11. 将指定应用的分组设置为参数提供的分组; +>12. 给应用分组变化注册回调; +>13. 将已注册过的应用分组回调解除注册; ## 相关仓 diff --git a/bundle.json b/bundle.json index cccf5f4b1588a4a293505b2ff6e4e874bf97284c..aca71c9c2a87a9b5f731aee77141accc43485399 100644 --- a/bundle.json +++ b/bundle.json @@ -23,25 +23,24 @@ "ram": "10240KB", "deps": { "components": [ - "libhilog", - "libpermissionsdk_standard", - "powermgr_client", - "cesfwk_innerkits", - "wantagent_innerkits", - "want", - "appexecfwk_base", - "appexecfwk_core", - "base", - "time_service", - "utils", - "ipc_core", - "system_ability_fwk", - "samgr_proxy", - "distributedschedsvr", - "libeventhandler", - "native_rdb", - "os_account_innerkits", - "libaccesstoken_sdk" + "bundle_framework", + "relational_store", + "safwk", + "common_event_service", + "os_account", + "ipc", + "access_token", + "ability_runtime", + "hiviewdfx_hilog_native", + "samgr_standard", + "utils_base", + "napi", + "startup_l2", + "ability_base", + "background_task_mgr", + "eventhandler", + "power_manager_native", + "time_native" ], "third_party": [ "googletest" ] }, @@ -51,8 +50,7 @@ "//foundation/resourceschedule/device_usage_statistics:usagestatservice", "//foundation/resourceschedule/device_usage_statistics:device_usage_statistics_sa_profile", "//foundation/resourceschedule/device_usage_statistics:device_usage_statistics_service_init", - "//foundation/resourceschedule/device_usage_statistics:bundlestate", - "//foundation/resourceschedule/device_usage_statistics:deviceusagestats" + "//foundation/resourceschedule/device_usage_statistics:bundlestate" ], "inner_kits": [ { diff --git a/frameworks/src/bundle_active_group_observer.cpp b/frameworks/src/bundle_active_group_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15aefc4b4752c71a0767459a2ee067753aff08d8 --- /dev/null +++ b/frameworks/src/bundle_active_group_observer.cpp @@ -0,0 +1,341 @@ +/* + * 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) +{ + 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, "appUsageOldGroup", value); + + // newGroup + napi_create_int32(commonEventDataWorkerData->env, commonEventDataWorkerData->newGroup, &value); + napi_set_named_property(commonEventDataWorkerData->env, result, "appUsageNewGroup", 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_LOGD( + "RegisterGroupCallBack appUsageOldGroup = %{public}d, appUsageNewGroup = %{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_LOGD("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_LOGD("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; + 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) +{ + napi_ref result = nullptr; + + registerObserver = new (std::nothrow) BundleActiveGroupObserver(); + if (!registerObserver) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack callback is null"); + return BundleStateCommon::NapiGetNull(env); + } + napi_create_reference(env, value, 1, &result); + registerObserver->SetCallbackInfo(env, result); + + return BundleStateCommon::NapiGetNull(env); +} + +napi_value ParseRegisterGroupCallBackParameters(const napi_env &env, const napi_callback_info &info, + RegisterCallbackInfo ¶ms, AsyncRegisterCallbackInfo* &asyncCallbackInfo) +{ + 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)); + if (registerObserver) { + BUNDLE_ACTIVE_LOGI("RegisterGroupCallBack repeat!"); + params.errorCode = ERR_REPEAT_OPERATION; + } else if (valuetype != napi_function || !GetBundleGroupChangeCallback(env, argv[0])) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack bundleActiveGroupObserverInfo parse failed"); + params.errorCode = ERR_OBSERVER_CALLBACK_IS_INVALID; + } + + // 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); + } + BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo); + return BundleStateCommon::NapiGetNull(env); +} + +napi_value RegisterGroupCallBack(napi_env env, napi_callback_info info) +{ + RegisterCallbackInfo params; + AsyncRegisterCallbackInfo *asyncCallbackInfo = nullptr; + ParseRegisterGroupCallBackParameters(env, info, params, asyncCallbackInfo); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->observer = registerObserver; + napi_value promise = nullptr; + 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; + napi_get_null(env, &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, AsyncUnRegisterCallbackInfo* &asyncCallbackInfo) +{ + 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); + } + if (!registerObserver) { + BUNDLE_ACTIVE_LOGI("UnRegisterGroupCallBack observer is not exist"); + params.errorCode = ERR_REGISTER_OBSERVER_IS_NULL; + return BundleStateCommon::NapiGetNull(env); + } + BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo); + return BundleStateCommon::NapiGetNull(env); +} + +napi_value UnRegisterGroupCallBack(napi_env env, napi_callback_info info) +{ + UnRegisterCallbackInfo params; + AsyncUnRegisterCallbackInfo *asyncCallbackInfo = nullptr; + ParseUnRegisterGroupCallBackParameters(env, info, params, asyncCallbackInfo); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->observer = registerObserver; + napi_value promise = nullptr; + BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, "UnRegisterGroupCallBack", NAPI_AUTO_LENGTH, &resourceName)); + NAPI_CALL(env, napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + 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; + napi_get_null(env, &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..9bcc0a8456a9db75cdc812a20dd5b3100f17eb6d 100644 --- a/frameworks/src/bundle_state_common.cpp +++ b/frameworks/src/bundle_state_common.cpp @@ -16,7 +16,6 @@ #include "securec.h" #include "bundle_active_log.h" -#include "bundle_state_data.h" #include "bundle_state_common.h" namespace OHOS { @@ -67,7 +66,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 +133,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 +305,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 +460,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..ab28cbc76e3133436726fa3ab2dd741ce5b902b7 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) @@ -214,7 +221,7 @@ napi_value IsIdleState(napi_env env, napi_callback_info info) AsyncCallbackInfoIsIdleState *asyncCallbackInfo = (AsyncCallbackInfoIsIdleState *)data; if (asyncCallbackInfo != nullptr) { asyncCallbackInfo->state = BundleActiveClient::GetInstance().IsBundleIdle( - asyncCallbackInfo->bundleName); + asyncCallbackInfo->bundleName, asyncCallbackInfo->errorCode); } else { BUNDLE_ACTIVE_LOGE("IsIdleState, asyncCallbackInfo == nullptr"); } @@ -240,43 +247,64 @@ napi_value IsIdleState(napi_env env, napi_callback_info info) } napi_value ParsePriorityGroupParameters(const napi_env &env, const napi_callback_info &info, - PriorityGroupParamsInfo ¶ms) + PriorityGroupParamsInfo ¶ms, AsyncCallbackInfoPriorityGroup* &asyncCallbackInfo) { 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); + } } + BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo); return BundleStateCommon::NapiGetNull(env); } napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) { PriorityGroupParamsInfo params; - ParsePriorityGroupParameters(env, info, params); - napi_value promise = nullptr; - AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = - new (std::nothrow) AsyncCallbackInfoPriorityGroup(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; + AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = nullptr; + ParsePriorityGroupParameters(env, info, params, asyncCallbackInfo); + if (params.errorCode != ERR_OK) { return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); } std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGD("QueryPackageGroup callbackPtr->bundleName: %{public}s", + callbackPtr->bundleName.c_str()); + napi_value promise = nullptr; 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 +313,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); @@ -380,10 +412,10 @@ napi_value QueryCurrentBundleActiveStates(napi_env env, napi_callback_info info) } std::unique_ptr callbackPtr {asyncCallbackInfo}; callbackPtr->beginTime = params.beginTime; - BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates callbackPtr->beginTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryCurrentBundleActiveStates callbackPtr->beginTime: %{public}lld", (long long)callbackPtr->beginTime); callbackPtr->endTime = params.endTime; - BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates callbackPtr->endTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryCurrentBundleActiveStates callbackPtr->endTime: %{public}lld", (long long)callbackPtr->endTime); BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); @@ -413,7 +445,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(); @@ -446,10 +477,10 @@ napi_value QueryBundleActiveStates(napi_env env, napi_callback_info info) } std::unique_ptr callbackPtr {asyncCallbackInfo}; callbackPtr->beginTime = params.beginTime; - BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates callbackPtr->beginTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleActiveStates callbackPtr->beginTime: %{public}lld", (long long)callbackPtr->beginTime); callbackPtr->endTime = params.endTime; - BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates callbackPtr->endTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleActiveStates callbackPtr->endTime: %{public}lld", (long long)callbackPtr->endTime); BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); @@ -572,13 +603,13 @@ napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info) } std::unique_ptr callbackPtr {asyncCallbackInfo}; callbackPtr->intervalType = params.intervalType; - BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval callbackPtr->intervalType: %{public}d", + BUNDLE_ACTIVE_LOGD("QueryBundleStateInfoByInterval callbackPtr->intervalType: %{public}d", callbackPtr->intervalType); callbackPtr->beginTime = params.beginTime; - BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval callbackPtr->beginTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleStateInfoByInterval callbackPtr->beginTime: %{public}lld", (long long)callbackPtr->beginTime); callbackPtr->endTime = params.endTime; - BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval callbackPtr->endTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleStateInfoByInterval callbackPtr->endTime: %{public}lld", (long long)callbackPtr->endTime); BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); napi_value resourceName = nullptr; @@ -684,10 +715,10 @@ napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) } std::unique_ptr callbackPtr {asyncCallbackInfo}; callbackPtr->beginTime = params.beginTime; - BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos callbackPtr->beginTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleStateInfos callbackPtr->beginTime: %{public}lld", (long long)callbackPtr->beginTime); callbackPtr->endTime = params.endTime; - BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos callbackPtr->endTime: %{public}lld", + BUNDLE_ACTIVE_LOGD("QueryBundleStateInfos callbackPtr->endTime: %{public}lld", (long long)callbackPtr->endTime); BundleStateCommon::SettingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise); napi_value resourceName = nullptr; @@ -724,6 +755,254 @@ 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, AsyncCallbackInfoSetBundleGroup* &asyncCallbackInfo) +{ + 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); + } + BundleStateCommon::AsyncInit(env, params, asyncCallbackInfo); + return BundleStateCommon::NapiGetNull(env); +} + +napi_value SetBundleGroup(napi_env env, napi_callback_info info) +{ + ParamsBundleGroupInfo params; + AsyncCallbackInfoSetBundleGroup *asyncCallbackInfo = nullptr; + ParseAppUsageBundleGroupInfoParameters(env, info, params, asyncCallbackInfo); + if (params.errorCode != ERR_OK) { + return BundleStateCommon::JSParaError(env, params.callback, params.errorCode); + } + std::unique_ptr callbackPtr {asyncCallbackInfo}; + callbackPtr->newGroup = params.newGroup; + callbackPtr->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGD("SetBundleGroup, bundleName is %{public}s, newGroup is %{public}d", + callbackPtr->bundleName.c_str(), callbackPtr->newGroup); + napi_value promise = nullptr; + 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; + napi_get_null(env, &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..a21e779499bbaf5f39bef4d0c49b1e7b509e31a4 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -16,11 +16,16 @@ #ifndef BUNDLE_ACTIVE_CLIENT_H #define BUNDLE_ACTIVE_CLIENT_H +#include + #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" +#include "event_handler.h" +#include "event_runner.h" namespace OHOS { namespace DeviceUsageStats { @@ -39,7 +44,7 @@ public: * parameters: bundleName * return: if bundle is idle, return true. if bundle is not idle, return false. */ - bool IsBundleIdle(const std::string& bundleName); + bool IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId = -1); /* * function: QueryPackageStats, query all bundle usage statistics in specific time span for calling user. * parameters: intervalType, beginTime, endTime, errCode @@ -57,8 +62,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,34 +80,88 @@ 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: GetInstance, get instance of client. - * return: object of BundleActiveClient. + * function: observe bundle group change event + * parameters: observer + * return: errorcode. */ - static BundleActiveClient& GetInstance(); + int32_t RegisterGroupCallBack(const sptr &observer); /* - * function: BundleActiveClient, default constructor. + * function: unobserve bundle group change event + * parameters: observer + * return: errorcode. */ - BundleActiveClient() {} + int32_t UnregisterGroupCallBack(const sptr &observer); + /* - * function: ~BundleActiveClient, default destructor. + * 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. */ - ~BundleActiveClient() {} + 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. + */ + static BundleActiveClient& GetInstance(); +private: + class BundleActiveClientDeathRecipient : public IRemoteObject::DeathRecipient { + public: + /* + * function: BundleActiveClientDeathRecipient, default constructor. + */ + BundleActiveClientDeathRecipient() = default; + /* + * function: ~BundleActiveClientDeathRecipient, default destructor. + */ + ~BundleActiveClientDeathRecipient() = default; + /* + * function: setObserver. + */ + void setObserver(const sptr &observer); + /* + * function: OnRemoteDied, PostTask when service(bundleActiveProxy_) is died. + */ + void OnRemoteDied(const wptr &object) override; + /* + * function: OnServiceDiedInner, get bundleActiveProxy_ and registerGroupCallBack again. + */ + void OnServiceDiedInner(const wptr &object); - int32_t ShellDump(const std::vector &dumpOption, std::vector &dumpInfo); + private: + sptr observer_ = nullptr; + }; private: bool GetBundleActiveProxy(); + BundleActiveClient() {} + ~BundleActiveClient() {} sptr bundleActiveProxy_; + sptr recipient_; + std::shared_ptr bundleClientRunner_ {nullptr}; + std::shared_ptr bundleClientHandler_ {nullptr}; + std::mutex mutex_; }; } // namespace DeviceUsageStats } // namespace OHOS 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..9e0a205ce81a8235735cf91e4a6b1fbf90184c24 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 { @@ -37,7 +38,7 @@ public: * parameters: bundleName * return: if bundle is idle, return true. if bundle is not idle, return false. */ - bool IsBundleIdle(const std::string& bundleName) override; + bool IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId = -1) override; /* * function: QueryPackageStats, query all bundle usage statistics in specific time span for calling user. * parameters: intervalType, beginTime, endTime, errCode @@ -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..0cd2f54efec4c8c82ac2e2dbd2f91d0ec46332b0 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -18,9 +18,8 @@ namespace OHOS { namespace DeviceUsageStats { namespace { - const int32_t EVENTS_PARAM = 5; - const int32_t PACKAGE_USAGE_PARAM = 6; - const int32_t MODULE_USAGE_PARAM = 4; + const std::string BUNDLE_ACTIVE_CLIENT_NAME = "bundleActiveName"; + static const int32_t DELAY_TIME = 5000; } BundleActiveClient& BundleActiveClient::GetInstance() { @@ -30,6 +29,10 @@ BundleActiveClient& BundleActiveClient::GetInstance() bool BundleActiveClient::GetBundleActiveProxy() { + if (bundleActiveProxy_ != nullptr) { + return true; + } + std::lock_guard lock(mutex_); sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (!samgr) { BUNDLE_ACTIVE_LOGE("Failed to get SystemAbilityManager."); @@ -38,13 +41,26 @@ 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; } bundleActiveProxy_ = iface_cast(object); if (!bundleActiveProxy_) { - BUNDLE_ACTIVE_LOGE("Failed to get BundleActiveClient."); + BUNDLE_ACTIVE_LOGE("Failed to get BundleActiveProxy."); + return false; + } + if (!recipient_) { + recipient_ = new (std::nothrow) BundleActiveClientDeathRecipient(); + } + bundleClientRunner_ = AppExecFwk::EventRunner::Create(BUNDLE_ACTIVE_CLIENT_NAME); + if (!bundleClientRunner_) { + BUNDLE_ACTIVE_LOGE("BundleActiveClient runner create failed!"); + return false; + } + bundleClientHandler_ = std::make_shared(bundleClientRunner_); + if (!bundleClientHandler_) { + BUNDLE_ACTIVE_LOGE("BundleActiveClient handler create failed!"); return false; } return true; @@ -59,12 +75,12 @@ int32_t BundleActiveClient::ReportEvent(BundleActiveEvent event, const int32_t u return bundleActiveProxy_->ReportEvent(event, userId); } -bool BundleActiveClient::IsBundleIdle(const std::string& bundleName) +bool BundleActiveClient::IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId) { if (!GetBundleActiveProxy()) { return -1; } - return bundleActiveProxy_->IsBundleIdle(bundleName); + return bundleActiveProxy_->IsBundleIdle(bundleName, errCode, userId); } std::vector BundleActiveClient::QueryPackageStats(const int32_t intervalType, @@ -85,13 +101,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 +127,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,54 +149,73 @@ int32_t BundleActiveClient::QueryFormStatistics(int32_t maxNum, std::vectorQueryFormStatistics(maxNum, results, userId); } -int32_t BundleActiveClient::ShellDump(const std::vector &dumpOption, std::vector &dumpInfo) -{ - int32_t ret = -1; - - if (dumpOption[1] == "Events") { - std::vector eventResult; - if (static_cast(dumpOption.size()) != EVENTS_PARAM) { - return ret; - } - int64_t beginTime = std::stoll(dumpOption[2]); - int64_t endTime = std::stoll(dumpOption[3]); - int32_t userId = std::stoi(dumpOption[4]); - eventResult = this->QueryEvents(beginTime, endTime, ret, userId); - for (auto& oneEvent : eventResult) { - dumpInfo.emplace_back(oneEvent.ToString()); - } - } else if (dumpOption[1] == "PackageUsage") { - std::vector packageUsageResult; - if (static_cast(dumpOption.size()) != PACKAGE_USAGE_PARAM) { - return ret; - } - int32_t intervalType = std::stoi(dumpOption[2]); - int64_t beginTime = std::stoll(dumpOption[3]); - int64_t endTime = std::stoll(dumpOption[4]); - int32_t userId = std::stoi(dumpOption[5]); - packageUsageResult = this->QueryPackageStats(intervalType, beginTime, endTime, ret, userId); - for (auto& onePackageRecord : packageUsageResult) { - dumpInfo.emplace_back(onePackageRecord.ToString()); - } - } else if (dumpOption[1] == "ModuleUsage") { - std::vector moduleResult; - if (static_cast(dumpOption.size()) != MODULE_USAGE_PARAM) { - return ret; - } - int32_t maxNum = std::stoi(dumpOption[2]); - int32_t userId = std::stoi(dumpOption[3]); - BUNDLE_ACTIVE_LOGI("M is %{public}d, u is %{public}d", maxNum, userId); - ret = this->QueryFormStatistics(maxNum, moduleResult, userId); - for (auto& oneModuleRecord : moduleResult) { - dumpInfo.emplace_back(oneModuleRecord.ToString()); - for (uint32_t i = 0; i < oneModuleRecord.formRecords_.size(); i++) { - std::string oneFormInfo = "form " + std::to_string(static_cast(i) + 1) + ", "; - dumpInfo.emplace_back(oneFormInfo + oneModuleRecord.formRecords_[i].ToString()); - } - } - } - - return ret; +int32_t BundleActiveClient::RegisterGroupCallBack(const sptr &observer) +{ + if (!GetBundleActiveProxy()) { + return -1; + } + int32_t result = bundleActiveProxy_->RegisterGroupCallBack(observer); + // AddDeathRecipient when RegisterGroupCallBack success + if (recipient_ && result == ERR_OK) { + recipient_->setObserver(observer); + bundleActiveProxy_->AsObject()->AddDeathRecipient(recipient_); + } + return result; +} + +int32_t BundleActiveClient::UnregisterGroupCallBack(const sptr &observer) +{ + if (!GetBundleActiveProxy()) { + return -1; + } + int32_t result = bundleActiveProxy_->UnregisterGroupCallBack(observer); + if (recipient_) { + bundleActiveProxy_->AsObject()->RemoveDeathRecipient(recipient_); + } + return result; +} + +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); +} + +void BundleActiveClient::BundleActiveClientDeathRecipient::setObserver(const sptr &observer) +{ + if (observer) { + observer_ = observer; + } +} +void BundleActiveClient::BundleActiveClientDeathRecipient::OnRemoteDied(const wptr &object) +{ + if (object == nullptr) { + BUNDLE_ACTIVE_LOGE("remote object is null."); + return; + } + BundleActiveClient::GetInstance().bundleActiveProxy_ = nullptr; + BundleActiveClient::GetInstance().bundleClientHandler_->PostTask([this, &object]() { + this->OnServiceDiedInner(object); + }, + DELAY_TIME); +} + +void BundleActiveClient::BundleActiveClientDeathRecipient::OnServiceDiedInner(const wptr &object) +{ + while (!BundleActiveClient::GetInstance().GetBundleActiveProxy()) { } + BundleActiveClient::GetInstance().RegisterGroupCallBack(observer_); } } // namespace DeviceUsageStats } // namespace OHOS 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..266ff17dc4d9a5a583ecf111df314a126cb89382 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_stub.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "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_LOGE("RegisterGroupCallBack OnRemoteRequest cannot get power mgr service"); + return -1; + } + switch (code) { + case static_cast(IBundleActiveGroupCallback::message::ON_BUNDLE_GROUP_CHANGED): { + std::shared_ptr groupInfo( + data.ReadParcelable()); + if (!groupInfo) { + BUNDLE_ACTIVE_LOGE("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..f9844895001348c194ef4ec0632d141556093fdf 100644 --- a/interfaces/innerkits/src/bundle_active_proxy.cpp +++ b/interfaces/innerkits/src/bundle_active_proxy.cpp @@ -33,18 +33,20 @@ int32_t BundleActiveProxy::ReportEvent(BundleActiveEvent& event, const int32_t u return result; } -bool BundleActiveProxy::IsBundleIdle(const std::string& bundleName) +bool BundleActiveProxy::IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId) { MessageParcel data; MessageParcel reply; MessageOption option; - if (!data.WriteInterfaceToken(GetDescriptor())) { + if (!data.WriteInterfaceToken(GetDescriptor()) || + !data.WriteString(bundleName) || + !data.WriteInt32(errCode) || + !data.WriteInt32(userId)) { return false; } - data.WriteString(bundleName); Remote() -> SendRequest(IS_BUNDLE_IDLE, data, reply, option); - int32_t result = reply.ReadInt32(); - BUNDLE_ACTIVE_LOGI("result is %{public}d", result); + bool result = reply.ReadInt32(); + errCode = reply.ReadInt32(); return result; } @@ -75,7 +77,7 @@ std::vector BundleActiveProxy::QueryPackageStats(const result.push_back(*tmp); } for (uint32_t i = 0; i < result.size(); i++) { - BUNDLE_ACTIVE_LOGI("QueryPackageStats result idx is %{public}d, bundleName_ is %{public}s, " + BUNDLE_ACTIVE_LOGD("QueryPackageStats result idx is %{public}d, bundleName_ is %{public}s, " "lastTimeUsed_ is %{public}lld, lastContiniousTaskUsed_ is %{public}lld, " "totalInFrontTime_ is %{public}lld, totalContiniousTaskUsedTime_ is %{public}lld", i + 1, result[i].bundleName_.c_str(), @@ -116,18 +118,22 @@ 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) { 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, @@ -154,7 +160,7 @@ std::vector BundleActiveProxy::QueryCurrentPackageStat result.push_back(*tmp); } for (uint32_t i = 0; i < result.size(); i++) { - BUNDLE_ACTIVE_LOGI("QueryPackageStats result idx is %{public}d, bundleName_ is %{public}s, " + BUNDLE_ACTIVE_LOGD("QueryPackageStats result idx is %{public}d, bundleName_ is %{public}s, " "lastTimeUsed_ is %{public}lld, lastContiniousTaskUsed_ is %{public}lld, " "totalInFrontTime_ is %{public}lld, totalContiniousTaskUsedTime_ is %{public}lld", i + 1, result[i].bundleName_.c_str(), @@ -186,25 +192,27 @@ std::vector BundleActiveProxy::QueryCurrentEvents(const int64 result.push_back(*tmp); } for (uint32_t i = 0; i < result.size(); i++) { - BUNDLE_ACTIVE_LOGI("QueryCurrentEvents event id is %{public}d, bundle name is %{public}s," + BUNDLE_ACTIVE_LOGD("QueryCurrentEvents event id is %{public}d, bundle name is %{public}s," "time stamp is %{public}lld", result[i].eventId_, result[i].bundleName_.c_str(), (long long)result[i].timeStamp_); } 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, @@ -230,11 +238,11 @@ int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector &observer) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGE("RegisterGroupCallBack observer is nullptr"); + 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("UnregisterGroupCallBack observer is nullptr"); + return false; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return false; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("UnregisterGroupCallBack 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_LOGD("QueryEventStats 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_LOGD("QueryAppNotificationNumber 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..2def2921ff3a1310fcf7debf92c7ae355184dd4f 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,28 @@ declare namespace bundleState { formRecords: Array; } + /** + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App + * @systemapi Hide this for inner system use. + */ + 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 +226,32 @@ declare namespace bundleState { */ stateType?: number; } + /** + * @since 9 + * @syscap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup + */ + 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. @@ -332,17 +380,138 @@ declare namespace bundleState { function queryCurrentBundleActiveStates(begin: number, end: number): Promise>; /** - * Queries module usage records. + * Queries recently module usage records. * * @since 9 * @syscap SystemCapability.ResourceSchedule.UsageStatistics.App * @permission ohos.permission.BUNDLE_ACTIVE_INFO * @systemapi Hide this for inner system use. * @param maxNum Indicates max record number in result, max value is 1000, default value is 1000. - * @return Returns the {@link BundleActiveModuleInfo} object Array containing the state data of the current module. + * @return Returns the {@link BundleActiveModuleInfo} object Array containing the usage data of the modules. */ 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 + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @param bundleName, name of the application. + * @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.AppGroup + */ + 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.AppGroup + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @param bundleName, name of the application. + * @param newGroup,the group of the application whose name is bundleName. + * @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.AppGroup + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @param Callback, callback when application group change,return the BundleActiveGroupCallbackInfo. + * @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.AppGroup + * @permission ohos.permission.BUNDLE_ACTIVE_INFO + * @systemapi Hide this for inner system use. + * @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..3ac5015a617f4271157770f8765409cc0aaf9a10 100644 --- a/interfaces/kits/bundlestats/napi/include/bundle_state_common.h +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_common.h @@ -21,6 +21,7 @@ #include "bundle_state_query.h" #include "napi/native_api.h" #include "napi/native_node_api.h" +#include "bundle_state_inner_errors.h" namespace OHOS { namespace DeviceUsageStats { @@ -50,6 +51,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,7 +81,32 @@ 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); + + template + static void AsyncInit(napi_env env, PARAMT ¶ms, ASYNCT* &asyncCallbackInfo); }; + +template +void BundleStateCommon::AsyncInit(napi_env env, PARAMT ¶ms, ASYNCT* &asyncCallbackInfo) +{ + if (params.errorCode != ERR_OK) { + return ; + } + asyncCallbackInfo = new (std::nothrow) ASYNCT(env); + if (!asyncCallbackInfo) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_NULLPTR; + return ; + } + if (memset_s(asyncCallbackInfo, sizeof(*asyncCallbackInfo), 0, sizeof(*asyncCallbackInfo)) + != EOK) { + params.errorCode = ERR_USAGE_STATS_ASYNC_CALLBACK_INIT_FAILED; + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } +} } // namespace DeviceUsageStats } // namespace OHOS #endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_COMMON_H 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..8118aabfa5b1cbab30e3af08253c699ffc96f8e1 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,15 +58,26 @@ 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 = ""; - bool state = true; + bool state = false; }; 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..7261d2bc90e2b41b74a00b7aff9b537223ea8800 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,16 @@ 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, + ERR_USAGE_STATS_METHOD_CALLED_FAILED, + ERR_USAGE_STATS_INVALID_PARAM, }; } // 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..cb8ec0523579377c9940e36b9958a15fee3659d9 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 @@ -58,14 +58,12 @@ describe("DeviceUsageStatisticsJsTest", function () { bundleState.isIdleState(bundleName).then((res) => { console.info('BUNDLE_ACTIVE isIdleState promise success.'); expect(true).assertEqual(true); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE isIdleState promise failure.'); expect(false).assertEqual(true); - }); - - setTimeout(()=>{ done(); - }, 500); + }); }) /* @@ -81,237 +79,177 @@ describe("DeviceUsageStatisticsJsTest", function () { if (err) { console.info('BUNDLE_ACTIVE isIdleState callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE isIdleState callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* * @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.'); - expect(true).assertEqual(true); - }).catch( err => { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); - expect(false).assertEqual(true); - }); - - setTimeout(()=>{ - done(); - }, 500); - }) - - /* - * @tc.name: DeviceUsageStatisticsJsTest004 - * @tc.desc: test queryAppUsagePriorityGroup callback. - * @tc.type: FUNC - * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G - */ - it("DeviceUsageStatisticsJsTest004", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest004---------------------------'); - bundleState.queryAppUsagePriorityGroup((err, res) => { - if (err) { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failure.'); - expect(false).assertEqual(true); - } else { - console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); - expect(true).assertEqual(true); - } - }); - - setTimeout(()=>{ - done(); - }, 500); - }) - - /* - * @tc.name: DeviceUsageStatisticsJsTest005 - * @tc.desc: test queryBundleActiveStates promise. - * @tc.type: FUNC - * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 - */ - it("DeviceUsageStatisticsJsTest005", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest005---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryBundleActiveStates(beginTime, endTime).then((res) => { console.info('BUNDLE_ACTIVE queryBundleActiveStates promise success.'); expect(true).assertEqual(true); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE queryBundleActiveStates promise failure.'); expect(false).assertEqual(true); - }); - - setTimeout(()=>{ done(); - }, 500); + }); }) /* - * @tc.name: DeviceUsageStatisticsJsTest006 + * @tc.name: DeviceUsageStatisticsJsTest004 * @tc.desc: test queryBundleActiveStates callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ - it("DeviceUsageStatisticsJsTest006", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest006---------------------------'); + it("DeviceUsageStatisticsJsTest004", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest004---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryBundleActiveStates(beginTime, endTime, (err, res) => { if (err) { console.info('BUNDLE_ACTIVE queryBundleActiveStates callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE queryBundleActiveStates callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* - * @tc.name: DeviceUsageStatisticsJsTest007 + * @tc.name: DeviceUsageStatisticsJsTest005 * @tc.desc: test queryBundleStateInfos promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ - it("DeviceUsageStatisticsJsTest007", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest007---------------------------'); + it("DeviceUsageStatisticsJsTest005", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest005---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryBundleStateInfos(beginTime, endTime).then((res) => { console.info('BUNDLE_ACTIVE queryBundleStateInfos promise success.'); expect(true).assertEqual(true); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE queryBundleStateInfos promise failure.'); expect(false).assertEqual(true); - }); - - setTimeout(()=>{ done(); - }, 500); + }); }) /* - * @tc.name: DeviceUsageStatisticsJsTest008 + * @tc.name: DeviceUsageStatisticsJsTest006 * @tc.desc: test queryBundleStateInfos callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ - it("DeviceUsageStatisticsJsTest008", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest008---------------------------'); + it("DeviceUsageStatisticsJsTest006", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest006---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryBundleStateInfos(beginTime, endTime, (err, res) => { if (err) { console.info('BUNDLE_ACTIVE queryBundleStateInfos callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE queryBundleStateInfos callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* - * @tc.name: DeviceUsageStatisticsJsTest009 + * @tc.name: DeviceUsageStatisticsJsTest007 * @tc.desc: test queryCurrentBundleActiveStates promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ - it("DeviceUsageStatisticsJsTest009", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest009---------------------------'); + it("DeviceUsageStatisticsJsTest007", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest007---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryCurrentBundleActiveStates(beginTime, endTime).then((res) => { console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise success.'); expect(true).assertEqual(true); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise failure.'); expect(false).assertEqual(true); - }); - - setTimeout(()=>{ done(); - }, 500); + }); }) /* - * @tc.name: DeviceUsageStatisticsJsTest010 + * @tc.name: DeviceUsageStatisticsJsTest008 * @tc.desc: test queryCurrentBundleActiveStates callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ - it("DeviceUsageStatisticsJsTest010", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest010---------------------------'); + it("DeviceUsageStatisticsJsTest008", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest008---------------------------'); let beginTime = 0; let endTime = 20000000000000; bundleState.queryCurrentBundleActiveStates(beginTime, endTime, (err, res) => { if (err) { console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* - * @tc.name: DeviceUsageStatisticsJsTest011 + * @tc.name: DeviceUsageStatisticsJsTest009 * @tc.desc: test queryBundleStateInfoByInterval promise. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89H AR000GH89I AR000GH899 */ - it("DeviceUsageStatisticsJsTest011", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest011---------------------------'); + it("DeviceUsageStatisticsJsTest009", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest009---------------------------'); 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); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise failure.'); expect(false).assertEqual(true); - }); - - setTimeout(()=>{ done(); - }, 500); + }); }) /* - * @tc.name: DeviceUsageStatisticsJsTest012 + * @tc.name: DeviceUsageStatisticsJsTest010 * @tc.desc: test queryBundleStateInfoByInterval callback. * @tc.type: FUNC * @tc.require: SR000GGTN7 AR000GH89E AR000GH89F AR000GH89G */ - it("DeviceUsageStatisticsJsTest012", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest012---------------------------'); + it("DeviceUsageStatisticsJsTest010", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest010---------------------------'); let intervalType = 0; let beginTime = 0; let endTime = 20000000000000; @@ -319,61 +257,365 @@ describe("DeviceUsageStatisticsJsTest", function () { if (err) { console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* - * @tc.name: DeviceUsageStatisticsJsTest013 + * @tc.name: DeviceUsageStatisticsJsTest011 * @tc.desc: test getRecentlyUsedModules callback. * @tc.type: FUNC * @tc.require: SR000GU2UE AR0003GU3EQ */ - it("DeviceUsageStatisticsJsTest013", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest013---------------------------'); + it("DeviceUsageStatisticsJsTest011", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest011---------------------------'); let maxNum = 1; bundleState.getRecentlyUsedModules(maxNum, (err, res) => { if (err) { console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback failure.'); expect(false).assertEqual(true); + done(); } else { console.info('BUNDLE_ACTIVE getRecentlyUsedModules callback success.'); expect(true).assertEqual(true); + done(); } }); - - setTimeout(()=>{ - done(); - }, 500); }) /* - * @tc.name: DeviceUsageStatisticsJsTest014 + * @tc.name: DeviceUsageStatisticsJsTest012 * @tc.desc: test getRecentlyUsedModules promise. * @tc.type: FUNC * @tc.require: SR000GU2UE AR0003GU3EQ */ - it("DeviceUsageStatisticsJsTest014", 0, async function (done) { - console.info('----------------------DeviceUsageStatisticsJsTest014---------------------------'); + it("DeviceUsageStatisticsJsTest012", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest012---------------------------'); let maxNum = 1; bundleState.getRecentlyUsedModules(maxNum).then((res) => { console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise success.'); expect(true).assertEqual(true); + done(); }).catch((err) => { console.info('BUNDLE_ACTIVE getRecentlyUsedModules promise failure.'); expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @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); + done(); + }).catch( err => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); + expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @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 queryAppUsagePriorityGroup callback failure.'); + expect(false).assertEqual(true); + done(); + } else { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); + expect(true).assertEqual(true); + done(); + } + }); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest015 + * @tc.desc: test queryAppUsagePriorityGroup promise, with no param. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + it("DeviceUsageStatisticsJsTest015", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest015---------------------------'); + bundleState.queryAppUsagePriorityGroup().then( res => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise success.'); + expect(true).assertEqual(true); + done(); + }).catch( err => { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failure.'); + expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @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 queryAppUsagePriorityGroup callback failure.'); + expect(false).assertEqual(true); + done(); + } else { + console.info('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback success.'); + expect(true).assertEqual(true); + done(); + } + }); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest017 + * @tc.desc: test setBundleGroup promise. + * @tc.type: FUNC + * @tc.require: SR000H0HAQ AR000H0ROE + */ + 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(false).assertEqual(true); + done(); + }).catch( err => { + console.info('BUNDLE_ACTIVE setBundleGroup promise failure.'); + expect(true).assertEqual(true); + done(); + }); + }) + + /* + * @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); + done(); + } else { + console.info('BUNDLE_ACTIVE setBundleGroup callback success.'); + expect(false).assertEqual(true); + done(); + } + }); + }) + + /* + * @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 RegisterGroupCallBack callback success.'); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack appUsageOldGroup is : ' + res.appUsageOldGroup); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack appUsageNewGroup is : ' + res.appUsageNewGroup); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack changeReason is : ' + res.changeReason); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack bundleName is : ' + res.bundleName); + }; + bundleState.registerGroupCallBack(onBundleGroupChanged).then( res => { + console.info('BUNDLE_ACTIVE RegisterGroupCallBack promise success.'); + expect(true).assertEqual(true); + done(); + }).catch( err => { + console.info('BUNDLE_ACTIVE RegisterGroupCallBack promise failure.'); + expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @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 RegisterGroupCallBack appUsageOldGroup is : ' + res.appUsageOldGroup); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack appUsageNewGroup is : ' + res.appUsageNewGroup); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack changeReason is : ' + res.changeReason); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack userId is : ' + res.userId); + console.log('BUNDLE_ACTIVE RegisterGroupCallBack bundleName is : ' + res.bundleName); + }; + bundleState.registerGroupCallBack(onBundleGroupChanged, (err, res) => { + if (err) { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback failure.'); + expect(true).assertEqual(true); + done(); + } else { + console.info('BUNDLE_ACTIVE registerGroupCallBack callback success.'); + expect(false).assertEqual(true); + done(); + } + }); + }) + + /* + * @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); + done(); + }).catch( err => { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack promise failure.'); + expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @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); + done(); + } else { + console.info('BUNDLE_ACTIVE unRegisterGroupCallBack callback success.'); + expect(false).assertEqual(true); + done(); + } + }); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest023 + * @tc.desc: test queryBundleActiveEventStates promise. + * @tc.type: FUNC + * @tc.require: SR000H0H9H AR000H0ROG + */ + it("DeviceUsageStatisticsJsTest023", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest023---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryBundleActiveEventStates(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates promise success.'); + expect(true).assertEqual(true); + done(); + }).catch((err) => { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates promise failure.'); + expect(false).assertEqual(true); + done(); + }); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest024 + * @tc.desc: test queryBundleActiveEventStates callback. + * @tc.type: FUNC + * @tc.require: SR000H0H9H AR000H0ROG + */ + it("DeviceUsageStatisticsJsTest024", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest024---------------------------'); + 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); + done(); + } else { + console.info('BUNDLE_ACTIVE queryBundleActiveEventStates callback success.'); + expect(true).assertEqual(true); + done(); + } }); + }) - setTimeout(()=>{ + /* + * @tc.name: DeviceUsageStatisticsJsTest025 + * @tc.desc: test queryAppNotificationNumber promise. + * @tc.type: FUNC + * @tc.require: SR000H0H7D AR000H0RR6 + */ + it("DeviceUsageStatisticsJsTest025", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest025---------------------------'); + let beginTime = 0; + let endTime = 20000000000000; + bundleState.queryAppNotificationNumber(beginTime, endTime).then((res) => { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber promise success.'); + expect(true).assertEqual(true); + done(); + }).catch((err) => { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber promise failure.'); + expect(false).assertEqual(true); done(); - }, 500); + }); + }) + + /* + * @tc.name: DeviceUsageStatisticsJsTest026 + * @tc.desc: test queryAppNotificationNumber callback. + * @tc.type: FUNC + * @tc.require: SR000H0H7D AR000H0RR6 + */ + it("DeviceUsageStatisticsJsTest026", 0, async function (done) { + console.info('----------------------DeviceUsageStatisticsJsTest026---------------------------'); + 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); + done(); + } else { + console.info('BUNDLE_ACTIVE queryAppNotificationNumber callback success.'); + expect(true).assertEqual(true); + done(); + } + }); }) }) 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..cc07f1cd3f4d6d4e0a64262b5fc788c1c3edadc7 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 SUFFIX_TYPE[] = {".db"}; +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..68f5282b1f3b2f251653d70110f42b475c0c40a4 100644 --- a/services/common/include/bundle_active_log.h +++ b/services/common/include/bundle_active_log.h @@ -22,7 +22,7 @@ namespace OHOS { namespace DeviceUsageStats { #ifndef LOG_TAG_DOMAIN_ID_BUNDLE_ACTIVE -#define LOG_TAG_DOMAIN_ID_BUNDLE_ACTIVE 0xD001701 +#define LOG_TAG_DOMAIN_ID_BUNDLE_ACTIVE 0xD001710 #endif #ifndef LOG_TAG_BUNDLE_ACTIVE @@ -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..ebe6615a511bac3b0b0c26af20b27304d643e221 100644 --- a/services/common/include/bundle_active_service.h +++ b/services/common/include/bundle_active_service.h @@ -24,9 +24,12 @@ #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" +#include "file_ex.h" +#include "string_ex.h" namespace OHOS { namespace DeviceUsageStats { @@ -35,7 +38,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; @@ -56,7 +58,7 @@ public: * parameters: bundleName * return: if bundle is idle, return true. if bundle is not idle, return false. */ - bool IsBundleIdle(const std::string& bundleName) override; + bool IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId = -1) override; /* * function: QueryPackageStats, query all bundle usage statistics in specific time span for calling user. * parameters: intervalType, beginTime, endTime, errCode @@ -75,7 +77,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 +95,51 @@ 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; + int32_t Dump(int32_t fd, const std::vector &args) override; + +protected: /** * @brief The OnStart callback. */ @@ -123,6 +156,7 @@ private: std::shared_ptr continuousTaskObserver_; sptr sptrBundleMgr_; sptr shutdownCallback_; + sptr powerStateCallback_; std::shared_ptr runner_; std::shared_ptr handler_; bool ready_ {false}; @@ -140,6 +174,8 @@ private: void QueryModuleRecordInfos(BundleActiveModuleRecord& moduleRecord); void SerModuleProperties(const HapModuleInfo& hapModuleInfo, const ApplicationInfo& appInfo, const AbilityInfo& abilityInfo, BundleActiveModuleRecord& moduleRecord); + void DumpUsage(std::string &result); + int32_t ShellDump(const std::vector &dumpOption, std::vector &dumpInfo); }; } // namespace DeviceUsageStats } // namespace OHOS 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..49351605d79f9dcc9913b15debde2966eb6f1c14 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 { @@ -58,7 +61,7 @@ public: * parameters: bundleName * return: if bundle is idle, return true. if bundle is not idle, return false. */ - virtual bool IsBundleIdle(const std::string& bundleName) = 0; + virtual bool IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId) = 0; /* * function: QueryPackageStats, query all bundle usage statistics in specific time span for calling user. * parameters: intervalType, beginTime, endTime, errCode @@ -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..723dd8bcafe69624a4c35cd4e9893c5ebb5c1e0a 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" @@ -69,7 +70,7 @@ void BundleActiveCommonEventSubscriber::OnReceiveEvent(const CommonEventData &da { std::lock_guard lock(mutex_); std::string action = data.GetWant().GetAction(); - BUNDLE_ACTIVE_LOGI("OnReceiveEvent action is %{public}s", action.c_str()); + BUNDLE_ACTIVE_LOGD("OnReceiveEvent action is %{public}s", action.c_str()); if (action == CommonEventSupport::COMMON_EVENT_SCREEN_OFF || action == CommonEventSupport::COMMON_EVENT_SCREEN_ON) { if (!activeGroupController_.expired()) { @@ -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,11 +151,13 @@ 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_); bool subscribeResult = CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_); - BUNDLE_ACTIVE_LOGI("Register for events result is %{public}d", subscribeResult); + BUNDLE_ACTIVE_LOGD("Register for events result is %{public}d", subscribeResult); } void BundleActiveCore::UnRegisterSubscriber() @@ -146,12 +175,12 @@ void BundleActiveCore::Init() realTimeShot_ = timer->GetBootTimeMs(); systemTimeShot_ = GetSystemTimeMs(); bundleGroupController_ = std::make_shared(debugCore_); - BUNDLE_ACTIVE_LOGI("system time shot is %{public}lld", (long long)systemTimeShot_); + BUNDLE_ACTIVE_LOGD("system time shot is %{public}lld", (long long)systemTimeShot_); } void BundleActiveCore::InitBundleGroupController() { - BUNDLE_ACTIVE_LOGI("InitBundleGroupController called"); + BUNDLE_ACTIVE_LOGD("InitBundleGroupController called"); std::string threadName = "bundle_active_group_handler"; auto runner = AppExecFwk::EventRunner::Create(threadName); if (runner == nullptr) { @@ -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; @@ -190,7 +219,7 @@ void BundleActiveCore::SetHandler(const std::shared_ptr BundleActiveCore::GetUserDataAndInitializeIfNeeded(const int32_t userId, const int64_t timeStamp, const bool debug) { - BUNDLE_ACTIVE_LOGI("GetUserDataAndInitializeIfNeeded called"); + BUNDLE_ACTIVE_LOGD("GetUserDataAndInitializeIfNeeded called"); std::map>::iterator it = userStatServices_.find(userId); if (it == userStatServices_.end()) { BUNDLE_ACTIVE_LOGI("first initialize user service"); @@ -209,7 +238,7 @@ std::shared_ptr BundleActiveCore::GetUserDataAndInitial void BundleActiveCore::OnBundleUninstalled(const int32_t userId, const std::string& bundleName) { - BUNDLE_ACTIVE_LOGI("OnBundleUninstalled CALLED"); + BUNDLE_ACTIVE_LOGD("OnBundleUninstalled CALLED"); std::lock_guard lock(mutex_); int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); if (timeNow == -1) { @@ -264,7 +293,7 @@ void BundleActiveCore::RestoreAllData() void BundleActiveCore::RestoreToDatabase(const int32_t userId) { - BUNDLE_ACTIVE_LOGI("RestoreToDatabase called"); + BUNDLE_ACTIVE_LOGD("RestoreToDatabase called"); sptr timer = MiscServices::TimeServiceClient::GetInstance(); BundleActiveEvent event; event.eventId_ = BundleActiveEvent::FLUSH; @@ -279,7 +308,7 @@ void BundleActiveCore::RestoreToDatabase(const int32_t userId) void BundleActiveCore::RestoreToDatabaseLocked(const int32_t userId) { - BUNDLE_ACTIVE_LOGI("RestoreToDatabaseLocked called"); + BUNDLE_ACTIVE_LOGD("RestoreToDatabaseLocked called"); auto it = userStatServices_.find(userId); if (it != userStatServices_.end()) { it->second->RestoreStats(false); @@ -293,10 +322,32 @@ 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_); - BUNDLE_ACTIVE_LOGI("ShutDown called"); + BUNDLE_ACTIVE_LOGD("ShutDown called"); sptr timer = MiscServices::TimeServiceClient::GetInstance(); int64_t timeStamp = timer->GetBootTimeMs(); BundleActiveEvent event(BundleActiveEvent::SHUTDOWN, timeStamp); @@ -316,7 +367,7 @@ void BundleActiveCore::ShutDown() void BundleActiveCore::OnStatsReload() { - BUNDLE_ACTIVE_LOGI("OnStatsReload called"); + BUNDLE_ACTIVE_LOGD("OnStatsReload called"); bundleGroupController_->CheckIdleStatsOneTime(); } @@ -326,7 +377,7 @@ void BundleActiveCore::OnSystemUpdate(int32_t userId) int64_t BundleActiveCore::CheckTimeChangeAndGetWallTime(int32_t userId) { - BUNDLE_ACTIVE_LOGI("CheckTimeChangeAndGetWallTime called, userId is %{public}d", userId); + BUNDLE_ACTIVE_LOGD("CheckTimeChangeAndGetWallTime called, userId is %{public}d", userId); sptr timer = MiscServices::TimeServiceClient::GetInstance(); int64_t actualSystemTime = GetSystemTimeMs(); int64_t actualRealTime = timer->GetBootTimeMs(); @@ -335,7 +386,7 @@ int64_t BundleActiveCore::CheckTimeChangeAndGetWallTime(int32_t userId) if (actualSystemTime == -1 || actualRealTime == -1) { return -1; } - BUNDLE_ACTIVE_LOGI("asystime is %{public}lld, artime is %{public}lld, esystime is %{public}lld, " + BUNDLE_ACTIVE_LOGD("asystime is %{public}lld, artime is %{public}lld, esystime is %{public}lld, " "diff is %{public}lld", (long long)actualSystemTime, (long long)actualRealTime, (long long)expectedSystemTime, (long long)diffSystemTime); if (std::abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) { @@ -364,13 +415,13 @@ int64_t BundleActiveCore::CheckTimeChangeAndGetWallTime(int32_t userId) void BundleActiveCore::ConvertToSystemTimeLocked(BundleActiveEvent& event) { - BUNDLE_ACTIVE_LOGI("ConvertToSystemTimeLocked called"); + BUNDLE_ACTIVE_LOGD("ConvertToSystemTimeLocked called"); event.timeStamp_ = std::max((int64_t)0, event.timeStamp_ - realTimeShot_) + systemTimeShot_; } void BundleActiveCore::OnUserRemoved(const int32_t userId) { - BUNDLE_ACTIVE_LOGI("OnUserRemoved called"); + BUNDLE_ACTIVE_LOGD("OnUserRemoved called"); std::lock_guard lock(mutex_); auto it = userStatServices_.find(userId); if (it == userStatServices_.end()) { @@ -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_); + BUNDLE_ACTIVE_LOGD("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,8 +481,7 @@ 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, " + BUNDLE_ACTIVE_LOGD("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_); int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); @@ -455,9 +505,29 @@ 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"); + BUNDLE_ACTIVE_LOGD("ReportEventToAllUserId called"); int64_t timeNow = CheckTimeChangeAndGetWallTime(); if (timeNow == -1) { return -1; @@ -484,14 +554,14 @@ int32_t BundleActiveCore::ReportEventToAllUserId(BundleActiveEvent& event) std::vector BundleActiveCore::QueryPackageStats(const int32_t userId, const int32_t intervalType, const int64_t beginTime, const int64_t endTime, std::string bundleName) { - BUNDLE_ACTIVE_LOGI("QueryPackageStats called"); + BUNDLE_ACTIVE_LOGD("QueryPackageStats called"); std::lock_guard lock(mutex_); std::vector result; int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); if (timeNow == -1) { return result; } - BUNDLE_ACTIVE_LOGI("QueryPackageStats begin time is %{public}lld, end time is %{public}lld, " + BUNDLE_ACTIVE_LOGD("QueryPackageStats begin time is %{public}lld, end time is %{public}lld, " "intervaltype is %{public}d", (long long)beginTime, (long long)endTime, intervalType); if (beginTime > timeNow || beginTime >= endTime) { BUNDLE_ACTIVE_LOGI("QueryPackageStats time span illegal"); @@ -509,7 +579,7 @@ std::vector BundleActiveCore::QueryPackageStats(const std::vector BundleActiveCore::QueryEvents(const int32_t userId, const int64_t beginTime, const int64_t endTime, std::string bundleName) { - BUNDLE_ACTIVE_LOGI("QueryEvents called"); + BUNDLE_ACTIVE_LOGD("QueryEvents called"); std::vector result; std::lock_guard lock(mutex_); int64_t timeNow = CheckTimeChangeAndGetWallTime(userId); @@ -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,124 @@ int64_t BundleActiveCore::GetSystemTimeMs() } return static_cast(tarDate); } + +void BundleActiveCore::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo) +{ + std::lock_guard lock(callbackMutex_); + AccessToken::HapTokenInfo tokenInfo = AccessToken::HapTokenInfo(); + 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()); + if (AccessToken::AccessTokenKit::GetTokenType(item.first) == AccessToken::ATokenTypeEnum::TOKEN_NATIVE) { + observer->OnBundleGroupChanged(callbackInfo); + } else if (AccessToken::AccessTokenKit::GetTokenType(item.first) == + AccessToken::ATokenTypeEnum::TOKEN_HAP) { + AccessToken::AccessTokenKit::GetHapTokenInfo(item.first, tokenInfo); + if (tokenInfo.userID == callbackInfo.GetUserId()) { + 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_LOGD("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..6d082fce7fe989e1bc781e6f675613b6b8f0e58a 100644 --- a/services/common/src/bundle_active_service.cpp +++ b/services/common/src/bundle_active_service.cpp @@ -19,6 +19,7 @@ #include "accesstoken_kit.h" #include "app_mgr_interface.h" +#include "bundle_state_inner_errors.h" #include "bundle_active_event.h" #include "bundle_active_package_stats.h" #include "bundle_active_account_helper.h" @@ -33,6 +34,11 @@ static const int32_t PERIOD_BEST_SERVICE = 4; static const int32_t DELAY_TIME = 2000; static const std::string PERMITTED_PROCESS_NAME = "foundation"; static const int32_t MAXNUM_UP_LIMIT = 1000; +const int32_t EVENTS_PARAM = 5; +static constexpr int32_t NO_DUMP_PARAM_NUMS = 0; +static constexpr int32_t MIN_DUMP_PARAM_NUMS = 1; +const int32_t PACKAGE_USAGE_PARAM = 6; +const int32_t MODULE_USAGE_PARAM = 4; const std::string NEEDED_PERMISSION = "ohos.permission.BUNDLE_ACTIVE_INFO"; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); @@ -62,15 +68,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 +102,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 +136,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(); @@ -171,7 +180,6 @@ void BundleActiveService::InitContinuousSubscriber(const std::shared_ptr appManager = GetAppManagerInstance(); if (appStateObserver_ == nullptr || appManager == nullptr) { BUNDLE_ACTIVE_LOGE("SubscribeAppState appstateobserver is null, return"); @@ -182,7 +190,7 @@ bool BundleActiveService::SubscribeAppState() BUNDLE_ACTIVE_LOGE("RegisterApplicationStateObserver failed. err:%{public}d", err); return false; } - BUNDLE_ACTIVE_LOGI("RegisterApplicationStateObserver success."); + BUNDLE_ACTIVE_LOGD("RegisterApplicationStateObserver success."); return true; } @@ -205,6 +213,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"); @@ -240,20 +249,45 @@ int32_t BundleActiveService::ReportEvent(BundleActiveEvent& event, const int32_t } } -bool BundleActiveService::IsBundleIdle(const std::string& bundleName) +bool BundleActiveService::IsBundleIdle(const std::string& bundleName, int32_t& errCode, int32_t userId) { // get uid - BUNDLE_ACTIVE_LOGI("Is bundle active called"); int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); - BUNDLE_ACTIVE_LOGI("UID is %{public}d", callingUid); + AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("get bundle manager proxy failed!"); + return false; + } + std::string callingBundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, callingBundleName); + BUNDLE_ACTIVE_LOGI("UID is %{public}d, bundle name is %{public}s", callingUid, callingBundleName.c_str()); // get user id - int32_t userId = -1; int32_t result = -1; - OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); - if (ret == ERR_OK && userId != -1) { - result = bundleActiveCore_->IsBundleIdle(bundleName, userId); + if (userId == -1) { + BundleActiveAccountHelper::GetUserId(callingUid, userId); } - if (result == 0) { + if (userId != -1) { + if (callingBundleName == bundleName) { + BUNDLE_ACTIVE_LOGI("%{public}s check its own idle state", bundleName.c_str()); + result = bundleActiveCore_->IsBundleIdle(bundleName, userId); + } else { + bool isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId, errCode); + BUNDLE_ACTIVE_LOGI("check other bundle idle state"); + if (isSystemAppAndHasPermission || + AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) == + AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { + errCode = 0; + result = bundleActiveCore_->IsBundleIdle(bundleName, userId); + } else { + errCode = -1; + return false; + } + } + } else { + errCode = -1; + return false; + } + if (result == 0 || result == -1) { return false; } return true; @@ -262,12 +296,12 @@ bool BundleActiveService::IsBundleIdle(const std::string& bundleName) std::vector BundleActiveService::QueryPackageStats(const int32_t intervalType, const int64_t beginTime, const int64_t endTime, int32_t& errCode, int32_t userId) { - BUNDLE_ACTIVE_LOGI("QueryPackageStats stats called, intervaltype is %{public}d", intervalType); + BUNDLE_ACTIVE_LOGD("QueryPackageStats stats called, intervaltype is %{public}d", intervalType); std::vector result; // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); - BUNDLE_ACTIVE_LOGI("QueryPackageStats UID is %{public}d", callingUid); + BUNDLE_ACTIVE_LOGD("QueryPackageStats UID is %{public}d", callingUid); if (userId == -1) { // get userid OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); @@ -294,12 +328,11 @@ std::vector BundleActiveService::QueryPackageStats(con std::vector BundleActiveService::QueryEvents(const int64_t beginTime, const int64_t endTime, int32_t& errCode, int32_t userId) { - BUNDLE_ACTIVE_LOGI("QueryEvents stats called"); std::vector result; // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); - BUNDLE_ACTIVE_LOGI("QueryEvents UID is %{public}d", callingUid); + BUNDLE_ACTIVE_LOGD("QueryEvents UID is %{public}d", callingUid); if (userId == -1) { // get userid OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); @@ -322,26 +355,54 @@ 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); + int32_t result = -1; + + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("get bundle manager proxy failed!"); + return result; + } + std::string localBundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, localBundleName); + if (localBundleName == bundleName) { + BUNDLE_ACTIVE_LOGI("SetBundleGroup can not set its bundleName"); + return -1; + } + 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; } std::vector BundleActiveService::QueryCurrentPackageStats(const int32_t intervalType, const int64_t beginTime, const int64_t endTime) { - BUNDLE_ACTIVE_LOGI("QueryCurrentPackageStats stats called"); std::vector result; // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); - BUNDLE_ACTIVE_LOGI("UID is %{public}d", callingUid); + BUNDLE_ACTIVE_LOGD("UID is %{public}d", callingUid); // get userid int32_t userId = -1; OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret == ERR_OK && userId != -1) { - BUNDLE_ACTIVE_LOGI("QueryCurrentPackageStats userid is %{public}d", userId); + BUNDLE_ACTIVE_LOGD("QueryCurrentPackageStats userid is %{public}d", userId); if (!GetBundleMgrProxy()) { BUNDLE_ACTIVE_LOGE("get bundle manager proxy failed!"); return result; @@ -363,11 +424,10 @@ std::vector BundleActiveService::QueryCurrentPackageSt std::vector BundleActiveService::QueryCurrentEvents(const int64_t beginTime, const int64_t endTime) { - BUNDLE_ACTIVE_LOGI("QueryCurrentEvents stats called"); std::vector result; // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); - BUNDLE_ACTIVE_LOGI("QueryCurrentEvents UID is %{public}d", callingUid); + BUNDLE_ACTIVE_LOGD("QueryCurrentEvents UID is %{public}d", callingUid); // get userid int32_t userId = -1; OHOS::ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); @@ -384,35 +444,76 @@ std::vector BundleActiveService::QueryCurrentEvents(const int result = bundleActiveCore_->QueryEvents(userId, beginTime, endTime, bundleName); } } - BUNDLE_ACTIVE_LOGI("QueryCurrentEvents result size is %{public}zu", result.size()); + BUNDLE_ACTIVE_LOGD("QueryCurrentEvents result size is %{public}zu", result.size()); 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 localBundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, localBundleName); + bundleName = localBundleName; + 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 +554,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()); 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("%{public}s has permission %{public}d", + bundleName.c_str(), bundleHasPermission); return true; } } @@ -486,7 +582,7 @@ int32_t BundleActiveService::QueryFormStatistics(int32_t maxNum, std::vector& eventStats, int32_t userId) +{ + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGD("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_LOGD("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_LOGD("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()) { @@ -519,13 +669,13 @@ void BundleActiveService::QueryModuleRecordInfos(BundleActiveModuleRecord& modul ApplicationInfo appInfo; if (!sptrBundleMgr_->GetApplicationInfo(moduleRecord.bundleName_, ApplicationFlag::GET_BASIC_APPLICATION_INFO, moduleRecord.userId_, appInfo)) { - BUNDLE_ACTIVE_LOGW("GetApplicationInfo failed!"); + BUNDLE_ACTIVE_LOGE("GetApplicationInfo failed!"); return; } BundleInfo bundleInfo; if (!sptrBundleMgr_->GetBundleInfo(moduleRecord.bundleName_, BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, moduleRecord.userId_)) { - BUNDLE_ACTIVE_LOGW("GetBundleInfo failed!"); + BUNDLE_ACTIVE_LOGE("GetBundleInfo failed!"); return; } for (const auto & oneModuleInfo : bundleInfo.hapModuleInfos) { @@ -556,6 +706,100 @@ void BundleActiveService::SerModuleProperties(const HapModuleInfo& hapModuleInfo moduleRecord.abilityIconId_ = abilityInfo.iconId; moduleRecord.installFreeSupported_ = hapModuleInfo.installationFree; } + +int32_t BundleActiveService::Dump(int32_t fd, const std::vector &args) +{ + std::vector argsInStr; + std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), + [](const std::u16string &arg) { + return Str16ToStr8(arg); + }); + std::string result; + int32_t ret = ERR_OK; + if (argsInStr.size() == NO_DUMP_PARAM_NUMS) { + DumpUsage(result); + } else if (argsInStr.size() >= MIN_DUMP_PARAM_NUMS) { + std::vector infos; + if (argsInStr[0] == "-h") { + DumpUsage(result); + } else if (argsInStr[0] == "-A") { + ret = ShellDump(argsInStr, infos); + } else { + infos.emplace_back("BundleActiveService Error params.\n"); + ret = ERR_USAGE_STATS_INVALID_PARAM; + } + for (auto info : infos) { + result.append(info); + } + } + if (!SaveStringToFd(fd, result)) { + BUNDLE_ACTIVE_LOGE("BundleActiveService dump save string to fd failed!"); + ret = ERR_USAGE_STATS_METHOD_CALLED_FAILED; + } + return ret; +} + +int32_t BundleActiveService::ShellDump(const std::vector &dumpOption, std::vector &dumpInfo) +{ + int32_t ret = -1; + + if (dumpOption[1] == "Events") { + std::vector eventResult; + if (static_cast(dumpOption.size()) != EVENTS_PARAM) { + return ret; + } + int64_t beginTime = std::stoll(dumpOption[2]); + int64_t endTime = std::stoll(dumpOption[3]); + int32_t userId = std::stoi(dumpOption[4]); + eventResult = this->QueryEvents(beginTime, endTime, ret, userId); + for (auto& oneEvent : eventResult) { + dumpInfo.emplace_back(oneEvent.ToString()); + } + } else if (dumpOption[1] == "PackageUsage") { + std::vector packageUsageResult; + if (static_cast(dumpOption.size()) != PACKAGE_USAGE_PARAM) { + return ret; + } + int32_t intervalType = std::stoi(dumpOption[2]); + int64_t beginTime = std::stoll(dumpOption[3]); + int64_t endTime = std::stoll(dumpOption[4]); + int32_t userId = std::stoi(dumpOption[5]); + packageUsageResult = this->QueryPackageStats(intervalType, beginTime, endTime, ret, userId); + for (auto& onePackageRecord : packageUsageResult) { + dumpInfo.emplace_back(onePackageRecord.ToString()); + } + } else if (dumpOption[1] == "ModuleUsage") { + std::vector moduleResult; + if (static_cast(dumpOption.size()) != MODULE_USAGE_PARAM) { + return ret; + } + int32_t maxNum = std::stoi(dumpOption[2]); + int32_t userId = std::stoi(dumpOption[3]); + BUNDLE_ACTIVE_LOGI("M is %{public}d, u is %{public}d", maxNum, userId); + ret = this->QueryFormStatistics(maxNum, moduleResult, userId); + for (auto& oneModuleRecord : moduleResult) { + dumpInfo.emplace_back(oneModuleRecord.ToString()); + for (uint32_t i = 0; i < oneModuleRecord.formRecords_.size(); i++) { + std::string oneFormInfo = "form " + std::to_string(static_cast(i) + 1) + ", "; + dumpInfo.emplace_back(oneFormInfo + oneModuleRecord.formRecords_[i].ToString()); + } + } + } + return ret; +} + +void BundleActiveService::DumpUsage(std::string &result) +{ + std::string dumpHelpMsg = + "usage: bundleactive dump []\n" + "options list:\n" + " -h help menu\n" + " -A \n" + " Events [beginTime] [endTime] [userId] get events for one user\n" + " PackageUsage [intervalType] [beginTime] [endTime] [userId] get package usage for one user\n" + " ModuleUsage [maxNum] [userId] get module usage for one user\n"; + result.append(dumpHelpMsg); +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_stub.cpp b/services/common/src/bundle_active_stub.cpp index ad5037cd8e4eb7371c9c42f8a929d51185d407fe..4745fe8592afec43b3a9a22ea86b5bdcbdfd4f35 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 { @@ -39,8 +40,11 @@ int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Me } case IS_BUNDLE_IDLE: { std::string bundleName = data.ReadString(); - int32_t result = IsBundleIdle(bundleName); - return reply.WriteInt32(result); + int32_t errCode = data.ReadInt32(); + int32_t userId = data.ReadInt32(); + int32_t result = IsBundleIdle(bundleName, errCode, userId); + reply.WriteInt32(result); + return reply.WriteInt32(errCode); } case QUERY_USAGE_STATS: { std::vector result; @@ -84,9 +88,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 +127,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 +148,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..6cbef5a45e66a1b4d35729fcfaf82f8f5482be8c 100644 --- a/services/common/src/bundle_active_usage_database.cpp +++ b/services/common/src/bundle_active_usage_database.cpp @@ -414,6 +414,7 @@ shared_ptr BundleActiveUsageDatabase::GetBundleActiveRdbSto string currDatabaseFileConfig = BUNDLE_ACTIVE_DATABASE_DIR + databaseFiles_.at(databaseType); RdbStoreConfig config(currDatabaseFileConfig); BundleActiveOpenCallback rdbDataCallBack; + config.SetJournalMode(NativeRdb::JournalMode::MODE_OFF); rdbStore = RdbHelper::GetRdbStore(config, BUNDLE_ACTIVE_RDB_VERSION, rdbDataCallBack, errCode); if ((rdbStore == nullptr)) { BUNDLE_ACTIVE_LOGE("rdbStore is nullptr"); @@ -786,6 +787,10 @@ pair BundleActiveUsageDatabase::GetDurationData() void BundleActiveUsageDatabase::FlushPackageInfo(uint32_t databaseType, const BundleActivePeriodStats &stats) { shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("rdbStore is nullptr"); + return; + } string tableName = PACKAGE_LOG_TABLE + to_string(stats.beginTime_); int32_t changeRow = BUNDLE_ACTIVE_FAIL; int64_t outRowId = BUNDLE_ACTIVE_FAIL; @@ -1167,7 +1172,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 +1193,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 +1309,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 +1598,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_package_stats.cpp b/services/packageusage/src/bundle_active_package_stats.cpp index 142d763189de30f2713ce84c37bf5a32901e735d..9a76a21ba92142c3eef7605596dc42704e774321 100644 --- a/services/packageusage/src/bundle_active_package_stats.cpp +++ b/services/packageusage/src/bundle_active_package_stats.cpp @@ -118,6 +118,7 @@ void BundleActivePackageStats::UpdateAbility(const int64_t timeStamp, const int3 break; case BundleActiveEvent::ABILITY_STOP: abilities_.erase(abilityId); + break; default: break; } @@ -137,6 +138,7 @@ void BundleActivePackageStats::UpdateLongTimeTask(const std::string& longTimeTas switch (lastEventId) { case BundleActiveEvent::LONG_TIME_TASK_STARTTED: IncrementServiceTimeUsed(timeStamp); + break; default: break; } @@ -151,6 +153,7 @@ void BundleActivePackageStats::UpdateLongTimeTask(const std::string& longTimeTas break; case BundleActiveEvent::LONG_TIME_TASK_ENDED: longTimeTasks_.erase(longTimeTaskName); + break; default: break; } 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_report_handler.cpp b/services/packageusage/src/bundle_active_report_handler.cpp index 40b90fceff958950b93e7304a1e1f93db814fea5..8a3b2265d4c9558d22182927a7b6c7c1e488c217 100644 --- a/services/packageusage/src/bundle_active_report_handler.cpp +++ b/services/packageusage/src/bundle_active_report_handler.cpp @@ -73,6 +73,7 @@ void BundleActiveReportHandler::ProcessEvent(const AppExecFwk::InnerEvent::Point auto ptrToHandlerobj = event->GetSharedObject(); BundleActiveReportHandlerObject tmpHandlerobj = *ptrToHandlerobj; bundleActiveCore_->OnUserSwitched(tmpHandlerobj.userId_); + break; } default: { break; 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..d3eebd5c95c76aa746bce60490afbb483ee8d97c 100644 --- a/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn +++ b/test/fuzztest/bundleactiveonremoterequest_fuzzer/BUILD.gn @@ -54,9 +54,8 @@ 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/BUILD.gn b/test/unittest/BUILD.gn index e5e9811a302e7118abcb9e9092154f4bfd28d449..650743041f38e061fc5fb8e08dc8da34fc4a31ab 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -38,6 +38,7 @@ ohos_unittest("DeviceUsageStatsTest") { ] external_deps = [ + "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "power_manager_native:powermgr_client", diff --git a/test/unittest/device_usage_statistics_test.cpp b/test/unittest/device_usage_statistics_test.cpp index 9a4eca3ef85d3f2f0fb083a593e3656a9149f46d..922bd7abe765f58d1212af2c3f1c8b8bd60e93f8 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: @@ -144,20 +150,10 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryPackagesStats */ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_IsBundleIdle_001, Function | MediumTest | Level0) { - bool result = BundleActiveClient::GetInstance().IsBundleIdle(DEFAULT_BUNDLENAME); - 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); + int32_t errCode = 0; + bool result = BundleActiveClient::GetInstance().IsBundleIdle(DEFAULT_BUNDLENAME, errCode, DEFAULT_USERID); + EXPECT_EQ(result, false); + EXPECT_EQ(errCode, 0); } /* @@ -177,6 +173,102 @@ HWTEST_F(DeviceUsageStatisticsTest, DeviceUsageStatisticsTest_QueryFormStatistic EXPECT_EQ(errCode, 0); EXPECT_EQ(results.size(), 0); } + +/* + * @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().QueryPackageGroup(DEFAULT_BUNDLENAME, COMMON_USERID); + DEFAULT_GROUP = (result == DEFAULT_GROUP) ? (result + 10) : DEFAULT_GROUP; + result = BundleActiveClient::GetInstance().SetBundleGroup(DEFAULT_BUNDLENAME, DEFAULT_GROUP, + DEFAULT_ERRCODE, COMMON_USERID); + EXPECT_EQ(result, DEFAULT_ERRCODE); +} + +/* + * @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) +{ + BundleActiveClient::GetInstance().SetBundleGroup(DEFAULT_BUNDLENAME, DEFAULT_GROUP, + DEFAULT_ERRCODE, COMMON_USERID); + 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_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