diff --git a/BUILD.gn b/BUILD.gn index ff06df6b1d18ae716b80a53bfcac73b188aca0bf..5ff2f226234fea0227f28297e5beeb10373250d2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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 @@ -11,69 +11,160 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/ohos/sa_profile/sa_profile.gni") import("device_usage_statistics.gni") +import("//build/ohos/sa_profile/sa_profile.gni") -ohos_sa_profile("bundleactive_sa_profile") { - sources = [ "sa_profile/1906.xml" ] - part_name = "device_usage_statistics" +ohos_sa_profile("device_usage_statistics_sa_profile") { + sources = [ + "sa_profile/1907.xml" + ] + part_name = "${device_usage_statistics_part_name}" } -ohos_shared_library("bundleactiveinner") { +ohos_shared_library("usagestatinner") { sources = [ - "interfaces/innerkits/src/bundle_active_client.cpp", - "interfaces/innerkits/src/bundle_active_proxy.cpp", + "interfaces/innerkits/src/bundle_active_proxy.cpp", + "interfaces/innerkits/src/bundle_active_client.cpp", + "services/packageusage/src/bundle_active_package_stats.cpp", + "services/packageusage/src/bundle_active_event.cpp" ] include_dirs = [ - "services/include", - "interfaces/innerkits/include", + "services/common/include", + "services/packageusage/include", + "services/packagegroup/include", + "interfaces/innerkits/include" ] deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//utils/native/base:utils", "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", - "//utils/native/base:utils", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy" ] part_name = "${device_usage_statistics_part_name}" subsystem_name = "resourceschedule" } -ohos_prebuilt_etc("bundleactive_service_init") { - if (use_musl) { - source = "init/bundleactive_service.cfg" - } else { - source = "init/bundleactive_service.rc" - } +ohos_prebuilt_etc("device_usage_statistics_service_init") { + source = "init/device_usage_statistics_service.cfg" relative_install_dir = "init" part_name = "${device_usage_statistics_part_name}" subsystem_name = "resourceschedule" } -ohos_shared_library("bundleactiveservice") { +ohos_shared_library("usagestatskit") { + sources = [ + "frameworks/src/bundle_state_init.cpp", + "frameworks/src/bundle_state_common.cpp", + "frameworks/src/bundle_state_query.cpp" + ] + include_dirs = [ + "interfaces/kits/bundlestats/napi/include", + "services/common/include", + "interfaces/innerkits/include", + "services/packageusage/include" + ] + + deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//utils/native/base:utils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/ace/napi:ace_napi", + "//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri", + "//foundation/resourceschedule/${device_usage_statistics_part_name}:usagestatinner" + ] + relative_install_dir = "module" + part_name = "${device_usage_statistics_part_name}" + subsystem_name = "resourceschedule" +} + +ohos_shared_library("usagestatservice") { sources = [ - "services/common/src/bundle_active_event.cpp", - "services/common/src/bundle_active_event_list.cpp", - "services/common/src/bundle_active_event_stats.cpp", - "services/common/src/bundle_active_event_tracker.cpp", - "services/common/src/bundle_active_package_stats.cpp", - "services/common/src/bundle_active_period_stats.cpp", - "services/common/src/bundle_active_user_service.cpp", - "services/src/bundle_active_service.cpp", - "services/src/bundle_active_stub.cpp", + "services/common/src/bundle_active_stub.cpp", + "services/common/src/bundle_active_service.cpp", + "services/common/src/bundle_active_usage_database.cpp", + "services/common/src/bundle_active_open_callback.cpp", + "services/common/src/bundle_active_binary_search.cpp", + "services/common/src/bundle_active_core.cpp", + "services/common/src/bundle_active_refresh_database_handler.cpp", + "services/packageusage/src/bundle_active_event.cpp", + "services/packageusage/src/bundle_active_event_list.cpp", + "services/packageusage/src/bundle_active_event_stats.cpp", + "services/packageusage/src/bundle_active_event_tracker.cpp", + "services/packageusage/src/bundle_active_package_stats.cpp", + "services/packageusage/src/bundle_active_period_stats.cpp", + "services/packageusage/src/bundle_active_user_service.cpp", + "services/packageusage/src/bundle_active_calendar.cpp", + "services/packageusage/src/bundle_active_report_handler.cpp", + "services/packageusage/src/bundle_active_stats_combiner.cpp", + "services/packagegroup/src/bundle_active_group_controller.cpp", + "services/packagegroup/src/bundle_active_group_handler.cpp", + "services/packagegroup/src/bundle_active_user_history.cpp", + "services/common/src/bundle_active_shutdown_callback_proxy.cpp", + "services/common/src/bundle_active_shutdown_callback_stub.cpp", + "services/common/src/bundle_active_shutdown_callback_service.cpp", + "services/common/src/bundle_active_app_state_obsever.cpp" ] include_dirs = [ - "services/include", + ":bundle_active_config", "services/common/include", + "services/packageusage/include", + "services/packagegroup/include" ] + deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk:libpermissionsdk_standard", + "//base/powermgr/power_manager/interfaces/innerkits:powermgr_client", + "//base/notification/ces_standard/frameworks/native:cesfwk_innerkits", + "//foundation/aafwk/standard/frameworks/kits/wantagent:wantagent_innerkits", + "//foundation/aafwk/standard/interfaces/innerkits/want:want", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core", + "//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//base/miscservices/time/services:time_service", + "//utils/native/base:utils", "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr:distributedschedsvr" + ] + + external_deps = [ + "eventhandler:libeventhandler", + "native_appdatamgr:native_rdb", + "os_account_standard:os_account_innerkits", + "access_token:libaccesstoken_sdk", + "ability_runtime:app_manager", + ] + part_name = "${device_usage_statistics_part_name}" + subsystem_name = "resourceschedule" +} + +ohos_executable("usagestats_test") { + sources = [ + "test/bundle_active_test.cpp" + ] + include_dirs = [ + "interfaces/innerkits/include", + "services/common/include", + "services/packageusage/include", + "services/packagegroup/include" + ] + deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", "//utils/native/base:utils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/resourceschedule/${device_usage_statistics_part_name}:usagestatinner", + "//base/powermgr/power_manager/interfaces/innerkits:powermgr_client" ] + install_enable = true part_name = "${device_usage_statistics_part_name}" subsystem_name = "resourceschedule" } diff --git a/LICENSE b/LICENSE index 29f81d812f3e768fa89638d1f72920dbfd1413a8..66a27ec5ff940d3a9652d2948746ebac4c9d0188 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,177 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000000000000000000000000000000000000..683a3f690e942c7a40cd112787457706b8e6abf1 --- /dev/null +++ b/bundle.json @@ -0,0 +1,73 @@ +{ + "name": "@ohos/device_usage_statistics", + "description": "device usage statistics", + "version": "3.1", + "license": "Apache License 2.0", + "publishAs": "code-segment", + "segment": { + "destPath" : "foundation/resourceschedule/device_usage_statistics" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "device_usage_statistics", + "subsystem": "resourceschedule", + "syscap": [ "SystemCapability.Ressched.DeviceUsageStatistics" ], + "features": [], + "adapted_system_type": [ + "standard" + ], + "rom": "11264KB", + "ram": "10240KB", + "deps": { + "components": [ + "libhilog", + "libpermissionsdk_standard", + "powermgr_client", + "cesfwk_innerkits", + "wantagent_innerkits", + "want", + "appexecfwk_base", + "appexecfwk_core", + "zuri", + "base", + "time_service", + "utils", + "ipc_core", + "system_ability_fwk", + "samgr_proxy", + "distributedschedsvr", + "libeventhandler", + "native_rdb", + "os_account_innerkits", + "libaccesstoken_sdk" + ], + "third_party": [ "googletest" ] + }, + "build": { + "sub_component": [ + "//foundation/resourceschedule/device_usage_statistics:usagestatinner", + "//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:usagestatskit", + "//foundation/resourceschedule/device_usage_statistics:usagestats_test" + ], + "inner_kits": [ + { + "header": { + "header_base": "//foundation/resourceschedule/device_usage_statistics/interfaces/innerkits/include", + "header_files": [ + "bundle_active_proxy.h", + "bundle_active_client.h" + ] + }, + "name": "//foundation/resourceschedule/device_usage_statistics:usagestatinner" + } + ], + "test": [ + "//foundation/resourceschedule/device_usage_statistics/test/unittest:unittest" + ] + } + } +} \ No newline at end of file diff --git a/device_usage_statistics.gni b/device_usage_statistics.gni index 730cc51aadb5b241c245de5ed8458cdc440cd94f..78d4f7b4602bfb492157a7bdb23a8029bc1901b4 100644 --- a/device_usage_statistics.gni +++ b/device_usage_statistics.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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 @@ -13,4 +13,4 @@ import("//build/ohos.gni") -device_usage_statistics_part_name = "device_usage_statistics" +device_usage_statistics_part_name = "device_usage_statistics" \ No newline at end of file diff --git a/frameworks/src/bundle_state_common.cpp b/frameworks/src/bundle_state_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d42fe951b168c6f6a77c5aa3ff6e02f1d20e548e --- /dev/null +++ b/frameworks/src/bundle_state_common.cpp @@ -0,0 +1,239 @@ +/* + * 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 "securec.h" + +#include "bundle_state_common.h" +#include "bundle_active_log.h" +#include "bundle_state_data.h" + +namespace OHOS { +namespace DeviceUsageStats { +napi_value BundleStateCommon::NapiGetNull(napi_env env) +{ + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +void BundleStateCommon::GetCallbackPromiseResult(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result) +{ + if (info.isCallback) { + SetCallbackInfo(env, info.callback, info.errorCode, result); + } else { + SetPromiseInfo(env, info.deferred, result); + } +} + +void BundleStateCommon::SetCallbackInfo( + const napi_env &env, const napi_ref &callbackIn, const int &errorCode, const napi_value &result) +{ + napi_value undefined = nullptr; + napi_get_undefined(env, &undefined); + + napi_value callback = nullptr; + napi_value resultout = nullptr; + napi_get_reference_value(env, callbackIn, &callback); + napi_value results[ARGS_TWO] = {nullptr}; + results[PARAM_FIRST] = GetCallbackErrorValue(env, errorCode); + results[PARAM_SECOND] = result; + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM_FIRST], + &resultout)); +} + +void BundleStateCommon::GetBundleActiveEventForResult( + napi_env env, const std::vector &bundleActiveStates, napi_value result) +{ + int32_t index = 0; + for (const auto &item : bundleActiveStates) { + napi_value bundleActiveState = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &bundleActiveState)); + + napi_value bundleName = nullptr; + NAPI_CALL_RETURN_VOID( + env, napi_create_string_utf8(env, item.bundleName_.c_str(), NAPI_AUTO_LENGTH, &bundleName)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, bundleActiveState, "bundleName", bundleName)); + + napi_value stateType = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, item.eventId_, &stateType)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, bundleActiveState, "stateType", stateType)); + + napi_value stateOccurredTime = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, item.timeStamp_, &stateOccurredTime)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, bundleActiveState, "stateOccurredTime", + stateOccurredTime)); + + NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, bundleActiveState)); + index++; + } +} + +void BundleStateCommon::GetBundleStateInfoByIntervalForResult( + napi_env env, const std::vector &packageStats, napi_value result) +{ + int32_t index = 0; + for (const auto &item : packageStats) { + napi_value packageObject = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &packageObject)); + + napi_value bundleName = nullptr; + NAPI_CALL_RETURN_VOID( + env, napi_create_string_utf8(env, item.bundleName_.c_str(), NAPI_AUTO_LENGTH, &bundleName)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "bundleName", bundleName)); + + napi_value abilityPrevAccessTime = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, item.lastTimeUsed_, &abilityPrevAccessTime)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "abilityPrevAccessTime", + abilityPrevAccessTime)); + + napi_value abilityInFgTotalTime = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, item.totalInFrontTime_, &abilityInFgTotalTime)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "abilityInFgTotalTime", + abilityInFgTotalTime)); + + NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, packageObject)); + index++; + } +} + +void BundleStateCommon::GetBundleStateInfoForResult( + napi_env env, const std::vector &packageStats, napi_value result) +{ + for (const auto &item : packageStats) { + napi_value packageObject = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &packageObject)); + napi_value bundleName = nullptr; + NAPI_CALL_RETURN_VOID( + env, napi_create_string_utf8(env, item.bundleName_.c_str(), NAPI_AUTO_LENGTH, &bundleName)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "bundleName", bundleName)); + + napi_value abilityPrevAccessTime = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, item.lastTimeUsed_, &abilityPrevAccessTime)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "abilityPrevAccessTime", + abilityPrevAccessTime)); + + napi_value abilityInFgTotalTime = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, item.totalInFrontTime_, &abilityInFgTotalTime)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, packageObject, "abilityInFgTotalTime", + abilityInFgTotalTime)); + + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, item.bundleName_.c_str(), packageObject)); + } +} + +void BundleStateCommon::SetPromiseInfo(const napi_env &env, const napi_deferred &deferred, const napi_value &result) +{ + napi_resolve_deferred(env, deferred, result); +} + +napi_value BundleStateCommon::GetCallbackErrorValue(napi_env env, int errCode) +{ + napi_value result = nullptr; + napi_value eCode = nullptr; + NAPI_CALL(env, napi_create_int32(env, errCode, &eCode)); + NAPI_CALL(env, napi_create_object(env, &result)); + NAPI_CALL(env, napi_set_named_property(env, result, "data", eCode)); + return result; +} + +napi_value BundleStateCommon::JSParaError(const napi_env &env, const napi_ref &callback) +{ + if (callback) { + return BundleStateCommon::NapiGetNull(env); + } else { + napi_value promise = nullptr; + napi_deferred deferred = nullptr; + napi_create_promise(env, &deferred, &promise); + napi_resolve_deferred(env, deferred, BundleStateCommon::NapiGetNull(env)); + return promise; + } +} + +std::string BundleStateCommon::GetTypeStringValue(napi_env env, napi_value param, const std::string &result) +{ + BUNDLE_ACTIVE_LOGI("GetTypeStringValue start"); + size_t size = 0; + if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != BUNDLE_STATE_OK) { + return result; + } + + std::string value(""); + if (size == 0) { + return result; + } + + char *buf = new (std::nothrow) char[size + 1]; + if (buf == nullptr) { + return value; + } + + if (memset_s(buf, sizeof buf, 0, size + 1) != EOK) { + return value; + } + + bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == BUNDLE_STATE_OK; + if (rev) { + value = buf; + } else { + value = result; + } + + delete[] buf; + buf = nullptr; + BUNDLE_ACTIVE_LOGI("string result: %{public}s", value.c_str()); + return value; +} + +napi_value BundleStateCommon::GetInt64NumberValue(const napi_env &env, const napi_value &value, int64_t &result) +{ + BUNDLE_ACTIVE_LOGI("GetInt64NumberValue start"); + napi_valuetype valuetype = napi_undefined; + + NAPI_CALL(env, napi_typeof(env, value, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number or function expected."); + napi_get_value_int64(env, value, &result); + BUNDLE_ACTIVE_LOGI("number result: %{public}lld", result); + + return BundleStateCommon::NapiGetNull(env); +} + +napi_value BundleStateCommon::GetInt32NumberValue(const napi_env &env, const napi_value &value, int32_t &result) +{ + BUNDLE_ACTIVE_LOGI("GetInt32NumberValue start"); + napi_valuetype valuetype = napi_undefined; + + NAPI_CALL(env, napi_typeof(env, value, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number or function expected."); + napi_get_value_int32(env, value, &result); + BUNDLE_ACTIVE_LOGI("number result: %{public}d", result); + + return BundleStateCommon::NapiGetNull(env); +} + +void BundleStateCommon::SettingCallbackPromiseInfo( + const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise) +{ + if (callback) { + info.callback = callback; + info.isCallback = true; + } else { + napi_deferred deferred = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); + info.deferred = deferred; + info.isCallback = false; + } +} +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/src/bundle_state_init.cpp b/frameworks/src/bundle_state_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5208f25c5112301784da484903dd55bbb1a36060 --- /dev/null +++ b/frameworks/src/bundle_state_init.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_state_init.h" +#include "bundle_state_query.h" + +namespace OHOS { +namespace DeviceUsageStats { +EXTERN_C_START + +/* + * Module export function + */ +static napi_value BundleStateInit(napi_env env, napi_value exports) +{ + /* + * Propertise define + */ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("isIdleState", IsIdleState), + DECLARE_NAPI_FUNCTION("queryAppUsagePriorityGroup", QueryAppUsagePriorityGroup), + DECLARE_NAPI_FUNCTION("queryCurrentBundleActiveStates", QueryCurrentBundleActiveStates), + DECLARE_NAPI_FUNCTION("queryBundleActiveStates", QueryBundleActiveStates), + DECLARE_NAPI_FUNCTION("queryBundleStateInfoByInterval", QueryBundleStateInfoByInterval), + DECLARE_NAPI_FUNCTION("queryBundleStateInfos", QueryBundleStateInfos) + }; + + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; +} + +/* + * Module register function + */ +__attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} +EXTERN_C_END +} // namespace BackgroundTaskMgr +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/src/bundle_state_query.cpp b/frameworks/src/bundle_state_query.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff107eb5254b9e03d36a9b99d211b29f501d5259 --- /dev/null +++ b/frameworks/src/bundle_state_query.cpp @@ -0,0 +1,585 @@ +/* + * 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 "bundle_state_common.h" +#include "bundle_active_log.h" +#include "bundle_active_client.h" +#include "bundle_state_data.h" +#include "bundle_state_query.h" + +namespace OHOS { +namespace DeviceUsageStats { +static const int32_t Is_Idle_State_MIN_PARAMS = 1; +static const int32_t Is_Idle_State_PARAMS = 2; +static const int32_t Priority_Group_MIN_PARAMS = 0; +static const int32_t Priority_Group_PARAMS = 1; +static const int32_t States_MIN_PARAMS = 2; +static const int32_t States_PARAMS = 3; +static const int32_t App_Usage_MIN_PARAMS_BY_INTERVAL = 3; +static const int32_t App_Usage_PARAMS_BY_INTERVAL = 4; +static const int32_t App_Usage_MIN_PARAMS = 2; +static const int32_t App_Usage_PARAMS = 3; + +napi_value ParseIsIdleStateParameters(const napi_env &env, const napi_callback_info &info, + IsIdleStateParamsInfo ¶ms) +{ + size_t argc = Is_Idle_State_PARAMS; + napi_value argv[Is_Idle_State_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == Is_Idle_State_MIN_PARAMS || argc == Is_Idle_State_PARAMS, + "invalid number of parameters"); + + // argv[0] : bundleName + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_string, "ParseIsIdleStateParameters invalid parameter type. " + "String expected."); + std::string result = ""; + params.bundleName = BundleStateCommon::GetTypeStringValue(env, argv[0], result); + if (params.bundleName.empty()) { + BUNDLE_ACTIVE_LOGI("ParseIsIdleStateParameters failed, bundleName is invalid."); + return nullptr; + } + + // argv[1]: callback + if (argc == Is_Idle_State_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseIsIdleStateParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[1], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value IsIdleState(napi_env env, napi_callback_info info) +{ + IsIdleStateParamsInfo params; + if (ParseIsIdleStateParameters(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoIsIdleState *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoIsIdleState {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + asyncCallbackInfo->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGI("asyncCallbackInfo->bundleName: %{public}s", asyncCallbackInfo->bundleName.c_str()); + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "IsIdleState", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("IsIdleState, worker pool thread execute."); + AsyncCallbackInfoIsIdleState *asyncCallbackInfo = (AsyncCallbackInfoIsIdleState *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->state = BundleActiveClient::GetInstance().IsBundleIdle( + asyncCallbackInfo->bundleName); + } else { + BUNDLE_ACTIVE_LOGE("IsIdleState, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("IsIdleState, worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoIsIdleState *asyncCallbackInfo = (AsyncCallbackInfoIsIdleState *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_get_boolean(env, asyncCallbackInfo->state, &result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParsePriorityGroupParameters(const napi_env &env, const napi_callback_info &info, + PriorityGroupParamsInfo ¶ms) +{ + 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_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); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) +{ + PriorityGroupParamsInfo params; + if (ParsePriorityGroupParameters(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoPriorityGroup {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "QueryAppUsagePriorityGroup", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("QueryAppUsagePriorityGroup, worker pool thread execute."); + AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = (AsyncCallbackInfoPriorityGroup *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->priorityGroup = BundleActiveClient::GetInstance().QueryPackageGroup(); + } else { + BUNDLE_ACTIVE_LOGE("QueryAppUsagePriorityGroup, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("QueryAppUsagePriorityGroup, worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = (AsyncCallbackInfoPriorityGroup *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_int32(env, asyncCallbackInfo->priorityGroup, &result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseStatesParameters(const napi_env &env, const napi_callback_info &info, StatesParamsInfo ¶ms) +{ + size_t argc = States_PARAMS; + napi_value argv[States_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == States_MIN_PARAMS || argc == States_PARAMS, + "invalid number of parameters"); + + // argv[0] : beginTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[0], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseStatesParameters failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : endTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[1], params.endTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseStatesParameters failed, endTime is invalid."); + return nullptr; + } + + // argv[2]: callback + if (argc == States_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[2], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseStatesParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[2], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value QueryCurrentBundleActiveStates(napi_env env, napi_callback_info info) +{ + StatesParamsInfo params; + if (ParseStatesParameters(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoStates *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoStates {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + asyncCallbackInfo->beginTime = params.beginTime; + BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates asyncCallbackInfo->beginTime: %{public}lld", + asyncCallbackInfo->beginTime); + asyncCallbackInfo->endTime = params.endTime; + BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates asyncCallbackInfo->endTime: %{public}lld", + asyncCallbackInfo->endTime); + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "QueryCurrentBundleActiveStates", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates, worker pool thread execute."); + AsyncCallbackInfoStates *asyncCallbackInfo = (AsyncCallbackInfoStates *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->BundleActiveState = + BundleActiveClient::GetInstance().QueryCurrentEvents(asyncCallbackInfo->beginTime, + asyncCallbackInfo->endTime); + } else { + BUNDLE_ACTIVE_LOGE("QueryCurrentBundleActiveStates, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("QueryCurrentBundleActiveStates, worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoStates *asyncCallbackInfo = (AsyncCallbackInfoStates *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleActiveEventForResult(env, asyncCallbackInfo->BundleActiveState, result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value QueryBundleActiveStates(napi_env env, napi_callback_info info) +{ + StatesParamsInfo params; + if (ParseStatesParameters(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoStates *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoStates {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + asyncCallbackInfo->beginTime = params.beginTime; + BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates asyncCallbackInfo->beginTime: %{public}lld", + asyncCallbackInfo->beginTime); + asyncCallbackInfo->endTime = params.endTime; + BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates asyncCallbackInfo->endTime: %{public}lld", + asyncCallbackInfo->endTime); + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "QueryBundleActiveStates", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates, worker pool thread execute."); + AsyncCallbackInfoStates *asyncCallbackInfo = (AsyncCallbackInfoStates *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->BundleActiveState = + BundleActiveClient::GetInstance().QueryEvents(asyncCallbackInfo->beginTime, + asyncCallbackInfo->endTime); + } else { + BUNDLE_ACTIVE_LOGE("QueryBundleActiveStates, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("QueryBundleActiveStates, worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoStates *asyncCallbackInfo = (AsyncCallbackInfoStates *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleActiveEventForResult(env, asyncCallbackInfo->BundleActiveState, result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseAppUsageParametersByInterval(const napi_env &env, const napi_callback_info &info, + AppUsageParamsByIntervalInfo ¶ms) +{ + size_t argc = App_Usage_PARAMS_BY_INTERVAL; + napi_value argv[App_Usage_PARAMS_BY_INTERVAL] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == App_Usage_MIN_PARAMS_BY_INTERVAL || argc == App_Usage_PARAMS_BY_INTERVAL, + "invalid number of parameters"); + + // argv[0] : intervalType + if (BundleStateCommon::GetInt32NumberValue(env, argv[0], params.intervalType) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParametersByInterval failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : beginTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[1], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParametersByInterval failed, beginTime is invalid."); + return nullptr; + } + + // argv[2] : endTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[2], params.endTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParametersByInterval failed, endTime is invalid."); + return nullptr; + } + + // argv[3]: callback + if (argc == App_Usage_PARAMS_BY_INTERVAL) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[3], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseAppUsageParametersByInterval invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[3], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info) +{ + AppUsageParamsByIntervalInfo params; + if (ParseAppUsageParametersByInterval(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoAppUsageByInterval *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoAppUsageByInterval {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + asyncCallbackInfo->intervalType = params.intervalType; + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval asyncCallbackInfo->intervalType: %{public}d", + asyncCallbackInfo->intervalType); + asyncCallbackInfo->beginTime = params.beginTime; + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval asyncCallbackInfo->beginTime: %{public}lld", + asyncCallbackInfo->beginTime); + asyncCallbackInfo->endTime = params.endTime; + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval asyncCallbackInfo->endTime: %{public}lld", + asyncCallbackInfo->endTime); + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "QueryBundleStateInfoByInterval", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval, worker pool thread execute."); + AsyncCallbackInfoAppUsageByInterval *asyncCallbackInfo = (AsyncCallbackInfoAppUsageByInterval *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->packageStats = + BundleActiveClient::GetInstance().QueryPackageStats(asyncCallbackInfo->intervalType, + asyncCallbackInfo->beginTime, asyncCallbackInfo->endTime); + } else { + BUNDLE_ACTIVE_LOGE("QueryBundleStateInfoByInterval, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfoByInterval, worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoAppUsageByInterval *asyncCallbackInfo = (AsyncCallbackInfoAppUsageByInterval *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleStateInfoByIntervalForResult(env, asyncCallbackInfo->packageStats, result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseAppUsageParameters(const napi_env &env, const napi_callback_info &info, AppUsageParamsInfo ¶ms) +{ + size_t argc = App_Usage_PARAMS; + napi_value argv[App_Usage_PARAMS] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); + NAPI_ASSERT(env, argc == App_Usage_MIN_PARAMS || argc == App_Usage_PARAMS, + "invalid number of parameters"); + + // argv[0] : beginTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[0], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParameters failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : endTime + if (BundleStateCommon::GetInt64NumberValue(env, argv[1], params.endTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParameters failed, endTime is invalid."); + return nullptr; + } + + // argv[2]: callback + if (argc == App_Usage_PARAMS) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[2], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "ParseAppUsageParameters invalid parameter type. " + "Function expected."); + napi_create_reference(env, argv[2], 1, ¶ms.callback); + } + return BundleStateCommon::NapiGetNull(env); +} + +napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) +{ + AppUsageParamsInfo params; + if (ParseAppUsageParameters(env, info, params) == nullptr) { + return BundleStateCommon::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoAppUsage *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoAppUsage {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return BundleStateCommon::JSParaError(env, params.callback); + } + asyncCallbackInfo->beginTime = params.beginTime; + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos asyncCallbackInfo->beginTime: %{public}lld", + asyncCallbackInfo->beginTime); + asyncCallbackInfo->endTime = params.endTime; + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos asyncCallbackInfo->endTime: %{public}lld", + asyncCallbackInfo->endTime); + BundleStateCommon::SettingCallbackPromiseInfo(env, params.callback, asyncCallbackInfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "QueryBundleStateInfos", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos, worker pool thread execute."); + AsyncCallbackInfoAppUsage *asyncCallbackInfo = (AsyncCallbackInfoAppUsage *)data; + if (asyncCallbackInfo != nullptr) { + asyncCallbackInfo->packageStats = + BundleActiveClient::GetInstance().QueryPackageStats(INTERVAL_TYPE_DEFAULT, + asyncCallbackInfo->beginTime, asyncCallbackInfo->endTime); + } else { + BUNDLE_ACTIVE_LOGE("QueryBundleStateInfos, asyncCallbackInfo == nullptr"); + } + BUNDLE_ACTIVE_LOGI("QueryBundleStateInfos worker pool thread execute end."); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoAppUsage *asyncCallbackInfo = (AsyncCallbackInfoAppUsage *)data; + if (asyncCallbackInfo != nullptr) { + napi_value result = nullptr; + napi_create_array(env, &result); + BundleStateCommon::GetBundleStateInfoForResult(env, asyncCallbackInfo->packageStats, result); + BundleStateCommon::GetCallbackPromiseResult(env, asyncCallbackInfo->info, result); + + if (asyncCallbackInfo->info.callback != nullptr) { + napi_delete_reference(env, asyncCallbackInfo->info.callback); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + }, + (void *)asyncCallbackInfo, + &asyncCallbackInfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + + if (asyncCallbackInfo->info.isCallback) { + return BundleStateCommon::NapiGetNull(env); + } else { + return promise; + } +} +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/init/bundleactive_service.rc b/init/bundleactive_service.rc deleted file mode 100644 index 59828318f4dee19e141cf0a8d42716d117061f76..0000000000000000000000000000000000000000 --- a/init/bundleactive_service.rc +++ /dev/null @@ -1,8 +0,0 @@ -on post-fs-data - start bundleactive_service - -service bundleactive_service /system/bin/sa_main /system/profile/bundleactive_service.xml - class z_core - user root - group root shell - seclabel u:r:bundleactive_service:s0 \ No newline at end of file diff --git a/init/bundleactive_service.cfg b/init/device_usage_statistics_service.cfg similarity index 51% rename from init/bundleactive_service.cfg rename to init/device_usage_statistics_service.cfg index 6f531093263673d85906c3c53590676cbef3e27a..c197a766062cea3140d3e620420fd3f8333ac90c 100644 --- a/init/bundleactive_service.cfg +++ b/init/device_usage_statistics_service.cfg @@ -2,13 +2,13 @@ "jobs" : [{ "name" : "post-fs-data", "cmds" : [ - "start bundleactive_service" + "start device_usage_stats_service" ] } ], "services" : [{ - "name" : "bundleactive_service", - "path" : ["/system/bin/sa_main", "/system/profile/bundleactive_service.xml"], + "name" : "device_usage_stats_service", + "path" : ["/system/bin/sa_main", "/system/profile/device_usage_stats_service.xml"], "uid" : "root", "gid" : ["root", "shell"] } diff --git a/interfaces/innerkits/include/bundle_active_client.h b/interfaces/innerkits/include/bundle_active_client.h index 0a44623c020ff2f042b45729fe0ffd18b92ef4d7..0cd8f294db74371722f0c4bdb01bab8ad5ee60f6 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -17,23 +17,31 @@ #define BUNDLE_ACTIVE_CLIENT_H #include "ibundle_active_service.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveClient { public: - int ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId); - int IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId); - int Query(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId); + int ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId); + bool IsBundleIdle(const std::string& bundleName); + std::vector QueryPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime); + std::vector QueryEvents(const int64_t& beginTime, const int64_t& endTime); + void SetBundleGroup(std::string bundleName, const int newGroup, const int& userId); + std::vector QueryCurrentPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime); + std::vector QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime); + int QueryPackageGroup(); static BundleActiveClient& GetInstance(); -public: BundleActiveClient() {} ~BundleActiveClient() {}; private: bool GetBundleActiveProxy(); - sptr bundleActiveProxy; + sptr bundleActiveProxy_; }; } } diff --git a/interfaces/innerkits/include/bundle_active_proxy.h b/interfaces/innerkits/include/bundle_active_proxy.h index b449be2181eb251f2a64c698b474999a1c19b220..0241411ea77c22f9dba63db40a5d9c034e53fe9c 100644 --- a/interfaces/innerkits/include/bundle_active_proxy.h +++ b/interfaces/innerkits/include/bundle_active_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -17,25 +17,30 @@ #define BUNDLE_ACTIVE_PROXY_H #include "ibundle_active_service.h" +#include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveProxy : public IRemoteProxy { public: - int ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) override; - int IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) override; - int Query(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) override; - -public: + int ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) override; + bool IsBundleIdle(const std::string& bundleName) override; + std::vector QueryPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime) override; + std::vector QueryEvents(const int64_t& beginTime, const int64_t& endTime) override; + void SetBundleGroup(const std::string& bundleName, int newGroup, int userId) override; + std::vector QueryCurrentPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime) override; + std::vector QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime) override; + int QueryPackageGroup() override; explicit BundleActiveProxy(const sptr& impl) : IRemoteProxy(impl) {} virtual ~BundleActiveProxy() {} - + private: static inline BrokerDelegator delegator_; }; } } - #endif diff --git a/interfaces/innerkits/src/bundle_active_client.cpp b/interfaces/innerkits/src/bundle_active_client.cpp index eb90b0f0553d3af8c224354e95a30f6c23c23200..2d35224611a3f3f465939cad7724d4e5f0f745ea 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -14,9 +14,10 @@ */ #include "bundle_active_client.h" +#include "bundle_active_package_stats.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { BundleActiveClient& BundleActiveClient::GetInstance() { static BundleActiveClient instance; @@ -31,45 +32,87 @@ bool BundleActiveClient::GetBundleActiveProxy() return false; } - sptr object = samgr->GetSystemAbility(BUNDLE_ACTIVE_SYS_ABILITY_ID); + sptr object = samgr->GetSystemAbility(DEVICE_UASAGE_STATISTICS_SYS_ABILITY_ID); if (object == nullptr) { - BUNDLE_ACTIVE_LOGE("Failed to get SystemAbility[1906] ."); + BUNDLE_ACTIVE_LOGE("Failed to get SystemAbility[1920] ."); return false; } - bundleActiveProxy = iface_cast(object); - if (bundleActiveProxy == nullptr) { + bundleActiveProxy_ = iface_cast(object); + if (bundleActiveProxy_ == nullptr) { BUNDLE_ACTIVE_LOGE("Failed to get BundleActiveClient."); return false; } return true; } -int BundleActiveClient::ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) +int BundleActiveClient::ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) { + BUNDLE_ACTIVE_LOGI("BundleActiveClient::ReportEvent called"); if (!GetBundleActiveProxy()) { return -1; } - return bundleActiveProxy->ReportEvent(bundleName, abilityName, abilityId, userId, eventId); + return bundleActiveProxy_->ReportEvent(bundleName, abilityName, abilityId, continuousTask, userId, eventId); } -int BundleActiveClient::IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) +bool BundleActiveClient::IsBundleIdle(const std::string& bundleName) { if (!GetBundleActiveProxy()) { return -1; } - return bundleActiveProxy->IsBundleIdle(bundleName, abilityName, abilityId, userId); + return bundleActiveProxy_->IsBundleIdle(bundleName); } -int BundleActiveClient::Query(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) +std::vector BundleActiveClient::QueryPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) { if (!GetBundleActiveProxy()) { - return -1; + return std::vector(0); + } + return bundleActiveProxy_->QueryPackageStats(intervalType, beginTime, endTime); +} + +std::vector BundleActiveClient::QueryEvents(const int64_t& beginTime, const int64_t& endTime) +{ + if (!GetBundleActiveProxy()) { + return std::vector(0); + } + return bundleActiveProxy_->QueryEvents(beginTime, endTime); +} + +void BundleActiveClient::SetBundleGroup(std::string bundleName, const int newGroup, const int& userId) +{ + if (!GetBundleActiveProxy()) { + return; + } + bundleActiveProxy_->SetBundleGroup(bundleName, newGroup, userId); + return; +} + +std::vector BundleActiveClient::QueryCurrentPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) +{ + if (!GetBundleActiveProxy()) { + return std::vector(0); } - return bundleActiveProxy->Query(bundleName, abilityName, abilityId, userId); + return bundleActiveProxy_->QueryCurrentPackageStats(intervalType, beginTime, endTime); } + +std::vector BundleActiveClient::QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime) +{ + if (!GetBundleActiveProxy()) { + return std::vector(0); + } + return bundleActiveProxy_->QueryCurrentEvents(beginTime, endTime); +} + +int BundleActiveClient::QueryPackageGroup() +{ + if (!GetBundleActiveProxy()) { + return -1; + } + return bundleActiveProxy_->QueryPackageGroup(); } } +} \ No newline at end of file diff --git a/interfaces/innerkits/src/bundle_active_proxy.cpp b/interfaces/innerkits/src/bundle_active_proxy.cpp index 04ae360e333c7dfebdab1c81d5d1c5c7f2edac42..a957b1b2d1836c95707373b6d70c32b4f908504c 100644 --- a/interfaces/innerkits/src/bundle_active_proxy.cpp +++ b/interfaces/innerkits/src/bundle_active_proxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -14,18 +14,21 @@ */ #include "bundle_active_proxy.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_package_stats.h" namespace OHOS { -namespace BundleActive { -int BundleActiveProxy::ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) +namespace DeviceUsageStats { +int BundleActiveProxy::ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) { MessageParcel data; MessageParcel reply; MessageOption option; data.WriteString(bundleName); data.WriteString(abilityName); - data.WriteInt32(abilityId); + data.WriteString(abilityId); + data.WriteString(continuousTask); data.WriteInt32(userId); data.WriteInt32(eventId); Remote() -> SendRequest(REPORT_EVENT, data, reply, option); @@ -34,35 +37,125 @@ int BundleActiveProxy::ReportEvent(std::string& bundleName, std::string& ability return result; } -int BundleActiveProxy::IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) +bool BundleActiveProxy::IsBundleIdle(const std::string& bundleName) { MessageParcel data; MessageParcel reply; MessageOption option; data.WriteString(bundleName); - data.WriteString(abilityName); - data.WriteInt32(abilityId); - data.WriteInt32(userId); Remote() -> SendRequest(IS_BUNDLE_IDLE, data, reply, option); int32_t result = reply.ReadInt32(); return result; } -int BundleActiveProxy::Query(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) +std::vector BundleActiveProxy::QueryPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInt32(intervalType); + data.WriteInt64(beginTime); + data.WriteInt64(endTime); + Remote() -> SendRequest(QUERY_USAGE_STATS, data, reply, option); + int32_t size = reply.ReadInt32(); + std::vector result; + std::shared_ptr tmp; + for (int i = 0; i < size; i++) { + tmp = tmp->Unmarshalling(reply); + if (tmp == nullptr) { + continue; + } + result.push_back(*tmp); + } + return result; +} + +std::vector BundleActiveProxy::QueryEvents(const int64_t& beginTime, const int64_t& endTime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInt64(beginTime); + data.WriteInt64(endTime); + Remote() -> SendRequest(QUERY_EVENTS, data, reply, option); + int32_t size = reply.ReadInt32(); + std::vector result; + std::shared_ptr tmp; + for (int i = 0; i < size; i++) { + tmp = tmp->Unmarshalling(reply); + if (tmp == nullptr) { + continue; + } + result.push_back(*tmp); + } + return result; +} + +void BundleActiveProxy::SetBundleGroup(const std::string& bundleName, int newGroup, int userId) { MessageParcel data; MessageParcel reply; MessageOption option; data.WriteString(bundleName); - data.WriteString(abilityName); - data.WriteInt32(abilityId); + data.WriteInt32(newGroup); data.WriteInt32(userId); - Remote() -> SendRequest(QUERY, data, reply, option); + Remote() -> SendRequest(SET_BUNDLE_GROUP, data, reply, option); +} - int32_t result = reply.ReadInt32(); +std::vector BundleActiveProxy::QueryCurrentPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInt32(intervalType); + data.WriteInt64(beginTime); + data.WriteInt64(endTime); + Remote() -> SendRequest(QUERY_CURRENT_USAGE_STATS, data, reply, option); + int32_t size = reply.ReadInt32(); + std::vector result; + std::shared_ptr tmp; + for (int i = 0; i < size; i++) { + tmp = tmp->Unmarshalling(reply); + if (tmp == nullptr) { + continue; + } + result.push_back(*tmp); + } return result; } + +std::vector BundleActiveProxy::QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInt64(beginTime); + data.WriteInt64(endTime); + Remote() -> SendRequest(QUERY_CURRENT_EVENTS, data, reply, option); + int32_t size = reply.ReadInt32(); + std::vector result; + std::shared_ptr tmp; + for (int i = 0; i < size; i++) { + tmp = tmp->Unmarshalling(reply); + if (tmp == nullptr) { + continue; + } + result.push_back(*tmp); + } + return result; +} + +int BundleActiveProxy::QueryPackageGroup() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + Remote() -> SendRequest(QUERY_BUNDLE_GROUP, data, reply, option); + int32_t packageGroup = reply.ReadInt32(); + return packageGroup; } } +} \ No newline at end of file diff --git a/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts b/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e28bf6ccf5a6c0ef29c37cb7bb20b0f5f26b2119 --- /dev/null +++ b/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts @@ -0,0 +1,255 @@ +/* + * 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. + */ + +import { AsyncCallback } from './basic'; + +/** + * Provides methods for managing bundle usage statistics, + * including the methods for querying bundle usage information and state data. + * + *

You can use the methods defined in this class to query + * the usage history and states of bundles in a specified period. + * The system stores the query result in a {@link BundleStateInfo} or {@link BundleActiveState} instance and + * then returns it to you. + * + * @since 7 + * @devices phone, tablet, tv, wearable, car + */ +declare namespace bundleState { + + /** + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + */ + interface BundleStateInfo { + /** + * the identifier of BundleStateInfo. + */ + id: number; + /** + * the total duration, in milliseconds. + */ + abilityInFgTotalTime?: number; + /** + * the last time when the application was accessed, in milliseconds. + */ + abilityPrevAccessTime?: number; + /** + * the last time when the application was visible in the foreground, in milliseconds. + */ + abilityPrevSeenTime?: number; + /** + * the total duration, in milliseconds. + */ + abilitySeenTotalTime?: number; + /** + * the bundle name of the application. + */ + bundleName?: string; + /** + * the total duration, in milliseconds. + */ + fgAbilityAccessTotalTime?: number; + /** + * the last time when the foreground application was accessed, in milliseconds. + */ + fgAbilityPrevAccessTime?: number; + /** + * the time of the first bundle usage record in this {@code BundleActiveInfo} object, + * in milliseconds. + */ + infosBeginTime?: number; + /** + * the time of the last bundle usage record in this {@code BundleActiveInfo} object, + * in milliseconds. + */ + infosEndTime?: number; + + /** + * Merges a specified {@link BundleActiveInfo} object with this {@link BundleActiveInfo} object. + * The bundle name of both objects must be the same. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + * @param toMerge Indicates the {@link BundleActiveInfo} object to merge. + * if the bundle names of the two {@link BundleActiveInfo} objects are different. + */ + merge(toMerge: BundleStateInfo): void; + } + + /** + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + */ + interface BundleActiveState { + /** + * the usage priority group of the application. + */ + appUsagePriorityGroup?: number; + /** + * the bundle name. + */ + bundleName?: string; + /** + * the shortcut ID. + */ + indexOfLink?: string; + /** + * the class name. + */ + nameOfClass?: string; + /** + * the time when this state occurred, in milliseconds. + */ + stateOccurredTime?: number; + /** + * the state type. + */ + stateType?: number; + } + + /** + * Checks whether the application with a specified bundle name is in the idle state. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup + * @devices phone, tablet, tv, wearable, car + * @param bundleName Indicates the bundle name of the application to query. + * @return Returns {@code true} if the application is idle in a particular period; + * returns {@code false} otherwise. The time range of the particular period is defined by the system, + * which may be hours or days. + */ + function isIdleState(bundleName: string, callback: AsyncCallback): void; + function isIdleState(bundleName: string): Promise; + + /** + * Queries the usage priority group of the calling application. + * + *

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

+ * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.AppGroup + * @devices phone, tablet, tv, wearable, car + * @return Returns the usage priority group of the calling application. + */ + function queryAppUsagePriorityGroup(callback: AsyncCallback): void; + function queryAppUsagePriorityGroup(): Promise; + + /** + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + */ + interface BundleActiveInfoResponse { + [key: string]: BundleStateInfo; + } + + /** + * Queries usage information about each bundle within a specified period. + * + *

This method queries usage information at the {@link #BY_OPTIMIZED} interval by default.

+ * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + * @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 BundleActiveInfoResponse} objects containing the usage information about each bundle. + */ + function queryBundleStateInfos(begin: number, end: number, callback: AsyncCallback): void; + function queryBundleStateInfos(begin: number, end: number): Promise; + + /** + * Declares interval type. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + */ + export enum IntervalType { + /** + * Indicates the interval type that will determine the optimal interval based on the start and end time. + */ + BY_OPTIMIZED = 0, + + /** + * Indicates the daily interval. + */ + BY_DAILY = 1, + + /** + * Indicates the weekly interval. + */ + BY_WEEKLY = 2, + + /** + * Indicates the monthly interval. + */ + BY_MONTHLY = 3, + + /** + * Indicates the annually interval. + */ + BY_ANNUALLY = 4 + } + + /** + * Queries usage information about each bundle within a specified period at a specified interval. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + * @param byInterval Indicates the interval at which the usage statistics are queried. + * The value can be {@link #BY_OPTIMIZED}, {@link #BY_DAILY}, + * {@link #BY_WEEKLY}, {@link #BY_MONTHLY}, or {@link #BY_ANNUALLY}. + * @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 list of {@link BundleStateInfo} objects containing the usage information about each bundle. + */ + function queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number, callback: AsyncCallback>): void; + function queryBundleStateInfoByInterval(byInterval: IntervalType, begin: number, end: number): Promise>; + + /** + * Queries state data of all bundles within a specified period identified by the start and end time. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + * @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 list of {@link BundleActiveState} objects containing the state data of all bundles. + */ + function queryBundleActiveStates(begin: number, end: number, callback: AsyncCallback>): void; + function queryBundleActiveStates(begin: number, end: number): Promise>; + + /** + * Queries state data of the current bundle within a specified period. + * + * @since 7 + * @sysCap SystemCapability.ResourceSchedule.UsageStatistics.App + * @devices phone, tablet, tv, wearable, car + * @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 BundleActiveState} object Array containing the state data of the current bundle. + */ + function queryCurrentBundleActiveStates(begin: number, end: number, callback: AsyncCallback>): void; + function queryCurrentBundleActiveStates(begin: number, end: number): Promise>; +} + +export default bundleState; \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..2c10cc11d5c6c1dc9c4e7fbbab96e898ff35b321 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_common.h @@ -0,0 +1,68 @@ +/* + * 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 "napi/native_api.h" +#include "napi/native_node_api.h" +#include "bundle_state_data.h" + +#ifndef FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_COMMON_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_COMMON_H + +namespace OHOS { +namespace DeviceUsageStats { +const std::int32_t STR_MAX_SIZE = 64; +class BundleStateCommon { +public: + static napi_value NapiGetboolean(napi_env env, const bool &isValue); + + static napi_value NapiGetNull(napi_env env); + + static napi_value NapiGetUndefined(napi_env env); + + static napi_value GetCallbackErrorValue(napi_env env, int errCode); + + static void SettingCallbackPromiseInfo( + const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise); + + static void GetCallbackPromiseResult(const napi_env &env, const CallbackPromiseInfo &info, + const napi_value &result); + + static void SetCallbackInfo( + const napi_env &env, const napi_ref &callbackIn, const int &errorCode, const napi_value &result); + + static void GetBundleActiveEventForResult( + napi_env env, const std::vector &BundleActiveState, napi_value result); + + static void GetBundleStateInfoByIntervalForResult( + napi_env env, const std::vector &packageStats, napi_value result); + + static void GetBundleStateInfoForResult( + napi_env env, const std::vector &packageStats, napi_value result); + + static void SetPromiseInfo(const napi_env &env, const napi_deferred &deferred, const napi_value &result); + + static napi_value JSParaError(const napi_env &env, const napi_ref &callback); + + static std::string GetTypeStringValue(napi_env env, napi_value param, const std::string &result); + + static napi_value GetInt64NumberValue(const napi_env &env, const napi_value &value, int64_t &result); + + static napi_value GetInt32NumberValue(const napi_env &env, const napi_value &value, int32_t &result); +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_COMMON_H \ No newline at end of file diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_data.h b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h new file mode 100644 index 0000000000000000000000000000000000000000..a44f85b3c6b3bb333ad492e3ff68e36c25a52e54 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_data.h @@ -0,0 +1,121 @@ +/* + * 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_STATE_DATA_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_DATA_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "bundle_active_event.h" +#include "bundle_active_package_stats.h" + +namespace OHOS { +namespace DeviceUsageStats { +#define ARGS_ONE 1 +#define ARGS_TWO 2 +#define ARGS_THREE 3 +#define ARGS_FOUR 4 + +#define PARAM_FIRST 0 +#define PARAM_SECOND 1 +#define PARAM_THIRD 2 +#define PARAM_FOURTH 3 + +#define BUNDLE_STATE_OK 0 +#define INTERVAL_TYPE_DEFAULT 0 + +struct CallbackPromiseInfo { + napi_ref callback = nullptr; + napi_deferred deferred = nullptr; + bool isCallback = false; + int errorCode = 0; +}; + +struct AsyncCallbackInfoIsIdleState { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + std::string bundleName; + bool state; + CallbackPromiseInfo info; +}; + +struct AsyncCallbackInfoPriorityGroup { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + int32_t priorityGroup; + CallbackPromiseInfo info; +}; + +struct AsyncCallbackInfoStates { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + int64_t beginTime; + int64_t endTime; + std::vector BundleActiveState; + CallbackPromiseInfo info; +}; + +struct AsyncCallbackInfoAppUsageByInterval { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + int32_t intervalType; + int64_t beginTime; + int64_t endTime; + std::vector packageStats; + CallbackPromiseInfo info; +}; + +struct AsyncCallbackInfoAppUsage { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + int64_t beginTime; + int64_t endTime; + std::vector packageStats; + CallbackPromiseInfo info; +}; + +struct IsIdleStateParamsInfo { + std::string bundleName; + napi_ref callback = nullptr; +}; + +struct PriorityGroupParamsInfo { + napi_ref callback = nullptr; +}; + +struct StatesParamsInfo { + int64_t beginTime; + int64_t endTime; + napi_ref callback = nullptr; +}; + +struct AppUsageParamsByIntervalInfo { + int32_t intervalType; + int64_t beginTime; + int64_t endTime; + napi_ref callback = nullptr; +}; + +struct AppUsageParamsInfo { + int64_t beginTime; + int64_t endTime; + napi_ref callback = nullptr; +}; +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..045d7bb9eb7cc6080286972913d8b939c3b25ee4 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_init.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 FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_INIT_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_INIT_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace DeviceUsageStats { +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((constructor)) void RegisterModule(void); +static napi_value BundleStateInit(napi_env env, napi_value exports); + +#ifdef __cplusplus +} +#endif + +/* + * Module define + */ +napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = BundleStateInit, + .nm_modname = "usagestatskit", + .nm_priv = ((void *)0), + .reserved = {0} +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_INIT_H \ No newline at end of file diff --git a/interfaces/kits/bundlestats/napi/include/bundle_state_query.h b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h new file mode 100644 index 0000000000000000000000000000000000000000..589ebbec076e32dae59ab05a741ac17f6809156e --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_query.h @@ -0,0 +1,32 @@ +/* + * 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_STATE_QUERY_H +#define FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_QUERY_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace DeviceUsageStats { + napi_value IsIdleState(napi_env env, napi_callback_info info); + napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info); + napi_value QueryCurrentBundleActiveStates(napi_env env, napi_callback_info info); + napi_value QueryBundleActiveStates(napi_env env, napi_callback_info info); + napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info); + napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info); +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_DEVICE_USAGE_STATISTICS_BUNDLE_STATE_QUERY_H \ No newline at end of file diff --git a/ohos.build b/ohos.build deleted file mode 100644 index 722a3a58106fcb929bb5ccddee812d82ce9a6db6..0000000000000000000000000000000000000000 --- a/ohos.build +++ /dev/null @@ -1,31 +0,0 @@ -{ - "subsystem": "resourceschedule", - "parts": { - "device_usage_statistics": { - "variants": [ - ], - "module_list": [ - "//foundation/resourceschedule/device_usage_statistics:bundleactiveinner", - "//foundation/resourceschedule/device_usage_statistics:bundleactiveservice", - "//foundation/resourceschedule/device_usage_statistics:bundleactive_sa_profile", - "//foundation/resourceschedule/device_usage_statistics:bundleactive_service_init" - ], - "inner_kits": [ - { - "header": { - "header_base": "//foundation/resourceschedule/device_usage_statistics/interfaces/innerkits/include", - "header_files": [ - "bundle_active_proxy.h", - "bundle_active_client.h" - ] - }, - "name": "//foundation/resourceschedule/device_usage_statistics:bundleactiveinner" - } - ], - "system_kits": [ - ], - "test_list":[ - ] - } - } -} diff --git a/sa_profile/1907.xml b/sa_profile/1907.xml new file mode 100644 index 0000000000000000000000000000000000000000..af488d8536096871b2bb2cd3f06ee26986260864 --- /dev/null +++ b/sa_profile/1907.xml @@ -0,0 +1,12 @@ + + + device_usage_stats_service + + 1907 + libusagestatservice.z.so + 60000 + true + false + 1 + + \ No newline at end of file diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..04e5660b34ba33906fcd8206d5726987cd21ffa3 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,29 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_prebuilt_etc("device_usage_statistics_service_init") { + source = "etc/device_usage_statistics_service.cfg" + relative_install_dir = "init" + part_name = "device_usage_statistics" + subsystem_name = "resourceschedule" +} + +ohos_sa_profile("usagestat_sa_profile") { + sources = [ + "1907.xml" + ] + part_name = "device_usage_statistics" +} \ No newline at end of file diff --git a/services/common/include/bundle_active_app_state_observer.h b/services/common/include/bundle_active_app_state_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..afca43fb7887ce6b9e9682af4b619f63eb03c392 --- /dev/null +++ b/services/common/include/bundle_active_app_state_observer.h @@ -0,0 +1,66 @@ +/* + * 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_APP_STATE_OBSERVER_H +#define BUNDLE_ACTIVE_APP_STATE_OBSERVER_H + +#include + +#include "os_account_manager.h" + +#include "application_state_observer_stub.h" +#include "bundle_active_report_handler.h" + +namespace OHOS { +namespace DeviceUsageStats { +using OHOS::AppExecFwk::ApplicationStateObserverStub; +using OHOS::AppExecFwk::AppStateData; +using OHOS::AppExecFwk::AbilityStateData; +using OHOS::AppExecFwk::ProcessData; + +class BundleActiveAppStateObserver : public ApplicationStateObserverStub { +public: + void OnForegroundApplicationChanged(const AppStateData &appStateData) override; + void OnAbilityStateChanged(const AbilityStateData &abilityStateData) override; + void OnExtensionStateChanged(const AbilityStateData &abilityStateData) override; + void OnProcessCreated(const ProcessData &processData) override; + void OnProcessDied(const ProcessData &processData) override; + void OnApplicationStateChanged(const AppStateData &appStateData) override; + void Init(const std::shared_ptr& reportHandler); +private: + inline bool ValidateAppStateData(const AppStateData &appStateData) const + { + return appStateData.uid > 0 + && appStateData.bundleName.size() > 0; + } + + inline bool ValidateAbilityStateData(const AbilityStateData &abilityStateData) const + { + return abilityStateData.uid > 0 && abilityStateData.pid >= 0 + && abilityStateData.bundleName.size() > 0 + && abilityStateData.abilityName.size() > 0 + && abilityStateData.token != nullptr; + } + + inline bool ValidateProcessData(const ProcessData &processData) const + { + return processData.uid > 0 && processData.pid >= 0 + && processData.bundleName.size() > 0; + } + std::shared_ptr reportHandler_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_binary_search.h b/services/common/include/bundle_active_binary_search.h new file mode 100644 index 0000000000000000000000000000000000000000..62bcfdc16007be2a7ac251c74db0a54203e0c603 --- /dev/null +++ b/services/common/include/bundle_active_binary_search.h @@ -0,0 +1,32 @@ +/* + * 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_BINARY_SEARCH_H +#define BUNDLE_ACTIVE_BINARY_SEARCH_H + +#include + +#include "singleton.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveBinarySearch : public DelayedSingleton { +public: + int32_t BinarySearch(const std::vector &tableNameArray, int64_t targetValue); + DECLARE_DELAYED_SINGLETON(BundleActiveBinarySearch); +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_common_event_subscriber.h b/services/common/include/bundle_active_common_event_subscriber.h new file mode 100644 index 0000000000000000000000000000000000000000..87fa36b618f09017c15a849ef4e5370fb46a32e5 --- /dev/null +++ b/services/common/include/bundle_active_common_event_subscriber.h @@ -0,0 +1,56 @@ +/* + * 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_COMMON_EVENT_SUBSCRIBER_H +#define BUNDLE_ACTIVE_COMMON_EVENT_SUBSCRIBER_H + +#include + +#include "common_event_manager.h" +#include "common_event_support.h" +#include "common_event_data.h" +#include "time_service_client.h" + +#include "ibundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +using CommonEventSubscriber = OHOS::EventFwk::CommonEventSubscriber; +using CommonEventData = OHOS::EventFwk::CommonEventData; +using CommonEventSubscribeInfo = OHOS::EventFwk::CommonEventSubscribeInfo; +using CommonEventSupport = OHOS::EventFwk::CommonEventSupport; +using CommonEventManager = OHOS::EventFwk::CommonEventManager; +using MatchingSkills = OHOS::EventFwk::MatchingSkills; +class BundleActiveGroupController; +class BundleActiveReportHandler; + +class BundleActiveCommonEventSubscriber : public CommonEventSubscriber { +public: + BundleActiveCommonEventSubscriber(const CommonEventSubscribeInfo &subscriberInfo, + const std::shared_ptr activeGroupController, + const std::weak_ptr bundleActiveReportHandler) : + CommonEventSubscriber(subscriberInfo), + activeGroupController_(activeGroupController), + bundleActiveReportHandler_(bundleActiveReportHandler) {}; + ~BundleActiveCommonEventSubscriber() = default; + void OnReceiveEvent(const CommonEventData &data) override; + +private: + std::weak_ptr activeGroupController_; + std::weak_ptr bundleActiveReportHandler_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_constant.h b/services/common/include/bundle_active_constant.h new file mode 100644 index 0000000000000000000000000000000000000000..0574f2351afc3fc593d7151e64203f3b39e7999d --- /dev/null +++ b/services/common/include/bundle_active_constant.h @@ -0,0 +1,125 @@ +/* + * 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_CONSTANT_H +#define BUNDLE_ACTIVE_CONSTANT_H + +#include + +namespace OHOS { +namespace DeviceUsageStats { +const static std::string REFRESH_DATABASE_RUNNER_NAME = "RefreshDatabase"; +const static std::string BUNDLE_ACTIVE_DATABASE_DIR = "/data/system_ce/bundle_usage/"; +const static std::string BUNDLE_ACTIVE_VERSION_FILE = "/version"; +const static std::string BUNDLE_ACTIVE_DATABASE_SUFFIX = ".db"; +const static std::string DAILY_DATABASE = "daily.db"; +const static std::string WEEKLY_DATABASE = "weekly.db"; +const static std::string MONTHLY_DATABASE = "monthly.db"; +const static std::string YEARLY_DATABASE = "yearly.db"; +const static std::string EVENT_DATABASE = "event.db"; +const static std::string USAGE_GROUP_DATABASE = "usageGroup.db"; +const static std::string DATABASE_FILE_TABLE_NAME = "table"; +const static std::string SQLITE_MASTER_NAME = "name"; + +const int32_t MAX_FILES_EVERY_INTERVAL_TYPE[] = {30, 30, 12, 10}; +const int64_t SIX_DAY_IN_MILLIS_MAX = 6 * 24 * 60 * 60 * 1000; +const int64_t LAST_TIME_IN_MILLIS_MIN = 0; +const int64_t EVENT_TIME_IN_MILLIS_MIN = 0; +const int64_t EVENT_BEGIN_TIME_INITIAL_VALUE = -1; +const int32_t DURATION_TABLE_ROW_NUMBER = 1; +const int32_t TABLE_ROW_ZERO = 0; +const int32_t SORTED_TABLE_ARRAY_NUMBER = 4; +const int32_t NO_UPDATE_ROW = 0; +const int32_t NO_DELETE_ROW = 0; +const int32_t EVENT_TABLE_NUMBER = 1; +const int32_t APP_GROUP_TABLE_NUMBER = 2; +const int32_t TABLE_NOT_EXIST = 0; +const int32_t DAILY_DATABASE_INDEX = 0; +const int32_t WEEKLY_DATABASE_INDEX = 1; +const int32_t MONTHLY_DATABASE_INDEX = 2; +const int32_t YEARLY_DATABASE_INDEX = 3; +const int32_t EVENT_DATABASE_INDEX = 4; +const int32_t APP_GROUP_DATABASE_INDEX = 5; +const int32_t BUNDLE_ACTIVE_CURRENT_VERSION = 1; +const int32_t BUNDLE_ACTIVE_SUCCESS = 0; +const int32_t BUNDLE_ACTIVE_FAIL = -1; +const int32_t BUNDLE_ACTIVE_RDB_VERSION = 1; +const int USER_ID_COLUMN_INDEX = 0; +const int BUNDLE_NAME_COLUMN_INDEX = 1; +const int BUNDLE_STARTED_COUNT_COLUMN_INDEX = 2; +const int LAST_TIME_COLUMN_INDEX = 3; +const int LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX = 4; +const int TOTAL_TIME_COLUMN_INDEX = 5; +const int TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX = 6; +const int EVENT_ID_COLUMN_INDEX = 2; +const int TIME_STAMP_COLUMN_INDEX = 3; +const int ABILITY_ID_COLUMN_INDEX = 4; +const int LAST_BOOT_FROM_USED_TIME_COLUMN_INDEX = 2; +const int LAST_SCREEN_USED_TIME_COLUMN_INDEX = 3; +const int CURRENT_GROUP_COLUMN_INDEX = 4; +const int REASON_IN_GROUP_COLUMN_INDEX = 5; +const int BUNDLE_ALIVE_TIMEOUT_TIME_COLUMN_INDEX = 6; +const int BUNDLE_DAILY_TIMEOUT_TIME_COLUMN_INDEX = 7; + +const int BOOT_BASED_DURATION_COLUMN_INDEX = 0; +const int SCREEN_ON_DURATION_COLUMN_INDEX = 1; +const int DURATION_FLAG_COLUMN_INDEX = 2; + +const std::string PACKAGE_LOG_TABLE = "PackageLog"; +const std::string PACKAGE_LOG_TABLE_INDEX_PREFIX = "PackageLogIndex"; +const std::string EVENT_LOG_TABLE = "EventLog"; +const std::string EVENT_LOG_TABLE_INDEX_PREFIX = "EventLogIndex"; +const std::string DURATION_LOG_TABLE = "DurationLog"; +const std::string BUNDLE_HISTORY_LOG_TABLE = "BundleHistoryLog"; +const std::string BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX = "BundleHistoryLogIndex"; +const std::string UNKNOWN_TABLE_NAME = "unknownTableName"; + +const std::string BUNDLE_ACTIVE_DB_USER_ID = "userId"; +const std::string BUNDLE_ACTIVE_DB_NAME = "bundleName"; +const std::string BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT = "bundleStartedCount"; +const std::string BUNDLE_ACTIVE_DB_LAST_TIME = "lastTime"; +const std::string BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK = "lastTimeContinuousTask"; +const std::string BUNDLE_ACTIVE_DB_TOTAL_TIME = "totalTime"; +const std::string BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK = "totalTimeContinuousTask"; +const std::string BUNDLE_ACTIVE_DB_EVENT_ID = "eventId"; +const std::string BUNDLE_ACTIVE_DB_TIME_STAMP = "timeStamp"; +const std::string BUNDLE_ACTIVE_DB_ABILITY_ID = "abilityId"; + +const std::string BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME = "lastBootFromUsedTime"; +const std::string BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME = "lastScreenUsedTime"; +const std::string BUNDLE_ACTIVE_DB_CURRENT_GROUP = "currentGroup"; +const std::string BUNDLE_ACTIVE_DB_REASON_IN_GROUP = "reasonInGroup"; +const std::string BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME = "bundleAliveTimeoutTime"; +const std::string BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME = "bundleDailyTimeoutTime"; + +const std::string BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION = "bootBasedDuration"; +const std::string BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION = "screenOnDuration"; + +const static bool COMPRESS_TIME = true; +const static long TWO_SECONDS = 2 * 1000; +const static long TEN_SECONDS = 10 * 1000; +const static long THIRTY_MINUTES = 30 * 60 * 1000; +const static long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : THIRTY_MINUTES; + +enum class RefreshHandlerType { + MSG_FLUSH_TO_DISK = 1, +}; + +enum class DatabaseFile { + MSG_FLUSH_TO_DISK = 1, +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_CONSTANT_H \ No newline at end of file diff --git a/services/common/include/bundle_active_continuous_task_observer.h b/services/common/include/bundle_active_continuous_task_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..6bb1430acc25787888185d01f1d5ea001035afc4 --- /dev/null +++ b/services/common/include/bundle_active_continuous_task_observer.h @@ -0,0 +1,59 @@ +/* + * 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_CONTINUOUS_TASK_H +#define BUNDLE_ACTIVE_CONTINUOUS_TASK_H + +#include +#include + +#include "continuous_task_dummy.h" + +namespace OHOS { +namespace DeviceUsageStats { +using OHOS::BackgroundTaskMgr::ContinuousTaskEventSubscriber; +using OHOS::BackgroundTaskMgr::ContinuousTaskConstant; +using OHOS::BackgroundTaskMgr::ContinuousTaskEventData; + +class BundleActiveContinuousTaskObserver : public ContinuousTaskEventSubscriber { +public: + ContinuousTaskObserver() {}; + ~ContinuousTaskObserver() {}; + + void OnSubscribeResult(ContinuousTaskConstant::SubscribeResult result); + void OnUnsubscribeResult(ContinuousTaskConstant::SubscribeResult result); + void OnContinuousTaskStart(const std::shared_ptr &eventData); + void OnContinuousTaskCancel(const std::shared_ptr &eventData); + void OnDied(); + +private: + void HandleContinuousTaskStart(uid_t uid, pid_t pid, std::string abilityName); + void HandleContinuousTaskCancel(uid_t uid, pid_t pid, std::string abilityName); + + inline bool ValidateTransientTaskAppInfo(const std::shared_ptr& eventData) const + { + return eventData->GetCreatorUid() > 0 && eventData->GetCreatorPid() >= 0 + && eventData->GetAbilityName().size() > 0; + } + + inline std::string PackPayload(const std::shared_ptr& eventData) const + { + return std::to_string(eventData->GetCreatorPid()) + "," + + std::to_string(eventData->GetCreatorUid()) + "," + + eventData->GetAbilityName(); + } +}; +} +} \ No newline at end of file diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h new file mode 100644 index 0000000000000000000000000000000000000000..321ba811c02258fb145565e65c498deb6e0ebe89 --- /dev/null +++ b/services/common/include/bundle_active_core.h @@ -0,0 +1,95 @@ +/* + * 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_CORE_H +#define BUNDLE_ACTIVE_CORE_H + +#include + +#include "power_mgr_client.h" +#include "os_account_manager.h" + +#include "ibundle_active_service.h" +#include "bundle_active_stats_update_listener.h" +#include "bundle_active_user_service.h" +#include "bundle_active_group_controller.h" +#include "bundle_active_group_handler.h" +#include "bundle_active_common_event_subscriber.h" +#include "bundle_active_constant.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveReportHandlerObject { +public: + BundleActiveEvent event_; + int userId_; + std::string bundleName_; + BundleActiveReportHandlerObject() {}; + BundleActiveReportHandlerObject(const BundleActiveReportHandlerObject& orig); + ~BundleActiveReportHandlerObject() {}; +}; + +class BundleActiveReportHandler; + +class BundleActiveCore : public BundleActiveStatsUpdateListener { +public: + BundleActiveCore(); + virtual ~BundleActiveCore(); + int ReportEvent(BundleActiveEvent& event, const int& userId); + int ReportEventToAllUserId(BundleActiveEvent& event); + void OnStatsChanged() override; + void OnStatsReload() override; + void OnSystemUpdate(int userId) override; + void OnBundleUninstalled(const int& userId, const std::string& bundleName); + void Init(); + void InitBundleGroupController(); + void SetHandler(const std::shared_ptr& reportHandler); + void RestoreToDatabase(); + void ShutDown(); + std::vector QueryPackageStats(const int& userId, const int& intervalType, + const int64_t& beginTime, const int64_t& endTime, std::string bundleName); + std::vector QueryEvents(const int& userId, const int64_t& beginTime, + const int64_t& endTime, std::string bundleName); + int IsBundleIdle(const std::string& bundleName, const int& userId); + int QueryPackageGroup(const int& userId, const std::string bundleName); + int64_t CheckTimeChangeAndGetWallTime(); + void ConvertToSystemTimeLocked(BundleActiveEvent& event); + std::shared_ptr GetUserDataAndInitializeIfNeeded(const int& userId, + const int64_t& timeStamp); + void OnUserRemoved(const int& userId); + void RestoreToDatabaseLocked(); + void SetBundleGroup(const std::string& bundleName, const int& newGroup, const int& userId); + void GetAllActiveUser(std::vector &osAccountInfos); + void UnRegisterSubscriber(); + +private: + static const int64_t FLUSH_INTERVAL = THIRTY_MINUTES; + static const int64_t TIME_CHANGE_THRESHOLD_MILLIS = TWO_SECONDS; + const int DEFAULT_USER_ID = -1; + // use weak_ptr to avoid circulate reference of core and handler. + std::map visibleActivities_; + std::weak_ptr handler_; + std::shared_ptr bundleGroupController_; + std::shared_ptr bundleGroupHandler_; + int64_t systemTimeShot_; + int64_t realTimeShot_; + std::mutex mutex_; + std::map> userStatServices_; + void RegisterSubscriber(); + std::shared_ptr commonEventSubscriber_; +}; +} +} +#endif diff --git a/services/include/bundle_active_log.h b/services/common/include/bundle_active_log.h similarity index 96% rename from services/include/bundle_active_log.h rename to services/common/include/bundle_active_log.h index 49aa5b8ae4eb98fafe8eadebf61160e5b8821581..d2056ed9be501c14e76f70e5a8a272eb00499274 100644 --- a/services/include/bundle_active_log.h +++ b/services/common/include/bundle_active_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 diff --git a/services/common/include/bundle_active_open_callback.h b/services/common/include/bundle_active_open_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..235c8d488384df48fef11184e320c3a66bc33b10 --- /dev/null +++ b/services/common/include/bundle_active_open_callback.h @@ -0,0 +1,35 @@ +/* + * 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_OPEN_CALLBACK_H +#define BUNDLE_ACTIVE_OPEN_CALLBACK_H + +#include + +#include "rdb_open_callback.h" +#include "rdb_errno.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveOpenCallback : public NativeRdb::RdbOpenCallback { +public: + BundleActiveOpenCallback(); + ~BundleActiveOpenCallback(); + int32_t OnCreate(NativeRdb::RdbStore &rdbStore) override; + int32_t OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override; +}; +} +} +#endif \ No newline at end of file diff --git a/services/include/bundle_active_service.h b/services/common/include/bundle_active_refresh_database_handler.h similarity index 43% rename from services/include/bundle_active_service.h rename to services/common/include/bundle_active_refresh_database_handler.h index 44a9eb6c6bff0e00cfb1460ddd3a1397a5943f1a..0bf1c0e33e78416581f498301237b1740b1b2d1b 100644 --- a/services/include/bundle_active_service.h +++ b/services/common/include/bundle_active_refresh_database_handler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,29 +13,29 @@ * limitations under the License. */ -#ifndef BUNDLE_ACTIVE_SERVICE_H -#define BUNDLE_ACTIVE_SERVICE_H +#ifndef BUNDLE_ACTIVE_REFRESH_DATABASE_HANDLER_H +#define BUNDLE_ACTIVE_REFRESH_DATABASE_HANDLER_H + +#include "event_handler.h" #include "ibundle_active_service.h" #include "bundle_active_stub.h" namespace OHOS { -namespace BundleActive { -class BundleActiveService : public SystemAbility, public BundleActiveStub { - DECLARE_SYSTEM_ABILITY(BundleActiveService); +namespace DeviceUsageStats { +using namespace AppExecFwk; +class RefreshDatabaseHandler : public EventHandler { public: - int ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) override; - int IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) override; - int Query(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) override; - BundleActiveService(int32_t systemAbilityId, int runOnCreate) - : SystemAbility(systemAbilityId, runOnCreate) {} - ~BundleActiveService() {} + explicit RefreshDatabaseHandler(const std::shared_ptr &runner); + ~RefreshDatabaseHandler() = default; -protected: - void OnStart() override; - void OnStop() override; + /** + * Process the event. Developers should override this method. + * + * @param event The event should be processed. + */ + void ProcessEvent(const InnerEvent::Pointer &event) override; }; } } diff --git a/services/common/include/bundle_active_service.h b/services/common/include/bundle_active_service.h new file mode 100644 index 0000000000000000000000000000000000000000..6bc07f342b549c250a7a783859548d6995a5f243 --- /dev/null +++ b/services/common/include/bundle_active_service.h @@ -0,0 +1,74 @@ +/* + * 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_SERVICE_H +#define BUNDLE_ACTIVE_SERVICE_H + +#include "bundle_mgr_interface.h" +#include "os_account_manager.h" + +#include "ibundle_active_service.h" +#include "bundle_active_stub.h" +#include "bundle_active_core.h" +#include "bundle_active_report_handler.h" +#include "bundle_active_shutdown_callback_service.h" +#include "bundle_active_app_state_observer.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveService : public SystemAbility, public BundleActiveStub { + DECLARE_SYSTEM_ABILITY(BundleActiveService); +public: + using IBundleMgr = OHOS::AppExecFwk::IBundleMgr; + using ApplicationInfo = OHOS::AppExecFwk::ApplicationInfo; + using BundleInfo = OHOS::AppExecFwk::BundleInfo; + using BundleFlag = OHOS::AppExecFwk::BundleFlag; + int ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) override; + bool IsBundleIdle(const std::string& bundleName) override; + std::vector QueryPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime) override; + std::vector QueryEvents(const int64_t& beginTime, const int64_t& endTime) override; + void SetBundleGroup(const std::string& bundleName, int newGroup, int userId) override; + std::vector QueryCurrentPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime) override; + std::vector QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime) override; + int QueryPackageGroup() override; + BundleActiveService(int32_t systemAbilityId, int runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate) {} + ~BundleActiveService() {} + +protected: + void OnStart() override; + void OnStop() override; + void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; + +private: + std::shared_ptr bundleActiveCore_; + std::shared_ptr reportHandler_; + std::shared_ptr appStateObserver_; + sptr sptrBundleMgr_; + sptr shutdownCallback_; + int ConvertIntervalType(const int& intervalType); + bool GetBundleMgrProxy(); + bool CheckBundleIsSystemAppAndHasPermission(const int& uid, const int& userId); + void InitAppStateSubscriber(const std::shared_ptr& reportHandler); + bool SubscribeAppState(const std::shared_ptr& reportHandler); + OHOS::sptr GetAppManagerInstance(); +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_user_service.h b/services/common/include/bundle_active_shutdown_callback_proxy.h similarity index 42% rename from services/common/include/bundle_active_user_service.h rename to services/common/include/bundle_active_shutdown_callback_proxy.h index 0f9bba30d61e3d4cc4253758608c780be7058846..b62c001ff1afe424cf02cda32595021ec94388bc 100644 --- a/services/common/include/bundle_active_user_service.h +++ b/services/common/include/bundle_active_shutdown_callback_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,31 +13,25 @@ * limitations under the License. */ -#ifndef BUNDLE_ACTIVE_USER_SERVICE_H -#define BUNDLE_ACTIVE_USER_SERVICE_H +#ifndef BUNDLE_ACTIVE_SHUTDOWN_CALLBACK_PROXY_H +#define BUNDLE_ACTIVE_SHUTDOWN_CALLBACK_PROXY_H #include "ibundle_active_service.h" -#include "bundle_active_event.h" -#include "bundle_active_package_stats.h" -#include "bundle_active_period_stats.h" -#include "bundle_active_event_stats.h" +#include "ishutdown_callback.h" +#include "nocopyable.h" namespace OHOS { -namespace BundleActive { -class BundleActiveUserService { +namespace DeviceUsageStats { +using IShutdownCallback = OHOS::PowerMgr::IShutdownCallback; +class BundleActiveShutdownCallbackProxy : public IRemoteProxy { public: - BundleActiveUserService(int userId); + explicit BundleActiveShutdownCallbackProxy(const sptr& impl) + : IRemoteProxy(impl) {} + ~BundleActiveShutdownCallbackProxy() = default; + DISALLOW_COPY_AND_MOVE(BundleActiveShutdownCallbackProxy); + void ShutdownCallback() override; private: - int incrementBundleLaunch_; - int userId_; - std::vector currentStats_; - bool statsChanged_; - std::string lastBackgroundBundle_; - inline static const std::vector PERIOD_LENGTH = {BundleActivePeriodStats::DAY_IN_MILLIS, - BundleActivePeriodStats::WEEK_IN_MILLIS, BundleActivePeriodStats::MONTH_IN_MILLIS, - BundleActivePeriodStats::YEAR_IN_MILLIS}; - void NotifyStatsChanged(); - void ReportEvent(BundleActiveEvent event); + static inline BrokerDelegator delegator_; }; } } diff --git a/services/common/include/bundle_active_shutdown_callback_service.h b/services/common/include/bundle_active_shutdown_callback_service.h new file mode 100644 index 0000000000000000000000000000000000000000..b31387302c3d726e1ae338568439f6628f6cd094 --- /dev/null +++ b/services/common/include/bundle_active_shutdown_callback_service.h @@ -0,0 +1,34 @@ + /* + * 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_SHUTDOWN_CALLBACK_SERVICE_H +#define BUNDLE_ACTIVE_SHUTDOWN_CALLBACK_SERVICE_H + +#include "bundle_active_shutdown_callback_stub.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveShutdownCallbackService : public BundleActiveShutdownCallbackStub { +public: + BundleActiveShutdownCallbackService(std::shared_ptr bundleActiveCore); + virtual ~BundleActiveShutdownCallbackService() {}; + void ShutdownCallback() override; +private: + std::shared_ptr bundleActiveCore_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_shutdown_callback_stub.h b/services/common/include/bundle_active_shutdown_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..e0c110fea242dd9f2b7a43fc94a837f4923424da --- /dev/null +++ b/services/common/include/bundle_active_shutdown_callback_stub.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_SHUTDOWN_CALLBACK_STUB_H +#define BUNDLE_ACTIVE_SHUTDOWN_CALLBACK_STUB_H + +#include "ishutdown_callback.h" +#include "nocopyable.h" + +#include "ibundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +using IShutdownCallback = OHOS::PowerMgr::IShutdownCallback; +class BundleActiveShutdownCallbackStub : public IRemoteStub { +public: + DISALLOW_COPY_AND_MOVE(BundleActiveShutdownCallbackStub); + BundleActiveShutdownCallbackStub() = default; + virtual ~BundleActiveShutdownCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, MessageOption &option) override; +private: + void ShutdownStub(); +}; +} +} + +#endif \ No newline at end of file diff --git a/services/include/bundle_active_stub.h b/services/common/include/bundle_active_stub.h similarity index 85% rename from services/include/bundle_active_stub.h rename to services/common/include/bundle_active_stub.h index c8e758c4825d42a6c73288d903881c0127aee581..596fb3cb1c95ee01b320fcfc5742c9abf551b800 100644 --- a/services/include/bundle_active_stub.h +++ b/services/common/include/bundle_active_stub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -19,15 +19,14 @@ #include "ibundle_active_service.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveStub : public IRemoteStub { public: - virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, MessageOption &option) override; - -public: + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) override; BundleActiveStub() {}; ~BundleActiveStub() {}; }; } } -#endif +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_usage_database.h b/services/common/include/bundle_active_usage_database.h new file mode 100644 index 0000000000000000000000000000000000000000..e6fd71e1bddf69dd262e38a3b678a20f322bd0e3 --- /dev/null +++ b/services/common/include/bundle_active_usage_database.h @@ -0,0 +1,99 @@ +/* + * 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_USAGE_DATABASE_H +#define BUNDLE_ACTIVE_USAGE_DATABASE_H + +#include +#include +#include + +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" +#include "rdb_store.h" +#include "rdb_store_config.h" +#include "result_set.h" +#include "values_bucket.h" + +#include "bundle_active_period_stats.h" +#include "bundle_active_calendar.h" +#include "bundle_active_package_history.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveUsageDatabase { +public: + BundleActiveUsageDatabase(); + ~BundleActiveUsageDatabase(); + void InitDatabaseTableInfo(int64_t currentTime); + void InitUsageGroupInfo(int32_t databaseType); + void UpdateUsageData(int32_t databaseType, BundleActivePeriodStats &stats); + std::shared_ptr GetCurrentUsageData(int32_t databaseType, int userId); + void RenewTableTime(int64_t timeDiffMillis); + int32_t GetOptimalIntervalType(int64_t beginTime, int64_t endTime); + void RemoveOldData(int64_t currentTime); + std::vector QueryDatabaseUsageStats(int32_t databaseType, int64_t beginTime, + int64_t endTime, int userId); + std::vector QueryDatabaseEvents(int64_t beginTime, int64_t endTime, int userId, + std::string bundleName); + void PutDurationData(int64_t bootBasedDuration, int64_t screenOnDuration); + std::pair GetDurationData(); + void PutBundleHistoryData(int userId, std::shared_ptr>> userHistory); + std::shared_ptr>> + GetBundleHistoryData(int userId); + void OnPackageUninstalled(const int& userId, const std::string& bundleName); + +private: + void CheckDatabaseVersion(); + void HandleTableInfo(unsigned int databaseType); + std::shared_ptr GetBundleActiveRdbStore(unsigned int databaseType); + int64_t ParseStartTime(const std::string &tableName); + int32_t NearIndexOnOrAfterCurrentTime(int64_t currentTime, std::vector sortedTableArray); + int32_t NearIndexOnOrBeforeCurrentTime(int64_t currentTime, std::vector sortedTableArray); + int32_t RenameTableName(unsigned int databaseType, int64_t tableOldTime, int64_t tableNewTime); + std::string GetTableIndexSql(unsigned int databaseType, int64_t tableTime, bool createFlag); + void FlushPackageInfo(unsigned int databaseType, const BundleActivePeriodStats &stats); + void FlushEventInfo(unsigned int databaseType, BundleActivePeriodStats &stats); + void DeleteExcessiveTableData(unsigned int databaseType); + int32_t DeleteInvalidTable(unsigned int databaseType, int64_t tableTimeMillis); + std::vector GetOverdueTableCreateTime(unsigned int databaseType, int64_t currentTimeMillis); + int32_t CreatePackageLogTable(unsigned int databaseType, int64_t currentTimeMillis); + int32_t CreateEventLogTable(unsigned int databaseType, int64_t currentTimeMillis); + int32_t CreateDurationTable(unsigned int databaseType); + int32_t CreateBundleHistoryTable(unsigned int databaseType); + std::unique_ptr QueryStatsInfoByStep(unsigned int databaseType, + const std::string &sql, const std::vector &selectionArgs); + void DeleteUninstalledInfo(const int& userId, const std::string& bundleName, const std::string& tableName, + unsigned int databaseType); + +private: + std::vector databaseFiles_; + std::vector> sortedTableArray_; + std::map> bundleActiveRdbStoreCache_; + std::shared_ptr calendar_; + std::string eventTableName_; + std::string durationTableName_; + std::string bundleHistoryTableName_; + std::string versionDirectoryPath_; + std::string versionFile_; + uint32_t currentVersion_; + std::mutex databaseMutex_; + std::int64_t eventBeginTime_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/include/ibundle_active_service.h b/services/common/include/ibundle_active_service.h similarity index 51% rename from services/include/ibundle_active_service.h rename to services/common/include/ibundle_active_service.h index 68bca28e35b60839d4e73c3e28c898dc4fd8bac2..c175b4fdc3557ed752f33628dfeebf510217a6dd 100644 --- a/services/include/ibundle_active_service.h +++ b/services/common/include/ibundle_active_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -22,31 +22,48 @@ #include #include #include -#include "bundle_active_log.h" +#include + #include "iremote_broker.h" #include "iremote_stub.h" #include "iremote_proxy.h" #include "iremote_object.h" +#include "ipc_skeleton.h" #include "system_ability.h" #include "system_ability_definition.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" +#include "bundle_active_log.h" + namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { +class BundleActivePackageStats; +class BundleActiveEvent; class IBundleActiveService : public IRemoteBroker { public: - virtual int ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) = 0; - virtual int IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) = 0; - virtual int Query(std::string& bundleName, std::string& abilityName, const int& abilityId, const int& userId) = 0; + virtual int ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) = 0; + virtual bool IsBundleIdle(const std::string& bundleName) = 0; + virtual std::vector QueryPackageStats(const int& intervalType, const int64_t& beginTime, + const int64_t& endTime) = 0; + virtual std::vector QueryEvents(const int64_t& beginTime, const int64_t& endTime) = 0; + virtual std::vector QueryCurrentPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) = 0; + virtual std::vector QueryCurrentEvents(const int64_t& beginTime, const int64_t& endTime) = 0; + virtual int QueryPackageGroup() = 0; + virtual void SetBundleGroup(const std::string& bundleName, int newGroup, int userId) = 0; public: enum { REPORT_EVENT = 1, IS_BUNDLE_IDLE = 2, - QUERY = 3, + QUERY_USAGE_STATS = 3, + QUERY_EVENTS = 4, + QUERY_CURRENT_USAGE_STATS = 5, + QUERY_CURRENT_EVENTS = 6, + QUERY_BUNDLE_GROUP = 7, + SET_BUNDLE_GROUP = 8 }; public: DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveService"); diff --git a/services/common/src/bundle_active_app_state_obsever.cpp b/services/common/src/bundle_active_app_state_obsever.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9729ef1fec9727bd09f7df764fe561c9ed1e7ebc --- /dev/null +++ b/services/common/src/bundle_active_app_state_obsever.cpp @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#include +#include + +#include "time_service_client.h" + +#include "bundle_active_app_state_observer.h" +#include "bundle_active_report_handler.h" +#include "bundle_active_event.h" + +namespace OHOS { +namespace DeviceUsageStats { +void BundleActiveAppStateObserver::Init(const std::shared_ptr& reportHandler) +{ + if (reportHandler != nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveAppStateObserver::Init report handler is not null, init success"); + reportHandler_ = reportHandler; + } +} + +void BundleActiveAppStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData) +{ + +} + +void BundleActiveAppStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData) +{ + if (!ValidateAbilityStateData(abilityStateData)) { + BUNDLE_ACTIVE_LOGI("%{public}s : validate ability state data failed!", __func__); + return; + } + int userId = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(abilityStateData.uid, userId); + if (ret == ERR_OK && userId != -1) { + std::stringstream stream; + stream << abilityStateData.token.GetRefPtr(); + std::string abilityId = stream.str(); + BundleActiveReportHandlerObject tmpHandlerObject; + tmpHandlerObject.event_.bundleName_ = abilityStateData.bundleName; + tmpHandlerObject.event_.abilityName_ = abilityStateData.abilityName; + tmpHandlerObject.event_.abilityId_ = abilityStateData.abilityName; + tmpHandlerObject.event_.longTimeTaskName_ = ""; + tmpHandlerObject.userId_ = userId; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs(); + switch (abilityStateData.abilityState) { + case static_cast(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND): + tmpHandlerObject.event_.eventId_ = BundleActiveEvent::ABILITY_FOREGROUND; + break; + case static_cast(AppExecFwk::AbilityState::ABILITY_STATE_BACKGROUND): + tmpHandlerObject.event_.eventId_ = BundleActiveEvent::ABILITY_BACKGROUND; + break; + case static_cast(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED): + tmpHandlerObject.event_.eventId_ = BundleActiveEvent::ABILITY_STOP; + break; + default: + return; + } + BUNDLE_ACTIVE_LOGI("OnAbilityStateChangeduser id is %{public}d, bundle name is %{public}s, " + "ability name is %{public}s, ability id is %{public}s, event id is %{public}d," + "uid is %{public}d, pid is %{public}d", + tmpHandlerObject.userId_, tmpHandlerObject.event_.bundleName_.c_str(), + tmpHandlerObject.event_.abilityName_.c_str(), abilityId.c_str(), tmpHandlerObject.event_.eventId_, + abilityStateData.uid, abilityStateData.pid); + if (reportHandler_ != nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveAppStateObserver::OnAbilityStateChanged handler not null, SEND"); + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpHandlerObject); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_REPORT_EVENT, handlerobjToPtr); + reportHandler_->SendEvent(event); + } + } + return; +} + +void BundleActiveAppStateObserver::OnExtensionStateChanged(const AbilityStateData &abilityStateData) +{ + +} + +void BundleActiveAppStateObserver::OnProcessCreated(const ProcessData &processData) +{ + +} + +void BundleActiveAppStateObserver::OnProcessDied(const ProcessData &processData) +{ + +} + +void BundleActiveAppStateObserver::OnApplicationStateChanged(const AppStateData &appStateData) +{ + +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_binary_search.cpp b/services/common/src/bundle_active_binary_search.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b284d8426f62c1e2ce3ed70ab6a62b9c1a011cd --- /dev/null +++ b/services/common/src/bundle_active_binary_search.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_binary_search.h" +#include "bundle_active_log.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveBinarySearch::BundleActiveBinarySearch() +{ +} + +BundleActiveBinarySearch::~BundleActiveBinarySearch() +{ +} + +int32_t BundleActiveBinarySearch::BinarySearch(const std::vector &tableNameArray, int64_t targetValue) +{ + int32_t low = 0; + int32_t high = tableNameArray.size() - 1; + while (low <= high) { + int32_t mid = (low + high) >> 1; + int64_t midValue = tableNameArray.at(mid); + if (midValue < targetValue) { + low = mid + 1; + } else if (midValue > targetValue) { + high = mid - 1; + } else { + return mid; + } + } + return ~low; +} +} +} \ No newline at end of file diff --git a/interfaces/innerkits/.gitkeep b/services/common/src/bundle_active_continuous_task_observer.cpp similarity index 100% rename from interfaces/innerkits/.gitkeep rename to services/common/src/bundle_active_continuous_task_observer.cpp diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..584dce3c6e6dbb0986754dacba8716a27c2760eb --- /dev/null +++ b/services/common/src/bundle_active_core.cpp @@ -0,0 +1,428 @@ +/* + * 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 "time_service_client.h" + +#include "bundle_active_event.h" +#include "bundle_active_report_handler.h" +#include "bundle_active_group_common.h" +#include "bundle_active_constant.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveReportHandlerObject::BundleActiveReportHandlerObject(const BundleActiveReportHandlerObject& orig) +{ + event_.bundleName_ = orig.event_.bundleName_; + event_.abilityName_ = orig.event_.abilityName_; + event_.abilityId_ = orig.event_.abilityId_; + event_.timeStamp_ = orig.event_.timeStamp_; + event_.eventId_ = orig.event_.eventId_; + event_.isidle_ = orig.event_.isidle_; + userId_ = orig.userId_; + bundleName_ = orig.bundleName_; +} + +BundleActiveCore::BundleActiveCore() +{ +} + +BundleActiveCore::~BundleActiveCore() +{ +} + +void BundleActiveCommonEventSubscriber::OnReceiveEvent(const CommonEventData &data) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCommonEventSubscriber::OnReceiveEvent called"); + std::string action = data.GetWant().GetAction(); + BUNDLE_ACTIVE_LOGI("BundleActiveCommonEventSubscriber::OnReceiveEvent action is %{public}s", action.c_str()); + auto want = data.GetWant(); + if (action == CommonEventSupport::COMMON_EVENT_SCREEN_OFF || + action == CommonEventSupport::COMMON_EVENT_SCREEN_ON) { + if (!activeGroupController_.expired()) { + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + bool isScreenOn = activeGroupController_.lock()->IsScreenOn(); + BUNDLE_ACTIVE_LOGI("BundleActiveCommonEventSubscriber::OnReceiveEvent Screen state changed " + "received, screen state chante to %{public}d", isScreenOn); + activeGroupController_.lock()->OnScreenChanged(isScreenOn, timer->GetBootTimeMs()); + } + } else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) { + if (!bundleActiveReportHandler_.expired()) { + int32_t userId = data.GetWant().GetIntParam("userId", 0); + BundleActiveReportHandlerObject tmpHandlerObject; + tmpHandlerObject.userId_ = userId; + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpHandlerObject); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_REMOVE_USER, handlerobjToPtr); + bundleActiveReportHandler_.lock()->SendEvent(event); + } + } else if (action == CommonEventSupport::COMMON_EVENT_USER_ADDED) { + int32_t userId = data.GetWant().GetIntParam("userId", 0); + BUNDLE_ACTIVE_LOGI("BundleActiveCommonEventSubscriber::OnReceiveEvent receive add user event"); + if (!activeGroupController_.expired() && userId >= 0) { + activeGroupController_.lock()->PeriodCheckBundleState(userId); + } + } else if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED || + action == CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED) { + int32_t userId = data.GetWant().GetIntParam("userId", 0); + std::string bundleName = data.GetWant().GetElement().GetBundleName(); + BUNDLE_ACTIVE_LOGI("action is %{public}s", action.c_str()); + if (!bundleActiveReportHandler_.expired()) { + BundleActiveReportHandlerObject tmpHandlerObject; + tmpHandlerObject.bundleName_ = bundleName; + tmpHandlerObject.userId_ = userId; + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpHandlerObject); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_BUNDLE_UNINSTALLED, + handlerobjToPtr); + bundleActiveReportHandler_.lock()->SendEvent(BundleActiveReportHandler::MSG_BUNDLE_UNINSTALLED); + } + } +} + +void BundleActiveCore::RegisterSubscriber() +{ + MatchingSkills matchingSkills; + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_OFF); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_ON); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_ADDED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BUNDLE_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_FULLY_REMOVED); + 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); +} + +void BundleActiveCore::UnRegisterSubscriber() +{ + CommonEventManager::UnSubscribeCommonEvent(commonEventSubscriber_); +} + +void BundleActiveCore::Init() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::Init called"); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + do { + realTimeShot_ = timer->GetBootTimeMs(); + systemTimeShot_ = timer->GetWallTimeMs(); + } while (realTimeShot_ == -1 && systemTimeShot_ == -1); + realTimeShot_ = timer->GetBootTimeMs(); + systemTimeShot_ = timer->GetWallTimeMs(); + bundleGroupController_ = std::make_shared(); + BUNDLE_ACTIVE_LOGI("GGG, system time shot is %{public}lld", systemTimeShot_); +} + +void BundleActiveCore::InitBundleGroupController() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::InitBundleGroupController called"); + std::string threadName = "bundle_active_group_handler"; + auto runner = AppExecFwk::EventRunner::Create(threadName); + if (runner == nullptr) { + BUNDLE_ACTIVE_LOGE("report handler is null"); + return; + } + bundleGroupHandler_ = std::make_shared(runner); + if (bundleGroupHandler_ == nullptr) { + return; + } + if (bundleGroupController_ != nullptr && bundleGroupHandler_ != nullptr) { + bundleGroupHandler_->Init(bundleGroupController_); + bundleGroupController_->SetHandlerAndCreateUserHistory(bundleGroupHandler_, realTimeShot_); + BUNDLE_ACTIVE_LOGI("BundleActiveCore::Init Set group controller and handler done"); + } + RegisterSubscriber(); + std::vector osAccountInfos; + GetAllActiveUser(osAccountInfos); + bundleGroupController_->bundleGroupEnable_ = true; + for (int i = 0; i < osAccountInfos.size(); i++) { + bundleGroupController_->PeriodCheckBundleState(osAccountInfos[i].GetLocalId()); + } +} + +void BundleActiveCore::SetHandler(const std::shared_ptr& reportHandler) +{ + handler_ = reportHandler; +} + +std::shared_ptr BundleActiveCore::GetUserDataAndInitializeIfNeeded(const int& userId, + const int64_t& timeStamp) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::GetUserDataAndInitializeIfNeeded called"); + std::map>::iterator it = userStatServices_.find(userId); + if (it == userStatServices_.end()) { + BUNDLE_ACTIVE_LOGI("first initialize user service"); + std::shared_ptr service = std::make_shared(userId, *this); + service->Init(timeStamp); + userStatServices_[userId] = service; + if (service == nullptr) { + BUNDLE_ACTIVE_LOGI("service is null"); + } + BUNDLE_ACTIVE_LOGI("service is not null"); + return service; + } + return it->second; +} +void BundleActiveCore::OnBundleUninstalled(const int& userId, const std::string& bundleName) +{ + std::lock_guard lock(mutex_); + int64_t timeNow = CheckTimeChangeAndGetWallTime(); + auto service = GetUserDataAndInitializeIfNeeded(userId, timeNow); + service->DeleteUninstalledBundleStats(bundleName); +} + +void BundleActiveCore::OnStatsChanged() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::OnStatsChanged called"); + auto event = AppExecFwk::InnerEvent::Get(BundleActiveReportHandler::MSG_FLUSH_TO_DISK); + if (!handler_.expired()) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::OnStatsChanged send flush to disk event"); + handler_.lock()->SendEvent(event, FLUSH_INTERVAL); + } +} + +void BundleActiveCore::RestoreToDatabase() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::RestoreToDatabase called"); + std::lock_guard lock(mutex_); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + BundleActiveEvent event; + event.eventId_ = BundleActiveEvent::FLUSH; + event.timeStamp_ = timer->GetBootTimeMs(); + event.abilityId_ = ""; + ReportEventToAllUserId(event); + RestoreToDatabaseLocked(); +} + +void BundleActiveCore::RestoreToDatabaseLocked() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::RestoreToDatabaseLocked called"); + for (std::map>::iterator it = userStatServices_.begin(); + it != userStatServices_.end(); it++) { + std::shared_ptr service = it->second; + if (service == nullptr) { + BUNDLE_ACTIVE_LOGI("service in BundleActiveCore::RestoreToDatabaseLocked() is null"); + } + BUNDLE_ACTIVE_LOGI("userid is %{public}d ", service->userId_); + service->RestoreStats(); + if (bundleGroupController_ != nullptr && bundleGroupController_->bundleUserHistory_ != nullptr) { + bundleGroupController_->RestoreToDatabase(it->first); + } + } + if (bundleGroupController_ != nullptr) { + bundleGroupController_->RestoreDurationToDatabase(); + } + if (!handler_.expired()) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::RestoreToDatabaseLocked remove flush to disk event"); + handler_.lock()->RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK); + } +} + +void BundleActiveCore::ShutDown() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::ShutDown called"); + std::lock_guard lock(mutex_); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t timeStamp = timer->GetBootTimeMs(); + BundleActiveEvent event(BundleActiveEvent::SHUTDOWN, timeStamp); + event.bundleName_ = BundleActiveEvent::DEVICE_EVENT_PACKAGE_NAME; + bundleGroupController_->ShutDown(timeStamp); + ReportEventToAllUserId(event); + RestoreToDatabaseLocked(); +} + +void BundleActiveCore::OnStatsReload() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::OnStatsReload called"); + bundleGroupController_->CheckIdleStatsOneTime(); +} + +void BundleActiveCore::OnSystemUpdate(int userId) +{ +} + +int64_t BundleActiveCore::CheckTimeChangeAndGetWallTime() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::CheckTimeChangeAndGetWallTime called"); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t actualSystemTime = timer->GetWallTimeMs(); + int64_t actualRealTime = timer->GetBootTimeMs(); + int64_t expectedSystemTime = (actualRealTime - realTimeShot_) + systemTimeShot_; + int64_t diffSystemTime = actualSystemTime - expectedSystemTime; + if (std::abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) { + // 时区变换逻辑 + BUNDLE_ACTIVE_LOGI("time changed!"); + for (std::map>::iterator it = userStatServices_.begin(); + it != userStatServices_.end(); it++) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::CheckTimeChangeAndGetWallTime in update time loop"); + std::shared_ptr service = it->second; + service->RenewTableTime(expectedSystemTime, actualSystemTime); + } + realTimeShot_ = actualRealTime; + systemTimeShot_ = actualSystemTime; + } + return actualSystemTime; +} + +void BundleActiveCore::ConvertToSystemTimeLocked(BundleActiveEvent& event) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::ConvertToSystemTimeLocked called"); + event.timeStamp_ = std::max((int64_t)0, event.timeStamp_ - realTimeShot_) + systemTimeShot_; +} + +void BundleActiveCore::OnUserRemoved(const int& userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::OnUserRemoved called"); + std::lock_guard lock(mutex_); + auto it = userStatServices_.find(userId); + if (it == userStatServices_.end()) { + return; + } + userStatServices_[userId].reset(); + userStatServices_.erase(userId); + bundleGroupController_->OnUserRemoved(userId); +} + +int BundleActiveCore::ReportEvent(BundleActiveEvent& event, const int& userId) +{ + std::lock_guard lock(mutex_); + BUNDLE_ACTIVE_LOGI("BundleActiveCore::ReportEvent called"); + BUNDLE_ACTIVE_LOGI("report event called bundle name %{public}s time %{public}lld userId %{public}d, " + "eventid %{public}d, in lock range", event.bundleName_.c_str(), event.timeStamp_, userId, event.eventId_); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t timeNow = CheckTimeChangeAndGetWallTime(); + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + ConvertToSystemTimeLocked(event); + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(userId, timeNow); + if (service == nullptr) { + BUNDLE_ACTIVE_LOGE("get user data service failed!"); + return -1; + } + service->ReportEvent(event); + bundleGroupController_->ReportEvent(event, bootBasedTimeStamp, userId); + return 0; +} + +int BundleActiveCore::ReportEventToAllUserId(BundleActiveEvent& event) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::ReportEventToAllUserId called"); + int64_t timeNow = CheckTimeChangeAndGetWallTime(); + if (userStatServices_.empty()) { + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(DEFAULT_USER_ID, timeNow); + } + for (std::map>::iterator it = userStatServices_.begin(); + it != userStatServices_.end(); it++) { + ConvertToSystemTimeLocked(event); + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(it->first, timeNow); + if (service == nullptr) { + BUNDLE_ACTIVE_LOGE("get user data service failed!"); + return -1; + } + BUNDLE_ACTIVE_LOGI("BundleActiveCore::ReportEventToAllUserId SERVICE user ID IS userId %{public}d", + service->userId_); + service->ReportForFlushAndShutdown(event); + return 0; + } + return 0; +} + +std::vector BundleActiveCore::QueryPackageStats(const int& userId, const int& intervalType, + const int64_t& beginTime, const int64_t& endTime, std::string bundleName) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryPackageStats called"); + std::lock_guard lock(mutex_); + std::vector result; + int64_t timeNow = CheckTimeChangeAndGetWallTime(); + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryPackageStats begin time is %{public}lld, end time is %{public}lld, " + "intervaltype is %{public}d", beginTime, endTime, intervalType); + if (beginTime > timeNow || beginTime >= endTime) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryPackageStats time span illegal"); + return result; + } + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(userId, timeNow); + if (service == nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryPackageStats service is null, failed"); + return result; + } + result = service->QueryPackageStats(intervalType, beginTime, endTime, userId, bundleName); + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryPackageStats result size is %{public}d", result.size()); + for (int i = 0; i < result.size(); i++) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::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(), result[i].lastTimeUsed_, result[i].lastContiniousTaskUsed_, + result[i].totalInFrontTime_, result[i].totalContiniousTaskUsedTime_); + } + return result; +} + +std::vector BundleActiveCore::QueryEvents(const int& userId, const int64_t& beginTime, + const int64_t& endTime, std::string bundleName) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryEvents called"); + std::vector result; + std::lock_guard lock(mutex_); + int64_t timeNow = CheckTimeChangeAndGetWallTime(); + if (beginTime > timeNow || beginTime >= endTime) { + return result; + } + std::shared_ptr service = GetUserDataAndInitializeIfNeeded(userId, timeNow); + if (service == nullptr) { + return result; + } + result = service->QueryEvents(beginTime, endTime, userId, bundleName); + BUNDLE_ACTIVE_LOGI("BundleActiveCore::QueryEvents result is:"); + for (int i = 0; i < result.size(); i++) { + BUNDLE_ACTIVE_LOGI("event id is %{public}d, bundle name is %{public}s, time stamp is %{public}lld", + result[i].eventId_, result[i].bundleName_.c_str(), result[i].timeStamp_); + } + return result; +} + +void BundleActiveCore::SetBundleGroup(const std::string& bundleName, const int& newGroup, const int& userId) +{ + int newReason = GROUP_CONTROL_REASON_FORCED; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + bundleGroupController_->SetBundleGroup(bundleName, userId, newGroup, newReason, bootBasedTimeStamp, false); +} + +int BundleActiveCore::QueryPackageGroup(const int& userId, const std::string bundleName) +{ + return bundleGroupController_->QueryPackageGroup(userId, bundleName); +} + +int BundleActiveCore::IsBundleIdle(const std::string& bundleName, const int& userId) +{ + return bundleGroupController_->IsBundleIdle(bundleName, userId); +} + +void BundleActiveCore::GetAllActiveUser(std::vector &osAccountInfos) +{ + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos); + if (ret != ERR_OK) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::GetAllActiveUser failed"); + return; + } + if (osAccountInfos.size() == 0) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::GetAllActiveUser size is 0"); + return; + } +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_open_callback.cpp b/services/common/src/bundle_active_open_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf951e1f677347ae879b005e4006aebd9c137c67 --- /dev/null +++ b/services/common/src/bundle_active_open_callback.cpp @@ -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. + */ + +#include "bundle_active_open_callback.h" +#include "bundle_active_log.h" +#include "bundle_active_constant.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveOpenCallback::BundleActiveOpenCallback() : NativeRdb::RdbOpenCallback() +{ +}; + +BundleActiveOpenCallback::~BundleActiveOpenCallback() +{ +}; + +int32_t BundleActiveOpenCallback::OnCreate(NativeRdb::RdbStore &rdbStore) +{ + BUNDLE_ACTIVE_LOGI("wangyuanchao FlushDatabase SUCCESS.BundleActiveOpenCallback"); + return NativeRdb::E_OK; +}; + +int32_t BundleActiveOpenCallback::OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) +{ + BUNDLE_ACTIVE_LOGI("FlushDatabase SUCCESS.OnUpgrade"); + return NativeRdb::E_OK; +}; +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/services/common/src/bundle_active_refresh_database_handler.cpp b/services/common/src/bundle_active_refresh_database_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c52850365e8547bca65f6d4555dee27a1590222 --- /dev/null +++ b/services/common/src/bundle_active_refresh_database_handler.cpp @@ -0,0 +1,33 @@ +/* + * 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_refresh_database_handler.h" + +namespace OHOS { +namespace DeviceUsageStats { +RefreshDatabaseHandler::RefreshDatabaseHandler(const std::shared_ptr &runner) : EventHandler(runner) +{ +} + +/** + * Process the event. Developers should override this method. + * + * @param event The event should be processed. + */ +void RefreshDatabaseHandler::ProcessEvent([[maybe_unused]] const InnerEvent::Pointer &event) +{ +} +} // namespace DeviceUsageStats +} // namespace OHOS \ No newline at end of file diff --git a/services/common/src/bundle_active_service.cpp b/services/common/src/bundle_active_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5e8e9d38143d8917fdfe7edffc84423e1b88352 --- /dev/null +++ b/services/common/src/bundle_active_service.cpp @@ -0,0 +1,372 @@ +/* + * 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 "time_service_client.h" +#include "power_mgr_client.h" +#include "unistd.h" +#include "accesstoken_kit.h" +#include "app_mgr_interface.h" + +#include "bundle_active_event.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +static const int PERIOD_BEST_JS = 0; +static const int PERIOD_YEARLY_JS = 4; +static const int PERIOD_BEST_SERVICE = 4; +REGISTER_SYSTEM_ABILITY_BY_ID(BundleActiveService, DEVICE_UASAGE_STATISTICS_SYS_ABILITY_ID, true); +using namespace OHOS::Security::AccessToken; +using AccessTokenKit = OHOS::Security::AccessToken::AccessTokenKit; +const std::string NEEDED_PERMISSION = "ohos.permission.BUNDLE_ACTIVE_INFO"; + +void BundleActiveService::OnStart() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::OnStart() called"); + int ret = Publish(this); + if (!ret) { + BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1907] FAIL."); + return; + } + AddSystemAbilityListener(POWER_MANAGER_SERVICE_ID); + AddSystemAbilityListener(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + AddSystemAbilityListener(APP_MGR_SERVICE_ID); + BUNDLE_ACTIVE_LOGI("[Server] OnStart, Register SystemAbility[1907] SUCCESS."); + return; +} + +void BundleActiveService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::OnAddSystemAbility called, SAID is %{public}d", systemAbilityId); + if (systemAbilityId == POWER_MANAGER_SERVICE_ID) { + if (bundleActiveCore_ == nullptr) { + bundleActiveCore_ = std::make_shared(); + bundleActiveCore_->Init(); + } + if (reportHandler_ == nullptr) { + std::string threadName = "bundle_active_report_handler"; + auto runner = AppExecFwk::EventRunner::Create(threadName); + if (runner == nullptr) { + BUNDLE_ACTIVE_LOGE("report handler is null"); + return; + } + reportHandler_ = std::make_shared(runner); + if (reportHandler_ == nullptr) { + return; + } + reportHandler_->Init(bundleActiveCore_); + } + if (reportHandler_ != nullptr && bundleActiveCore_ != nullptr) { + BUNDLE_ACTIVE_LOGI("core and handler is not null"); + bundleActiveCore_->SetHandler(reportHandler_); + } else { + return; + } + shutdownCallback_ = new BundleActiveShutdownCallbackService(bundleActiveCore_); + auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); + powerManagerClient.RegisterShutdownCallback(shutdownCallback_); + InitAppStateSubscriber(reportHandler_); + } + if (systemAbilityId == APP_MGR_SERVICE_ID) { + if (reportHandler_ != nullptr) { + SubscribeAppState(reportHandler_); + } + } + if (systemAbilityId == BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) { + bundleActiveCore_->InitBundleGroupController(); + } +} + + +OHOS::sptr BundleActiveService::GetAppManagerInstance() +{ + OHOS::sptr systemAbilityManager = + OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + OHOS::sptr object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID); + return OHOS::iface_cast(object); +} + +void BundleActiveService::InitAppStateSubscriber(const std::shared_ptr& reportHandler) +{ + if (appStateObserver_ == nullptr) { + appStateObserver_ = std::make_shared(); + appStateObserver_->Init(reportHandler); + } +} + +bool BundleActiveService::SubscribeAppState(const std::shared_ptr& reportHandler) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::SubscribeAppState called"); + sptr appManager = GetAppManagerInstance(); + if (appStateObserver_ == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveService::SubscribeAppState appstateobserver is null, return"); + return false; + } + int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_.get()); + if (err != 0) { + BUNDLE_ACTIVE_LOGE("RegisterApplicationStateObserver failed. err:%{public}d", err); + appStateObserver_ = nullptr; + return false; + } + BUNDLE_ACTIVE_LOGI("RegisterApplicationStateObserver success."); + return true; +} + +void BundleActiveService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) +{ +} + +void BundleActiveService::OnStop() +{ + if (shutdownCallback_ != nullptr) { + auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); + powerManagerClient.UnRegisterShutdownCallback(shutdownCallback_); + } else { + shutdownCallback_ = new BundleActiveShutdownCallbackService(bundleActiveCore_); + } + auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); + powerManagerClient.UnRegisterShutdownCallback(shutdownCallback_); + bundleActiveCore_->UnRegisterSubscriber(); + BUNDLE_ACTIVE_LOGI("[Server] OnStop"); +} + +int BundleActiveService::ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, + const std::string& continuousTask, const int& userId, const int& eventId) +{ + BUNDLE_ACTIVE_LOGI("report event called123123"); + BundleActiveReportHandlerObject tmpHandlerObject; + tmpHandlerObject.event_.bundleName_ = bundleName; + tmpHandlerObject.event_.abilityName_ = abilityName; + tmpHandlerObject.event_.abilityId_ = abilityId; + tmpHandlerObject.event_.eventId_ = eventId; + tmpHandlerObject.event_.longTimeTaskName_ = continuousTask; + tmpHandlerObject.userId_ = userId; + 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); + reportHandler_->SendEvent(event); + return 0; +} + +bool BundleActiveService::IsBundleIdle(const std::string& bundleName) +{ + // get uid + BUNDLE_ACTIVE_LOGI("Is bundle active called"); + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("UID is %{public}d", callingUid); + // get user id + int userId = -1; + int result = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret == ERR_OK && userId != -1) { + result = bundleActiveCore_->IsBundleIdle(bundleName, userId); + } + + return result == 1 ? true : false; +} + +std::vector BundleActiveService::QueryPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageStats stats called, intervaltype is %{public}d", + intervalType); + std::vector result; + // get uid + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageStats UID is %{public}d", callingUid); + // get userid + int userId = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret == ERR_OK && userId != -1) { + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageStats user id is %{public}d", userId); + bool isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, userId); + if (isSystemAppAndHasPermission == true) { + int convertedIntervalType = ConvertIntervalType(intervalType); + result = bundleActiveCore_->QueryPackageStats(userId, convertedIntervalType, beginTime, endTime, ""); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageStats result size is %{public}d", result.size()); + return result; +} + +std::vector BundleActiveService::QueryEvents(const int64_t& beginTime, const int64_t& endTime) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryEvents stats called"); + std::vector result; + // get uid + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryEvents UID is %{public}d", callingUid); + // get userid + int userId = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret == ERR_OK && userId != -1) { + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryEvents userid is %{public}d", userId); + bool isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, userId); + if (isSystemAppAndHasPermission == true) { + result = bundleActiveCore_->QueryEvents(userId, beginTime, endTime, ""); + } + } + return result; +} + +void BundleActiveService::SetBundleGroup(const std::string& bundleName, int newGroup, int userId) +{ + bundleActiveCore_->SetBundleGroup(bundleName, newGroup, userId); +} + + +std::vector BundleActiveService::QueryCurrentPackageStats(const int& intervalType, + const int64_t& beginTime, const int64_t& endTime) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentPackageStats stats called"); + std::vector result; + // get uid + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("UID is %{public}d", callingUid); + // get userid + int userId = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret == ERR_OK && userId != -1) { + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentPackageStats userid is %{public}d", userId); + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState get bundle manager proxy failed!"); + return result; + } + std::string bundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + bool isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, userId); + if (!bundleName.empty() && isSystemAppAndHasPermission == true) { + int convertedIntervalType = ConvertIntervalType(intervalType); + result = bundleActiveCore_->QueryPackageStats(userId, convertedIntervalType, beginTime, endTime, + bundleName); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentPackageStats result size is %{public}d", result.size()); + return result; +} + +std::vector BundleActiveService::QueryCurrentEvents(const int64_t& beginTime, + const int64_t& endTime) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentEvents stats called"); + std::vector result; + // get uid + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentEvents UID is %{public}d", callingUid); + // get userid + int userId = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret == ERR_OK && userId != -1) { + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentEvents userid is %{public}d", userId); + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveService::QueryCurrentEvents get bundle manager proxy failed!"); + return result; + } + std::string bundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + bool isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, userId); + if (!bundleName.empty() && isSystemAppAndHasPermission == true) { + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentEvents buindle name is %{public}s", + bundleName.c_str()); + result = bundleActiveCore_->QueryEvents(userId, beginTime, endTime, bundleName); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryCurrentEvents result size is %{public}d", result.size()); + return result; +} + +int BundleActiveService::QueryPackageGroup() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup stats called"); + // get uid + int callingUid = OHOS::IPCSkeleton::GetCallingUid(); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup UID is %{public}d", callingUid); + // get userid + int userId = -1; + int result = -1; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup user id is %{public}d", userId); + if (ret == ERR_OK && userId != -1) { + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState get bundle manager proxy failed!"); + return result; + } + std::string bundleName = ""; + // get bundle name + sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup bundlename is %{public}s", bundleName.c_str()); + if (!bundleName.empty()) { + result = bundleActiveCore_->QueryPackageGroup(userId, bundleName); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup result is %{public}d", result); + return result; +} + +bool BundleActiveService::GetBundleMgrProxy() +{ + if (!sptrBundleMgr_) { + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + BUNDLE_ACTIVE_LOGE("Failed to get system ability mgr."); + return false; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + BUNDLE_ACTIVE_LOGE("Failed to get bundle manager service."); + return false; + } + sptrBundleMgr_ = iface_cast(remoteObject); + if ((!sptrBundleMgr_) || (!sptrBundleMgr_->AsObject())) { + BUNDLE_ACTIVE_LOGE("Failed to get system bundle manager services ability"); + return false; + } + } + return true; +} + +int BundleActiveService::ConvertIntervalType(const int& intervalType) +{ + if (intervalType == PERIOD_BEST_JS) { + return PERIOD_BEST_SERVICE; + } else if (intervalType > PERIOD_BEST_JS && intervalType <= PERIOD_YEARLY_JS) { + return intervalType - 1; + } + return -1; +} + +bool BundleActiveService::CheckBundleIsSystemAppAndHasPermission(const int& uid, const int& userId) +{ + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::QueryEvents get bundle manager proxy failed!"); + return false; + } + std::string bundleName = ""; + sptrBundleMgr_->GetBundleNameForUid(uid, bundleName); + bool bundleIsSystemApp = sptrBundleMgr_->CheckIsSystemAppByUid(uid); + int bundleHasPermission = sptrBundleMgr_->CheckPermissionByUid(bundleName, NEEDED_PERMISSION, userId); + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::QueryEvents %{public}s is system app %{public}d, " + "has permission %{public}d", bundleName.c_str(), bundleIsSystemApp, bundleHasPermission); + if (bundleIsSystemApp == true && bundleHasPermission == 0) { + return true; + } + return false; +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_shutdown_callback_proxy.cpp b/services/common/src/bundle_active_shutdown_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ef9740adf25e1b4c3c9db89cd3cf97a027bd7c6 --- /dev/null +++ b/services/common/src/bundle_active_shutdown_callback_proxy.cpp @@ -0,0 +1,38 @@ +/* + * 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_shutdown_callback_proxy.h" + +namespace OHOS { +namespace DeviceUsageStats { +void BundleActiveShutdownCallbackProxy::ShutdownCallback() +{ + sptr remote = Remote(); + if (remote == nullptr) { + return; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(BundleActiveShutdownCallbackProxy::GetDescriptor())) { + return; + } + int ret = remote->SendRequest(IShutdownCallback::POWER_SHUTDOWN_CHANGED, data, reply, option); + if (ret != ERR_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveShutdownCallbackProxy::ShutdownCallback failed!"); + } +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_shutdown_callback_service.cpp b/services/common/src/bundle_active_shutdown_callback_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4832a465607e83636f58a0d9a6cdcf71e6096f44 --- /dev/null +++ b/services/common/src/bundle_active_shutdown_callback_service.cpp @@ -0,0 +1,33 @@ +/* + * 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_shutdown_callback_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveShutdownCallbackService::BundleActiveShutdownCallbackService( + std::shared_ptr bundleActiveCore) +{ + if (bundleActiveCore != nullptr) { + bundleActiveCore_ = bundleActiveCore; + } +} + +void BundleActiveShutdownCallbackService::ShutdownCallback() +{ + bundleActiveCore_->ShutDown(); +} +} +} diff --git a/services/common/src/bundle_active_shutdown_callback_stub.cpp b/services/common/src/bundle_active_shutdown_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f4cac49b152fea8c7224262b318622dedf966e75 --- /dev/null +++ b/services/common/src/bundle_active_shutdown_callback_stub.cpp @@ -0,0 +1,44 @@ +/* + * 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_shutdown_callback_stub.h" + +namespace OHOS { +namespace DeviceUsageStats { +int32_t BundleActiveShutdownCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) +{ + std::u16string descriptor = BundleActiveShutdownCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + BUNDLE_ACTIVE_LOGI("BundleActiveShutdownCallbackStub::OnRemoteRequest cannot get power mgr service"); + return -1; + } + switch (code) { + case IShutdownCallback::POWER_SHUTDOWN_CHANGED: { + ShutdownStub(); + return ERR_OK; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} + +void BundleActiveShutdownCallbackStub::ShutdownStub() +{ + ShutdownCallback(); +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_stub.cpp b/services/common/src/bundle_active_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c0fae5c10da76611998f8d6304aeb931fdb6130 --- /dev/null +++ b/services/common/src/bundle_active_stub.cpp @@ -0,0 +1,133 @@ +/* + * 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_stub.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_event.h" + +namespace OHOS { +namespace DeviceUsageStats { +int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) +{ + switch (code) { + case REPORT_EVENT: { + std::string bundleName = data.ReadString(); + std::string ablityName = data.ReadString(); + std::string abilityId = data.ReadString(); + std::string continuousTaskName = data.ReadString(); + int userId = data.ReadInt32(); + int eventId = data.ReadInt32(); + int result = ReportEvent(bundleName, ablityName, abilityId, continuousTaskName, userId, eventId); + return reply.WriteInt32(result); + } + case IS_BUNDLE_IDLE: { + std::string bundleName = data.ReadString(); + int result = IsBundleIdle(bundleName); + return reply.WriteInt32(result); + } + case QUERY_USAGE_STATS: { + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_USAGE_STATS called"); + std::vector result; + int size = 0; + int intervalType = data.ReadInt32(); + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_USAGE_STATS intervaltype is %{public}d", + intervalType); + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + result = QueryPackageStats(intervalType, beginTime, endTime); + size = result.size(); + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_USAGE_STATS result size is %{public}d", size); + reply.WriteInt32(size); + for (int i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (tmp == false) { + return 1; + } + } + return size == 0; + } + case QUERY_EVENTS: { + std::vector result; + int size = 0; + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + result = QueryEvents(beginTime, endTime); + size = result.size(); + reply.WriteInt32(size); + for (int i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (tmp == false) { + return 1; + } + } + return size == 0; + } + case SET_BUNDLE_GROUP: { + std::string bundleName = data.ReadString(); + int newGroup = data.ReadInt32(); + int userId = data.ReadInt32(); + SetBundleGroup(bundleName, newGroup, userId); + return 0; + } + case QUERY_CURRENT_USAGE_STATS: { + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_CURRENT_USAGE_STATS called"); + std::vector result; + int size = 0; + int intervalType = data.ReadInt32(); + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_CURRENT_USAGE_STATS intervaltype " + "is %{public}d", intervalType); + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + result = QueryPackageStats(intervalType, beginTime, endTime); + size = result.size(); + BUNDLE_ACTIVE_LOGI("BundleActiveStub::OnRemoteRequest QUERY_CURRENT_USAGE_STATS result size " + "is %{public}d", size); + reply.WriteInt32(size); + for (int i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (tmp == false) { + return 1; + } + } + return size == 0; + } + case QUERY_CURRENT_EVENTS: { + std::vector result; + int size = 0; + int64_t beginTime = data.ReadInt64(); + int64_t endTime = data.ReadInt64(); + result = QueryCurrentEvents(beginTime, endTime); + size = result.size(); + reply.WriteInt32(size); + for (int i = 0; i < size; i++) { + bool tmp = result[i].Marshalling(reply); + if (tmp == false) { + return 1; + } + } + return size == 0; + } + case QUERY_BUNDLE_GROUP: { + int result = -1; + result = QueryPackageGroup(); + return result; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_usage_database.cpp b/services/common/src/bundle_active_usage_database.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45cf2e8962c0c946a5326f3b83fd42f2f40166e8 --- /dev/null +++ b/services/common/src/bundle_active_usage_database.cpp @@ -0,0 +1,1221 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "time_service_client.h" + +#include "bundle_active_constant.h" +#include "bundle_active_open_callback.h" +#include "bundle_active_log.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_binary_search.h" +#include "bundle_active_period_stats.h" +#include "bundle_active_usage_database.h" + +namespace OHOS { +namespace DeviceUsageStats { +using namespace OHOS::NativeRdb; + +BundleActiveUsageDatabase::BundleActiveUsageDatabase() +{ + currentVersion_ = BUNDLE_ACTIVE_CURRENT_VERSION; + versionDirectoryPath_ = BUNDLE_ACTIVE_DATABASE_DIR + BUNDLE_ACTIVE_VERSION_FILE; + databaseFiles_.push_back(DAILY_DATABASE); + databaseFiles_.push_back(WEEKLY_DATABASE); + databaseFiles_.push_back(MONTHLY_DATABASE); + databaseFiles_.push_back(YEARLY_DATABASE); + databaseFiles_.push_back(EVENT_DATABASE); + databaseFiles_.push_back(USAGE_GROUP_DATABASE); + eventTableName_ = UNKNOWN_TABLE_NAME; + durationTableName_ = UNKNOWN_TABLE_NAME; + bundleHistoryTableName_ = UNKNOWN_TABLE_NAME; + sortedTableArray_ = std::vector>(SORTED_TABLE_ARRAY_NUMBER); + calendar_ = std::make_shared(); + eventBeginTime_ = EVENT_BEGIN_TIME_INITIAL_VALUE; +} + +BundleActiveUsageDatabase::~BundleActiveUsageDatabase() +{ + RdbHelper::ClearCache(); +} + +void BundleActiveUsageDatabase::InitUsageGroupInfo(int32_t databaseType) +{ + std::lock_guard lock(databaseMutex_); + if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) != 0) { + int createDir = mkdir(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), S_IRWXU); + if (createDir != 0) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase InitDatabaseTableInfo Failed to create directory %{public}s", + BUNDLE_ACTIVE_DATABASE_DIR.c_str()); + return; + } + } + if (databaseType != APP_GROUP_DATABASE_INDEX) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase InitUsageGroupInfo databaseType is invalid, " + "databaseType = %{public}d", databaseType); + return; + } + std::string queryDatabaseTableNames = "select * from sqlite_master where type = ?"; + std::vector queryCondition; + queryCondition.push_back(DATABASE_FILE_TABLE_NAME); + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(databaseType, + queryDatabaseTableNames, queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase InitUsageGroupInfo bundleActiveResult is invalid"); + return; + } + int32_t tableNumber; + bundleActiveResult->GetRowCount(tableNumber); + if (tableNumber == TABLE_NOT_EXIST) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase InitUsageGroupInfo table not exist"); + return; + } + int32_t tableNameIndex; + bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex); + std::string tableName; + for (int32_t i = 0; i < tableNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(tableNameIndex, tableName); + if (DURATION_LOG_TABLE == tableName) { + durationTableName_ = DURATION_LOG_TABLE; + } else if (BUNDLE_HISTORY_LOG_TABLE == tableName) { + bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE; + } else { + // 无效的数据表 + } + } +} + +void BundleActiveUsageDatabase::InitDatabaseTableInfo(int64_t currentTime) +{ + std::lock_guard lock(databaseMutex_); + if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) != 0) { + int createDir = mkdir(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), S_IRWXU); + if (createDir != 0) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase InitDatabaseTableInfo Failed to create directory %{public}s", + BUNDLE_ACTIVE_DATABASE_DIR.c_str()); + return; + } + } + + CheckDatabaseVersion(); + for (unsigned int i = 0; i < databaseFiles_.size(); i++) { + HandleTableInfo(i); + DeleteExcessiveTableData(i); + } + for (unsigned int i = 0; i < sortedTableArray_.size(); i++) { + int32_t startIndex = NearIndexOnOrAfterCurrentTime(currentTime, sortedTableArray_.at(i)); + if (startIndex < BUNDLE_ACTIVE_SUCCESS) { + continue; + } + int32_t tableNumber = sortedTableArray_.at(i).size(); + for (int32_t j = startIndex; j < tableNumber; j++) { + DeleteInvalidTable(i, sortedTableArray_.at(i).at(startIndex)); + sortedTableArray_.at(i).erase(sortedTableArray_.at(i).begin() + startIndex); + } + if (!sortedTableArray_.at(i).empty()) { + for (unsigned int k = 0; k < sortedTableArray_.at(i).size(); k++) { + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase InitDatabaseTableInfo tableCreateTime = %{public}lld", + sortedTableArray_.at(i).at(k)); + } + } + } + if (eventTableName_ != UNKNOWN_TABLE_NAME) { + int64_t eventTableTime = ParseStartTime(eventTableName_); + if (currentTime < eventTableTime) { + DeleteInvalidTable(EVENT_DATABASE_INDEX, eventTableTime); + } + } +} + +int32_t BundleActiveUsageDatabase::NearIndexOnOrAfterCurrentTime(int64_t currentTime, + std::vector sortedTableArray) +{ + int32_t low = 0; + int32_t high = sortedTableArray.size() - 1; + int32_t mid = -1; + int64_t tableTime = -1; + while (low <= high) { + mid = (low + high) >> 1; + tableTime = sortedTableArray.at(mid); + if (currentTime > tableTime) { + low = mid + 1; + } else if (currentTime < tableTime) { + high = mid - 1; + } else { + return mid; + } + } + if (currentTime < tableTime) { + return mid; + } else if (currentTime > tableTime && low < sortedTableArray.size()) { + return low; + } else { + return BUNDLE_ACTIVE_FAIL; + } +} + +int32_t BundleActiveUsageDatabase::NearIndexOnOrBeforeCurrentTime(int64_t currentTime, + std::vector sortedTableArray) +{ + int32_t index = NearIndexOnOrAfterCurrentTime(currentTime, sortedTableArray); + if (index < 0) { + return sortedTableArray.size() - 1; + } + if (sortedTableArray.at(index) == currentTime) { + return index; + } + return index - 1; +} + +std::unique_ptr BundleActiveUsageDatabase::QueryStatsInfoByStep(unsigned int databaseType, + const std::string &sql, const std::vector &selectionArgs) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryStatsInfoByStep is failed"); + return nullptr; + } + std::unique_ptr result; + if (selectionArgs.empty()) { + result = rdbStore->QueryByStep(sql); + } else { + result = rdbStore->QueryByStep(sql, selectionArgs); + } + return result; +} + +void BundleActiveUsageDatabase::HandleTableInfo(unsigned int databaseType) +{ + std::string queryDatabaseTableNames = "select * from sqlite_master where type = ?"; + std::vector queryCondition; + queryCondition.push_back(DATABASE_FILE_TABLE_NAME); + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(databaseType, + queryDatabaseTableNames, queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase HandleTableInfo bundleActiveResult is invalid"); + return; + } + int32_t tableNumber; + bundleActiveResult->GetRowCount(tableNumber); + if (tableNumber == TABLE_NOT_EXIST) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase HandleTableInfo table not exist"); + return; + } + int32_t tableNameIndex; + bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex); + std::string tableName; + if (databaseType >= 0 && databaseType < sortedTableArray_.size()) { + if (!sortedTableArray_.at(databaseType).empty()) { + sortedTableArray_.at(databaseType).clear(); + } + for (int32_t i = 0; i < tableNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(tableNameIndex, tableName); + sortedTableArray_.at(databaseType).push_back(ParseStartTime(tableName)); + } + if (!sortedTableArray_.at(databaseType).empty()) { + sort(sortedTableArray_.at(databaseType).begin(), sortedTableArray_.at(databaseType).end()); + } + if ((databaseType == DAILY_DATABASE_INDEX) && !sortedTableArray_.at(databaseType).empty()) { + int lastTableIndex = sortedTableArray_.at(databaseType).size() - 1; + eventBeginTime_ = sortedTableArray_.at(databaseType).at(lastTableIndex); + } + } else if (databaseType == EVENT_DATABASE_INDEX) { + if (tableNumber == EVENT_TABLE_NUMBER) { + bundleActiveResult->GoToRow(tableNumber - EVENT_TABLE_NUMBER); + bundleActiveResult->GetString(tableNameIndex, eventTableName_); + } + } else if (databaseType == APP_GROUP_DATABASE_INDEX) { + if (tableNumber == APP_GROUP_TABLE_NUMBER) { + durationTableName_ = DURATION_LOG_TABLE; + bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE; + } + } +} + +void BundleActiveUsageDatabase::DeleteExcessiveTableData(unsigned int databaseType) +{ + if (databaseType >= 0 && databaseType < sortedTableArray_.size()) { + if (sortedTableArray_.at(databaseType).empty()) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteExcessiveTableData database table not exist"); + return; + } + int32_t deleteNumber = sortedTableArray_.at(databaseType).size() - MAX_FILES_EVERY_INTERVAL_TYPE[databaseType]; + if (deleteNumber > 0) { + for (int32_t i = 0; i < deleteNumber; i++) { + // 删除多余文件 + DeleteInvalidTable(databaseType, sortedTableArray_.at(databaseType).at(0)); + sortedTableArray_.at(databaseType).erase(sortedTableArray_.at(databaseType).begin()); + } + BUNDLE_ACTIVE_LOGD("BundleActiveUsageDatabase DeleteExcessiveTableData Deleted %{public}d tables from " + "database type %{public}d", deleteNumber, databaseType); + } + } else if (databaseType == EVENT_DATABASE_INDEX) { + // 删除多余数据 + if ((eventTableName_ == UNKNOWN_TABLE_NAME) || (eventBeginTime_ == EVENT_BEGIN_TIME_INITIAL_VALUE)) { + return; + } + int64_t eventTableTime = ParseStartTime(eventTableName_); + int64_t deleteTimePoint = eventBeginTime_ - SIX_DAY_IN_MILLIS_MAX - eventTableTime; + if (deleteTimePoint <= 0) { + return; + } + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteExcessiveTableData is failed"); + return; + } + std::string deleteEventDataSql = "delete from " + eventTableName_ + " where timeStamp <= " + + std::to_string(deleteTimePoint); + int32_t deleteResult = rdbStore->ExecuteSql(deleteEventDataSql); + if (deleteResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteExcessiveTableData deleteEventData is failed"); + } + } else if (databaseType == APP_GROUP_DATABASE_INDEX) { + // 无数据删除 + } else { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteExcessiveTableData databaseType is invalid, databaseType = " + "%{public}d", databaseType); + } +} + +std::vector BundleActiveUsageDatabase::GetOverdueTableCreateTime(unsigned int databaseType, + int64_t currentTimeMillis) +{ + std::vector overdueTableCreateTime; + if (databaseType < 0 || databaseType >= sortedTableArray_.size()) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetOverdueTableCreateTime databaseType is invalid, databaseType " + "= %{public}d", databaseType); + return overdueTableCreateTime; + } + std::string queryDatabaseTableNames = "select * from sqlite_master where type = ?"; + std::vector queryCondition; + queryCondition.push_back(DATABASE_FILE_TABLE_NAME); + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(databaseType, + queryDatabaseTableNames, queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetOverdueTableCreateTime bundleActiveResult is invalid"); + return overdueTableCreateTime; + } + int32_t tableNumber; + bundleActiveResult->GetRowCount(tableNumber); + if (tableNumber == 0) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetOverdueTableCreateTime table does not exist"); + return overdueTableCreateTime; + } + int32_t tableNameIndex; + bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex); + std::string tableName; + for (int32_t i = 0; i < tableNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(tableNameIndex, tableName); + if (ParseStartTime(tableName) < currentTimeMillis) { + overdueTableCreateTime.push_back(ParseStartTime(tableName)); + } + } + return overdueTableCreateTime; +} + +int32_t BundleActiveUsageDatabase::DeleteInvalidTable(unsigned int databaseType, int64_t tableTimeMillis) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteInvalidTable is failed"); + return BUNDLE_ACTIVE_FAIL; + } + if (databaseType >= 0 && databaseType < sortedTableArray_.size()) { + std::string packageTable = PACKAGE_LOG_TABLE + std::to_string(tableTimeMillis); + std::string deletePackageTableSql = "drop table " + packageTable; + int32_t deletePackageTable = rdbStore->ExecuteSql(deletePackageTableSql); + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteInvalidTable deletePackageTable is failed, " + "%{public}d", deletePackageTable); + if (deletePackageTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteInvalidTable deletePackageTable is failed"); + return deletePackageTable; + } + } else if (databaseType == EVENT_DATABASE_INDEX) { + std::string eventTable = EVENT_LOG_TABLE + std::to_string(tableTimeMillis); + std::string deleteEventTableSql = "drop table " + eventTable; + int32_t deleteEventTable = rdbStore->ExecuteSql(deleteEventTableSql); + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteInvalidTable deleteEventTable is failed, " + "%{public}d", deleteEventTable); + if (deleteEventTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteInvalidTable deleteEventTable is failed"); + return deleteEventTable; + } + } else if (databaseType == APP_GROUP_DATABASE_INDEX) { + } + return BUNDLE_ACTIVE_SUCCESS; +} + +int64_t BundleActiveUsageDatabase::ParseStartTime(const std::string &tableName) +{ + int64_t invalidStartTime(BUNDLE_ACTIVE_FAIL); + if (tableName.empty()) { + return invalidStartTime; + } + std::string tableTime = tableName; + for (uint32_t i = 0; i < tableTime.length(); i++) { + if (tableTime[i] >= '0' && tableTime[i] <= '9') { + tableTime = tableTime.substr(i); + break; + } + } + int64_t time = atoll(tableTime.c_str()); + return time; +} + +void BundleActiveUsageDatabase::CheckDatabaseVersion() +{ + if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) == 0) { + std::ofstream openVersionFile; + openVersionFile.open(versionDirectoryPath_, std::ios::out); + if (openVersionFile) { + openVersionFile << "version : " << BUNDLE_ACTIVE_CURRENT_VERSION; + } + openVersionFile.close(); + } +} + +std::shared_ptr BundleActiveUsageDatabase::GetBundleActiveRdbStore(unsigned int databaseType) +{ + std::shared_ptr rdbStore; + std::string file = databaseFiles_.at(databaseType); + if (bundleActiveRdbStoreCache_.find(file) == bundleActiveRdbStoreCache_.end()) { + int errCode(BUNDLE_ACTIVE_FAIL); + std::string currDatabaseFileConfig = BUNDLE_ACTIVE_DATABASE_DIR + databaseFiles_.at(databaseType); + RdbStoreConfig config(currDatabaseFileConfig); + BundleActiveOpenCallback rdbDataCallBack; + rdbStore = RdbHelper::GetRdbStore(config, BUNDLE_ACTIVE_RDB_VERSION, rdbDataCallBack, errCode); + if ((rdbStore == nullptr)) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetBundleActiveRdbStore fail to open RdbStore"); + return nullptr; + } + bundleActiveRdbStoreCache_.insert(std::pair {file, rdbStore}); + } else { + rdbStore = bundleActiveRdbStoreCache_[file]; + } + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetBundleActiveRdbStore is failed"); + return nullptr; + } + return rdbStore; +} + +int32_t BundleActiveUsageDatabase::CreateEventLogTable(unsigned int databaseType, int64_t currentTimeMillis) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateEventLogTable is failed"); + return BUNDLE_ACTIVE_FAIL; + } + std::string eventTable = EVENT_LOG_TABLE + std::to_string(currentTimeMillis); + eventTableName_ = eventTable; + const std::string createEventTableSql = "CREATE TABLE IF NOT EXISTS " + + eventTable + + " (" + + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_NAME + " TEXT NOT NULL, " + + BUNDLE_ACTIVE_DB_EVENT_ID + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_TIME_STAMP + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_ABILITY_ID + " TEXT NOT NULL);"; + int32_t createEventTable = rdbStore->ExecuteSql(createEventTableSql); + if (createEventTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateEventLogTable is failed"); + return createEventTable; + } + std::string createEventTableIndex = GetTableIndexSql(EVENT_DATABASE_INDEX, currentTimeMillis, true); + int32_t createResult = rdbStore->ExecuteSql(createEventTableIndex); + if (createResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateEventLogTable createEventTableIndex is failed"); + return createResult; + } + return BUNDLE_ACTIVE_SUCCESS; +} + +int32_t BundleActiveUsageDatabase::CreatePackageLogTable(unsigned int databaseType, int64_t currentTimeMillis) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreatePackageLogTable is failed"); + return BUNDLE_ACTIVE_FAIL; + } + std::string packageTable = PACKAGE_LOG_TABLE + std::to_string(currentTimeMillis); + std::string createPackageTableSql = "CREATE TABLE IF NOT EXISTS " + + packageTable + + " (" + + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_NAME + " TEXT NOT NULL, " + + BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_TOTAL_TIME + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL);"; + int32_t createPackageTable = rdbStore->ExecuteSql(createPackageTableSql); + if (createPackageTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreatePackageLogTable is failed"); + return createPackageTable; + } + std::string createPackageTableIndex = GetTableIndexSql(databaseType, currentTimeMillis, true); + int32_t createResult = rdbStore->ExecuteSql(createPackageTableIndex); + if (createResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreatePackageLogTable createNewPackageTableIndex is failed"); + return createResult; + } + return BUNDLE_ACTIVE_SUCCESS; +} + +int32_t BundleActiveUsageDatabase::CreateDurationTable(unsigned int databaseType) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateDurationTable is failed"); + return BUNDLE_ACTIVE_FAIL; + } + std::string createDurationTableSql = "CREATE TABLE IF NOT EXISTS " + + DURATION_LOG_TABLE + + " (" + + BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION + " INTEGER NOT NULL);"; + int32_t createDurationTable = rdbStore->ExecuteSql(createDurationTableSql); + if (createDurationTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateDurationTable is failed"); + return createDurationTable; + } + return BUNDLE_ACTIVE_SUCCESS; +} + +int32_t BundleActiveUsageDatabase::CreateBundleHistoryTable(unsigned int databaseType) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateBundleHistoryTable is failed"); + return BUNDLE_ACTIVE_FAIL; + } + std::string createBundleHistoryTableSql = "CREATE TABLE IF NOT EXISTS " + + BUNDLE_HISTORY_LOG_TABLE + + " (" + + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_NAME + " TEXT NOT NULL, " + + BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_CURRENT_GROUP + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_REASON_IN_GROUP + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME + " INTEGER NOT NULL, " + + BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME + " INTEGER NOT NULL);"; + int32_t createBundleHistoryTable = rdbStore->ExecuteSql(createBundleHistoryTableSql); + if (createBundleHistoryTable != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateBundleHistoryTable is failed"); + return createBundleHistoryTable; + } + int32_t time = 0; + std::string createBundleHistoryTableIndex = GetTableIndexSql(databaseType, time, true); + int32_t createResult = rdbStore->ExecuteSql(createBundleHistoryTableIndex); + if (createResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase CreateBundleHistoryTable createNewPackageTableIndex is failed"); + return createResult; + } + return BUNDLE_ACTIVE_SUCCESS; +} + +void BundleActiveUsageDatabase::PutBundleHistoryData(int userId, + std::shared_ptr>> userHistory) +{ + std::lock_guard lock(databaseMutex_); + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase::PutBundleHistoryData num of handler is %{public}d, " + "cache size is %{public}d", databaseFiles_.size(), bundleActiveRdbStoreCache_.size()); + if (userHistory == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase PutBundleHistoryData bundleHistoryData is empty"); + return; + } + if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) { + CreateBundleHistoryTable(APP_GROUP_DATABASE_INDEX); + bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE; + } + std::shared_ptr rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase PutBundleHistoryData cannot get rdbStore!"); + return; + } + int32_t changeRow = BUNDLE_ACTIVE_FAIL; + int64_t outRowId = BUNDLE_ACTIVE_FAIL; + NativeRdb::ValuesBucket valuesBucket; + std::vector queryCondition; + for (auto iter = userHistory->begin(); iter != userHistory->end(); iter++) { + if (iter->second == nullptr) { + continue; + } + queryCondition.push_back(std::to_string(userId)); + queryCondition.push_back(iter->first); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME, iter->second->lastBootFromUsedTimeStamp_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME, iter->second->lastScreenUsedTimeStamp_); + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_CURRENT_GROUP, iter->second->currentGroup_); + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_REASON_IN_GROUP, iter->second->reasonInGroup_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME, iter->second->bundleAliveTimeoutTimeStamp_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME, iter->second->bundleDailyTimeoutTimeStamp_); + rdbStore->Update(changeRow, BUNDLE_HISTORY_LOG_TABLE, valuesBucket, "userId = ? and bundleName = ?", + queryCondition); + if (changeRow == NO_UPDATE_ROW) { + valuesBucket.PutString(BUNDLE_ACTIVE_DB_NAME, iter->first); + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId); + rdbStore->Insert(outRowId, BUNDLE_HISTORY_LOG_TABLE, valuesBucket); + outRowId = BUNDLE_ACTIVE_FAIL; + } else { + changeRow = BUNDLE_ACTIVE_FAIL; + } + valuesBucket.Clear(); + queryCondition.clear(); + } +} + +std::shared_ptr>> BundleActiveUsageDatabase::GetBundleHistoryData(int userId) +{ + std::lock_guard lock(databaseMutex_); + if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) { + return nullptr; + } + std::string queryHistoryDataSql = "select * from " + BUNDLE_HISTORY_LOG_TABLE + " where userId = ?"; + std::vector queryCondition; + queryCondition.push_back(std::to_string(userId)); + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, + queryHistoryDataSql, queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetBundleHistoryData bundleActiveResult is invalid"); + return nullptr; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + if (tableRowNumber == TABLE_ROW_ZERO) { + return nullptr; + } + std::string bundleName; + std::shared_ptr>> userUsageHistory = + std::make_shared>>(); + std::shared_ptr usageHistory; + for (int32_t i = 0; i < tableRowNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName); + std::shared_ptr usageHistory = std::make_shared(); + bundleActiveResult->GetLong(LAST_BOOT_FROM_USED_TIME_COLUMN_INDEX, usageHistory->lastBootFromUsedTimeStamp_); + bundleActiveResult->GetLong(LAST_SCREEN_USED_TIME_COLUMN_INDEX, usageHistory->lastScreenUsedTimeStamp_); + bundleActiveResult->GetInt(CURRENT_GROUP_COLUMN_INDEX, usageHistory->currentGroup_); + bundleActiveResult->GetInt(REASON_IN_GROUP_COLUMN_INDEX, usageHistory->reasonInGroup_); + bundleActiveResult->GetLong(BUNDLE_ALIVE_TIMEOUT_TIME_COLUMN_INDEX, + usageHistory->bundleAliveTimeoutTimeStamp_); + bundleActiveResult->GetLong(BUNDLE_DAILY_TIMEOUT_TIME_COLUMN_INDEX, + usageHistory->bundleDailyTimeoutTimeStamp_); + userUsageHistory->insert(std::pair>(bundleName, + usageHistory)); + } + return userUsageHistory; +} + +void BundleActiveUsageDatabase::PutDurationData(int64_t bootBasedDuration, int64_t screenOnDuration) +{ + std::lock_guard lock(databaseMutex_); + if (durationTableName_ == UNKNOWN_TABLE_NAME) { + CreateDurationTable(APP_GROUP_DATABASE_INDEX); + durationTableName_ = DURATION_LOG_TABLE; + } + std::shared_ptr rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase PutDurationData cannot get rdbStore!"); + return; + } + int32_t changeRow = BUNDLE_ACTIVE_FAIL; + int64_t outRowId = BUNDLE_ACTIVE_FAIL; + NativeRdb::ValuesBucket valuesBucket; + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION, bootBasedDuration); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION, screenOnDuration); + rdbStore->Update(changeRow, DURATION_LOG_TABLE, valuesBucket); + if (changeRow == NO_UPDATE_ROW) { + rdbStore->Insert(outRowId, DURATION_LOG_TABLE, valuesBucket); + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase PutDurationData Insert SUCCESS, outRowId = %{public}lld", + outRowId); + } else { + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase PutDurationData Update SUCCESS, changeRow = %{public}d", + changeRow); + } +} + +std::pair BundleActiveUsageDatabase::GetDurationData() +{ + std::lock_guard lock(databaseMutex_); + std::pair durationData; + if (durationTableName_ == UNKNOWN_TABLE_NAME) { + return durationData; + } + std::string queryDurationDataSql = "select * from " + DURATION_LOG_TABLE; + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, + queryDurationDataSql, + std::vector {}); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetDurationData bundleActiveResult is invalid"); + return durationData; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + if (tableRowNumber == DURATION_TABLE_ROW_NUMBER) { + bundleActiveResult->GoToRow(tableRowNumber - DURATION_TABLE_ROW_NUMBER); + bundleActiveResult->GetLong(BOOT_BASED_DURATION_COLUMN_INDEX, durationData.first); + bundleActiveResult->GetLong(SCREEN_ON_DURATION_COLUMN_INDEX, durationData.second); + } + return durationData; +} + +void BundleActiveUsageDatabase::FlushPackageInfo(unsigned int databaseType, const BundleActivePeriodStats &stats) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + std::string tableName = PACKAGE_LOG_TABLE + std::to_string(stats.beginTime_); + int32_t changeRow = BUNDLE_ACTIVE_FAIL; + int64_t outRowId = BUNDLE_ACTIVE_FAIL; + NativeRdb::ValuesBucket valuesBucket; + std::vector queryCondition; + for (auto iter = stats.bundleStats_.begin(); iter != stats.bundleStats_.end(); iter++) { + if (iter->second == nullptr || (iter->second->totalInFrontTime_ == 0 && iter->second->totalContiniousTaskUsedTime_ == 0)) { + continue; + } + queryCondition.push_back(std::to_string(stats.userId_)); + queryCondition.push_back(iter->first); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT, iter->second->bundleStartedCount_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, (iter->second->lastTimeUsed_ - stats.beginTime_)); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK, (iter->second->lastContiniousTaskUsed_ - + stats.beginTime_)); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME, iter->second->totalInFrontTime_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK, iter->second->totalContiniousTaskUsedTime_); + rdbStore->Update(changeRow, tableName, valuesBucket, "userId = ? and bundleName = ?", queryCondition); + if (changeRow == NO_UPDATE_ROW) { + valuesBucket.PutString(BUNDLE_ACTIVE_DB_NAME, iter->second->bundleName_); + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_); + rdbStore->Insert(outRowId, tableName, valuesBucket); + outRowId = BUNDLE_ACTIVE_FAIL; + } else { + changeRow = BUNDLE_ACTIVE_FAIL; + } + valuesBucket.Clear(); + queryCondition.clear(); + } +} + +std::shared_ptr BundleActiveUsageDatabase::GetCurrentUsageData(int32_t databaseType, + int userId) +{ + std::lock_guard lock(databaseMutex_); + if (databaseType < 0 || databaseType >= sortedTableArray_.size()) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetCurrentUsageData databaseType is invalid, databaseType = " + "%{public}d", databaseType); + return nullptr; + } + + int tableNumber = sortedTableArray_.at(databaseType).size(); + if (tableNumber == TABLE_NOT_EXIST) { + return nullptr; + } + std::shared_ptr intervalStats = std::make_shared(); + intervalStats->userId_ = userId; + int64_t currentPackageTime = sortedTableArray_.at(databaseType).at(tableNumber - 1); + intervalStats->beginTime_ = currentPackageTime; + std::string packageTableName = PACKAGE_LOG_TABLE + std::to_string(currentPackageTime); + std::string queryPackageSql = "select * from " + packageTableName + " where userId = ?"; + std::vector queryCondition; + queryCondition.push_back(std::to_string(userId)); + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql, + queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetCurrentUsageData bundleActiveResult is invalid"); + return nullptr; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + std::map> bundleStats; + int64_t relativeLastTimeUsed; + int64_t relativeLastTimeFrontServiceUsed; + for (int32_t i = 0; i < tableRowNumber; i++) { + std::shared_ptr usageStats = std::make_shared(); + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetInt(USER_ID_COLUMN_INDEX, intervalStats->userId_); + bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats->bundleName_); + bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats->bundleStartedCount_); + bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed); + usageStats->lastTimeUsed_ = relativeLastTimeUsed + currentPackageTime; + bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed); + usageStats->lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed + currentPackageTime; + bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats->totalInFrontTime_); + bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX, usageStats->totalContiniousTaskUsedTime_); + bundleStats.insert(std::pair>(usageStats->bundleName_, + usageStats)); + } + intervalStats->bundleStats_ = bundleStats; + if (databaseType == DAILY_DATABASE_INDEX) { + // 加载event信息 + eventBeginTime_ = currentPackageTime; + } + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t systemTime = timer->GetWallTimeMs(); + intervalStats->lastTimeSaved_ = systemTime; + return intervalStats; +} + +void BundleActiveUsageDatabase::FlushEventInfo(unsigned int databaseType, BundleActivePeriodStats &stats) +{ + if (eventTableName_ == UNKNOWN_TABLE_NAME) { + CreateEventLogTable(databaseType, stats.beginTime_); + } + int64_t eventTableTime = ParseStartTime(eventTableName_); + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + int64_t outRowId = BUNDLE_ACTIVE_FAIL; + NativeRdb::ValuesBucket valuesBucket; + for (int32_t i = 0; i < stats.events_.Size(); i++) { + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_); + valuesBucket.PutString(BUNDLE_ACTIVE_DB_NAME, stats.events_.events_.at(i).bundleName_); + valuesBucket.PutInt(BUNDLE_ACTIVE_DB_EVENT_ID, stats.events_.events_.at(i).eventId_); + valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TIME_STAMP, stats.events_.events_.at(i).timeStamp_ - eventTableTime); + valuesBucket.PutString(BUNDLE_ACTIVE_DB_ABILITY_ID, stats.events_.events_.at(i).abilityId_); + rdbStore->Insert(outRowId, eventTableName_, valuesBucket); + valuesBucket.Clear(); + } +} + +std::string BundleActiveUsageDatabase::GetTableIndexSql(unsigned int databaseType, int64_t tableTime, bool createFlag) +{ + std::string tableIndexSql; + if (databaseType >= 0 && databaseType < sortedTableArray_.size()) { + std::string packageTableIndex = PACKAGE_LOG_TABLE_INDEX_PREFIX + std::to_string(tableTime); + std::string PackageTableName = PACKAGE_LOG_TABLE + std::to_string(tableTime); + if (createFlag) { + tableIndexSql = "CREATE INDEX " + packageTableIndex + " ON " + + PackageTableName + " (userId, lastTime, bundleName);"; + } else { + tableIndexSql = "DROP INDEX " + packageTableIndex; + } + } else if (databaseType == EVENT_DATABASE_INDEX) { + std::string eventTableIndex = EVENT_LOG_TABLE_INDEX_PREFIX + std::to_string(tableTime); + std::string eventTableName = EVENT_LOG_TABLE + std::to_string(tableTime); + if (createFlag) { + tableIndexSql = "CREATE INDEX " + eventTableIndex + " ON " + eventTableName + + " (timeStamp, userId, bundleName);"; + } else { + tableIndexSql = "DROP INDEX " + eventTableIndex; + } + } else if (databaseType == APP_GROUP_DATABASE_INDEX) { + if (createFlag) { + tableIndexSql = "CREATE INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX + + " ON " + BUNDLE_HISTORY_LOG_TABLE + " (userId, bundleName);"; + } else { + tableIndexSql = "DROP INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX; + } + } else { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase GetTableIndexSql databaseType is invalid, databaseType = " + "%{public}d", databaseType); + } + return tableIndexSql; +} + +int32_t BundleActiveUsageDatabase::RenameTableName(unsigned int databaseType, int64_t tableOldTime, + int64_t tableNewTime) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName get rdbStore failed"); + return BUNDLE_ACTIVE_FAIL; + } + if (databaseType >= 0 && databaseType < sortedTableArray_.size()) { + std::string oldPackageTableName = PACKAGE_LOG_TABLE + std::to_string(tableOldTime); + std::string newPackageTableName = PACKAGE_LOG_TABLE + std::to_string(tableNewTime); + std::string renamePackageTableNameSql = "alter table " + oldPackageTableName + " rename to " + + newPackageTableName; + int32_t renamePackageTableName = rdbStore->ExecuteSql(renamePackageTableNameSql); + if (renamePackageTableName != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName renamePackageTableName is failed"); + return renamePackageTableName; + } + std::string deleteOldPackageTableIndex = GetTableIndexSql(databaseType, tableOldTime, false); + int32_t deleteResult = rdbStore->ExecuteSql(deleteOldPackageTableIndex); + if (deleteResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName deleteOldPackageTableIndex is failed"); + return deleteResult; + } + std::string createNewPackageTableIndex = GetTableIndexSql(databaseType, tableNewTime, true); + int32_t createResult = rdbStore->ExecuteSql(createNewPackageTableIndex); + if (createResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName createNewPackageTableIndex is failed"); + return createResult; + } + } else if (databaseType == EVENT_DATABASE_INDEX) { + std::string oldEventTableName = EVENT_LOG_TABLE + std::to_string(tableOldTime); + std::string newEventTableName = EVENT_LOG_TABLE + std::to_string(tableNewTime); + std::string renameEventTableNameSql = "alter table " + oldEventTableName + " rename to " + newEventTableName; + int32_t renameEventTableName = rdbStore->ExecuteSql(renameEventTableNameSql); + if (renameEventTableName != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName renameEventTableName is failed"); + return renameEventTableName; + } + std::string deleteOldEventTableIndex = GetTableIndexSql(databaseType, tableOldTime, false); + int32_t deleteResult = rdbStore->ExecuteSql(deleteOldEventTableIndex); + if (deleteResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName deleteOldEventTableIndex is failed"); + return deleteResult; + } + std::string createNewEventTableIndex = GetTableIndexSql(databaseType, tableNewTime, true); + int32_t createResult = rdbStore->ExecuteSql(createNewEventTableIndex); + if (createResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase RenameTableName createNewEventTableIndex is failed"); + return createResult; + } + } else if (databaseType == APP_GROUP_DATABASE_INDEX) { + } + return BUNDLE_ACTIVE_SUCCESS; +} + +int32_t BundleActiveUsageDatabase::GetOptimalIntervalType(int64_t beginTime, int64_t endTime) +{ + std::lock_guard lock(databaseMutex_); + int32_t optimalIntervalType = -1; + int64_t leastTimeDiff = std::numeric_limits::max(); + for (int32_t i = sortedTableArray_.size() - 1; i >= 0; i--) { + int32_t index = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(i)); + int32_t size = sortedTableArray_.at(i).size(); + if (index >= 0 && index < size) { + int64_t diff = abs(sortedTableArray_.at(i).at(index) - beginTime); + if (diff < leastTimeDiff) { + leastTimeDiff = diff; + optimalIntervalType = i; + } + } + } + return optimalIntervalType; +} + +void BundleActiveUsageDatabase::RemoveOldData(int64_t currentTime) +{ + std::lock_guard lock(databaseMutex_); + calendar_->SetMilliseconds(currentTime); + calendar_->IncreaseYears(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[YEARLY_DATABASE_INDEX]); + std::vector overdueYearsTableCreateTime = GetOverdueTableCreateTime(YEARLY_DATABASE_INDEX, + calendar_->GetMilliseconds()); + if (!overdueYearsTableCreateTime.empty()) { + for (unsigned int i = 0; i < overdueYearsTableCreateTime.size(); i++) { + DeleteInvalidTable(YEARLY_DATABASE_INDEX, overdueYearsTableCreateTime.at(i)); + } + } + calendar_->SetMilliseconds(currentTime); + calendar_->IncreaseMonths(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[MONTHLY_DATABASE_INDEX]); + std::vector overdueMonthsTableCreateTime = GetOverdueTableCreateTime(MONTHLY_DATABASE_INDEX, + calendar_->GetMilliseconds()); + if (!overdueMonthsTableCreateTime.empty()) { + for (unsigned int i = 0; i < overdueMonthsTableCreateTime.size(); i++) { + DeleteInvalidTable(MONTHLY_DATABASE_INDEX, overdueMonthsTableCreateTime.at(i)); + } + } + calendar_->SetMilliseconds(currentTime); + calendar_->IncreaseWeeks(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[WEEKLY_DATABASE_INDEX]); + std::vector overdueWeeksTableCreateTime = GetOverdueTableCreateTime(WEEKLY_DATABASE_INDEX, + calendar_->GetMilliseconds()); + if (!overdueWeeksTableCreateTime.empty()) { + for (unsigned int i = 0; i < overdueWeeksTableCreateTime.size(); i++) { + DeleteInvalidTable(WEEKLY_DATABASE_INDEX, overdueWeeksTableCreateTime.at(i)); + } + } + calendar_->SetMilliseconds(currentTime); + calendar_->IncreaseDays(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[DAILY_DATABASE_INDEX]); + std::vector overdueDaysTableCreateTime = GetOverdueTableCreateTime(DAILY_DATABASE_INDEX, + calendar_->GetMilliseconds()); + if (!overdueDaysTableCreateTime.empty()) { + for (unsigned int i = 0; i < overdueDaysTableCreateTime.size(); i++) { + DeleteInvalidTable(DAILY_DATABASE_INDEX, overdueDaysTableCreateTime.at(i)); + } + } + for (unsigned int i = 0; i < sortedTableArray_.size(); i++) { + HandleTableInfo(i); + DeleteExcessiveTableData(i); + } +} + +void BundleActiveUsageDatabase::RenewTableTime(int64_t changedTime) +{ + std::lock_guard lock(databaseMutex_); + std::string logInfo; + for (unsigned int i = 0; i < sortedTableArray_.size(); i++) { + if (sortedTableArray_.at(i).empty()) { + continue; + } + std::vector tableArray = sortedTableArray_.at(i); + for (unsigned int j = 0; j < tableArray.size(); j++) { + int64_t newTime = tableArray.at(j) + changedTime; + if (newTime < 0) { + DeleteInvalidTable(i, tableArray.at(j)); + } else { + RenameTableName(i, tableArray.at(j), newTime); + } + } + sortedTableArray_.at(i).clear(); + HandleTableInfo(i); + DeleteExcessiveTableData(i); + } + if (eventTableName_ != UNKNOWN_TABLE_NAME) { + int64_t oldTime = ParseStartTime(eventTableName_); + int64_t newTime = oldTime + changedTime; + if (newTime < 0) { + int32_t deletedResult = DeleteInvalidTable(EVENT_DATABASE_INDEX, oldTime); + if (deletedResult == BUNDLE_ACTIVE_SUCCESS) { + eventTableName_ = UNKNOWN_TABLE_NAME; + } + } else { + int32_t renamedResult = RenameTableName(EVENT_DATABASE_INDEX, oldTime, newTime); + if (renamedResult == BUNDLE_ACTIVE_SUCCESS) { + eventTableName_ = EVENT_LOG_TABLE + std::to_string(newTime); + } + } + } +} + +void BundleActiveUsageDatabase::UpdateUsageData(int32_t databaseType, BundleActivePeriodStats &stats) +{ + std::lock_guard lock(databaseMutex_); + if (databaseType < 0 || databaseType >= EVENT_DATABASE_INDEX) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase UpdateUsageData databaseType is invalid : %{public}d", + databaseType); + return; + } + if (databaseType == DAILY_DATABASE_INDEX) { + if (stats.events_.Size() != 0) { + FlushEventInfo(EVENT_DATABASE_INDEX, stats); + } + } + int32_t packageTableIndex = BundleActiveBinarySearch::GetInstance()->BinarySearch( + sortedTableArray_.at(databaseType), stats.beginTime_); + if (packageTableIndex < 0) { + CreatePackageLogTable(databaseType, stats.beginTime_); + if (databaseType == DAILY_DATABASE_INDEX) { + eventBeginTime_ = stats.beginTime_; + DeleteExcessiveTableData(EVENT_DATABASE_INDEX); + } + packageTableIndex = ~packageTableIndex; + sortedTableArray_.at(databaseType).insert(sortedTableArray_.at(databaseType).begin() + packageTableIndex, + stats.beginTime_); + DeleteExcessiveTableData(databaseType); + } + FlushPackageInfo(databaseType, stats); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t systemTime = timer->GetWallTimeMs(); + stats.lastTimeSaved_ = systemTime; +} + +std::vector BundleActiveUsageDatabase::QueryDatabaseUsageStats(int32_t databaseType, + int64_t beginTime, int64_t endTime, int userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase::QueryDatabaseUsageStats called, begin time is %{public}lld, " + "end time is %{public}lld", beginTime, endTime); + std::lock_guard lock(databaseMutex_); + std::vector databaseUsageStats; + if (databaseType < 0 || databaseType >= sortedTableArray_.size()) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseUsageStats databaseType is invalid, databaseType = " + "%{public}d", databaseType); + return databaseUsageStats; + } + if (endTime <= beginTime) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseUsageStats endTime(%{public}lld) <= " + "beginTime(%{public}lld)", endTime, beginTime); + return databaseUsageStats; + } + int32_t startIndex = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(databaseType)); + if (startIndex < 0) { + startIndex = 0; + } + int32_t endIndex = NearIndexOnOrBeforeCurrentTime(endTime, sortedTableArray_.at(databaseType)); + if (endIndex < 0) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseUsageStats no usage stats data"); + return databaseUsageStats; + } + if (sortedTableArray_.at(databaseType).at(endIndex) == endTime) { + endIndex--; + if (endIndex < 0) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseUsageStats no usage stats data"); + return databaseUsageStats; + } + } + int64_t packageTableTime; + std::string packageTableName; + std::string queryPackageSql; + std::vector queryCondition; + for (int32_t i = startIndex; i <= endIndex; i++) { + packageTableTime = sortedTableArray_.at(databaseType).at(i); + packageTableName = PACKAGE_LOG_TABLE + std::to_string(packageTableTime); + queryCondition.push_back(std::to_string(userId)); + if (startIndex == endIndex) { + int64_t diff = beginTime - packageTableTime; + if (diff >= 0) { + queryCondition.push_back(std::to_string(diff)); + } else { + queryCondition.push_back(std::to_string(LAST_TIME_IN_MILLIS_MIN)); + } + queryCondition.push_back(std::to_string(endTime - packageTableTime)); + queryPackageSql = "select * from " + packageTableName + + " where userId = ? and lastTime >= ? and lastTime <= ?"; + } else { + if (i == startIndex) { + int64_t diff = beginTime - packageTableTime; + if (diff >= 0) { + queryCondition.push_back(std::to_string(diff)); + } else { + queryCondition.push_back(std::to_string(LAST_TIME_IN_MILLIS_MIN)); + } + queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime >= ?"; + } else if (i == endIndex) { + queryCondition.push_back(std::to_string(endTime - packageTableTime)); + queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime <= ?"; + } else { + queryPackageSql = "select * from " + packageTableName + " where userId = ?"; + } + } + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql, + queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseUsageStats bundleActiveResult is invalid"); + return databaseUsageStats; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + BundleActivePackageStats usageStats; + int64_t relativeLastTimeUsed; + int64_t relativeLastTimeFrontServiceUsed; + for (int32_t j = 0; j < tableRowNumber; j++) { + bundleActiveResult->GoToRow(j); + bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats.bundleName_); + bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats.bundleStartedCount_); + bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, usageStats.lastTimeUsed_); + bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed); + usageStats.lastTimeUsed_ = relativeLastTimeUsed + packageTableTime; + bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed); + usageStats.lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed + packageTableTime; + bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats.totalInFrontTime_); + bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX, + usageStats.totalContiniousTaskUsedTime_); + databaseUsageStats.push_back(usageStats); + } + queryCondition.clear(); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase::QueryDatabaseUsageStats normally end"); + return databaseUsageStats; +} + +std::vector BundleActiveUsageDatabase::QueryDatabaseEvents(int64_t beginTime, int64_t endTime, + int userId, std::string bundleName) +{ + std::lock_guard lock(databaseMutex_); + std::vector databaseEvents; + if (eventTableName_ == UNKNOWN_TABLE_NAME) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseEvents eventTable does not exist"); + return databaseEvents; + } + if (endTime <= beginTime) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseEvents endTime(%{public}lld) <= " + "beginTime(%{public}lld)", endTime, beginTime); + return databaseEvents; + } + int64_t eventTableTime = ParseStartTime(eventTableName_); + if (endTime < eventTableTime) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseEvents endTime(%{public}lld) <= " + "eventTableTime(%{public}lld)", endTime, eventTableTime); + return databaseEvents; + } + std::vector queryCondition; + int64_t diff = beginTime - eventTableTime; + if (diff >= 0) { + queryCondition.push_back(std::to_string(diff)); + } else { + queryCondition.push_back(std::to_string(EVENT_TIME_IN_MILLIS_MIN)); + } + queryCondition.push_back(std::to_string(endTime - eventTableTime)); + queryCondition.push_back(std::to_string(userId)); + std::string queryEventSql; + if (bundleName.empty()) { + queryEventSql = "select * from " + eventTableName_ + " where timeStamp >= ? and timeStamp <= ? and userId = ?"; + } else { + queryCondition.push_back(bundleName); + queryEventSql = "select * from " + eventTableName_ + + " where timeStamp >= ? and timeStamp <= ? and userId = ? and bundleName = ?"; + } + std::unique_ptr bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX, + queryEventSql, queryCondition); + if (bundleActiveResult == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase QueryDatabaseEvents bundleActiveResult is invalid"); + return databaseEvents; + } + int32_t tableRowNumber; + bundleActiveResult->GetRowCount(tableRowNumber); + BundleActiveEvent event; + std::string timeStamp; + std::string relativeTimeStamp; + for (int32_t i = 0; i < tableRowNumber; i++) { + bundleActiveResult->GoToRow(i); + bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.bundleName_); + bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_); + bundleActiveResult->GetString(TIME_STAMP_COLUMN_INDEX, relativeTimeStamp); + event.timeStamp_ = atoll(relativeTimeStamp.c_str()) + eventTableTime; + bundleActiveResult->GetString(ABILITY_ID_COLUMN_INDEX, event.abilityId_); + databaseEvents.push_back(event); + } + return databaseEvents; +} + +void BundleActiveUsageDatabase::OnPackageUninstalled(const int& userId, const std::string& bundleName) +{ + std::lock_guard lock(databaseMutex_); + for (uint32_t i = 0; i < sortedTableArray_.size(); i++) { + if (sortedTableArray_.at(i).empty()) { + continue; + } + for (uint32_t j = 0; j < sortedTableArray_.at(i).size(); j++) { + std::string packageTableName = PACKAGE_LOG_TABLE + std::to_string(sortedTableArray_.at(i).at(j)); + DeleteUninstalledInfo(userId, bundleName, packageTableName, i); + } + } + if (eventTableName_ != UNKNOWN_TABLE_NAME) { + DeleteUninstalledInfo(userId, bundleName, eventTableName_, EVENT_DATABASE_INDEX); + } + if (bundleHistoryTableName_ != UNKNOWN_TABLE_NAME) { + DeleteUninstalledInfo(userId, bundleName, bundleHistoryTableName_, APP_GROUP_DATABASE_INDEX); + } +} + +void BundleActiveUsageDatabase::DeleteUninstalledInfo(const int& userId, const std::string& bundleName, + const std::string& tableName, unsigned int databaseType) +{ + std::shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveUsageDatabase DeleteUninstalledInfo get rdbStore failed"); + return; + } + int32_t deletedRows = BUNDLE_ACTIVE_FAIL; + std::vector queryCondition; + queryCondition.push_back(std::to_string(userId)); + queryCondition.push_back(bundleName); + rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ?", queryCondition); +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_user_service.cpp b/services/common/src/bundle_active_user_service.cpp deleted file mode 100644 index 932fcc2acea6e1364979d670dbb838d1ce748bf7..0000000000000000000000000000000000000000 --- a/services/common/src/bundle_active_user_service.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - */ - -#include "bundle_active_user_service.h" - -namespace OHOS { -namespace BundleActive { -BundleActiveUserService::BundleActiveUserService(int userId) -{ - currentStats_.reserve(BundleActivePeriodStats::PERIOD_COUNT); - userId_ = userId; - statsChanged_ = false; -} - -void BundleActiveUserService::NotifyStatsChanged() -{ - if (!statsChanged_) { - statsChanged_ = true; - } -} - -void BundleActiveUserService::ReportEvent(BundleActiveEvent event) -{ - BundleActivePeriodStats currentDailyStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; - if (event.eventId_ == BundleActiveEvent::ABILITY_FOREGROUND) { - if (!event.bundleName_.empty() && event.bundleName_ != lastBackgroundBundle_) { - incrementBundleLaunch_ = true; - } - } else if (event.eventId_ == BundleActiveEvent::ABILITY_BACKGROUND) { - if (!event.bundleName_.empty()) { - lastBackgroundBundle_ = event.bundleName_; - } - } - for (int i = 0; i < currentStats_.size(); i++) { - switch (event.eventId_) { - case BundleActiveEvent::SCREEN_INTERACTIVE: - currentStats_[i].UpdateScreenInteractive(event.timeStamp_); - break; - case BundleActiveEvent::SCREEN_NON_INTERACTIVE: - currentStats_[i].UpdateScreenNonInteractive(event.timeStamp_); - break; - case BundleActiveEvent::KEYGUARD_SHOWN: - currentStats_[i].UpdateKeyguardShown(event.timeStamp_); - break; - case BundleActiveEvent::KEYGUARD_HIDDEN: - currentStats_[i].UpdateKeyguardHidden(event.timeStamp_); - break; - default: - currentStats_[i].Update(event.bundleName_, event.longTimeTaskName_, event.timeStamp_, - event.eventId_, event.abilityId_); - if (incrementBundleLaunch_) { - currentStats_[i].bundleStats_[event.bundleName_].IncrementBundleLaunchedCount(); - } - break; - } - } -} -} -} diff --git a/services/packagegroup/include/bundle_active_group_common.h b/services/packagegroup/include/bundle_active_group_common.h new file mode 100644 index 0000000000000000000000000000000000000000..b910ea5cf5bb464494cb452b64fdbbc296490d2d --- /dev/null +++ b/services/packagegroup/include/bundle_active_group_common.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_GROUP_COMMON_H +#define BUNDLE_ACTIVE_GROUP_COMMON_H + +namespace OHOS { +namespace DeviceUsageStats { +namespace DeviceUsageStatsGroupConst { +const int ACTIVE_GROUP_UNKNOWN = -1; +const int ACTIVE_GROUP_FORCED_SET = 5; +const int ACTIVE_GROUP_ALIVE = 10; +const int ACTIVE_GROUP_DAILY = 20; +const int ACTIVE_GROUP_FIXED = 30; +const int ACTIVE_GROUP_RARE = 40; +const int ACTIVE_GROUP_LIMIT = 50; +const int ACTIVE_GROUP_NEVER = 60; +const int64_t ONE_MINUTE = 60 * 1000; +const int64_t TWO_MINUTE = 2 * ONE_MINUTE; +const int64_t FOUR_MINUTE = 4 * ONE_MINUTE; +const int64_t TEN_MINUTE = 10 * ONE_MINUTE; +const int64_t SIXTEEN_MINUTE = 16 * ONE_MINUTE; +const int64_t ONE_HOUR = 60 * ONE_MINUTE; +const int64_t TWO_HOUR = 2 * ONE_HOUR; +const int64_t THREE_HOUR = 3 * ONE_HOUR; +const int64_t TWELVE_HOUR = 12 * ONE_HOUR; +const int64_t TWENTY_FOUR_HOUR = 24 * ONE_HOUR; +const int64_t FOURTY_EIGHT_HOUR = 48 * ONE_HOUR; +const int64_t DEFAULT_EVENT_TIMEOUT = ONE_HOUR; +const int64_t DEFAULT_NOTIFY_EVENT_TIMEOUT = 12 * ONE_HOUR; +const int64_t DEFAULT_SYSTEevent__TIMEOUT = 2 * ONE_HOUR; +const int64_t DEFAULT_LONT_TIME_TASK_START_EVENT_TIMEOUT = 30 * ONE_MINUTE; +const int GROUP_CONTROL_REASON_MASK = 0xFF00; +const int GROUP_CONTROL_REASON_DEFAULT = 0x0100; +const int GROUP_CONTROL_REASON_TIMEOUT = 0x0200; +const int GROUP_CONTROL_REASON_USAGE = 0x0300; +const int GROUP_CONTROL_REASON_FORCED = 0x0400; +const int GROUP_CONTROL_REASON_CALCULATED = 0x0500; +const int GROUP_EVENT_REASON_MASK = 0x00FF; +const int GROUP_EVENT_REASON_SYSTEM = 0x0001; +const int GROUP_EVENT_REASON_NOTIFY_SEEN = 0x0002; +const int GROUP_EVENT_REASON_USER_INTERACTION = 0x0003; +const int GROUP_EVENT_REASON_FOREGROUND = 0x0004; +const int GROUP_EVENT_REASON_BACKGROUND = 0x0005; +const int GROUP_EVENT_REASON_ALIVE_TIMEOUT = 0x0006; +const int GROUP_EVENT_REASON_LONG_TIME_TASK_STARTTED = 0x0007; +const int GROUP_EVENT_REASON_CALCULATED_RESTORED = 0x0008; +} +} +} +#endif \ No newline at end of file diff --git a/services/packagegroup/include/bundle_active_group_controller.h b/services/packagegroup/include/bundle_active_group_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..f094803418a80f4f8b182c04968c03adaf69bf03 --- /dev/null +++ b/services/packagegroup/include/bundle_active_group_controller.h @@ -0,0 +1,104 @@ +/* + * 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_CONTROLLER_H +#define BUNDLE_ACTIVE_GROUP_CONTROLLER_H + +#include +#include + +#include "power_mgr_client.h" +#include "application_info.h" + +#include "ibundle_active_service.h" +#include "bundle_active_event.h" +#include "bundle_active_user_history.h" +#include "bundle_mgr_interface.h" + +namespace OHOS { +namespace DeviceUsageStats { +using namespace DeviceUsageStatsGroupConst; + +class BundleActiveGroupHandler; + +class BundleActiveGroupController { +public: + using PowerMgrClient = OHOS::PowerMgr::PowerMgrClient; + using IBundleMgr = OHOS::AppExecFwk::IBundleMgr; + using ApplicationInfo = OHOS::AppExecFwk::ApplicationInfo; + using BundleInfo = OHOS::AppExecFwk::BundleInfo; + using BundleFlag = OHOS::AppExecFwk::BundleFlag; + using ApplicationFlag = OHOS::AppExecFwk::ApplicationFlag; + OHOS::AppExecFwk::ApplicationFlag flag = OHOS::AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO; + bool bundleGroupEnable_; + bool debug_ = true; + const int LEVEL_GROUP[4] = { + ACTIVE_GROUP_ALIVE, + ACTIVE_GROUP_DAILY, + ACTIVE_GROUP_FIXED, + ACTIVE_GROUP_RARE + }; + const int64_t SCREEN_TIME_LEVEL[4] = { + 0, + 0, + debug_ ? TWO_MINUTE : ONE_HOUR, + debug_ ? FOUR_MINUTE : TWO_HOUR + }; + const int64_t BOOT_TIME_LEVEL[4] = { + 0, + debug_ ? ONE_MINUTE : TWELVE_HOUR, + debug_ ? FOUR_MINUTE : TWENTY_FOUR_HOUR, + debug_ ? SIXTEEN_MINUTE : FOURTY_EIGHT_HOUR + }; + BundleActiveGroupController() {}; + ~BundleActiveGroupController() {}; + std::shared_ptr bundleUserHistory_; + void SetHandlerAndCreateUserHistory(const std::shared_ptr& groupHandler, + const int64_t& bootFromTimeStamp); + void ReportEvent(const BundleActiveEvent& event, const int64_t& bootBasedTimeStamp, const int& userId); + void CheckAndUpdateGroup(const std::string& bundleName, const int& userId, const int64_t& bootBasedTimeStamp); + bool CheckEachBundleState(const int& userId); + void CheckIdleStatsOneTime(); + void PeriodCheckBundleState(const int& userId); + void OnUserRemoved(const int& userId); + void OnScreenChanged(const bool& isScreenOn, const int64_t& bootFromTimeStamp); + void SetBundleGroup(const std::string& bundleName, const int& userId, int newGroup, int reason, + const int64_t& bootBasedTimeStamp, const bool& resetTimeout); + void RestoreToDatabase(const int& userId); + void RestoreDurationToDatabase(); + bool IsBundleInstalled(const std::string& bundleName, const int userId); + bool IsScreenOn(); + int IsBundleIdle(const std::string& bundleName, const int& userId); + int QueryPackageGroup(const int& userId, const std::string& bundleName); + void ShutDown(const int64_t bootBasedTimeStamp); + +private: + std::mutex mutex_; + bool GetBundleMgrProxy(); + std::weak_ptr activeGroupHandler_; + int EventToGroupReason(const int& eventId); + int64_t timeoutForDirectlyUse_ = debug_ ? ONE_MINUTE : ONE_HOUR; + int64_t timeoutForNotifySeen_ = debug_ ? ONE_MINUTE : TWELVE_HOUR; + int64_t timeoutForSystemInteraction_ = debug_ ? ONE_MINUTE : TEN_MINUTE; + int64_t timeoutCalculated_; + sptr sptrBundleMgr_; + bool calculationTimeOut(const std::shared_ptr& oneBundleHistory, + const int64_t& bootBasedTimeStamp); + int GetNewGroup(const std::string& bundleName, const int& userId, const int64_t& bootBasedTimeStamp); +}; +} +} + +#endif \ No newline at end of file diff --git a/services/packagegroup/include/bundle_active_group_handler.h b/services/packagegroup/include/bundle_active_group_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..2bf694bf78af9a76ccbfaa258e5dd3afa3284de8 --- /dev/null +++ b/services/packagegroup/include/bundle_active_group_handler.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 BUNDLE_ACTIVE_GROUP_HANDLER_H +#define BUNDLE_ACTIVE_GROUP_HANDLER_H + +#include "event_handler.h" +#include "event_runner.h" + +#include "ibundle_active_service.h" +#include "bundle_active_group_controller.h" +#include "bundle_active_group_common.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupHandlerObject { +public: + std::string bundleName_; + int userId_; + BundleActiveGroupHandlerObject() {}; + BundleActiveGroupHandlerObject(const BundleActiveGroupHandlerObject& orig); + ~BundleActiveGroupHandlerObject() {}; +}; + +class BundleActiveGroupHandler : public AppExecFwk::EventHandler { +public: + explicit BundleActiveGroupHandler(const std::shared_ptr &runner); + ~BundleActiveGroupHandler() = default; + /** + * Process the event. Developers should override this method. + * + * @param event The event should be processed. + */ + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; + void Init(const std::shared_ptr& bundleActiveController); + static const int MSG_CHECK_BUNDLE_STATE = 0; + static const int MSG_ONE_TIME_CHECK_BUNDLE_STATE = 1; + static const int MSG_CHECK_IDLE_STATE = 2; + static const int CHECK_IDLE_INTERVAL = THREE_HOUR; + +private: + std::shared_ptr bundleActiveGroupController_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/packagegroup/include/bundle_active_package_history.h b/services/packagegroup/include/bundle_active_package_history.h new file mode 100644 index 0000000000000000000000000000000000000000..c78c30408a973ad9b76a477ffe5d9d1f2a2c57f1 --- /dev/null +++ b/services/packagegroup/include/bundle_active_package_history.h @@ -0,0 +1,38 @@ +/* + * 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_USAGE_HISTORY_H +#define BUNDLE_ACTIVE_USAGE_HISTORY_H + +#include "ibundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActivePackageHistory { +public: + int64_t lastBootFromUsedTimeStamp_; + int64_t lastScreenUsedTimeStamp_; + int64_t lastGroupCalculatedTimeStamp_; + int lastCalculatedGroup_; + int currentGroup_; + int reasonInGroup_; + int64_t bundleAliveTimeoutTimeStamp_; + int64_t bundleDailyTimeoutTimeStamp_; + BundleActivePackageHistory() {}; + ~BundleActivePackageHistory() {}; +}; +} +} +#endif \ No newline at end of file diff --git a/services/packagegroup/include/bundle_active_user_history.h b/services/packagegroup/include/bundle_active_user_history.h new file mode 100644 index 0000000000000000000000000000000000000000..3177dcb81b9a7092a53b516711d0dafa4387deef --- /dev/null +++ b/services/packagegroup/include/bundle_active_user_history.h @@ -0,0 +1,66 @@ +/* + * 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_USER_HISTORY_H +#define BUNDLE_ACTIVE_USER_HISTORY_H + +#include +#include +#include + +#include "bundle_active_package_history.h" +#include "bundle_active_group_common.h" +#include "bundle_active_usage_database.h" + +namespace OHOS { +namespace DeviceUsageStats { +using namespace DeviceUsageStatsGroupConst; + +class BundleActiveUserHistory { +public: + std::map>>> userHistory_; + int64_t bootBasedTimeStamp_; + int64_t bootBasedDuration_; + int64_t screenOnTimeStamp_; + int64_t ScreenOnDuration_; + BundleActiveUsageDatabase database_; + BundleActiveUserHistory(const int64_t& bootBasedTimeStamp); + std::shared_ptr GetUsageHistoryForBundle(const std::string& bundleName, + const int& userId, const int64_t& bootBasedTimeStamp, const bool& create); + std::shared_ptr>> GetUserHistory( + const int& userId, const bool& create); + std::shared_ptr GetUsageHistoryInUserHistory(std::shared_ptr>> oneUserHistory, std::string bundleName, + int64_t bootBasedTimeStamp, bool create); + int64_t GetBootBasedTimeStamp(int64_t bootBasedTimeStamp); + int64_t GetScreenOnTimeStamp(int64_t bootBasedTimeStamp); + void ReportUsage(std::shared_ptr oneBundleUsageHistory, const std::string& bundleName, + const int& newGroup, const int& groupReason, const int64_t& bootBasedTimeStamp, + const int64_t& timeUntilNextCheck); + void SetBundleGroup(const std::string& bundleName, const int& userId, const int64_t& bootBasedTimeStamp, + int newGroup, int groupReason, const bool& resetTimeout); + int GetLevelIndex(const std::string& bundleName, const int& userId, const int64_t& bootBasedTimeStamp, + const int64_t screenTimeLevel[4], const int64_t bootFromTimeLevel[4]); + void WriteDeviceDuration(); + void WriteBundleUsage(const int& userId); + void printdata(int userId); + void UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t& bootBasedTimeStamp, + const bool& isShutdown = false); +private: + bool isScreenOn_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/packagegroup/src/bundle_active_group_controller.cpp b/services/packagegroup/src/bundle_active_group_controller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bdd2d7af30beff9ad2536aec14047dfde0a9d614 --- /dev/null +++ b/services/packagegroup/src/bundle_active_group_controller.cpp @@ -0,0 +1,360 @@ +/* + * 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 "time_service_client.h" + +#include "bundle_active_user_history.h" +#include "bundle_active_group_handler.h" +#include "ibundle_active_service.h" +#include "bundle_active_group_controller.h" + +namespace OHOS { +namespace DeviceUsageStats { +using namespace DeviceUsageStatsGroupConst; + +void BundleActiveGroupController::RestoreDurationToDatabase() +{ + std::lock_guard lock(mutex_); + bundleUserHistory_->WriteDeviceDuration(); +} + +void BundleActiveGroupController::RestoreToDatabase(const int& userId) +{ + std::lock_guard lock(mutex_); + bundleUserHistory_->WriteBundleUsage(userId); +} + +void BundleActiveGroupController::OnUserRemoved(const int& userId) +{ + std::lock_guard lock(mutex_); + bundleUserHistory_->userHistory_.erase(userId); +} + +void BundleActiveGroupController::OnScreenChanged(const bool& isScreenOn, const int64_t& bootFromTimeStamp) +{ + std::lock_guard lock(mutex_); + bundleUserHistory_->UpdateBootBasedAndScreenTime(isScreenOn, bootFromTimeStamp); +} + +void BundleActiveGroupController::SetHandlerAndCreateUserHistory( + const std::shared_ptr& groupHandler, const int64_t& bootFromTimeStamp) +{ + if (bundleUserHistory_ == nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::SetHandlerAndCreateUserHistory bundleUserHistory_ is null, " + "called constructor, bootstamp is %{public}lld", bootFromTimeStamp); + bundleUserHistory_ = std::make_shared(bootFromTimeStamp); + } + OnScreenChanged(IsScreenOn(), bootFromTimeStamp); + activeGroupHandler_ = groupHandler; +} + +bool BundleActiveGroupController::GetBundleMgrProxy() +{ + if (!sptrBundleMgr_) { + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + BUNDLE_ACTIVE_LOGE("Failed to get system ability mgr."); + return false; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + BUNDLE_ACTIVE_LOGE("Failed to get bundle manager service."); + return false; + } + sptrBundleMgr_ = iface_cast(remoteObject); + if ((!sptrBundleMgr_) || (!sptrBundleMgr_->AsObject())) { + BUNDLE_ACTIVE_LOGE("Failed to get system bundle manager services ability"); + return false; + } + } + return true; +} + +void BundleActiveGroupController::PeriodCheckBundleState(const int& userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::PeriodCheckBundleState called"); + if (!activeGroupHandler_.expired()) { + BundleActiveGroupHandlerObject tmpGroupHandlerObj; + tmpGroupHandlerObj.userId_ = userId; + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpGroupHandlerObj); + auto handlerEvent = AppExecFwk::InnerEvent::Get(BundleActiveGroupHandler::MSG_CHECK_IDLE_STATE, + handlerobjToPtr); + activeGroupHandler_.lock()->SendEvent(handlerEvent); + } +} + +bool BundleActiveGroupController::CheckEachBundleState(const int& userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::CheckEachBundleState called, userid is %{public}d", userId); + std::vector allBundlesForUser; + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState get bundle manager proxy failed!"); + return false; + } + sptrBundleMgr_->GetApplicationInfos(flag, userId, allBundlesForUser); + std::vector bundleNamesOfUser; + for (auto oneBundle : allBundlesForUser) { + bundleNamesOfUser.push_back(oneBundle.bundleName); + } + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + for (auto oneBundleName : bundleNamesOfUser) { + CheckAndUpdateGroup(oneBundleName, userId, bootBasedTimeStamp); + } + bundleUserHistory_->printdata(userId); + return true; +} + +void BundleActiveGroupController::CheckIdleStatsOneTime() +{ + auto handlerEvent = AppExecFwk::InnerEvent::Get( + BundleActiveGroupHandler::MSG_ONE_TIME_CHECK_BUNDLE_STATE); + if (!activeGroupHandler_.expired()) { + activeGroupHandler_.lock()->SendEvent(handlerEvent); + } +} + +int BundleActiveGroupController::GetNewGroup(const std::string& bundleName, const int& userId, + const int64_t& bootBasedTimeStamp) +{ + int groupIndex = bundleUserHistory_->GetLevelIndex(bundleName, userId, bootBasedTimeStamp, SCREEN_TIME_LEVEL, + BOOT_TIME_LEVEL); + if (groupIndex < 0) { + return -1; + } + return LEVEL_GROUP[groupIndex]; +} + +bool BundleActiveGroupController::calculationTimeOut( + const std::shared_ptr& oneBundleHistory, const int64_t& bootBasedTimeStamp) +{ + if (oneBundleHistory == nullptr) { + return false; + } + int64_t lastGroupCalculatedTimeStamp = oneBundleHistory->lastGroupCalculatedTimeStamp_; + return lastGroupCalculatedTimeStamp > 0 && bundleUserHistory_->GetBootBasedTimeStamp(bootBasedTimeStamp) + - lastGroupCalculatedTimeStamp > timeoutCalculated_; +} + +int BundleActiveGroupController::EventToGroupReason(const int& eventId) +{ + switch (eventId) { + case BundleActiveEvent::ABILITY_FOREGROUND: + return GROUP_EVENT_REASON_FOREGROUND; + case BundleActiveEvent::ABILITY_BACKGROUND: + return GROUP_EVENT_REASON_BACKGROUND; + case BundleActiveEvent::SYSTEM_INTERACTIVE: + return GROUP_EVENT_REASON_SYSTEM; + case BundleActiveEvent::USER_INTERACTIVE: + return GROUP_EVENT_REASON_USER_INTERACTION; + case BundleActiveEvent::NOTIFICATION_SEEN: + return GROUP_EVENT_REASON_NOTIFY_SEEN; + case BundleActiveEvent::LONG_TIME_TASK_STARTTED: + return GROUP_EVENT_REASON_LONG_TIME_TASK_STARTTED; + default: + return 0; + } +} + +void BundleActiveGroupController::ReportEvent(const BundleActiveEvent& event, const int64_t& bootBasedTimeStamp, + const int& userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::ReportEvent called"); + if (bundleGroupEnable_ == false) { + return; + } + std::lock_guard lock(mutex_); + if (IsBundleInstalled(event.bundleName_, userId) == false) { + return; + } + int eventId = event.eventId_; + if (eventId == BundleActiveEvent::ABILITY_FOREGROUND || + eventId == BundleActiveEvent::ABILITY_BACKGROUND || + eventId == BundleActiveEvent::SYSTEM_INTERACTIVE || + eventId == BundleActiveEvent::USER_INTERACTIVE || + eventId == BundleActiveEvent::NOTIFICATION_SEEN || + eventId == BundleActiveEvent::LONG_TIME_TASK_STARTTED) { + std::shared_ptr bundleUsageHistory = bundleUserHistory_->GetUsageHistoryForBundle( + event.bundleName_, userId, bootBasedTimeStamp, true); + if (bundleUsageHistory == nullptr) { + return; + } + int64_t timeUntilNextCheck; + int eventReason = EventToGroupReason(eventId); + switch (eventId) { + case BundleActiveEvent::NOTIFICATION_SEEN: + bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_DAILY, + eventReason, 0, bootBasedTimeStamp + timeoutForNotifySeen_); + timeUntilNextCheck = timeoutForNotifySeen_; + break; + case BundleActiveEvent::SYSTEM_INTERACTIVE: + bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, + eventReason, 0, bootBasedTimeStamp + timeoutForSystemInteraction_); + timeUntilNextCheck = timeoutForSystemInteraction_; + break; + default: + bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, + eventReason, bootBasedTimeStamp, bootBasedTimeStamp + timeoutForDirectlyUse_); + timeUntilNextCheck = timeoutForDirectlyUse_; + break; + } + BundleActiveGroupHandlerObject tmpGroupHandlerObj; + tmpGroupHandlerObj.userId_ = userId; + tmpGroupHandlerObj.bundleName_ = event.bundleName_; + std::shared_ptr handlerobjToPtr = + std::make_shared(tmpGroupHandlerObj); + auto handlerEvent = AppExecFwk::InnerEvent::Get(BundleActiveGroupHandler::MSG_CHECK_BUNDLE_STATE, + handlerobjToPtr); + if (!activeGroupHandler_.expired()) { + activeGroupHandler_.lock()->SendEvent(handlerEvent, timeUntilNextCheck); + } + } +} + +void BundleActiveGroupController::CheckAndUpdateGroup(const std::string& bundleName, const int& userId, + const int64_t& bootBasedTimeStamp) +{ + std::lock_guard lock(mutex_); + auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle(bundleName, userId, bootBasedTimeStamp, true); + if (oneBundleHistory == nullptr) { + return; + } + int groupReason = oneBundleHistory->reasonInGroup_; + int oldGroupControlReason = groupReason & GROUP_CONTROL_REASON_MASK; + if (oldGroupControlReason == GROUP_CONTROL_REASON_FORCED) { + return; + } + int oldGroup = oneBundleHistory->currentGroup_; + int newGroup = std::max(oldGroup, ACTIVE_GROUP_ALIVE); + if (oldGroupControlReason == GROUP_CONTROL_REASON_DEFAULT || + oldGroupControlReason == GROUP_CONTROL_REASON_USAGE || + oldGroupControlReason == GROUP_CONTROL_REASON_TIMEOUT) { + newGroup = GetNewGroup(bundleName, userId, bootBasedTimeStamp); + if (newGroup < 0) { + return; + } + groupReason = GROUP_CONTROL_REASON_TIMEOUT; + } + int64_t bootBasedTimeStampAdjusted = bundleUserHistory_->GetBootBasedTimeStamp(bootBasedTimeStamp); + if (newGroup >= ACTIVE_GROUP_ALIVE && oneBundleHistory->bundleAliveTimeoutTimeStamp_ > + bootBasedTimeStampAdjusted) { + newGroup = ACTIVE_GROUP_ALIVE; + groupReason = oneBundleHistory->reasonInGroup_; + } else if (newGroup >= ACTIVE_GROUP_DAILY && oneBundleHistory->bundleDailyTimeoutTimeStamp_ > + bootBasedTimeStampAdjusted) { + newGroup = ACTIVE_GROUP_DAILY; + groupReason = (newGroup == oldGroup) ? oneBundleHistory->reasonInGroup_ : GROUP_CONTROL_REASON_USAGE | + GROUP_EVENT_REASON_ALIVE_TIMEOUT; + } + if (oldGroup < newGroup) { + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::CheckAndUpdateGroup called SetBundleGroup"); + bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, groupReason, false); + } +} + +void BundleActiveGroupController::SetBundleGroup(const std::string& bundleName, const int& userId, int newGroup, + int reason, const int64_t& bootBasedTimeStamp, const bool& resetTimeout) +{ + std::lock_guard lock(mutex_); + if (IsBundleInstalled(bundleName, userId) == false) { + return; + } + 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) { + newGroup = ACTIVE_GROUP_ALIVE; + reason = oneBundleHistory->reasonInGroup_; + } else if (newGroup > ACTIVE_GROUP_DAILY && oneBundleHistory->bundleDailyTimeoutTimeStamp_ > + bootBasedTimeStampAdjusted) { + newGroup = ACTIVE_GROUP_DAILY; + if (oneBundleHistory->currentGroup_ != newGroup) { + reason = GROUP_CONTROL_REASON_USAGE | GROUP_CONTROL_REASON_TIMEOUT; + } else { + reason = oneBundleHistory->reasonInGroup_; + } + } + bundleUserHistory_->SetBundleGroup(bundleName, userId, bootBasedTimeStamp, newGroup, reason, false); +} + +int BundleActiveGroupController::IsBundleIdle(const std::string& bundleName, const int& userId) +{ + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + if (IsBundleInstalled(bundleName, userId) == false) { + return -1; + } + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle( + bundleName, userId, bootBasedTimeStamp, false); + if (oneBundleHistory == nullptr) { + return 1; + } else if (oneBundleHistory->currentGroup_ >= ACTIVE_GROUP_RARE) { + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::IsBundleIdle, bundle group is %{public}d", + oneBundleHistory->currentGroup_); + return 1; + } else { + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::IsBundleIdle, bundle group is %{public}d", + oneBundleHistory->currentGroup_); + return 0; + } +} + +int BundleActiveGroupController::QueryPackageGroup(const int& userId, const std::string& bundleName) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::QueryPackageGroup called"); + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + if (IsBundleInstalled(bundleName, userId) == false) { + return -1; + } + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + auto oneBundleHistory = bundleUserHistory_->GetUsageHistoryForBundle( + bundleName, userId, bootBasedTimeStamp, false); + if (oneBundleHistory == nullptr) { + return -1; + } else { + return oneBundleHistory->currentGroup_; + } +} + +bool BundleActiveGroupController::IsBundleInstalled(const std::string& bundleName, const int userId) +{ + ApplicationInfo bundleInfo; + if (sptrBundleMgr_ != nullptr && sptrBundleMgr_->GetApplicationInfo( + bundleName, ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, bundleInfo) == false) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::IsBundleInstalled bundle is not installed!"); + return false; + } + return true; +} + +void BundleActiveGroupController::ShutDown(const int64_t bootBasedTimeStamp) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::ShutDown called"); + bundleUserHistory_->UpdateBootBasedAndScreenTime(false, bootBasedTimeStamp, true); +} + +bool BundleActiveGroupController::IsScreenOn() +{ + bool result = PowerMgrClient::GetInstance().IsScreenOn(); + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::IsScreenOn() is %{public}d", result); + return result; +} +} +} \ No newline at end of file diff --git a/services/packagegroup/src/bundle_active_group_handler.cpp b/services/packagegroup/src/bundle_active_group_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce1e0898361635bbbc535092faada9508f1223c6 --- /dev/null +++ b/services/packagegroup/src/bundle_active_group_handler.cpp @@ -0,0 +1,96 @@ +/* + * 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 "time_service_client.h" +#include "os_account_manager.h" + +#include "bundle_active_group_handler.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveGroupHandlerObject::BundleActiveGroupHandlerObject(const BundleActiveGroupHandlerObject& orig) +{ + bundleName_ = orig.bundleName_; + userId_ = orig.userId_; +} + +BundleActiveGroupHandler::BundleActiveGroupHandler + (const std::shared_ptr &runner) : AppExecFwk::EventHandler(runner) +{ +} + +void BundleActiveGroupHandler::Init(const std::shared_ptr& bundleActiveController) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveGroupHandler::Init called"); + if (bundleActiveController == nullptr) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupHandler::Init failed bundleActiveController is null"); + } + bundleActiveGroupController_ = bundleActiveController; +} + +void BundleActiveGroupHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) +{ + switch (event->GetInnerEventId()) { + case MSG_CHECK_BUNDLE_STATE: { + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveGroupHandlerObject tmpHandlerobj = *ptrToHandlerobj; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + bundleActiveGroupController_->CheckAndUpdateGroup( + tmpHandlerobj.bundleName_, tmpHandlerobj.userId_, bootBasedTimeStamp); + bundleActiveGroupController_->RestoreToDatabase(tmpHandlerobj.userId_); + break; + } + case MSG_ONE_TIME_CHECK_BUNDLE_STATE: { + std::vector osAccountInfos; + OHOS::ErrCode ret = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos); + if (ret != ERR_OK) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::GetAllActiveUser failed"); + return; + } + if (osAccountInfos.size() == 0) { + BUNDLE_ACTIVE_LOGI("BundleActiveCore::GetAllActiveUser size is 0"); + return; + } + for (int i = 0; i < osAccountInfos.size(); i++) { + bundleActiveGroupController_->CheckEachBundleState(osAccountInfos[i].GetLocalId()); + bundleActiveGroupController_->RestoreToDatabase(osAccountInfos[i].GetLocalId()); + } + RemoveEvent(MSG_ONE_TIME_CHECK_BUNDLE_STATE); + break; + } + case MSG_CHECK_IDLE_STATE: { + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveGroupHandlerObject tmpHandlerobj = *ptrToHandlerobj; + if (bundleActiveGroupController_->CheckEachBundleState(tmpHandlerobj.userId_) && + bundleActiveGroupController_->bundleGroupEnable_) { + BundleActiveGroupHandlerObject GroupHandlerObj; + GroupHandlerObj.userId_ = tmpHandlerobj.userId_; + std::shared_ptr handlerobjToPtr = + std::make_shared(GroupHandlerObj); + auto handlerEvent = AppExecFwk::InnerEvent::Get(BundleActiveGroupHandler::MSG_CHECK_IDLE_STATE, + handlerobjToPtr); + bundleActiveGroupController_->RestoreToDatabase(GroupHandlerObj.userId_); + SendEvent(handlerEvent, CHECK_IDLE_INTERVAL); + } + break; + } + default: { + break; + } + } +} +} +} \ No newline at end of file diff --git a/services/packagegroup/src/bundle_active_user_history.cpp b/services/packagegroup/src/bundle_active_user_history.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4fc6ec26e8a6a0e47d87d0a091e19a17ef2e3c99 --- /dev/null +++ b/services/packagegroup/src/bundle_active_user_history.cpp @@ -0,0 +1,220 @@ +/* + * 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_user_history.h" +#include "bundle_active_group_common.h" +#include "bundle_active_constant.h" + +namespace OHOS { +namespace DeviceUsageStats { +using namespace DeviceUsageStatsGroupConst; + +void BundleActiveUserHistory::WriteDeviceDuration() +{ + database_.PutDurationData(bootBasedDuration_, ScreenOnDuration_); +} + +void BundleActiveUserHistory::WriteBundleUsage(const int& userId) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::WriteBundleUsage called"); + auto userHistory = GetUserHistory(userId, false); + if (userHistory == nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::WriteBundleUsage called, no existed user history, return"); + return; + } + database_.PutBundleHistoryData(userId, userHistory); +} + +BundleActiveUserHistory::BundleActiveUserHistory(const int64_t& bootBasedTimeStamp) +{ + bootBasedTimeStamp_ = bootBasedTimeStamp; + screenOnTimeStamp_ = bootBasedTimeStamp; + database_.InitUsageGroupInfo(APP_GROUP_DATABASE_INDEX); + auto bootAndScreenOnDuraton = database_.GetDurationData(); + bootBasedDuration_ = bootAndScreenOnDuraton.first; + ScreenOnDuration_ = bootAndScreenOnDuraton.second; + isScreenOn_ = false; +} + +int BundleActiveUserHistory::GetLevelIndex(const std::string& bundleName, const int& userId, + const int64_t& bootBasedTimeStamp, const int64_t screenTimeLevel[4], const int64_t bootFromTimeLevel[4]) +{ + auto oneUserHistory = GetUserHistory(userId, false); + if (oneUserHistory == nullptr) { + return -1; + } + auto oneBundleHistory = GetUsageHistoryInUserHistory(oneUserHistory, bundleName, bootBasedTimeStamp, false); + if (oneBundleHistory == nullptr) { + return -1; + } + int64_t screenDiff = GetScreenOnTimeStamp(bootBasedTimeStamp) - oneBundleHistory->lastScreenUsedTimeStamp_; + int64_t bootFromDiff = GetBootBasedTimeStamp(bootBasedTimeStamp) - oneBundleHistory->lastBootFromUsedTimeStamp_; + for (int i = 3; i >= 0; i--) { + if (screenDiff >= screenTimeLevel[i] && bootFromDiff >= bootFromTimeLevel[i]) { + return i; + } + } + return -1; +} + +int64_t BundleActiveUserHistory::GetBootBasedTimeStamp(int64_t bootBasedTimeStamp) +{ + return bootBasedTimeStamp - bootBasedTimeStamp_ + bootBasedDuration_; +} + +int64_t BundleActiveUserHistory::GetScreenOnTimeStamp(int64_t bootBasedTimeStamp) +{ + int64_t result = ScreenOnDuration_; + if (isScreenOn_) { + result += bootBasedTimeStamp - screenOnTimeStamp_; + } + return result; +} + +std::shared_ptr>> BundleActiveUserHistory::GetUserHistory(const int& userId, const bool& create) +{ + auto it = userHistory_.find(userId); + if (it == userHistory_.end() && create) { + std::shared_ptr>> usageHistoryInserted = + database_.GetBundleHistoryData(userId); + if (usageHistoryInserted == nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::GetUserHistory READ FROM DATABASE FAILD"); + usageHistoryInserted = + std::make_shared>>(); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::GetUserHistory usageHistoryInserted not null"); + userHistory_[userId] = usageHistoryInserted; + } + return userHistory_[userId]; +} + +std::shared_ptr BundleActiveUserHistory::GetUsageHistoryInUserHistory( + std::shared_ptr>> oneUserHistory, + std::string bundleName, int64_t bootBasedTimeStamp, bool create) +{ + if (oneUserHistory == nullptr) { + return nullptr; + } + auto it = oneUserHistory->find(bundleName); + if (it == oneUserHistory->end() && create) { + std::shared_ptr usageHistoryInserted = + std::make_shared(); + usageHistoryInserted->lastBootFromUsedTimeStamp_ = GetBootBasedTimeStamp(bootBasedTimeStamp); + usageHistoryInserted->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp); + usageHistoryInserted->currentGroup_ = ACTIVE_GROUP_NEVER; + usageHistoryInserted->reasonInGroup_ = GROUP_CONTROL_REASON_DEFAULT; + usageHistoryInserted->bundleAliveTimeoutTimeStamp_ = 0; + usageHistoryInserted->bundleDailyTimeoutTimeStamp_ = 0; + (*oneUserHistory)[bundleName] = usageHistoryInserted; + } + return (*oneUserHistory)[bundleName]; +} + +std::shared_ptr BundleActiveUserHistory::GetUsageHistoryForBundle( + const std::string& bundleName, const int& userId, const int64_t& bootBasedTimeStamp, const bool& create) +{ + auto oneUserHistory = GetUserHistory(userId, create); + if (oneUserHistory == nullptr) { + return nullptr; + } + auto oneBundleHistory = GetUsageHistoryInUserHistory(oneUserHistory, bundleName, bootBasedTimeStamp, create); + if (oneBundleHistory == nullptr) { + return nullptr; + } + return oneBundleHistory; +} + +void BundleActiveUserHistory::ReportUsage(std::shared_ptr oneBundleUsageHistory, + const std::string& bundleName, const int& newGroup, const int& groupReason, const int64_t& bootBasedTimeStamp, + const int64_t& timeUntilNextCheck) +{ + if (timeUntilNextCheck > bootBasedTimeStamp) { + int64_t nextCheckTimeStamp = bootBasedDuration_ + (timeUntilNextCheck - bootBasedTimeStamp_); + if (newGroup == ACTIVE_GROUP_ALIVE) { + oneBundleUsageHistory->bundleAliveTimeoutTimeStamp_ = std::max(nextCheckTimeStamp, + oneBundleUsageHistory->bundleAliveTimeoutTimeStamp_); + } else if (newGroup == ACTIVE_GROUP_DAILY) { + oneBundleUsageHistory->bundleDailyTimeoutTimeStamp_ = std::max(nextCheckTimeStamp, + oneBundleUsageHistory->bundleDailyTimeoutTimeStamp_); + } else { + return; + } + } + if (bootBasedTimeStamp > 0) { + oneBundleUsageHistory->lastBootFromUsedTimeStamp_ = bootBasedDuration_ + + (bootBasedTimeStamp - bootBasedTimeStamp_); + oneBundleUsageHistory->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp); + } + if (oneBundleUsageHistory->currentGroup_ > newGroup) { + BUNDLE_ACTIVE_LOGI("ReportUsage increase group"); + oneBundleUsageHistory->currentGroup_ = newGroup; + } + oneBundleUsageHistory->reasonInGroup_ = GROUP_CONTROL_REASON_USAGE | groupReason; +} + +void BundleActiveUserHistory::SetBundleGroup(const std::string& bundleName, const int& userId, + const int64_t& bootBasedTimeStamp, int newGroup, int groupReason, const bool& resetTimeout) +{ + std::shared_ptr>> userBundleHistory = + GetUserHistory(userId, false); + if (userBundleHistory == nullptr) { + return; + } + std::shared_ptr oneBundleHistory = GetUsageHistoryInUserHistory( + userBundleHistory, bundleName, bootBasedTimeStamp, false); + if (oneBundleHistory == nullptr) { + return; + } + oneBundleHistory->currentGroup_ = newGroup; + oneBundleHistory->reasonInGroup_ = groupReason; + int64_t setTimeStamp = GetBootBasedTimeStamp(bootBasedTimeStamp); + if (resetTimeout) { + oneBundleHistory->bundleAliveTimeoutTimeStamp_ = setTimeStamp; + oneBundleHistory->bundleDailyTimeoutTimeStamp_ = setTimeStamp; + } +} + +void BundleActiveUserHistory::UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t& bootBasedTimeStamp, + const bool& isShutdown) +{ + if (isScreenOn_ == isScreenOn && isShutdown == false) { + return; + } + isScreenOn_ = isScreenOn; + if (isScreenOn_) { + screenOnTimeStamp_ = bootBasedTimeStamp; + } else { + ScreenOnDuration_ += bootBasedTimeStamp - screenOnTimeStamp_; + bootBasedDuration_ += bootBasedTimeStamp - bootBasedTimeStamp_; + bootBasedTimeStamp_ = bootBasedTimeStamp; + } + database_.PutDurationData(bootBasedDuration_, ScreenOnDuration_); +} + +void BundleActiveUserHistory::printdata(int userId) +{ + auto oneUserHistory = GetUserHistory(userId, false); + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::printdata screen is %{public}d", isScreenOn_); + for (auto oneBundleUsage : (*oneUserHistory)) { + BUNDLE_ACTIVE_LOGI("bundle name is %{public}s, lastBootFromUsedTimeStamp_ is %{public}lld, " + "lastScreenUsedTimeStamp_ is %{public}lld, currentGroup_ is %{public}d, reasonInGroup_ is %{public}d, " + "daily time out %{public}lld, alive time out %{public}lld", oneBundleUsage.first.c_str(), + oneBundleUsage.second->lastBootFromUsedTimeStamp_, oneBundleUsage.second->lastScreenUsedTimeStamp_, + oneBundleUsage.second->currentGroup_, oneBundleUsage.second->reasonInGroup_, + oneBundleUsage.second->bundleDailyTimeoutTimeStamp_, oneBundleUsage.second->bundleAliveTimeoutTimeStamp_); + } +} +} +} \ No newline at end of file diff --git a/services/packageusage/include/bundle_active_calendar.h b/services/packageusage/include/bundle_active_calendar.h new file mode 100644 index 0000000000000000000000000000000000000000..c57f47f5a7af4858ec41f7db63539be052ba4b1e --- /dev/null +++ b/services/packageusage/include/bundle_active_calendar.h @@ -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. + */ + +#ifndef BUNDLE_ACTIVE_CALENDER_H +#define BUNDLE_ACTIVE_CALENDER_H + +#include + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveCalendar { +public: + static const int64_t ONE_SECOND_MILLISECONDS = 1000; + static const int64_t DAY_MILLISECONDS = (int64_t)1 * 1 * 5 * 60 * 1000; + static const int64_t WEEK_MILLISECONDS = (int64_t)7 * 24 * 60 * 60 * 1000; + static const int64_t MONTH_MILLISECONDS = (int64_t)30 * 24 * 60 * 60 * 1000; + static const int64_t YEAR_MILLISECONDS = (int64_t)365 * 24 * 60 * 60 * 1000; + BundleActiveCalendar(const int64_t& timeStamp); + BundleActiveCalendar() + { + time_ = 0; + } + void TruncateToDay(); + void TruncateToWeek(); + void TruncateToMonth(); + void TruncateToYear(); + void IncreaseDays(const int& val); + void IncreaseWeeks(const int& val); + void IncreaseMonths(const int& val); + void IncreaseYears(const int& val); + void SetMilliseconds(const int64_t& timeStamp); + int64_t GetMilliseconds(); + void TruncateTo(int intervalType); + +private: + int64_t time_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/common/include/bundle_active_event.h b/services/packageusage/include/bundle_active_event.h similarity index 62% rename from services/common/include/bundle_active_event.h rename to services/packageusage/include/bundle_active_event.h index 0ec081d9636bc5104538666d5c090e90cc6b9b7d..944713d305f50fae2ec2eb17eed82c4c110f79db 100644 --- a/services/common/include/bundle_active_event.h +++ b/services/packageusage/include/bundle_active_event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -19,43 +19,49 @@ #include "ibundle_active_service.h" namespace OHOS { -namespace BundleActive { -class BundleActiveEvent { +namespace DeviceUsageStats { +class BundleActiveEvent : public Parcelable { public: - static const int ABILITY_FOREGROUND = 2; - static const int ABILITY_BACKGROUND = 3; - static const int ABILITY_STOP = 4; + // external events + static const int ABILITY_FOREGROUND = 2; // onForeground() called, ability is in front. + static const int ABILITY_BACKGROUND = 3; // onBackground() called, ability is in background. + static const int ABILITY_STOP = 4; // onStop() called, ability is destroyed. static const int LONG_TIME_TASK_STARTTED = 5; - static const int LONG_TIME_TASK_STOPPED = 6; + static const int LONG_TIME_TASK_ENDED = 6; static const int SYSTEM_INTERACTIVE = 7; static const int USER_INTERACTIVE = 8; + // internal events static const int END_OF_THE_DAY = 9; - static const int DEVICE_SHUTDOWN = 10; - static const int DEVICE_STARTUP = 11; - static const int FLUSH_TO_DISK = 12; + static const int SHUTDOWN = 10; + static const int STARTUP = 11; + static const int FLUSH = 12; static const int SCREEN_INTERACTIVE = 13; static const int SCREEN_NON_INTERACTIVE = 14; static const int KEYGUARD_SHOWN = 15; static const int KEYGUARD_HIDDEN = 16; + static const int NOTIFICATION_SEEN = 17; inline static const std::string DEVICE_EVENT_PACKAGE_NAME = "openharmony"; std::string bundleName_; std::string longTimeTaskName_; std::string abilityName_; - int abilityId_; + std::string abilityId_; int64_t timeStamp_; int eventId_; - bool isIdle_; + bool isidle_; + +public: BundleActiveEvent() {}; BundleActiveEvent(const BundleActiveEvent& orig); - BundleActiveEvent(const int eventId, const int64_t timeStamp); + BundleActiveEvent(int eventId, int64_t timeStamp); std::string GetBundleName(); std::string GetAbilityName(); - int GetAbilityId(); + std::string GetAbilityId(); int64_t GetTimeStamp(); int GetEventId(); bool GetIsIdle(); + virtual bool Marshalling(Parcel &parcel) const override; + std::shared_ptr Unmarshalling(Parcel &parcel); }; } } - #endif \ No newline at end of file diff --git a/services/common/include/bundle_active_event_list.h b/services/packageusage/include/bundle_active_event_list.h similarity index 86% rename from services/common/include/bundle_active_event_list.h rename to services/packageusage/include/bundle_active_event_list.h index 17ede3f84254a7e239cbb6c1dc0a7c5c6b6dd310..68a355cdeef9d54539990cc64c743d149497514c 100644 --- a/services/common/include/bundle_active_event_list.h +++ b/services/packageusage/include/bundle_active_event_list.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -20,16 +20,16 @@ #include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveEventList { public: BundleActiveEventList(); + ~BundleActiveEventList() {}; int Size(); void Clear(); void Insert(BundleActiveEvent event); - int FindBestIndex(int64_t timeStamp); + int FindBestIndex(const int64_t& timeStamp); void Merge(const BundleActiveEventList& right); -private: std::vector events_; }; } diff --git a/services/common/include/bundle_active_event_stats.h b/services/packageusage/include/bundle_active_event_stats.h similarity index 94% rename from services/common/include/bundle_active_event_stats.h rename to services/packageusage/include/bundle_active_event_stats.h index 8400c92239a4a38215d59873029c11513f2abb45..a2f390016721708f69af820c2a459e01097d9325 100644 --- a/services/common/include/bundle_active_event_stats.h +++ b/services/packageusage/include/bundle_active_event_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -19,7 +19,7 @@ #include "ibundle_active_service.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveEventStats { public: int eventId_; diff --git a/services/common/include/bundle_active_event_tracker.h b/services/packageusage/include/bundle_active_event_tracker.h similarity index 80% rename from services/common/include/bundle_active_event_tracker.h rename to services/packageusage/include/bundle_active_event_tracker.h index 0866a4cd28ec6d029d2b4e2975ce4db758615944..13686c67c3eff1f4673d5f168c4170021ab82448 100644 --- a/services/common/include/bundle_active_event_tracker.h +++ b/services/packageusage/include/bundle_active_event_tracker.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -20,18 +20,18 @@ #include "bundle_active_event_stats.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActiveEventTracker { public: int64_t curStartTime_; int64_t lastEventTime_; int64_t duration_; int64_t count_; - void CommitTime(const int64_t timeStamp); + void CommitTime(const int64_t& timeStamp); void Update(int64_t timeStamp); - void AddToEventStats(std::vector& eventStatsList, const int eventId, - const int64_t beginTime, const int64_t endTime); - BundleActiveEventTracker() {}; + void AddToEventStats(std::vector& eventStatsList, int eventId, int64_t beginTime, + int64_t endTime); + BundleActiveEventTracker(); }; } } diff --git a/services/common/include/bundle_active_package_stats.h b/services/packageusage/include/bundle_active_package_stats.h similarity index 42% rename from services/common/include/bundle_active_package_stats.h rename to services/packageusage/include/bundle_active_package_stats.h index c893a1bc64059920a3e919e8cc34f4cb6c48d647..7c4a56a62005066efebc25dac393ea3c207deb30 100644 --- a/services/common/include/bundle_active_package_stats.h +++ b/services/packageusage/include/bundle_active_package_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,29 +13,32 @@ * limitations under the License. */ -#ifndef bundle_active_package_stats_H -#define bundle_active_package_stats_H +#ifndef BUNDLE_ACTIVE_USAGE_STATS_H +#define BUNDLE_ACTIVE_USAGE_STATS_H #include "ibundle_active_service.h" #include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { -class BundleActivePackageStats { +namespace DeviceUsageStats { +class BundleActivePackageStats : public Parcelable { public: std::string bundleName_; - int64_t beginTimeStamp_; - int64_t endTimeStamp_; - int64_t lastTimeUsed_; - int64_t totalTimeInFront_; - int64_t lastTimeLongTimeTaskUsed_; - int64_t totalTimeLongTimeTaskUsed_; - int launchedCount_; - int bundleLaunchedCount_; + int64_t beginTimeStamp_; // start time of counting + int64_t endTimeStamp_; // stop time of counting + int64_t lastTimeUsed_; // the timestamp of last launch + int64_t totalInFrontTime_; // the total time of using the bundle + int64_t lastContiniousTaskUsed_; + int64_t totalContiniousTaskUsedTime_; + int startCount_; + int bundleStartedCount_; int lastEvent_; - std::map abilities_; - std::map frontServices_; - BundleActivePackageStats() {}; + // key is abilityId, value is the last event of this ability. Restore all abilities' last event of bundle. + std::map abilities_; + // key is name of continous task, value is last event of this last continous task. + std::map longTimeTasks_; + BundleActivePackageStats(); + ~BundleActivePackageStats() {}; BundleActivePackageStats(const BundleActivePackageStats& orig); std::string GetBundleName(); int64_t GetBeginTimeStamp(); @@ -46,17 +49,20 @@ public: int64_t GetTotalTimeFrontServiceUsed(); int GetLaunchedCount(); int GetBundleLaunchedCount(); - void Update(std::string longTimeTaskName, const int64_t timeStamp, const int eventId, const int abilityId); - void IncrementTimeUsed(const int64_t timeStamp); - void IncrementLongTimeTaskTimeUsed(const int64_t timeStamp); + void Update(const std::string& longTimeTaskName, const int64_t& timeStamp, const int& eventId, + const std::string& abilityId); + void IncrementTimeUsed(const int64_t& timeStamp); + void IncrementServiceTimeUsed(const int64_t& timeStamp); void IncrementBundleLaunchedCount(); + virtual bool Marshalling(Parcel &parcel) const override; + std::shared_ptr Unmarshalling(Parcel &parcel); + void printdata(); private: bool HasFrontAbility(); - bool AnyFrontServiceStarted(); - void UpdateAbility(const int64_t timeStamp, const int eventId, const int abilityId); - void UpdateLongTimeTask(std::string longTimeTaskName, - const int64_t timeStamp, const int eventId); + bool AnyLongTimeTaskStarted(); + void UpdateAbility(const int64_t& timeStamp, const int& eventId, const std::string& abilityId); + void UpdateLongTimeTask(const std::string& longTimeTaskName, const int64_t& timeStamp, const int& eventId); }; } } diff --git a/services/common/include/bundle_active_period_stats.h b/services/packageusage/include/bundle_active_period_stats.h similarity index 61% rename from services/common/include/bundle_active_period_stats.h rename to services/packageusage/include/bundle_active_period_stats.h index fb64d5ec2ec0f316b21035f0ea1e9323cca2eca3..45294e564b6d94511424f10f5a6d3939c8fb28d8 100644 --- a/services/common/include/bundle_active_period_stats.h +++ b/services/packageusage/include/bundle_active_period_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,8 +13,10 @@ * limitations under the License. */ -#ifndef bundle_active_period_stats_H -#define bundle_active_period_stats_H +#ifndef BUNDLE_ACTIVE_PERIOD_STATS_H +#define BUNDLE_ACTIVE_PERIOD_STATS_H + +#include #include "ibundle_active_service.h" #include "bundle_active_event.h" @@ -22,8 +24,9 @@ #include "bundle_active_event_list.h" #include "bundle_active_event_tracker.h" + namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { class BundleActivePeriodStats { public: static const int PERIOD_DAILY = 0; @@ -32,32 +35,28 @@ public: static const int PERIOD_YEARLY = 3; static const int PERIOD_BEST = 4; static const int PERIOD_COUNT = 4; - static const int64_t DAY_IN_MILLIS = (int64_t)24 * 60 * 60 * 1000; - static const int64_t WEEK_IN_MILLIS = (int64_t)7 * 24 * 60 * 60 * 1000; - static const int64_t MONTH_IN_MILLIS = (int64_t)30 * 24 * 60 * 60 * 1000; - static const int64_t YEAR_IN_MILLIS = (int64_t)365 * 24 * 60 * 60 * 1000; int64_t beginTime_; int64_t endTime_; int64_t lastTimeSaved_; - std::map bundleStats_; + int userId_; + std::map> bundleStats_; BundleActiveEventList events_; std::set packetNamesCache_; BundleActiveEventTracker interactiveTracker_; BundleActiveEventTracker noninteractiveTracker_; BundleActiveEventTracker keyguardShownTracker_; BundleActiveEventTracker keyguardHiddenTracker_; - BundleActivePackageStats& GetOrCreateUsageStats(std::string bundleName); - BundleActiveEvent BuildEvent(std::string bundleName, std::string longTimeTaskName); - void Update(std::string bundleName, std::string longTimeTaskName, const int64_t timeStamp, const int eventId, - const int abilityId); + BundleActivePeriodStats(); + std::shared_ptr GetOrCreateUsageStats(const std::string& bundleName); + BundleActiveEvent BuildEvent(std::string bundleName, std::string timeTaskName); + void Update(const std::string bundleName, const std::string longTimeTaskName, const int64_t timeStamp, + const int eventId, const std::string abilityId); void AddEvent(BundleActiveEvent event); - void UpdateScreenInteractive(const int64_t timeStamp); - void UpdateScreenNonInteractive(const int64_t timeStamp); - void UpdateKeyguardShown(const int64_t timeStamp); - void UpdateKeyguardHidden(const int64_t timeStamp); - -private: - void CommitTime(const int64_t timeStamp); + void UpdateScreenInteractive(const int64_t& timeStamp); + void UpdateScreenNonInteractive(const int64_t& timeStamp); + void UpdateKeyguardShown(const int64_t& timeStamp); + void UpdateKeyguardHidden(const int64_t& timeStamp); + void CommitTime(const int64_t& timeStamp); void AddEventStatsTo(std::vector& eventStatsList); std::string GetCachedString(std::string str); }; diff --git a/services/packageusage/include/bundle_active_report_handler.h b/services/packageusage/include/bundle_active_report_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..bc9ea44107018c56147b28fc1a0706073fd5393a --- /dev/null +++ b/services/packageusage/include/bundle_active_report_handler.h @@ -0,0 +1,50 @@ +/* + * 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_REPORT_HANDLER_H +#define BUNDLE_ACTIVE_REPORT_HANDLER_H + +#include "event_handler.h" +#include "event_runner.h" + +#include "ibundle_active_service.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveReportHandler : public AppExecFwk::EventHandler { +public: + explicit BundleActiveReportHandler(const std::shared_ptr &runner); + ~BundleActiveReportHandler() = default; + /** + * Process the event. Developers should override this method. + * + * @param event The event should be processed. + */ + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; + void Init(const std::shared_ptr& bundleActiveCore); + static const int MSG_REPORT_EVENT = 0; + static const int MSG_REPORT_EVENT_TO_ALL_USER = 1; + static const int MSG_FLUSH_TO_DISK = 2; + static const int MSG_REMOVE_USER = 3; + static const int MSG_DEVICE_SHUTDOWN = 4; + static const int MSG_BUNDLE_UNINSTALLED = 5; + +private: + std::shared_ptr bundleActiveCore_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/packageusage/include/bundle_active_stats_combiner.h b/services/packageusage/include/bundle_active_stats_combiner.h new file mode 100644 index 0000000000000000000000000000000000000000..710abc52a0db6736dbfb1fb4ca4ebf3d0e6bd3d8 --- /dev/null +++ b/services/packageusage/include/bundle_active_stats_combiner.h @@ -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. + */ + +#ifndef BUNDLE_ACTIVE_STATS_COMBINER_H +#define BUNDLE_ACTIVE_STATS_COMBINER_H + +#include + +#include "bundle_active_period_stats.h" + +namespace OHOS { +namespace DeviceUsageStats { +template +class BundleActiveStatsCombiner { +public: + void combine(const std::shared_ptr& stats, std::vector& accumulatedResult, + int64_t beginTime = 0); +}; + +template <> class BundleActiveStatsCombiner { +public: + void combine(const std::shared_ptr& stats, + std::vector& accumulatedResult, int64_t beginTime = 0); +}; + +template <> class BundleActiveStatsCombiner { +public: + void combine(const std::shared_ptr& stats, + std::vector& accumulatedResult, int64_t beginTime = 0); +}; +} +} +#endif \ No newline at end of file diff --git a/sa_profile/1906.xml b/services/packageusage/include/bundle_active_stats_update_listener.h similarity index 58% rename from sa_profile/1906.xml rename to services/packageusage/include/bundle_active_stats_update_listener.h index 60c148a83f87349ce752828093a9eee10095c864..5f0b3b82e58617f21fd65fd7c5cacb35737e48fd 100644 --- a/sa_profile/1906.xml +++ b/services/packageusage/include/bundle_active_stats_update_listener.h @@ -1,6 +1,5 @@ - - - - bundleactive_service - - 1906 - libbundleactiveservice.z.so - true - false - 1 - - + */ + +#ifndef BUNDLE_ACTIVE_STATS_UPDATE_LISTENER_H +#define BUNDLE_ACTIVE_STATS_UPDATE_LISTENER_H + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveStatsUpdateListener { + virtual void OnStatsChanged() = 0; + virtual void OnStatsReload() = 0; + virtual void OnSystemUpdate(int userId) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/packageusage/include/bundle_active_user_service.h b/services/packageusage/include/bundle_active_user_service.h new file mode 100644 index 0000000000000000000000000000000000000000..ff81be1e67b819e348abcd887fe8e6f7414e4632 --- /dev/null +++ b/services/packageusage/include/bundle_active_user_service.h @@ -0,0 +1,77 @@ +/* + * 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_USER_SERVICE_H +#define BUNDLE_ACTIVE_USER_SERVICE_H + +#include + +#include "ibundle_active_service.h" +#include "bundle_active_event.h" +#include "bundle_active_period_stats.h" +#include "bundle_active_event_stats.h" +#include "bundle_active_calendar.h" +#include "bundle_active_stats_combiner.h" +#include "bundle_active_usage_database.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveCore; + +class BundleActiveUserService { +public: + BundleActiveUserService() = delete; + BundleActiveUserService(const int userId, BundleActiveCore& listener):listener_(listener) + { + for (int i = 0; i < BundleActivePeriodStats::PERIOD_COUNT; i++) { + currentStats_.push_back(nullptr); + } + userId_ = userId; + dailyExpiryDate_.SetMilliseconds(0); + statsChanged_ = false; + } + void Init(const int64_t& timeStamp); + ~BundleActiveUserService() {}; + void ReportForFlushAndShutdown(const BundleActiveEvent& event); + void ReportEvent(const BundleActiveEvent& event); + void RestoreStats(); + void RenewStatsInMemory(const int64_t& timeStamp); + void RenewTableTime(int64_t oldTime, int64_t newTime); + void DeleteUninstalledBundleStats(const std::string& bundleName); + int userId_; + BundleActiveCalendar dailyExpiryDate_; + std::vector QueryPackageStats(int intervalType, const int64_t& beginTime, + const int64_t& endTime, const int& userId, const std::string& bundleName); + std::vector QueryEvents(const int64_t& beginTime, const int64_t& endTime, const int& userId, + const std::string& bundleName); + +private: + static const int64_t ONE_SECOND_MILLISECONDS = 1000; + BundleActiveUsageDatabase database_; + std::vector> currentStats_; + bool statsChanged_; + std::string lastBackgroundBundle_; + BundleActiveCore& listener_; + inline static const std::vector PERIOD_LENGTH = {BundleActiveCalendar::DAY_MILLISECONDS, + BundleActiveCalendar::WEEK_MILLISECONDS, BundleActiveCalendar::MONTH_MILLISECONDS, + BundleActiveCalendar::YEAR_MILLISECONDS}; + void LoadActiveStats(const int64_t& timeStamp, const bool& force); + void NotifyStatsChanged(); + void NotifyNewUpdate(); + void printstat(); +}; +} +} +#endif \ No newline at end of file diff --git a/services/packageusage/src/bundle_active_calendar.cpp b/services/packageusage/src/bundle_active_calendar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af1f65b7279fb1087b09e351a9b424f17dbb796c --- /dev/null +++ b/services/packageusage/src/bundle_active_calendar.cpp @@ -0,0 +1,96 @@ +/* + * 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_calendar.h" +#include "bundle_active_period_stats.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveCalendar::BundleActiveCalendar(const int64_t& timeStamp) +{ + time_ = timeStamp; +} + +void BundleActiveCalendar::TruncateToDay() +{ + time_ -= time_ % DAY_MILLISECONDS; +} + +void BundleActiveCalendar::TruncateToWeek() +{ + time_ -= time_ % WEEK_MILLISECONDS; +} + +void BundleActiveCalendar::TruncateToMonth() +{ + time_ -= time_ % MONTH_MILLISECONDS; +} + +void BundleActiveCalendar::TruncateToYear() +{ + time_ -= time_ % YEAR_MILLISECONDS; +} + +void BundleActiveCalendar::IncreaseDays(const int& val) +{ + time_ += val * DAY_MILLISECONDS; +} + +void BundleActiveCalendar::IncreaseWeeks(const int& val) +{ + time_ += val* WEEK_MILLISECONDS; +} + +void BundleActiveCalendar::IncreaseMonths(const int& val) +{ + time_ += val * MONTH_MILLISECONDS; +} + +void BundleActiveCalendar::IncreaseYears(const int& val) +{ + time_ += val * YEAR_MILLISECONDS; +} + +void BundleActiveCalendar::SetMilliseconds(const int64_t& timeStamp) +{ + time_ = timeStamp; +} + +int64_t BundleActiveCalendar::GetMilliseconds() +{ + return time_; +} + +void BundleActiveCalendar::TruncateTo(int intervalType) +{ + switch (intervalType) { + case BundleActivePeriodStats::PERIOD_DAILY: + TruncateToDay(); + break; + case BundleActivePeriodStats::PERIOD_WEEKLY: + TruncateToWeek(); + break; + case BundleActivePeriodStats::PERIOD_MONTHLY: + TruncateToMonth(); + break; + case BundleActivePeriodStats::PERIOD_YEARLY: + TruncateToYear(); + break; + default: + break; + } +} +} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_event.cpp b/services/packageusage/src/bundle_active_event.cpp similarity index 58% rename from services/common/src/bundle_active_event.cpp rename to services/packageusage/src/bundle_active_event.cpp index 722583a19a24c9796d87e28fd2c92fc137bd7c07..22bc7d38ab733f5907aa9bf660e8d5eaddff0b4b 100644 --- a/services/common/src/bundle_active_event.cpp +++ b/services/packageusage/src/bundle_active_event.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,10 +13,12 @@ * limitations under the License. */ +#include + #include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { BundleActiveEvent::BundleActiveEvent (const BundleActiveEvent& orig) { bundleName_ = orig.bundleName_; @@ -24,11 +26,14 @@ BundleActiveEvent::BundleActiveEvent (const BundleActiveEvent& orig) abilityId_ = orig.abilityId_; timeStamp_ = orig.timeStamp_; eventId_ = orig.eventId_; - isIdle_ = orig.isIdle_; + isidle_ = orig.isidle_; } -BundleActiveEvent::BundleActiveEvent(const int eventId, const int64_t timeStamp) +BundleActiveEvent::BundleActiveEvent(int eventId, int64_t timeStamp) { + bundleName_.clear(); + abilityName_.clear(); + abilityId_ = ""; eventId_ = eventId; timeStamp_ = timeStamp; } @@ -43,7 +48,7 @@ std::string BundleActiveEvent::GetAbilityName() return abilityName_; } -int BundleActiveEvent::GetAbilityId() +std::string BundleActiveEvent::GetAbilityId() { return abilityId_; } @@ -60,7 +65,26 @@ int BundleActiveEvent::GetEventId() bool BundleActiveEvent::GetIsIdle() { - return isIdle_; + return isidle_; +} + +bool BundleActiveEvent::Marshalling(Parcel &parcel) const +{ + if (parcel.WriteString(bundleName_) && + parcel.WriteInt32(eventId_) && + parcel.WriteInt64(timeStamp_)) { + return true; + } + return false; +} + +std::shared_ptr BundleActiveEvent::Unmarshalling(Parcel &parcel) +{ + std::shared_ptr result = std::make_shared(); + result->bundleName_ = parcel.ReadString(); + result->eventId_ = parcel.ReadInt32(); + result->timeStamp_ = parcel.ReadInt64(); + return result; } } } diff --git a/services/common/src/bundle_active_event_list.cpp b/services/packageusage/src/bundle_active_event_list.cpp similarity index 92% rename from services/common/src/bundle_active_event_list.cpp rename to services/packageusage/src/bundle_active_event_list.cpp index 3e4b715f7a4249d11482bfa3a449803b280bff0e..1bbf487e544a94480174320760d2565f7d7a71d7 100644 --- a/services/common/src/bundle_active_event_list.cpp +++ b/services/packageusage/src/bundle_active_event_list.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -16,7 +16,7 @@ #include "bundle_active_event_list.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { BundleActiveEventList::BundleActiveEventList() { } @@ -42,7 +42,7 @@ void BundleActiveEventList::Insert(BundleActiveEvent event) events_.insert(events_.begin() + insertIdx, event); } -int BundleActiveEventList::FindBestIndex(int64_t timeStamp) +int BundleActiveEventList::FindBestIndex(const int64_t& timeStamp) { int size = events_.size(); int result = size; @@ -69,4 +69,4 @@ void BundleActiveEventList::Merge(const BundleActiveEventList& right) } } } -} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_event_stats.cpp b/services/packageusage/src/bundle_active_event_stats.cpp similarity index 96% rename from services/common/src/bundle_active_event_stats.cpp rename to services/packageusage/src/bundle_active_event_stats.cpp index 707564d5bbead6a4c3b01f20f24a068626476272..02d527cb37463c6c9022c64c52a3bf15e345bbb1 100644 --- a/services/common/src/bundle_active_event_stats.cpp +++ b/services/packageusage/src/bundle_active_event_stats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -16,7 +16,7 @@ #include "bundle_active_event_stats.h" namespace OHOS { -namespace BundleActive { +namespace DeviceUsageStats { BundleActiveEventStats::BundleActiveEventStats(const BundleActiveEventStats& orig) { eventId_ = orig.eventId_; @@ -72,4 +72,4 @@ void BundleActiveEventStats::add(const BundleActiveEventStats& right) count_ += right.count_; } } -} +} \ No newline at end of file diff --git a/services/common/src/bundle_active_event_tracker.cpp b/services/packageusage/src/bundle_active_event_tracker.cpp similarity index 79% rename from services/common/src/bundle_active_event_tracker.cpp rename to services/packageusage/src/bundle_active_event_tracker.cpp index 7735d72f2c38900253cec18dbe96378d528ececb..13edc15f4f5cf47f794e451a959ddddf2b94ca31 100644 --- a/services/common/src/bundle_active_event_tracker.cpp +++ b/services/packageusage/src/bundle_active_event_tracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -16,8 +16,16 @@ #include "bundle_active_event_tracker.h" namespace OHOS { -namespace BundleActive { -void BundleActiveEventTracker::CommitTime(const int64_t timeStamp) +namespace DeviceUsageStats { +BundleActiveEventTracker::BundleActiveEventTracker() +{ + curStartTime_ = 0; + lastEventTime_ = 0; + duration_ = 0; + count_ =0; +} + +void BundleActiveEventTracker::CommitTime(const int64_t& timeStamp) { if (curStartTime_ != 0) { duration_ += timeStamp - curStartTime_; @@ -35,8 +43,8 @@ void BundleActiveEventTracker::Update(int64_t timeStamp) lastEventTime_ = timeStamp; } -void BundleActiveEventTracker::AddToEventStats(std::vector& eventStatsList, const int eventId, - const int64_t beginTime, const int64_t endTime) +void BundleActiveEventTracker::AddToEventStats(std::vector& eventStatsList, int eventId, + int64_t beginTime, int64_t endTime) { if (count_ != 0 || duration_ != 0) { BundleActiveEventStats newEvent; @@ -50,4 +58,4 @@ void BundleActiveEventTracker::AddToEventStats(std::vector lastTimeUsed_) { - totalTimeInFront_ += timeStamp - lastTimeUsed_; + totalInFrontTime_ += timeStamp - lastTimeUsed_; lastTimeUsed_ = timeStamp; } } -void BundleActivePackageStats::IncrementLongTimeTaskTimeUsed(const int64_t timeStamp) +void BundleActivePackageStats::IncrementServiceTimeUsed(const int64_t& timeStamp) { - if (timeStamp > lastTimeLongTimeTaskUsed_) { - totalTimeLongTimeTaskUsed_ += timeStamp - lastTimeLongTimeTaskUsed_; - lastTimeLongTimeTaskUsed_ = timeStamp; + if (timeStamp > lastContiniousTaskUsed_) { + totalContiniousTaskUsedTime_ += timeStamp - lastContiniousTaskUsed_; + lastContiniousTaskUsed_ = timeStamp; } } void BundleActivePackageStats::IncrementBundleLaunchedCount() { - bundleLaunchedCount_ += 1; + bundleStartedCount_ += 1; } -void BundleActivePackageStats::UpdateAbility(const int64_t timeStamp, const int eventId, const int abilityId) +void BundleActivePackageStats::UpdateAbility(const int64_t& timeStamp, const int& eventId, + const std::string& abilityId) { if (eventId != BundleActiveEvent::ABILITY_FOREGROUND && eventId != BundleActiveEvent::ABILITY_BACKGROUND && eventId != BundleActiveEvent::ABILITY_STOP) { return; } - std::map::iterator it = abilities_.find(abilityId); + if (abilities_.empty() && eventId == BundleActiveEvent::ABILITY_FOREGROUND) { + beginTimeStamp_ = timeStamp; + } + std::map::iterator it = abilities_.find(abilityId); if (it != abilities_.end()) { int lastEventId = it->second; + // When we recieve a new event, first update the time stats according to the last event in map. switch (lastEventId) { case BundleActiveEvent::ABILITY_FOREGROUND: IncrementTimeUsed(timeStamp); @@ -149,18 +168,20 @@ void BundleActivePackageStats::UpdateAbility(const int64_t timeStamp, const int } } -void BundleActivePackageStats::UpdateLongTimeTask(std::string longTimeTaskName, - const int64_t timeStamp, const int eventId) +void BundleActivePackageStats::UpdateLongTimeTask(const std::string& longTimeTaskName, const int64_t& timeStamp, + const int& eventId) { - if (eventId != BundleActiveEvent::LONG_TIME_TASK_STARTTED && eventId != BundleActiveEvent::LONG_TIME_TASK_STOPPED) { + if (eventId != BundleActiveEvent::LONG_TIME_TASK_STARTTED && eventId != BundleActiveEvent::LONG_TIME_TASK_ENDED) { return; } - std::map::iterator it = frontServices_.find(longTimeTaskName); - if (it != frontServices_.end()) { + + // When we recieve a new event, first update the time stats according to the last service event in map. + std::map::iterator it = longTimeTasks_.find(longTimeTaskName); + if (it != longTimeTasks_.end()) { int lastEventId = it->second; switch (lastEventId) { case BundleActiveEvent::LONG_TIME_TASK_STARTTED: - IncrementLongTimeTaskTimeUsed(timeStamp); + IncrementServiceTimeUsed(timeStamp); default: break; } @@ -168,20 +189,20 @@ void BundleActivePackageStats::UpdateLongTimeTask(std::string longTimeTaskName, switch (eventId) { case BundleActiveEvent::LONG_TIME_TASK_STARTTED: - if (!AnyFrontServiceStarted()) { - lastTimeLongTimeTaskUsed_ = timeStamp; + if (!AnyLongTimeTaskStarted()) { + lastContiniousTaskUsed_ = timeStamp; } - frontServices_[longTimeTaskName] = eventId; + longTimeTasks_[longTimeTaskName] = eventId; break; - case BundleActiveEvent::LONG_TIME_TASK_STOPPED: - frontServices_.erase(longTimeTaskName); + case BundleActiveEvent::LONG_TIME_TASK_ENDED: + longTimeTasks_.erase(longTimeTaskName); default: break; } } -void BundleActivePackageStats::Update(std::string longTimeTaskName, const int64_t timeStamp, const int eventId, - const int abilityId) +void BundleActivePackageStats::Update(const std::string& longTimeTaskName, const int64_t& timeStamp, + const int& eventId, const std::string& abilityId) { switch (eventId) { case BundleActiveEvent::ABILITY_FOREGROUND: @@ -193,17 +214,21 @@ void BundleActivePackageStats::Update(std::string longTimeTaskName, const int64_ if (HasFrontAbility()) { IncrementTimeUsed(timeStamp); } + if (AnyLongTimeTaskStarted()) { + IncrementServiceTimeUsed(timeStamp); + } + break; case BundleActiveEvent::LONG_TIME_TASK_STARTTED: - case BundleActiveEvent::LONG_TIME_TASK_STOPPED: + case BundleActiveEvent::LONG_TIME_TASK_ENDED: UpdateLongTimeTask(longTimeTaskName, timeStamp, eventId); break; - case BundleActiveEvent::DEVICE_SHUTDOWN: - case BundleActiveEvent::FLUSH_TO_DISK: + case BundleActiveEvent::SHUTDOWN: + case BundleActiveEvent::FLUSH: if (HasFrontAbility()) { IncrementTimeUsed(timeStamp); } - if (AnyFrontServiceStarted()) { - IncrementLongTimeTaskTimeUsed(timeStamp); + if (AnyLongTimeTaskStarted()) { + IncrementServiceTimeUsed(timeStamp); } break; default: @@ -211,8 +236,33 @@ void BundleActivePackageStats::Update(std::string longTimeTaskName, const int64_ } endTimeStamp_ = timeStamp; if (eventId == BundleActiveEvent::ABILITY_FOREGROUND) { - launchedCount_ += 1; + startCount_ += 1; } } + +bool BundleActivePackageStats::Marshalling(Parcel &parcel) const +{ + if (parcel.WriteString(bundleName_) && + parcel.WriteInt64(beginTimeStamp_) && + parcel.WriteInt64(lastTimeUsed_) && + parcel.WriteInt64(totalInFrontTime_) && + parcel.WriteInt64(lastContiniousTaskUsed_) && + parcel.WriteInt64(totalContiniousTaskUsedTime_)) { + return true; + } + return false; +} + +std::shared_ptr BundleActivePackageStats::Unmarshalling(Parcel &parcel) +{ + std::shared_ptr result = std::make_shared(); + result->bundleName_ = parcel.ReadString(); + result->beginTimeStamp_ = parcel.ReadInt64(); + result->lastTimeUsed_ = parcel.ReadInt64(); + result->totalInFrontTime_ = parcel.ReadInt64(); + result->lastContiniousTaskUsed_ = parcel.ReadInt64(); + result->totalContiniousTaskUsedTime_ = parcel.ReadInt64(); + return result; } } +} \ No newline at end of file diff --git a/services/common/src/bundle_active_period_stats.cpp b/services/packageusage/src/bundle_active_period_stats.cpp similarity index 48% rename from services/common/src/bundle_active_period_stats.cpp rename to services/packageusage/src/bundle_active_period_stats.cpp index d74063495998998ce3594a021d04cd4685561412..fffa05c0a9466f4b192c288ef0c0074b96dbb619 100644 --- a/services/common/src/bundle_active_period_stats.cpp +++ b/services/packageusage/src/bundle_active_period_stats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -17,30 +17,56 @@ #include "bundle_active_event.h" namespace OHOS { -namespace BundleActive { -BundleActivePackageStats& BundleActivePeriodStats::GetOrCreateUsageStats(std::string bundleName) +namespace DeviceUsageStats { +BundleActivePeriodStats::BundleActivePeriodStats() { - std::map::iterator it = bundleStats_.find(bundleName); + userId_ = -1; + beginTime_ = 0; + endTime_ = 0; + lastTimeSaved_ = 0; + bundleStats_.clear(); + events_.events_.clear(); + packetNamesCache_.clear(); +} + +std::shared_ptr BundleActivePeriodStats::GetOrCreateUsageStats( + const std::string& bundleName) +{ + std::map>::iterator it; + it = bundleStats_.find(bundleName); if (it == bundleStats_.end()) { - BundleActivePackageStats newStats; - newStats.beginTimeStamp_ = beginTime_; - newStats.endTimeStamp_ = endTime_; - newStats.bundleName_ = GetCachedString(bundleName); - bundleStats_[newStats.bundleName_] = newStats; + std::shared_ptr newStats = std::make_shared(); + newStats->endTimeStamp_ = endTime_; + newStats->bundleName_ = GetCachedString(bundleName); + bundleStats_[newStats->bundleName_] = newStats; } return bundleStats_[bundleName]; } -void BundleActivePeriodStats::Update(std::string bundleName, std::string longTimeTaskName, const int64_t timeStamp, - const int eventId, const int abilityId) +BundleActiveEvent BundleActivePeriodStats::BuildEvent(std::string bundleName, std::string timeTaskName) +{ + BundleActiveEvent newEvent; + newEvent.bundleName_ = bundleName; + if (!timeTaskName.empty()) { + newEvent.longTimeTaskName_ = timeTaskName; + } + return newEvent; +} + +void BundleActivePeriodStats::Update(const std::string bundleName, const std::string longTimeTaskName, + const int64_t timeStamp, const int eventId, const std::string abilityId) { - if (eventId == BundleActiveEvent::DEVICE_SHUTDOWN || eventId == BundleActiveEvent::FLUSH_TO_DISK) { - for (auto usageStatsPair : bundleStats_) { - usageStatsPair.second.Update("", timeStamp, eventId, abilityId); + if (eventId == BundleActiveEvent::SHUTDOWN || eventId == BundleActiveEvent::FLUSH) { + for (std::map>::iterator it = bundleStats_.begin(); + it != bundleStats_.end(); it++) { + std::shared_ptr tmpUsageStats = it->second; + if (tmpUsageStats != nullptr) { + tmpUsageStats->Update("", timeStamp, eventId, abilityId); + } } } else { - BundleActivePackageStats& usageStats = GetOrCreateUsageStats(bundleName); - usageStats.Update("", timeStamp, eventId, abilityId); + auto usageStats = GetOrCreateUsageStats(bundleName); + usageStats->Update(longTimeTaskName, timeStamp, eventId, abilityId); } if (timeStamp > endTime_) { endTime_ = timeStamp; @@ -59,7 +85,7 @@ void BundleActivePeriodStats::AddEvent(BundleActiveEvent event) } } -void BundleActivePeriodStats::CommitTime(const int64_t timeStamp) +void BundleActivePeriodStats::CommitTime(const int64_t& timeStamp) { interactiveTracker_.CommitTime(timeStamp); noninteractiveTracker_.CommitTime(timeStamp); @@ -67,25 +93,25 @@ void BundleActivePeriodStats::CommitTime(const int64_t timeStamp) keyguardHiddenTracker_.CommitTime(timeStamp); } -void BundleActivePeriodStats::UpdateScreenInteractive(const int64_t timeStamp) +void BundleActivePeriodStats::UpdateScreenInteractive(const int64_t& timeStamp) { interactiveTracker_.Update(timeStamp); noninteractiveTracker_.CommitTime(timeStamp); } -void BundleActivePeriodStats::UpdateScreenNonInteractive(const int64_t timeStamp) +void BundleActivePeriodStats::UpdateScreenNonInteractive(const int64_t& timeStamp) { noninteractiveTracker_.Update(timeStamp); interactiveTracker_.CommitTime(timeStamp); } -void BundleActivePeriodStats::UpdateKeyguardShown(const int64_t timeStamp) +void BundleActivePeriodStats::UpdateKeyguardShown(const int64_t& timeStamp) { keyguardShownTracker_.Update(timeStamp); keyguardHiddenTracker_.CommitTime(timeStamp); } -void BundleActivePeriodStats::UpdateKeyguardHidden(const int64_t timeStamp) +void BundleActivePeriodStats::UpdateKeyguardHidden(const int64_t& timeStamp) { keyguardHiddenTracker_.Update(timeStamp); keyguardShownTracker_.CommitTime(timeStamp); @@ -93,11 +119,14 @@ void BundleActivePeriodStats::UpdateKeyguardHidden(const int64_t timeStamp) void BundleActivePeriodStats::AddEventStatsTo(std::vector& eventStatsList) { - interactiveTracker_.AddToEventStats(eventStatsList, BundleActiveEvent::SCREEN_INTERACTIVE, beginTime_, endTime_); - noninteractiveTracker_.AddToEventStats(eventStatsList, BundleActiveEvent::SCREEN_NON_INTERACTIVE, - beginTime_, endTime_); - keyguardShownTracker_.AddToEventStats(eventStatsList, BundleActiveEvent::KEYGUARD_SHOWN, beginTime_, endTime_); - keyguardHiddenTracker_.AddToEventStats(eventStatsList, BundleActiveEvent::KEYGUARD_HIDDEN, beginTime_, endTime_); + interactiveTracker_.AddToEventStats( + eventStatsList, BundleActiveEvent::SCREEN_INTERACTIVE, beginTime_, endTime_); + noninteractiveTracker_.AddToEventStats( + eventStatsList, BundleActiveEvent::SCREEN_NON_INTERACTIVE, beginTime_, endTime_); + keyguardShownTracker_.AddToEventStats( + eventStatsList, BundleActiveEvent::KEYGUARD_SHOWN, beginTime_, endTime_); + keyguardHiddenTracker_.AddToEventStats( + eventStatsList, BundleActiveEvent::KEYGUARD_HIDDEN, beginTime_, endTime_); } std::string BundleActivePeriodStats::GetCachedString(std::string str) @@ -110,4 +139,4 @@ std::string BundleActivePeriodStats::GetCachedString(std::string str) return *it; } } -} +} \ No newline at end of file diff --git a/services/packageusage/src/bundle_active_report_handler.cpp b/services/packageusage/src/bundle_active_report_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..590608a52e7d276b1444a239794dcfa82ac05dab --- /dev/null +++ b/services/packageusage/src/bundle_active_report_handler.cpp @@ -0,0 +1,74 @@ +/* + * 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_report_handler.h" +#include "bundle_active_event.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveReportHandler::BundleActiveReportHandler + (const std::shared_ptr &runner) : AppExecFwk::EventHandler(runner) +{ +} + +void BundleActiveReportHandler::Init(const std::shared_ptr& bundleActiveCore) +{ + bundleActiveCore_ = bundleActiveCore; +} + +void BundleActiveReportHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) +{ + switch (event->GetInnerEventId()) { + case MSG_REPORT_EVENT: { + BUNDLE_ACTIVE_LOGI("MSG_REPORT_EVENT CALLED"); + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveReportHandlerObject tmpHandlerobj = *ptrToHandlerobj; + bundleActiveCore_->ReportEvent(tmpHandlerobj.event_, tmpHandlerobj.userId_); + break; + } + case MSG_REPORT_EVENT_TO_ALL_USER: { + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveReportHandlerObject tmpHandlerobj = *ptrToHandlerobj; + bundleActiveCore_->ReportEventToAllUserId(tmpHandlerobj.event_); + break; + } + case MSG_FLUSH_TO_DISK: { + BUNDLE_ACTIVE_LOGI("FLUSH TO DISK HANDLE"); + bundleActiveCore_->RestoreToDatabase(); + break; + } + case MSG_REMOVE_USER: { + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveReportHandlerObject tmpHandlerobj = *ptrToHandlerobj; + bundleActiveCore_->OnUserRemoved(tmpHandlerobj.userId_); + break; + } + case MSG_DEVICE_SHUTDOWN: { + bundleActiveCore_->ShutDown(); + break; + } + case MSG_BUNDLE_UNINSTALLED: { + auto ptrToHandlerobj = event->GetSharedObject(); + BundleActiveReportHandlerObject tmpHandlerobj = *ptrToHandlerobj; + bundleActiveCore_->OnBundleUninstalled(tmpHandlerobj.userId_, tmpHandlerobj.bundleName_); + break; + } + default: { + break; + } + } +} +} +} \ No newline at end of file diff --git a/services/src/bundle_active_service.cpp b/services/packageusage/src/bundle_active_stats_combiner.cpp similarity index 34% rename from services/src/bundle_active_service.cpp rename to services/packageusage/src/bundle_active_stats_combiner.cpp index 5673d570d974ba11cb6c6aae990a6157f908bb1a..88ddd974801d008a9a35733f00458f014928a57b 100644 --- a/services/src/bundle_active_service.cpp +++ b/services/packageusage/src/bundle_active_stats_combiner.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,46 +13,32 @@ * limitations under the License. */ -#include "bundle_active_service.h" +#include "bundle_active_stats_combiner.h" namespace OHOS { -namespace BundleActive { -REGISTER_SYSTEM_ABILITY_BY_ID(BundleActiveService, BUNDLE_ACTIVE_SYS_ABILITY_ID, true); - -void BundleActiveService::OnStart() +namespace DeviceUsageStats { +void BundleActiveStatsCombiner::combine( + const std::shared_ptr& stats, std::vector& accumulatedResult, + int64_t beginTime) { - int ret = Publish(this); - if (!ret) { - BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1906] FAIL."); - return; + BUNDLE_ACTIVE_LOGI("BundleActiveStatsCombiner::combine called"); + for (auto it : stats->bundleStats_) { + if (it.second != nullptr) { + accumulatedResult.push_back(*(it.second)); + } } - BUNDLE_ACTIVE_LOGI("[Server] OnStart, Register SystemAbility[1906] SUCCESS."); -} - -void BundleActiveService::OnStop() -{ - BUNDLE_ACTIVE_LOGI("[Server] OnStop"); -} - -int BundleActiveService::ReportEvent(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId, const int& eventId) -{ - BUNDLE_ACTIVE_LOGI("Report event called"); - return 0; -} - -int BundleActiveService::IsBundleIdle(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) -{ - BUNDLE_ACTIVE_LOGI("Is bundle active called"); - return true; } -int BundleActiveService::Query(std::string& bundleName, std::string& abilityName, const int& abilityId, - const int& userId) +void BundleActiveStatsCombiner::combine(const std::shared_ptr& stats, + std::vector& accumulatedResult, + int64_t beginTime) { - BUNDLE_ACTIVE_LOGI("Query called"); - return 0; -} + BUNDLE_ACTIVE_LOGI("BundleActiveStatsCombiner::combine called"); + int startIndex = stats->events_.FindBestIndex(beginTime); + int size = stats->events_.events_.size(); + for (int i = startIndex; i < size; i++) { + accumulatedResult.push_back(stats->events_.events_[i]); + } } } +} \ No newline at end of file diff --git a/services/packageusage/src/bundle_active_user_service.cpp b/services/packageusage/src/bundle_active_user_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afd51cd60fdc79cbd026d96ff5bd3737bd2e8044 --- /dev/null +++ b/services/packageusage/src/bundle_active_user_service.cpp @@ -0,0 +1,387 @@ +/* + * 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_user_service.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace DeviceUsageStats { +void BundleActiveUserService::Init(const int64_t& timeStamp) +{ + database_.InitDatabaseTableInfo(timeStamp); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::Init called"); + LoadActiveStats(timeStamp, false); + std::shared_ptr currentDailyStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; + if (currentDailyStats != nullptr) { + BundleActiveEvent startupEvent(BundleActiveEvent::STARTUP, timeStamp - ONE_SECOND_MILLISECONDS); + startupEvent.bundleName_ = BundleActiveEvent::DEVICE_EVENT_PACKAGE_NAME; + currentDailyStats->AddEvent(startupEvent); + for (auto it : currentDailyStats->events_.events_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::Init event id is %{public}d, time stamp is %{public}lld", + it.eventId_, it.timeStamp_); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::Init currentDailyStats begintime is %{public}lld, " + "expire time is %{public}lld", currentDailyStats->beginTime_, dailyExpiryDate_.GetMilliseconds()); + } +} + +void BundleActiveUserService::DeleteUninstalledBundleStats(const std::string& bundleName) +{ + for (auto it : currentStats_) { + if (it != nullptr) { + if (it->bundleStats_.find(bundleName) != it->bundleStats_.end()) { + it->bundleStats_.erase(bundleName); + } + for (auto eventIter = it->events_.events_.begin(); eventIter != it->events_.events_.end();) { + if (eventIter->bundleName_ == bundleName) { + it->events_.events_.erase(eventIter); + } else { + eventIter++; + } + } + } + } + database_.OnPackageUninstalled(userId_, bundleName); +} + +void BundleActiveUserService::RenewTableTime(int64_t oldTime, int64_t newTime) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewTableTime called"); + RestoreStats(); + database_.RenewTableTime(newTime - oldTime); + LoadActiveStats(newTime, true); +} + +void BundleActiveUserService::NotifyStatsChanged() +{ + if (!statsChanged_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::NotifyStatsChanged() set stats changed to true"); + statsChanged_ = true; + listener_.OnStatsChanged(); + } +} + +void BundleActiveUserService::NotifyNewUpdate() +{ + listener_.OnSystemUpdate(userId_); +} + +void BundleActiveUserService::ReportEvent(const BundleActiveEvent& event) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::ReportEvent called"); + if (event.timeStamp_ >= dailyExpiryDate_.GetMilliseconds()) { + BUNDLE_ACTIVE_LOGI(" BundleActiveUserService::ReportEvent later than daily expire"); + RenewStatsInMemory(event.timeStamp_); + } + BUNDLE_ACTIVE_LOGI(" BundleActiveUserService::ReportEvent later than daily expire check done"); + std::shared_ptr currentDailyStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; + if (!currentDailyStats) { + return; + } + bool incrementBundleLaunch = false; + if (event.eventId_ != BundleActiveEvent::SYSTEM_INTERACTIVE && event.eventId_ != BundleActiveEvent::FLUSH) { + currentDailyStats->AddEvent(event); + } + if (event.eventId_ == BundleActiveEvent::ABILITY_FOREGROUND) { + if (!event.bundleName_.empty() && event.bundleName_ != lastBackgroundBundle_) { + incrementBundleLaunch = true; + } + } else if (event.eventId_ == BundleActiveEvent::ABILITY_BACKGROUND) { + if (!event.bundleName_.empty()) { + lastBackgroundBundle_ = event.bundleName_; + } + } + for (auto it : currentStats_) { + switch (event.eventId_) { + case BundleActiveEvent::SCREEN_INTERACTIVE: + it->UpdateScreenInteractive(event.timeStamp_); + break; + case BundleActiveEvent::SCREEN_NON_INTERACTIVE: + it->UpdateScreenNonInteractive(event.timeStamp_); + break; + case BundleActiveEvent::KEYGUARD_SHOWN: + it->UpdateKeyguardShown(event.timeStamp_); + break; + case BundleActiveEvent::KEYGUARD_HIDDEN: + it->UpdateKeyguardHidden(event.timeStamp_); + break; + default: + it->Update(event.bundleName_, event.longTimeTaskName_, event.timeStamp_, event.eventId_, + event.abilityId_); + if (incrementBundleLaunch) { + BUNDLE_ACTIVE_LOGI(" BundleActiveUserService::ReportEvent increase bundle started count"); + it->bundleStats_[event.bundleName_]->IncrementBundleLaunchedCount(); + } + break; + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::ReportEvent called notify"); + NotifyStatsChanged(); +} + +void BundleActiveUserService::ReportForFlushAndShutdown(const BundleActiveEvent& event) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::ReportForFlushAndShutdown() called"); + if (event.eventId_ != BundleActiveEvent::FLUSH && event.eventId_ != BundleActiveEvent::SHUTDOWN) { + return; + } + if (event.eventId_ == BundleActiveEvent::SHUTDOWN) { + currentStats_[BundleActivePeriodStats::PERIOD_DAILY]->AddEvent(event); + } + if (event.timeStamp_ >= dailyExpiryDate_.GetMilliseconds()) { + BUNDLE_ACTIVE_LOGI(" BundleActiveUserService::ReportEvent later than daily expire"); + RenewStatsInMemory(event.timeStamp_); + } + for (auto it : currentStats_) { + it->Update(event.bundleName_, event.longTimeTaskName_, event.timeStamp_, event.eventId_, event.abilityId_); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::ReportForFlushAndShutdown called notify"); + NotifyStatsChanged(); +} + +void BundleActiveUserService::RestoreStats() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RestoreStats() called"); + if (statsChanged_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RestoreStats() stat changed is true"); + for (int i = 0; i < currentStats_.size(); i++) { + database_.UpdateUsageData(i, *(currentStats_[i])); + } + currentStats_[BundleActivePeriodStats::PERIOD_DAILY]->events_.Clear(); + statsChanged_ = false; + } +} + +void BundleActiveUserService::LoadActiveStats(const int64_t& timeStamp, const bool& force) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats called"); + BundleActiveCalendar tmpCalendar(0); + tmpCalendar.SetMilliseconds(timeStamp); + tmpCalendar.TruncateTo(BundleActivePeriodStats::PERIOD_DAILY); + for (int intervalType = 0; intervalType < PERIOD_LENGTH.size(); intervalType++) { + if (!force && currentStats_[intervalType] != nullptr && + currentStats_[intervalType]->beginTime_ == tmpCalendar.GetMilliseconds()) { + continue; + } + std::shared_ptr stats = database_.GetCurrentUsageData(intervalType, userId_); + currentStats_[intervalType].reset(); // 当前interval stat置空 + if (stats != nullptr) { // 找出最近的stats + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats inter type is %{public}d, " + "bundle size is %{public}d", intervalType, stats->bundleStats_.size()); + // 如果当前时间在stats的统计时间范围内,则可以从数据库加载数据 + BUNDLE_ACTIVE_LOGI("interval type is %{public}d, database stat BEGIN time is %{public}lld, " + "timestamp is %{public}lld, expect end is %{public}lld", + intervalType, stats->beginTime_, timeStamp, stats->beginTime_ + PERIOD_LENGTH[intervalType]); + if (timeStamp > stats->beginTime_ && timeStamp < stats->beginTime_ + PERIOD_LENGTH[intervalType]) { + currentStats_[intervalType] = stats; + } + } + if (currentStats_[intervalType] != nullptr) { + continue; + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats [Server]create new interval stats!"); + currentStats_[intervalType] = std::make_shared(); + currentStats_[intervalType]->userId_ = userId_; + currentStats_[intervalType]->beginTime_ = tmpCalendar.GetMilliseconds(); + currentStats_[intervalType]->endTime_ = timeStamp; + } + statsChanged_ = false; + // 延长统计时间到第二天0点 + dailyExpiryDate_.SetMilliseconds(timeStamp); + dailyExpiryDate_.IncreaseDays(1); + dailyExpiryDate_.TruncateToDay(); + listener_.OnStatsReload(); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats current expire time is %{public}lld, " + "begin time is %{public}lld", dailyExpiryDate_.GetMilliseconds(), tmpCalendar.GetMilliseconds()); +} + +void BundleActiveUserService::RenewStatsInMemory(const int64_t& timeStamp) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory called"); + std::set continueBundles; + std::map> continueAbilities; + std::map> continueServices; + //更新使用时长 + for (std::vector>::iterator it = currentStats_.begin(); + it != currentStats_.end(); it++) { + if (*it == nullptr) { + continue; + } + for (auto bundleUsageStatsPair : (*it)->bundleStats_) { + BundleActivePackageStats bundleUsageStats(*(bundleUsageStatsPair.second)); + if (!bundleUsageStats.abilities_.empty()) { + continueAbilities[bundleUsageStats.bundleName_] = bundleUsageStats.abilities_; + } + if (!bundleUsageStats.longTimeTasks_.empty()) { + continueServices[bundleUsageStats.bundleName_] = bundleUsageStats.longTimeTasks_; + } + if (*it == nullptr) { + } + (*it)->Update(bundleUsageStats.bundleName_, "", dailyExpiryDate_.GetMilliseconds() - 1, + BundleActiveEvent::END_OF_THE_DAY, ""); + + continueBundles.insert(bundleUsageStats.bundleName_); + NotifyStatsChanged(); + } + (*it)->CommitTime(dailyExpiryDate_.GetMilliseconds() - 1); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory print user stats after update yesterday data"); + RestoreStats(); + database_.RemoveOldData(timeStamp); + LoadActiveStats(timeStamp, false); // 新建intervalstat或加载当前数据库数据 + // 更新所有事件的时间戳到新的begintime + for (std::string continueBundleName : continueBundles) { + int64_t beginTime = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]->beginTime_; + for (std::vector>::iterator itInterval = currentStats_.begin(); + itInterval != currentStats_.end(); itInterval++) { + if (continueAbilities.find(continueBundleName) != continueAbilities.end()) { + for (std::map::iterator it = continueAbilities[continueBundleName].begin(); + it != continueAbilities[continueBundleName].end(); it++) { + (*itInterval)->Update(continueBundleName, "", beginTime, it->second, it->first); + } + } + if (continueServices.find(continueBundleName) != continueServices.end()) { + for (std::map::iterator it = continueServices[continueBundleName].begin(); + it != continueServices[continueBundleName].end(); it++) { + (*itInterval)->Update(continueBundleName, it->first, beginTime, it->second, 0); + } + } + NotifyStatsChanged(); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory print user stats after update today data"); + RestoreStats(); +} + +std::vector BundleActiveUserService::QueryPackageStats(int intervalType, + const int64_t& beginTime, const int64_t& endTime, const int& userId, const std::string& bundleName) +{ + std::vector result; + if (intervalType == BundleActivePeriodStats::PERIOD_BEST) { + intervalType = database_.GetOptimalIntervalType(beginTime, endTime); + if (intervalType < 0) { + intervalType = BundleActivePeriodStats::PERIOD_DAILY; + } + } + if (intervalType < 0 || intervalType >= currentStats_.size()) { + return result; + } + + auto currentStats = currentStats_[intervalType]; + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryPackageStats, intervaltype is %{public}d, " + "current begin time is %{public}lld, current end time is %{public}lld", + intervalType, currentStats->beginTime_, currentStats->endTime_); + if (currentStats == nullptr) { + BUNDLE_ACTIVE_LOGE("current interval stat is null!"); + return result; + } + if (currentStats->endTime_ == 0) { + if (beginTime > currentStats->beginTime_ + PERIOD_LENGTH[intervalType]) { + return result; + } else { + result = database_.QueryDatabaseUsageStats(intervalType, beginTime, endTime, userId); + return result; + } + } else if (beginTime >= currentStats->endTime_) { + return result; + } + int64_t truncatedEndTime = std::min(currentStats->beginTime_, endTime); + + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryPackageStats bundle name is %{public}s", bundleName.c_str()); + result = database_.QueryDatabaseUsageStats(intervalType, beginTime, truncatedEndTime, userId); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryPackageStats is %{public}d", result.size()); + // if we need a in-memory stats, combine current stats with result from database. + if (currentStats->endTime_ != 0 && endTime > currentStats->beginTime_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryPackageStats need in memory stats"); + for (auto it : currentStats->bundleStats_) { + if (bundleName.empty()) { + if ((it.second->totalInFrontTime_ != 0 || it.second->totalContiniousTaskUsedTime_ != 0) && + it.second->lastTimeUsed_ > beginTime && it.second->lastTimeUsed_ < endTime) { + result.push_back(*(it.second)); + } + } else { + if ((it.second->totalInFrontTime_ != 0 || it.second->totalContiniousTaskUsedTime_ != 0) && + it.second->bundleName_ == bundleName && it.second->lastTimeUsed_ > beginTime && + it.second->lastTimeUsed_ < endTime) { + result.push_back(*(it.second)); + } + } + } + } + return result; +} + +std::vector BundleActiveUserService::QueryEvents(const int64_t& beginTime, const int64_t& endTime, + const int& userId, const std::string& bundleName) +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryEvents called"); + std::vector result; + auto currentStats = currentStats_[BundleActivePeriodStats::PERIOD_DAILY]; + if (currentStats == nullptr) { + BUNDLE_ACTIVE_LOGE("current interval stat is null!"); + return result; + } + if (beginTime >= currentStats->endTime_) { + return result; + } + int64_t truncatedEndTime = 0; + if (currentStats->events_.events_.empty()) { + truncatedEndTime = endTime; + } else { + truncatedEndTime = std::min(currentStats->beginTime_, endTime); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryEvents bundle name is %{public}s", bundleName.c_str()); + result = database_.QueryDatabaseEvents(beginTime, truncatedEndTime, userId, bundleName); + // if we need a in-memory stats, combine current stats with result from database. + if (currentStats->endTime_ != 0 && endTime > currentStats->beginTime_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryEvents need in memory stats"); + int eventBeginIdx = currentStats->events_.FindBestIndex(beginTime); + int eventSize = currentStats->events_.Size(); + for (int i = eventBeginIdx; i < eventSize; i++) { + if (currentStats->events_.events_[i].timeStamp_ <= endTime) { + if (bundleName.empty() || currentStats->events_.events_[i].bundleName_ == bundleName) { + result.push_back(currentStats->events_.events_[i]); + } + } + } + } + return result; +} + +void BundleActiveUserService::printstat() +{ + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::printstat called"); + int idx = 0; + for (auto it : currentStats_[idx]->bundleStats_) { + BUNDLE_ACTIVE_LOGI("bundle name is %{public}s", it.first.c_str()); + int64_t lasttimeused = it.second->lastTimeUsed_; + int64_t totalusedtime = it.second->totalInFrontTime_; + BUNDLE_ACTIVE_LOGI("event stat is, totaltime is %{public}lld, lasttimeused is %{public}lld", + totalusedtime, lasttimeused); + } + int size = currentStats_[idx]->events_.events_.size(); + for (int i = 0; i < size; i++) { + std::string abilityId = currentStats_[idx]->events_.events_[i].abilityId_; + std::string abilityname = currentStats_[idx]->events_.events_[i].abilityName_; + std::string bundlename = currentStats_[idx]->events_.events_[i].bundleName_; + int eventid = currentStats_[idx]->events_.events_[i].eventId_; + int64_t timestamp = currentStats_[idx]->events_.events_[i].timeStamp_; + BUNDLE_ACTIVE_LOGI("event stat is, abilityid is %{public}s, abilityname is %{public}s, " + "bundlename is %{public}s, eventid is %{public}d, timestamp is %{public}lld", + abilityId.c_str(), abilityname.c_str(), bundlename.c_str(), eventid, timestamp); + } +} +} +} \ No newline at end of file diff --git a/services/src/bundle_active_stub.cpp b/services/src/bundle_active_stub.cpp deleted file mode 100644 index 7f2337c167eb1c76183ba0d4c318f3a2dd739930..0000000000000000000000000000000000000000 --- a/services/src/bundle_active_stub.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#include -#include "bundle_active_stub.h" - -namespace OHOS { -namespace BundleActive { -int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, - MessageOption &option) -{ - switch (code) { - case REPORT_EVENT: { - std::string bundleName = data.ReadString(); - std::string ablityName = data.ReadString(); - int abilityId = data.ReadInt32(); - int userId = data.ReadInt32(); - int eventId = data.ReadInt32(); - int result = ReportEvent(bundleName, ablityName, abilityId, userId, eventId); - return reply.WriteInt32(result); - } - case IS_BUNDLE_IDLE: { - std::string bundleName = data.ReadString(); - std::string ablityName = data.ReadString(); - int abilityId = data.ReadInt32(); - int userId = data.ReadInt32(); - int result = IsBundleIdle(bundleName, ablityName, abilityId, userId); - return reply.WriteInt32(result); - } - case QUERY: { - std::string bundleName = data.ReadString(); - std::string ablityName = data.ReadString(); - int abilityId = data.ReadInt32(); - int userId = data.ReadInt32(); - int result = Query(bundleName, ablityName, abilityId, userId); - return reply.WriteInt32(result); - } - - default: - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } -} -} -} diff --git a/test/bundle_active_test.cpp b/test/bundle_active_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0da09a3b53a4d7d3df5e2cb727d47fa8833fbf9a --- /dev/null +++ b/test/bundle_active_test.cpp @@ -0,0 +1,143 @@ +/* + * 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_client.h" +#include "power_mgr_client.h" + +#include +using namespace OHOS::DeviceUsageStats; +using PowerMgrClient = OHOS::PowerMgr::PowerMgrClient; +using SuspendDeviceType = OHOS::PowerMgr::SuspendDeviceType; +static inline void ReportEvent (int argc, char *argv[]) +{ + BUNDLE_ACTIVE_LOGI("ReportEvent called"); + if (argc == 8) { + std::string bundleName(argv[2]); + std::string abilityName(argv[3]); + std::string abilityId(argv[4]); + std::string continuousTask(argv[5]); + int userId = atoi(argv[6]); + int eventId = atoi(argv[7]); + BundleActiveClient::GetInstance().ReportEvent(bundleName, abilityName, abilityId, continuousTask, userId, eventId); + } +} + +static inline void QueryPackageStats(int argc, char *argv[]) +{ + BUNDLE_ACTIVE_LOGI("QueryPackageStats called"); + if (argc == 5) { + int intervalType = atoi(argv[2]); + int64_t beginTime = atoll(argv[3]); + int64_t endTime = atoll(argv[4]); + BundleActiveClient::GetInstance().QueryPackageStats(intervalType, beginTime, endTime); + } +} + +static inline void QueryEvents(int argc, char *argv[]) +{ + BUNDLE_ACTIVE_LOGI("QueryEvents called"); + if (argc == 4) { + int64_t beginTime = atoll(argv[2]); + int64_t endTime = atoll(argv[3]); + BundleActiveClient::GetInstance().QueryEvents(beginTime, endTime); + } +} + +static inline void IsBundleIdle(int argc, char *argv[]) +{ + if (argc == 3) { + BUNDLE_ACTIVE_LOGI("IsBundleIdle called"); + std::string bundleName(argv[2]); + BundleActiveClient::GetInstance().IsBundleIdle(bundleName); + } +} + +static inline void SetBundleGroup(int argc, char *argv[]) +{ + if (argc == 5) { + BUNDLE_ACTIVE_LOGI("SetBundleGroup called"); + std::string bundleName(argv[2]); + int newGroup = atoi(argv[3]); + int userId = atoi(argv[4]); + BundleActiveClient::GetInstance().SetBundleGroup(bundleName, newGroup, userId); + } +} + +static inline void SuspendDevice(int argc, char *argv[]) +{ + if (argc == 2) { + BUNDLE_ACTIVE_LOGI("SuspendDevice called"); + PowerMgrClient::GetInstance().SuspendDevice(); + } +} + +static inline void WakeupDevice(int argc, char *argv[]) +{ + if (argc == 2) { + BUNDLE_ACTIVE_LOGI("WakeupDevice called"); + PowerMgrClient::GetInstance().WakeupDevice(); + } +} + +static inline void ShutDownDevice(int argc, char *argv[]) +{ + if (argc == 2) { + BUNDLE_ACTIVE_LOGI("ShutDownDevice called"); + PowerMgrClient::GetInstance().ShutDownDevice("recovery"); + } +} + +static inline void RebootDevice(int argc, char *argv[]) +{ + if (argc == 2) { + BUNDLE_ACTIVE_LOGI("RebootDevice called"); + PowerMgrClient::GetInstance().RebootDevice("recovery"); + } +} + +int main(int argc, char *argv[]) +{ + if (argc >= 2) { + char* function = argv[1]; + if (strcmp(function, "ReportEvent") == 0) { + ReportEvent(argc, argv); + } + if (strcmp(function, "QueryPackageStats") == 0) { + QueryPackageStats(argc, argv); + } + if (strcmp(function, "QueryEvents") == 0) { + QueryEvents(argc, argv); + } + if (strcmp(function, "IsBundleIdle") == 0) { + IsBundleIdle(argc, argv); + } + if (strcmp(function, "SetBundleGroup") == 0) { + SetBundleGroup(argc, argv); + } + if (strcmp(function, "SuspendDevice") == 0) { + SuspendDevice(argc, argv); + } + if (strcmp(function, "WakeupDevice") == 0) { + WakeupDevice(argc, argv); + } + if (strcmp(function, "ShutDownDevice") == 0) { + ShutDownDevice(argc, argv); + } + if (strcmp(function, "RebootDevice") == 0) { + RebootDevice(argc, argv); + } + } + return 0; +} \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..cfc5b9c06b77e823b709e37da94d4a50cf6fd767 --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,51 @@ +# 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. + +import("//build/test.gni") + +module_output_path = "device_usage_statistics/deviceusagestatisticstest" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "//foundation/resourceschedule/device_usage_statistics/interfaces/innerkits/include", + "//foundation/resourceschedule/device_usage_statistics/services/common/include", + "//foundation/resourceschedule/device_usage_statistics/services/packageusage/include", + "//foundation/resourceschedule/device_usage_statistics/services/packagegroup/include" + ] +} + +ohos_unittest("DeviceUsageStatsTest") { + module_out_path = module_output_path + + sources = [ "device_usage_statistics_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//utils/native/base:utils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/resourceschedule/device_usage_statistics:usagestatinner", + "//base/powermgr/power_manager/interfaces/innerkits:powermgr_client", + "//third_party/googletest:gtest_main" + ] +} + +group("unittest") { + testonly = true + deps = [ ":DeviceUsageStatsTest" ] +} \ No newline at end of file diff --git a/test/unittest/device_usage_statistics_test.cpp b/test/unittest/device_usage_statistics_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f184457857eebf149951638daf52213b6b53ffa2 --- /dev/null +++ b/test/unittest/device_usage_statistics_test.cpp @@ -0,0 +1,155 @@ +/* + * 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. + */ + +#define private public +#define protected public +#undef private +#undef protected + +#include + +#include +#include "system_ability_definition.h" + +#include "bundle_active_client.h" +#include "bundle_active_event.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DeviceUsageStats { +static std::string DEFAULT_BUNDLENAME = "com.ohos.camera"; +static std::string DEFAULT_ABILITYID = "1234"; +static std::string DEFAULT_ABILITYNAME = "testability"; +static int DEFAULT_USERID = 0; +class BundleActiveTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void BundleActiveTest::SetUpTestCase(void) +{ +} + +void BundleActiveTest::TearDownTestCase(void) +{ +} + +void BundleActiveTest::SetUp(void) +{ +} + +void BundleActiveTest::TearDown(void) +{ +} + +/* + * @tc.name: BundleActiveTest_GetServiceObject_001 + * @tc.desc: get service object + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_GetServiceObject_001, Function | MediumTest | Level0) +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + EXPECT_NE(systemAbilityManager, nullptr); + + sptr remoteObject = + systemAbilityManager->GetSystemAbility(DEVICE_UASAGE_STATISTICS_SYS_ABILITY_ID); + EXPECT_NE(remoteObject, nullptr); +} + +/* + * @tc.name: BundleActiveTest_ReportEvent_001 + * @tc.desc: report a mock event + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_ReportEvent_001, Function | MediumTest | Level0) +{ + BundleActiveClient::GetInstance().ReportEvent(DEFAULT_BUNDLENAME, DEFAULT_ABILITYNAME, DEFAULT_ABILITYID, + DEFAULT_USERID, 2); + BundleActiveClient::GetInstance().ReportEvent(DEFAULT_BUNDLENAME, DEFAULT_ABILITYNAME, DEFAULT_ABILITYID, + DEFAULT_USERID, 3); + BundleActiveClient::GetInstance().ReportEvent(DEFAULT_BUNDLENAME, DEFAULT_ABILITYNAME, DEFAULT_ABILITYID, + DEFAULT_USERID, 4); +} + +/* + * @tc.name: BundleActiveTest_QueryEvents_001 + * @tc.desc: queryevents + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_QueryEvents_001, Function | MediumTest | Level0) +{ + std::vector result = BundleActiveClient::GetInstance().QueryEvents(0, 20000000000000); + EXPECT_NE(result.size(), 0); +} + +/* + * @tc.name: BundleActiveTest_QueryCurrentEvents_001 + * @tc.desc: querycurrentevents + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_QueryCurrentEvents_001, Function | MediumTest | Level0) +{ + std::vector result = BundleActiveClient::GetInstance().QueryCurrentEvents(0, 20000000000000); + EXPECT_EQ(result.size(), 0); +} + +/* + * @tc.name: BundleActiveTest_QueryPackagesStats_001 + * @tc.desc: querypackagestats + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_QueryPackagesStats_001, Function | MediumTest | Level0) +{ + std::vector result = BundleActiveClient::GetInstance().QueryPackageStats(4, 0, + 20000000000000); + EXPECT_NE(result.size(), 0); +} + +/* + * @tc.name: BundleActiveTest_IsBundleIdle_001 + * @tc.desc: isbundleidle + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_IsBundleIdle_001, Function | MediumTest | Level0) +{ + bool result = BundleActiveClient::GetInstance().IsBundleIdle(DEFAULT_BUNDLENAME); + EXPECT_NE(result, true); +} + +/* + * @tc.name: BundleActiveTest_QueryPackageGroup_001 + * @tc.desc: querypackagegroup + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_QueryPackageGroup_001, Function | MediumTest | Level0) +{ + int result = BundleActiveClient::GetInstance().QueryPackageGroup(); + EXPECT_EQ(result, -1); +} +} +}