diff --git a/bundle.json b/bundle.json index 79a289f3bfe746c2c4ceaee8740e52f423a0889e..b6b27df762351ba4d143410b1c86b47c4b280d8d 100644 --- a/bundle.json +++ b/bundle.json @@ -24,6 +24,7 @@ "deps": { "components": [ "relational_store", + "runtime_core", "safwk", "config_policy", "os_account", @@ -51,7 +52,8 @@ "group_type" : { "base_group": [], "fwk_group": [ - "//foundation/resourceschedule/device_usage_statistics:bfwk_group_all" + "//foundation/resourceschedule/device_usage_statistics:bfwk_group_all", + "//foundation/resourceschedule/device_usage_statistics/interfaces/kits/bundlestats/taihe/usage_statistics:usageStatistics_taihe" ], "service_group": [ "//foundation/resourceschedule/device_usage_statistics:service_group_all" @@ -73,6 +75,9 @@ ] }, "name": "//foundation/resourceschedule/device_usage_statistics:usagestatsinner" + }, + { + "name": "//foundation/resourceschedule/device_usage_statistics/interfaces/kits/bundlestats/taihe/usage_statistics:usageStatistics_taihe" } ], "test": [ diff --git a/interfaces/innerkits/include/bundle_active_client.h b/interfaces/innerkits/include/bundle_active_client.h index bcce2170298302eccd4e78fa08e9a2cb2fe44ab0..87205d004a36aa49ce04dbab390e22e589cc37e0 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -133,7 +133,7 @@ public: * @param userId default userId is -1 for JS API, if other SAs call this API, they should explicit define userId. * @return errCode. */ - ErrCode QueryAppGroup(int32_t& appGroup, std::string& bundleName, const int32_t userId = -1); + ErrCode QueryAppGroup(int32_t& appGroup, const std::string& bundleName, const int32_t userId = -1); /** * @brief QueryModuleUsageRecords, query all from usage statistics in specific time span for calling user. diff --git a/interfaces/innerkits/src/bundle_active_client.cpp b/interfaces/innerkits/src/bundle_active_client.cpp index ac873cbcd3f4e115b6d28dd591bfd4ad41cd22a6..475402b2fe732cce736799bf3222303e84fa299f 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -173,7 +173,7 @@ ErrCode BundleActiveClient::QueryCurrentBundleEvents(std::vectorQueryCurrentBundleEvents(bundleActiveEvents, beginTime, endTime); } -ErrCode BundleActiveClient::QueryAppGroup(int32_t& appGroup, std::string& bundleName, const int32_t userId) +ErrCode BundleActiveClient::QueryAppGroup(int32_t& appGroup, const std::string& bundleName, const int32_t userId) { std::lock_guard lock(mutex_); ErrCode ret = GetBundleActiveProxy(); diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/BUILD.gn b/interfaces/kits/bundlestats/taihe/usage_statistics/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..13749bc0f0b0f73f18810c54afdf8f0eee61704a --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (c) 2025 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") + +subsystem_name = "resourceschedule" +part_name = "device_usage_statistics" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_usage_statistics_taihe") { + sources = [ "idl/ohos.resourceschedule.usageStatistics.taihe" ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_usage_statistics_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.resourceschedule.usageStatistics.ani.cpp", + "$taihe_generated_file_path/src/ohos.resourceschedule.usageStatistics.abi.c", + ] +} + +taihe_shared_library("usageStatistics_taihe_native") { + taihe_generated_file_path = "$taihe_generated_file_path" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + include_dirs = [ "include" ] + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/bundle_state_idl_common.cpp", + "src/bundle_state_idl_err_code.cpp", + "src/ohos.resourceschedule.usageStatistics.impl.cpp", + ] + deps = [ + ":run_taihe", + "//foundation/resourceschedule/device_usage_statistics:usagestatsinner", + "//foundation/resourceschedule/device_usage_statistics:usagestatsutils", + ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } +} + +generate_static_abc("usage_statistics_abc") { + base_url = "$taihe_generated_file_path" + files = [ + "$taihe_generated_file_path/@ohos.resourceschedule.usageStatistics.ets", + ] + is_boot_abc = "True" + device_dst_file = "system/framework/usage_statistics_abc.abc" + dependencies = [":run_taihe"] +} + +ohos_prebuilt_etc("usageStatistics_etc") { + source = "$target_out_dir/usage_statistics_abc.abc" + module_install_dir = "framework" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [":usage_statistics_abc"] +} + +group("usageStatistics_taihe") { + deps = [ + ":usageStatistics_etc", + ":usageStatistics_taihe_native", + ] +} \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/idl/ohos.resourceschedule.usageStatistics.taihe b/interfaces/kits/bundlestats/taihe/usage_statistics/idl/ohos.resourceschedule.usageStatistics.taihe new file mode 100644 index 0000000000000000000000000000000000000000..43f8e697e6d9aadd759b5c05f975c53c83b79870 --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/idl/ohos.resourceschedule.usageStatistics.taihe @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025 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. + */ +@!sts_inject(""" + loadLibrary("usageStatistics_taihe_native.z"); +""") +@!namespace("@ohos.resourceschedule.usageStatistics", "usageStatistics") +enum IntervalType: i32 {BY_OPTIMIZED = 0, BY_DAILY = 1, BY_WEEKLY = 2, BY_MONTHLY = 3, BY_ANNUALLY = 4} +enum GroupType: i32 {ALIVE_GROUP = 10, DAILY_GROUP = 20, FIXED_GROUP = 30, RARE_GROUP = 40, LIMITED_GROUP = 50, NEVER_GROUP = 60} + +struct BundleStatsInfo { + id: f64; + abilityInFgTotalTime: Optional; + abilityPrevAccessTime: Optional; + abilityPrevSeenTime: Optional; + abilitySeenTotalTime: Optional; + bundleName: Optional; + fgAbilityAccessTotalTime: Optional; + fgAbilityPrevAccessTime: Optional; + infosBeginTime: Optional; + infosEndTime: Optional; + appIndex: Optional; +} +struct HapFormInfo { + formName: String; + formDimension: f64; + formId: f64; + formLastUsedTime: f64; + count: f64; +} + +struct HapModuleInfo { + deviceId: Optional; + bundleName: String; + moduleName: String; + abilityName: Optional; + appLabelId: Optional; + labelId: Optional; + descriptionId: Optional; + abilityLableId: Optional; + abilityDescriptionId: Optional; + abilityIconId: Optional; + launchedCount: f64; + lastModuleUsedTime: f64; + formRecords: Array; +} + +struct DeviceEventStats { + name: String; + eventId: f64; + count: f64; +} + +struct BundleEvents { + appGroup: Optional; + bundleName: Optional; + indexOfLink: Optional; + nameOfClass: Optional; + eventOccurredTime: Optional; + eventId: Optional; +} + +struct AppGroupCallbackInfo { + appOldGroup: f64; + appNewGroup: f64; + userId: f64; + changeReason: f64; + bundleName: String; +} + + +@gen_async("isIdleState") +@gen_promise("isIdleState") +function IsIdleStateSync(bundleName: String): bool; + +@gen_async("queryAppGroup") +@gen_promise("queryAppGroup") +@overload("queryAppGroupSync") +function QueryAppGroupSync(): f64; + +@gen_async("queryAppGroup") +@gen_promise("queryAppGroup") +@overload("queryAppGroupSync") +function QueryAppGroupSyncByBundleName(bundleName: String): f64; + +@gen_async("setAppGroup") +@gen_promise("setAppGroup") +function SetAppGroupSync(bundleName: String, newGroup: GroupType): void; + +@gen_async("queryBundleStatsInfos") +@gen_promise("queryBundleStatsInfos") +function QueryBundleStatsInfosAsync(beginTime: f64, endTime: f64): @record Map; + +@gen_async("queryAppStatsInfos") +@gen_promise("queryAppStatsInfos") +function QueryAppStatsInfosAsync(beginTime: f64, endTime: f64): @record Map>; + +@gen_async("queryLastUseTime") +@gen_promise("queryLastUseTime") +function QueryLastUseTimeAsync(appInfos: @record Map>): @record Map>; + +@gen_async("queryBundleStatsInfoByInterval") +@gen_promise("queryBundleStatsInfoByInterval") +function QueryBundleStatsInfoByIntervalAsync(byInterval: IntervalType, beginTime: f64, endTime: f64): Array; + +@gen_async("queryBundleEvents") +@gen_promise("queryBundleEvents") +function QueryBundleEventsAsync(beginTime: f64, endTime: f64): Array; + +@gen_async("queryCurrentBundleEvents") +@gen_promise("queryCurrentBundleEvents") +function QueryCurrentBundleEventsAsync(beginTime: f64, endTime: f64): Array; + +@gen_async("queryDeviceEventStats") +@gen_promise("queryDeviceEventStats") +function QueryDeviceEventStatsAsync(beginTime: f64, endTime: f64): Array; + +@gen_async("queryNotificationEventStats") +@gen_promise("queryNotificationEventStats") +function QueryNotificationEventStatsAsync(beginTime: f64, endTime: f64): Array; + +@gen_async("queryModuleUsageRecords") +@gen_promise("queryModuleUsageRecords") +@overload("queryModuleUsageRecordsAsync") +function QueryModuleUsageRecordsAsync(): Array; + +@gen_async("queryModuleUsageRecords") +@gen_promise("queryModuleUsageRecords") +@overload("queryModuleUsageRecordsAsync") +function QueryModuleUsageRecordsAsyncByMaxNum(maxNum: f64): Array; + +@gen_async("registerAppGroupCallBack") +@gen_promise("registerAppGroupCallBack") +function RegisterAppGroupCallBackAsync(registerCallback: (groupCallback: AppGroupCallbackInfo) => void): void; + +@gen_async("unregisterAppGroupCallBack") +@gen_promise("unregisterAppGroupCallBack") +function UnregisterAppGroupCallBackAsync(): void; + diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_common.h b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1e746cc002863896c9f861cc89057f692bf6ecd2 --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_common.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 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_STATE_IDL_COMMON_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_COMMON_H + +#include "ohos.resourceschedule.usageStatistics.proj.hpp" +#include "ohos.resourceschedule.usageStatistics.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include "bundle_active_client.h" +#include +namespace OHOS { +namespace DeviceUsageStats { +class BundleStateIDLCommon { +public: + static std::shared_ptr> QueryBundleStatsInfos( + int64_t& beginTime, int64_t& endTime, int32_t& errCode); + static void ParseBundleStatsInfo(const BundleActivePackageStats& bundleActivePackageStats, + ::ohos::resourceschedule::usageStatistics::BundleStatsInfo& bundleStatsInfo); + static void ParseBundleEvents(const BundleActiveEvent& bundleActiveEvent, + ::ohos::resourceschedule::usageStatistics::BundleEvents& bundleEvent); + static void MergePackageStats(BundleActivePackageStats& left, const BundleActivePackageStats& right); + static void ParseQueryInfosMap(const taihe::map>& appInfos, + std::map>& queryInfos); + static taihe::array<::ohos::resourceschedule::usageStatistics::HapFormInfo> ParseformRecords( + const std::vector& formRecords); + static std::shared_ptr>> QueryAppStatsInfos( + int64_t& beginTime, int64_t& endTime, int32_t& errCode); + static std::shared_ptr>> QueryLastUseTime( + const std::map>& queryInfos, int32_t& errCode); + static void MergeAppStatsInfos(const std::vector& packageStats, + std::shared_ptr>>& mergedPackageStats); +}; + +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_COMMON_H + + \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_condition.h b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_condition.h new file mode 100644 index 0000000000000000000000000000000000000000..b89c795800ffed11dc167a3e5f4b692bca2f0147 --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_condition.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 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_STATE_IDL_CONDITION_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_CONDITION_H + +namespace OHOS { +namespace DeviceUsageStats { + +enum IntervalType { + BY_OPTIMIZED = 0, + BY_DAILY, + BY_WEEKLY, + BY_MONTHLY, + BY_ANNUALLY, +}; +enum GroupType { + ALIVE_GROUP = 10, + DAILY_GROUP = 20, + FIXED_GROUP = 30, + RARE_GROUP = 40, + LIMITED_GROUP = 50, + NEVER_GROUP = 60, +}; + +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_CONDITION_H + diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_err_code.h b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_err_code.h new file mode 100644 index 0000000000000000000000000000000000000000..9291bdc0bf3deddfe826c725f9c05886229dfefc --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/include/bundle_state_idl_err_code.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 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_STATE_IDL_ERR_CODE_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_ERR_CODE_H + +#include "string_ex.h" +#include + +namespace OHOS { +namespace DeviceUsageStats { +class BundleStateIDLErrCode { +public: + static std::string GetSaErrCodeMsg(int32_t errCode, int32_t reflectCode); + static int32_t GetReflectErrCode(int32_t errCode); + static std::string GetErrorCode(int32_t errCode); + static std::string HandleParamErr(int32_t errCode, const std::string& operation); +}; + +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_IDL_ERR_CODE_H + + \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/src/ani_constructor.cpp b/interfaces/kits/bundlestats/taihe/usage_statistics/src/ani_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8180adef2bf6afbcd733e0519601ae7ac04b0c60 --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/src/ani_constructor.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 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 "taihe/runtime.hpp" +#include "ohos.resourceschedule.usageStatistics.ani.hpp" +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::resourceschedule::usageStatistics::ANIRegister(env)) { + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_common.cpp b/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba675edb2f3a0616e47672f07e71e08b837eed0a --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_common.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2025 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_client.h" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include "bundle_state_idl_common.h" +#include "bundle_state_idl_condition.h" +using namespace ohos::resourceschedule::usageStatistics; +using namespace taihe; +namespace OHOS { +namespace DeviceUsageStats { +const int32_t INTERVAL_TYPE_DEFAULT = 0; +const int64_t INTERVAL_TYPE_YEAR = 4; +const int64_t MAX_TIME = 20000000000000; +const int64_t INTERVAL_TIME = (30 * 24 * 60 * 60 * 1000LL); // 30天 + +std::shared_ptr> BundleStateIDLCommon::QueryBundleStatsInfos( + int64_t& beginTime, int64_t& endTime, int32_t& errCode) +{ + std::vector packageStats; + errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(packageStats, INTERVAL_TYPE_DEFAULT, + beginTime, endTime); + std::shared_ptr> mergedPackageStats = + std::make_shared>(); + if (packageStats.empty()) { + return nullptr; + } + for (auto packageStat : packageStats) { + std::map::iterator iter = + mergedPackageStats->find(packageStat.bundleName_); + if (iter != mergedPackageStats->end()) { + MergePackageStats(iter->second, packageStat); + } else { + mergedPackageStats-> + insert(std::pair(packageStat.bundleName_, packageStat)); + } + } + return mergedPackageStats; +} + +void BundleStateIDLCommon::ParseBundleStatsInfo(const BundleActivePackageStats& bundleActivePackageStats, + BundleStatsInfo& bundleStatsInfo) +{ + bundleStatsInfo.bundleName = + taihe::optional(std::in_place, taihe::string(bundleActivePackageStats.bundleName_)); + bundleStatsInfo.abilityPrevAccessTime = + taihe::optional(std::in_place, bundleActivePackageStats.lastTimeUsed_); + bundleStatsInfo.abilityInFgTotalTime = + taihe::optional(std::in_place, bundleActivePackageStats.totalInFrontTime_); + bundleStatsInfo.appIndex = + taihe::optional(std::in_place, bundleActivePackageStats.appIndex_); +} + +void BundleStateIDLCommon::ParseBundleEvents(const BundleActiveEvent& bundleActiveEvent, + BundleEvents& bundleEvent) +{ + bundleEvent.bundleName = + taihe::optional(std::in_place, taihe::string(bundleActiveEvent.bundleName_)); + bundleEvent.eventId = + taihe::optional(std::in_place, bundleActiveEvent.eventId_); + bundleEvent.eventOccurredTime = + taihe::optional(std::in_place, bundleActiveEvent.timeStamp_); +} + +void BundleStateIDLCommon::MergePackageStats(BundleActivePackageStats& left, const BundleActivePackageStats& right) +{ + if (left.bundleName_ != right.bundleName_) { + BUNDLE_ACTIVE_LOGE("Merge package stats failed, existing packageName : %{public}s," + " new packageName : %{public}s,", left.bundleName_.c_str(), right.bundleName_.c_str()); + return; + } + left.lastTimeUsed_ = std::max(left.lastTimeUsed_, right.lastTimeUsed_); + left.lastContiniousTaskUsed_ = std::max(left.lastContiniousTaskUsed_, right.lastContiniousTaskUsed_); + left.totalInFrontTime_ += right.totalInFrontTime_; + left.totalContiniousTaskUsedTime_ += right.totalContiniousTaskUsedTime_; + left.bundleStartedCount_ += right.bundleStartedCount_; +} + +void BundleStateIDLCommon::ParseQueryInfosMap(const taihe::map>& appInfos, + std::map>& queryInfos) +{ + for (const auto& iter : appInfos) { + std::vector appIndexVector; + for (double appIndex : iter.second) { + appIndexVector.push_back(static_cast(appIndex)); + } + queryInfos.emplace(std::string(iter.first.c_str()), appIndexVector); + } +} + +array BundleStateIDLCommon::ParseformRecords(const std::vector& formRecords) +{ + std::vector HapFormInfoVector; + for (auto& formRecord : formRecords) { + HapFormInfo HapFormInfo { + .formName = formRecord.formName_, + .formDimension = static_cast(formRecord.formDimension_), + .formId = static_cast(formRecord.formId_), + .formLastUsedTime = static_cast(formRecord.formLastUsedTime_), + .count = static_cast(formRecord.count_), + }; + HapFormInfoVector.push_back(HapFormInfo); + } + return array(HapFormInfoVector); +} + +std::shared_ptr>> BundleStateIDLCommon::QueryAppStatsInfos( + int64_t& beginTime, int64_t& endTime, int32_t& errCode) +{ + std::vector packageStats; + if (endTime - beginTime <= INTERVAL_TIME) { + errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(packageStats, + DeviceUsageStats::IntervalType::BY_DAILY, beginTime, endTime); + } else { + errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(packageStats, + DeviceUsageStats::IntervalType::BY_OPTIMIZED, beginTime, endTime); + } + std::shared_ptr>> mergedPackageStats = + std::make_shared>>(); + if (packageStats.empty()) { + return nullptr; + } + MergeAppStatsInfos(packageStats, mergedPackageStats); + return mergedPackageStats; +} + +std::shared_ptr>> BundleStateIDLCommon::QueryLastUseTime( + const std::map>& queryInfos, int32_t& errCode) +{ + std::vector packageStats; + errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(packageStats, + INTERVAL_TYPE_YEAR, 0, MAX_TIME); + std::shared_ptr>> mergedPackageStats = + std::make_shared>>(); + if (packageStats.empty()) { + return nullptr; + } + + std::vector tempQueryInfos; + for (auto queryInfo : queryInfos) { + for (std::vector::iterator queryInfoIter = queryInfo.second.begin(); + queryInfoIter != queryInfo.second.end(); queryInfoIter++) { + std::string tempQueryInfo = queryInfo.first + std::to_string(*queryInfoIter); + tempQueryInfos.push_back(tempQueryInfo); + } + } + std::vector tempPackageStats; + for (auto tempQueryInfoIter : tempQueryInfos) { + for (auto packageStat : packageStats) { + if (tempQueryInfoIter == packageStat.bundleName_ + std::to_string(packageStat.appIndex_)) { + tempPackageStats.push_back(packageStat); + } + } + } + MergeAppStatsInfos(tempPackageStats, mergedPackageStats); + return mergedPackageStats; +} + +void BundleStateIDLCommon::MergeAppStatsInfos(const std::vector& packageStats, + std::shared_ptr>>& mergedPackageStats) +{ + for (auto packageStat : packageStats) { + std::map>::iterator iter = + mergedPackageStats->find(packageStat.bundleName_); + if (iter == mergedPackageStats->end()) { + std::vector temp; + temp.push_back(packageStat); + mergedPackageStats->insert(std::pair>( + packageStat.bundleName_, temp)); + continue; + } + bool sign = false; + for (auto& packageMerge : iter->second) { + if (packageMerge.appIndex_ == packageStat.appIndex_) { + MergePackageStats(packageMerge, packageStat); + sign = true; + } + } + if (sign == false) { + iter->second.push_back(packageStat); + } + } +} +} +} \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_err_code.cpp b/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_err_code.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aafe73cfacea8aae185b0d3fa0396547f0520936 --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/src/bundle_state_idl_err_code.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 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_state_idl_err_code.h" +#include "bundle_state_inner_errors.h" + +namespace OHOS { +namespace DeviceUsageStats { +const int32_t ERR_MULTIPLE = 100; +std::string BundleStateIDLErrCode::GetSaErrCodeMsg(int32_t errCode, int32_t reflectCode) +{ + BUNDLE_ACTIVE_LOGE("GetSaErrCodeMsg %{public}d", errCode); + auto iter = saErrCodeMsgMap.find(errCode); + std::string errMessage; + if (iter != saErrCodeMsgMap.end()) { + errMessage.append("BussinessError "); + errMessage.append(std::to_string(reflectCode)).append(":").append(iter->second); + } + return errMessage; +} + +int32_t BundleStateIDLErrCode::GetReflectErrCode(int32_t errCode) +{ + if (errCode < ERR_GET_SYSTEM_ABILITY_MANAGER_FAILED) { + return errCode; + } + return errCode / ERR_MULTIPLE; +} + +std::string BundleStateIDLErrCode::GetErrorCode(int32_t errCode) +{ + if (errCode == ERR_OK) { + return ""; + } + int32_t reflectCode = GetReflectErrCode(errCode); + return GetSaErrCodeMsg(errCode, reflectCode); +} + +std::string BundleStateIDLErrCode::HandleParamErr(int32_t errCode, const std::string& operation) +{ + if (errCode == ERR_OK) { + return ""; + } + BUNDLE_ACTIVE_LOGE("HandleParamErr %{public}d", errCode); + std::string errMessage = "BussinessError 401: Parameter error. "; + auto iter = paramErrCodeMsgMap.find(errCode); + if (iter != paramErrCodeMsgMap.end()) { + errMessage.append(operation); + errMessage.append(iter->second); + } + return errMessage; +} + +} // namespace DeviceUsageStats +} // namespace OHOS + + \ No newline at end of file diff --git a/interfaces/kits/bundlestats/taihe/usage_statistics/src/ohos.resourceschedule.usageStatistics.impl.cpp b/interfaces/kits/bundlestats/taihe/usage_statistics/src/ohos.resourceschedule.usageStatistics.impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d15276c0c91776697b6ea2663a07e4fa46ef53cb --- /dev/null +++ b/interfaces/kits/bundlestats/taihe/usage_statistics/src/ohos.resourceschedule.usageStatistics.impl.cpp @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2025 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 "ohos.resourceschedule.usageStatistics.proj.hpp" +#include "ohos.resourceschedule.usageStatistics.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include + +#include "bundle_active_client.h" +#include "bundle_active_log.h" +#include "bundle_state_idl_condition.h" +#include "bundle_state_idl_err_code.h" +#include "bundle_state_idl_common.h" +#include "app_group_callback_stub.h" + +using namespace taihe; +using namespace OHOS::DeviceUsageStats; +using namespace ohos::resourceschedule::usageStatistics; +using namespace OHOS; +const int32_t MAXNUM_UP_LIMIT = 1000; +const int64_t TIME_NUMBER_MIN = 0; +const int32_t INTERVAL_NUMBER_MIN = 0; +const int32_t INTERVAL_NUMBER_MAX = 4; +const std::vector GROUP_TYPE_VALUE {10, 20, 30, 40, 50, 60}; +namespace { +class GroupChangeObserver : public DeviceUsageStats::AppGroupCallbackStub { +public: + ErrCode OnAppGroupChanged(const DeviceUsageStats::AppGroupCallbackInfo& appGroupCallbackInfo); + explicit GroupChangeObserver(std::shared_ptr> callback) + : innerCallback_(callback) {} + virtual ~GroupChangeObserver() = default; + static std::mutex callbackMutex_; +private: + std::shared_ptr> innerCallback_ = nullptr; +}; + +sptr groupChangeObserver_; +std::mutex GroupChangeObserver::callbackMutex_; + +bool CheckBeginTimeAndEndTime(int64_t beginTime, int64_t endTime) +{ + int32_t errCode = 0; + if (beginTime < TIME_NUMBER_MIN) { + BUNDLE_ACTIVE_LOGE("CheckBeginTimeAndEndTime failed, beginTime value is invalid."); + errCode = ParamError::ERR_BEGIN_TIME_LESS_THEN_ZERO; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return false; + } + if (endTime <= beginTime) { + BUNDLE_ACTIVE_LOGE("CheckBeginTimeAndEndTime endTime(%{public}lld) <= beginTime(%{public}lld)", + static_cast(endTime), static_cast(beginTime)); + errCode = ParamError::ERR_END_TIME_LESS_THEN_BEGIN_TIME; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return false; + } + return true; +} + +bool CheckInterval(int32_t interval) +{ + if (((interval < INTERVAL_NUMBER_MIN) || (interval > INTERVAL_NUMBER_MAX))) { + BUNDLE_ACTIVE_LOGE("CheckInterval failed, intervalType number is invalid."); + int32_t errCode = ParamError::ERR_INTERVAL_OUT_OF_RANGE; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return false; + } + return true; +} + +bool CheckMaxNum(int32_t maxNum) +{ + if (maxNum > MAXNUM_UP_LIMIT || maxNum <= 0) { + BUNDLE_ACTIVE_LOGE("CheckMaxNum failed, maxNum is larger than 1000 or less/equal than 0"); + int32_t errCode = ParamError::ERR_MAX_RECORDS_NUM_BIGER_THEN_ONE_THOUSAND; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return false; + } + return true; +} + +bool CheckNewGroupType(int32_t newGroupType) +{ + for (const auto& item : GROUP_TYPE_VALUE) { + if (item == newGroupType) { + return true; + } + } + int32_t errCode = ParamError::ERR_NEW_GROUP_OUT_OF_RANGE; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return false; +} + +bool IsIdleStateSync(string bundleName) +{ + int32_t appGroup = 0; + bool isBundleIdle = false; + int32_t errCode = BundleActiveClient::GetInstance().IsBundleIdle(isBundleIdle, + std::string(bundleName.c_str())); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return false; + } + return isBundleIdle; +} + +double QueryAppGroupSync() +{ + int32_t appGroup = 0; + std::string bundleName = ""; + int32_t errCode = BundleActiveClient::GetInstance().QueryAppGroup(appGroup, bundleName); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return static_cast(DeviceUsageStats::GroupType::NEVER_GROUP); + } + return static_cast(appGroup); +} + +int32_t QueryAppGroupSyncByBundleName(string bundleName) +{ + int32_t appGroup = 0; + int32_t errCode = BundleActiveClient::GetInstance().QueryAppGroup(appGroup, std::string(bundleName.c_str())); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return static_cast(DeviceUsageStats::GroupType::NEVER_GROUP); + } + return static_cast(appGroup); +} + +void SetAppGroupSync(string bundleName, double newGroup) +{ + int32_t intNewGroup = static_cast(newGroup); + if (!CheckNewGroupType(intNewGroup)) { + return; + } + int32_t appGroup = 0; + int32_t errCode = BundleActiveClient::GetInstance().SetAppGroup(std::string(bundleName.c_str()), intNewGroup); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return; + } +} + +map QueryBundleStatsInfosAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + map bundleStatsInfoMap; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return bundleStatsInfoMap; + } + int32_t errCode = 0; + auto packageStatsMap = BundleStateIDLCommon::QueryBundleStatsInfos(intBeginTime, intEndTime, errCode); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return bundleStatsInfoMap; + } + if (packageStatsMap == nullptr) { + errCode = ServiceError::ERR_SYSTEM_ABILITY_SUPPORT_FAILED; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return bundleStatsInfoMap; + } + for (auto& iter : *packageStatsMap) { + auto packageStats = iter.second; + BundleStatsInfo bundleStatsInfo { + .id = packageStats.userId_, + }; + BundleStateIDLCommon::ParseBundleStatsInfo(packageStats, bundleStatsInfo); + bundleStatsInfoMap.emplace(iter.first, bundleStatsInfo); + } + return bundleStatsInfoMap; +} + +map> QueryAppStatsInfosAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + map> appStatsInfosMap; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return appStatsInfosMap; + } + int32_t errCode = 0; + std::shared_ptr>> appStatsMap = nullptr; + appStatsMap = BundleStateIDLCommon::QueryAppStatsInfos(intBeginTime, intEndTime, errCode); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return appStatsInfosMap; + } + if (appStatsMap == nullptr) { + errCode = ServiceError::ERR_SYSTEM_ABILITY_SUPPORT_FAILED; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return appStatsInfosMap; + } + for (auto& iter : *appStatsMap) { + std::vector packageStatsVector; + for (auto packageStats: iter.second) { + BundleStatsInfo bundleStatsInfo { + .id = static_cast(packageStats.userId_), + }; + BundleStateIDLCommon::ParseBundleStatsInfo(packageStats, bundleStatsInfo); + packageStatsVector.push_back(bundleStatsInfo); + } + array bundleStatsInfoArray(packageStatsVector); + appStatsInfosMap.emplace(iter.first, bundleStatsInfoArray); + } + return appStatsInfosMap; +} + +map> QueryLastUseTimeAsync(map> appInfos) +{ + map> appStatsInfosMap; + std::map> queryInfos; + BundleStateIDLCommon::ParseQueryInfosMap(appInfos, queryInfos); + int32_t errCode = 0; + std::shared_ptr>> appStatsMap = nullptr; + appStatsMap = BundleStateIDLCommon::QueryLastUseTime(queryInfos, errCode); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return appStatsInfosMap; + } + if (appStatsMap == nullptr) { + errCode = ServiceError::ERR_SYSTEM_ABILITY_SUPPORT_FAILED; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return appStatsInfosMap; + } + for (auto& iter : *appStatsMap) { + std::vector packageStatsVector; + for (auto packageStats: iter.second) { + BundleStatsInfo bundleStatsInfo { + .id = static_cast(packageStats.userId_), + }; + BundleStateIDLCommon::ParseBundleStatsInfo(packageStats, bundleStatsInfo); + packageStatsVector.push_back(bundleStatsInfo); + } + array bundleStatsInfoArray(packageStatsVector); + appStatsInfosMap.emplace(iter.first, bundleStatsInfoArray); + } + return appStatsInfosMap; +} + +array QueryBundleStatsInfoByIntervalAsync( + ::ohos::resourceschedule::usageStatistics::IntervalType byInterval, double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + std::vector bundleStatsInfoVector; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return array(bundleStatsInfoVector); + } + int32_t interval = static_cast(byInterval); + if (!CheckInterval(interval)) { + return array(bundleStatsInfoVector); + } + std::vector bundleActivePackageStats; + int32_t errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(bundleActivePackageStats, + interval, intBeginTime, intEndTime); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(bundleStatsInfoVector); + } + for (auto &packageStats: bundleActivePackageStats) { + BundleStatsInfo bundleStatsInfo { + .id = packageStats.userId_, + }; + BundleStateIDLCommon::ParseBundleStatsInfo(packageStats, bundleStatsInfo); + bundleStatsInfoVector.push_back(bundleStatsInfo); + } + return array(bundleStatsInfoVector); +} + +array QueryBundleEventsAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + std::vector bundleEventVector; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return array(bundleEventVector); + } + std::vector bundleActiveEvents; + int32_t errCode = BundleActiveClient::GetInstance().QueryBundleEvents(bundleActiveEvents, + intBeginTime, intEndTime); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(bundleEventVector); + } + for (auto &bundleActiveEvent: bundleActiveEvents) { + BundleEvents bundleEvent; + BundleStateIDLCommon::ParseBundleEvents(bundleActiveEvent, bundleEvent); + bundleEventVector.push_back(bundleEvent); + } + return array(bundleEventVector); +} + +array QueryCurrentBundleEventsAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + std::vector bundleEventVector; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return array(bundleEventVector); + } + std::vector bundleActiveEvents; + int32_t errCode = BundleActiveClient::GetInstance().QueryCurrentBundleEvents(bundleActiveEvents, + intBeginTime, intEndTime); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(bundleEventVector); + } + for (auto &bundleActiveEvent: bundleActiveEvents) { + BundleEvents bundleEvent; + BundleStateIDLCommon::ParseBundleEvents(bundleActiveEvent, bundleEvent); + bundleEventVector.push_back(bundleEvent); + } + return array(bundleEventVector); +} + +array QueryDeviceEventStatsAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + std::vector deviceEventStatsVector; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return array(deviceEventStatsVector); + } + std::vector bundleActiveEventStatsVector; + int32_t errCode = BundleActiveClient::GetInstance().QueryDeviceEventStats(intBeginTime, intEndTime, + bundleActiveEventStatsVector); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(deviceEventStatsVector); + } + for (auto &bundleActiveEventStats: bundleActiveEventStatsVector) { + DeviceEventStats deviceEventStats { + .name = bundleActiveEventStats.name_, + .eventId = static_cast(bundleActiveEventStats.eventId_), + .count = static_cast(bundleActiveEventStats.count_), + }; + deviceEventStatsVector.push_back(deviceEventStats); + } + return array(deviceEventStatsVector); +} + +array QueryNotificationEventStatsAsync(double beginTime, double endTime) +{ + int64_t intBeginTime = static_cast(beginTime); + int64_t intEndTime = static_cast(endTime); + std::vector deviceEventStatsVector; + if (!CheckBeginTimeAndEndTime(intBeginTime, intEndTime)) { + return array(deviceEventStatsVector); + } + std::vector bundleActiveEventStatsVector; + + int32_t errCode = BundleActiveClient::GetInstance().QueryNotificationEventStats(intBeginTime, intEndTime, + bundleActiveEventStatsVector); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(deviceEventStatsVector); + } + for (auto &bundleActiveEventStats: bundleActiveEventStatsVector) { + DeviceEventStats deviceEventStats { + .name = bundleActiveEventStats.name_, + .eventId = static_cast(bundleActiveEventStats.eventId_), + .count = static_cast(bundleActiveEventStats.count_), + }; + deviceEventStatsVector.push_back(deviceEventStats); + } + return array(deviceEventStatsVector); +} + +array QueryModuleUsageRecordsAsync() +{ + std::vector moduleRecords; + std::vector hapModuleInfos; + int32_t errCode = BundleActiveClient::GetInstance().QueryModuleUsageRecords(MAXNUM_UP_LIMIT, moduleRecords); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(hapModuleInfos); + } + for (auto& moduleRecord: moduleRecords) { + array hapFromInfos = BundleStateIDLCommon::ParseformRecords(moduleRecord.formRecords_); + HapModuleInfo hapModuleInfo { + .bundleName = moduleRecord.bundleName_, + .moduleName = moduleRecord.moduleName_, + .launchedCount = static_cast(moduleRecord.launchedCount_), + .lastModuleUsedTime = static_cast(moduleRecord.lastModuleUsedTime_), + .formRecords = hapFromInfos, + }; + hapModuleInfos.emplace_back(hapModuleInfo); + } + return array(hapModuleInfos); +} + +array QueryModuleUsageRecordsAsyncByMaxNum(double maxNum) +{ + int32_t intMaxNum = static_cast(maxNum); + std::vector hapModuleInfos; + if (!CheckMaxNum(intMaxNum)) { + return array(hapModuleInfos); + } + std::vector moduleRecords; + int32_t errCode = BundleActiveClient::GetInstance().QueryModuleUsageRecords(intMaxNum, moduleRecords); + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return array(hapModuleInfos); + } + for (auto& moduleRecord: moduleRecords) { + array hapFromInfos = BundleStateIDLCommon::ParseformRecords(moduleRecord.formRecords_); + HapModuleInfo hapModuleInfo { + .bundleName = moduleRecord.bundleName_, + .moduleName = moduleRecord.moduleName_, + .launchedCount = static_cast(moduleRecord.launchedCount_), + .lastModuleUsedTime = static_cast(moduleRecord.lastModuleUsedTime_), + .formRecords = hapFromInfos, + }; + hapModuleInfos.emplace_back(hapModuleInfo); + } + return array(hapModuleInfos); +} + +ErrCode GroupChangeObserver::OnAppGroupChanged(const DeviceUsageStats::AppGroupCallbackInfo& appGroupCallbackInfo) +{ + std::lock_guard autoLock(GroupChangeObserver::callbackMutex_); + ohos::resourceschedule::usageStatistics::AppGroupCallbackInfo innerGroupInfo { + .appOldGroup = static_cast(appGroupCallbackInfo.GetOldGroup()), + .appNewGroup = static_cast(appGroupCallbackInfo.GetNewGroup()), + .userId = static_cast(appGroupCallbackInfo.GetUserId()), + .changeReason = static_cast(appGroupCallbackInfo.GetChangeReason()), + .bundleName = appGroupCallbackInfo.GetBundleName(), + }; + if (innerCallback_ != nullptr) { + (*innerCallback_)(innerGroupInfo); + } + return ERR_OK; +} + +void RegisterAppGroupCallBackAsync( + callback_view callback) +{ + std::lock_guard autoLock(GroupChangeObserver::callbackMutex_); + if (groupChangeObserver_ != nullptr) { + BUNDLE_ACTIVE_LOGI("registerAppGroupCallBack repeat!"); + int32_t errCode = ParamError::ERR_REPEAT_REGISTER_APP_GROUP_OBSERVER; + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return; + } + std::shared_ptr> taiheCallback = + std::make_shared>(callback); + if (taiheCallback == nullptr) { + int32_t errCode = ParamError::ERR_ASYNC_CALLBACK_NULLPTR; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return; + } + groupChangeObserver_ = new(std::nothrow) GroupChangeObserver(taiheCallback); + if (groupChangeObserver_ == nullptr) { + int32_t errCode = ParamError::ERR_ASYNC_CALLBACK_NULLPTR; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return; + } + int32_t errCode = BundleActiveClient::GetInstance().RegisterAppGroupCallBack(groupChangeObserver_); + if (errCode != ERR_OK) { + BundleActiveClient::GetInstance().UnRegisterAppGroupCallBack(groupChangeObserver_); + groupChangeObserver_ = nullptr; + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return; + } + BUNDLE_ACTIVE_LOGD("registerAppGroupCallBack success!"); +} + +void UnregisterAppGroupCallBackAsync() +{ + std::lock_guard autoLock(GroupChangeObserver::callbackMutex_); + if (groupChangeObserver_ == nullptr) { + int32_t errCode = ParamError::ERR_APP_GROUP_OBSERVER_IS_NULLPTR; + BUNDLE_ACTIVE_LOGI("UnregisterAppGroupCallBackobserver is not exist!"); + set_business_error(errCode, BundleStateIDLErrCode::HandleParamErr(errCode, "")); + return; + } + int32_t errCode = BundleActiveClient::GetInstance().UnRegisterAppGroupCallBack(groupChangeObserver_); + groupChangeObserver_ = nullptr; + if (errCode != ERR_OK) { + set_business_error(errCode, BundleStateIDLErrCode::GetErrorCode(errCode)); + return; + } + BUNDLE_ACTIVE_LOGD("UnregisterAppGroupCallBack success!"); +} + +} +TH_EXPORT_CPP_API_IsIdleStateSync(IsIdleStateSync); +TH_EXPORT_CPP_API_QueryAppGroupSync(QueryAppGroupSync); +TH_EXPORT_CPP_API_QueryAppGroupSyncByBundleName(QueryAppGroupSyncByBundleName); +TH_EXPORT_CPP_API_SetAppGroupSync(SetAppGroupSync); +TH_EXPORT_CPP_API_QueryBundleStatsInfosAsync(QueryBundleStatsInfosAsync); +TH_EXPORT_CPP_API_QueryAppStatsInfosAsync(QueryAppStatsInfosAsync); +TH_EXPORT_CPP_API_QueryLastUseTimeAsync(QueryLastUseTimeAsync); +TH_EXPORT_CPP_API_QueryBundleStatsInfoByIntervalAsync(QueryBundleStatsInfoByIntervalAsync); +TH_EXPORT_CPP_API_QueryBundleEventsAsync(QueryBundleEventsAsync); +TH_EXPORT_CPP_API_QueryCurrentBundleEventsAsync(QueryCurrentBundleEventsAsync); +TH_EXPORT_CPP_API_QueryDeviceEventStatsAsync(QueryDeviceEventStatsAsync); +TH_EXPORT_CPP_API_QueryNotificationEventStatsAsync(QueryNotificationEventStatsAsync); +TH_EXPORT_CPP_API_QueryModuleUsageRecordsAsync(QueryModuleUsageRecordsAsync); +TH_EXPORT_CPP_API_QueryModuleUsageRecordsAsyncByMaxNum(QueryModuleUsageRecordsAsyncByMaxNum); +TH_EXPORT_CPP_API_RegisterAppGroupCallBackAsync(RegisterAppGroupCallBackAsync); +TH_EXPORT_CPP_API_UnregisterAppGroupCallBackAsync(UnregisterAppGroupCallBackAsync); \ No newline at end of file