diff --git a/BUILD.gn b/BUILD.gn index ff06df6b1d18ae716b80a53bfcac73b188aca0bf..242efd1b6757725bb9763f8e57efc40dc165b6c1 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,157 @@ # 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 = [ - "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", + "frameworks/src/bundle_state_init.cpp", + "frameworks/src/bundle_state_common.cpp", + "frameworks/src/bundle_state_query.cpp" ] include_dirs = [ - "services/include", + "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_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" + ] + include_dirs = [ + ":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", + "//base/notification/ans_standard/frameworks/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" + ] + 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..4f5549997ac7e79432f5d08843e5c9f00adcfbe9 --- /dev/null +++ b/bundle.json @@ -0,0 +1,72 @@ +{ + "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" + ], + "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..dc204355d87da99f7be259002236490517c52ba8 --- /dev/null +++ b/frameworks/src/bundle_state_common.cpp @@ -0,0 +1,228 @@ +/* + * 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_common.h" +#include "bundle_active_log.h" +#include "bundle_state_data.h" + +namespace OHOS { +namespace BundleActive { +napi_value Common::NapiGetNull(napi_env env) +{ + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +void Common::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 Common::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 Common::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 Common::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 Common::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 Common::SetPromiseInfo(const napi_env &env, const napi_deferred &deferred, const napi_value &result) +{ + napi_resolve_deferred(env, deferred, result); +} + +napi_value Common::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 Common::JSParaError(const napi_env &env, const napi_ref &callback) +{ + if (callback) { + return Common::NapiGetNull(env); + } else { + napi_value promise = nullptr; + napi_deferred deferred = nullptr; + napi_create_promise(env, &deferred, &promise); + napi_resolve_deferred(env, deferred, Common::NapiGetNull(env)); + return promise; + } +} + +std::string Common::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; + } + memset(buf, 0, size + 1); + + 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 Common::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 Common::NapiGetNull(env); +} + +napi_value Common::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 Common::NapiGetNull(env); +} + +void Common::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 BundleActive +} // 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..4bc2d272981275924bd7383672e86e01c7912193 --- /dev/null +++ b/frameworks/src/bundle_state_init.cpp @@ -0,0 +1,55 @@ +/* + * 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 BundleActive { + +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..ebe90299950969aedd8380b2e9ee7c7f2443fa92 --- /dev/null +++ b/frameworks/src/bundle_state_query.cpp @@ -0,0 +1,562 @@ +/* + * 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_query.h" +#include "bundle_state_common.h" +#include +#include "bundle_active_log.h" +#include "bundle_active_client.h" +#include "bundle_state_data.h" + +namespace OHOS { +namespace BundleActive { + +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 = Common::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 Common::NapiGetNull(env); +} + +napi_value IsIdleState(napi_env env, napi_callback_info info) +{ + IsIdleStateParamsInfo params; + if (ParseIsIdleStateParameters(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoIsIdleState *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoIsIdleState {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::JSParaError(env, params.callback); + } + asyncCallbackInfo->bundleName = params.bundleName; + BUNDLE_ACTIVE_LOGI("asyncCallbackInfo->bundleName: %{public}s", asyncCallbackInfo->bundleName.c_str()); + Common::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); + Common::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 Common::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 Common::NapiGetNull(env); +} + +napi_value QueryAppUsagePriorityGroup(napi_env env, napi_callback_info info) +{ + PriorityGroupParamsInfo params; + if (ParsePriorityGroupParameters(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoPriorityGroup *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoPriorityGroup {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::JSParaError(env, params.callback); + } + Common::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); + Common::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 Common::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 (Common::GetInt64NumberValue(env, argv[0], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseStatesParameters failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : endTime + if (Common::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 Common::NapiGetNull(env); +} + +napi_value QueryCurrentBundleActiveStates(napi_env env, napi_callback_info info) +{ + StatesParamsInfo params; + if (ParseStatesParameters(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoStates *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoStates {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::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); + Common::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); + Common::GetBundleActiveEventForResult(env, asyncCallbackInfo->BundleActiveState, result); + Common::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 Common::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value QueryBundleActiveStates(napi_env env, napi_callback_info info) +{ + StatesParamsInfo params; + if (ParseStatesParameters(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoStates *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoStates {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::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); + Common::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); + Common::GetBundleActiveEventForResult(env, asyncCallbackInfo->BundleActiveState, result); + Common::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 Common::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 (Common::GetInt32NumberValue(env, argv[0], params.intervalType) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParametersByInterval failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : beginTime + if (Common::GetInt64NumberValue(env, argv[1], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParametersByInterval failed, beginTime is invalid."); + return nullptr; + } + + // argv[2] : endTime + if (Common::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 Common::NapiGetNull(env); +} + +napi_value QueryBundleStateInfoByInterval(napi_env env, napi_callback_info info) +{ + AppUsageParamsByIntervalInfo params; + if (ParseAppUsageParametersByInterval(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoAppUsageByInterval *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoAppUsageByInterval {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::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); + Common::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); + Common::GetBundleStateInfoByIntervalForResult(env, asyncCallbackInfo->packageStats, result); + Common::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 Common::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 (Common::GetInt64NumberValue(env, argv[0], params.beginTime) == nullptr) { + BUNDLE_ACTIVE_LOGE("ParseAppUsageParameters failed, beginTime is invalid."); + return nullptr; + } + + // argv[1] : endTime + if (Common::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 Common::NapiGetNull(env); +} + +napi_value QueryBundleStateInfos(napi_env env, napi_callback_info info) +{ + AppUsageParamsInfo params; + if (ParseAppUsageParameters(env, info, params) == nullptr) { + return Common::JSParaError(env, params.callback); + } + + napi_value promise = nullptr; + AsyncCallbackInfoAppUsage *asyncCallbackInfo = + new (std::nothrow) AsyncCallbackInfoAppUsage {.env = env, .asyncWork = nullptr}; + if (!asyncCallbackInfo) { + return Common::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); + Common::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); + Common::GetBundleStateInfoForResult(env, asyncCallbackInfo->packageStats, result); + Common::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 Common::NapiGetNull(env); + } else { + return promise; + } +} +} // namespace BundleActive +} // 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/.gitkeep b/interfaces/innerkits/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/interfaces/innerkits/include/bundle_active_client.h b/interfaces/innerkits/include/bundle_active_client.h index 1576288a21f001a1027cc1ecabd33b779b61c380..bdf8284631960dbfd52032f135c239c3b1602c74 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,22 +17,28 @@ #define BUNDLE_ACTIVE_CLIENT_H #include "bundle_active_iservice.h" +#include "bundle_active_package_stats.h" +#include "bundle_active_event.h" namespace OHOS { namespace BundleActive { 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 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 ac9d22cadbe884479a24afd7d8606580363ad3be..5cd98e41654dae497699a4aecc1efc14a21775c5 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,16 +17,20 @@ #define BUNDLE_ACTIVE_PROXY_H #include "bundle_active_iservice.h" +#include "bundle_active_event.h" namespace OHOS { namespace BundleActive { 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 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() {} diff --git a/interfaces/innerkits/src/bundle_active_client.cpp b/interfaces/innerkits/src/bundle_active_client.cpp index 7ddb46d3d86954219a792106ddf94f6e48ae2047..cca4fdfd76cf87c6cc646e625b7fc76d601b3866 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,6 +14,7 @@ */ #include "bundle_active_client.h" +#include "bundle_active_package_stats.h" namespace OHOS { namespace BundleActive { @@ -29,39 +30,76 @@ 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 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, 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 4b941b8a46444ed530b9f96c274e666347af34d1..03c2c23507f546ffe6d7aec141e3e7870946b4c9 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,16 +14,19 @@ */ #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) { +int BundleActiveProxy::ReportEvent(std::string& bundleName, std::string& abilityName, std::string abilityId, 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.WriteInt32(userId); data.WriteInt32(eventId); Remote() -> SendRequest(REPORT_EVENT, data, reply, option); @@ -32,32 +35,116 @@ 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..0ae001b587238c4029b5b2e04ce278854b0c325d --- /dev/null +++ b/interfaces/kits/bundlestats/js/@ohos.bundleState.d.ts @@ -0,0 +1,256 @@ +/* + * 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 + * @sysCap SystemCapability.Ressched.BundleActive + * @devices phone, tablet, tv, wearable, car + */ +declare namespace bundleState { + + /** + * @since 7 + * @sysCap SystemCapability.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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.Ressched.BundleActive + * @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..21e5d863ce8c2171c2d14566274739513d0435b8 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_common.h @@ -0,0 +1,70 @@ +/* + * 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 BundleActive { +const std::int32_t STR_MAX_SIZE = 64; + +class Common { + +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 BundleActive +} // 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..a0156de2bfe9932620a1d7fdd112b748563cb2e0 --- /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 "napi/native_api.h" +#include "napi/native_node_api.h" +#include +#include "bundle_active_event.h" +#include "bundle_active_package_stats.h" + +namespace OHOS { +namespace BundleActive { + +#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 BundleActive +} // 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..47331a93254dbcaea3a805d20bc57caacd424973 --- /dev/null +++ b/interfaces/kits/bundlestats/napi/include/bundle_state_init.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 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 BundleActive { +#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 BundleActive +} // 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..f146a75218dbe1a6637d2e9af2c90d1f728f58b3 --- /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 BundleActive { + 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 BundleActive +} // 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_binary_search.h b/services/common/include/bundle_active_binary_search.h new file mode 100644 index 0000000000000000000000000000000000000000..d2e5524d4cb28a9925df549d3f1a8e58aaf950f6 --- /dev/null +++ b/services/common/include/bundle_active_binary_search.h @@ -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. + */ + +#ifndef BUNDLE_ACTIVE_BINARY_SEARCH_H +#define BUNDLE_ACTIVE_BINARY_SEARCH_H + +#include + +#include "singleton.h" + +namespace OHOS { +namespace BundleActive { +class BundleActiveBinarySearch : public DelayedSingleton { +public: + int32_t BinarySearch(const std::vector &tableNameArray, int64_t targetValue); + DECLARE_DELAYED_SINGLETON(BundleActiveBinarySearch); +}; +} // namespace BundleActive +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_BINARY_SEARCH_H \ 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..39e6b5340a4e5ffd8a0a728a67bddb806a08a848 --- /dev/null +++ b/services/common/include/bundle_active_common_event_subscriber.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#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 "bundle_active_iservice.h" + +namespace OHOS { +namespace BundleActive { + +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..6863a78fd5539e2165b51ea60922f81e6670dee6 --- /dev/null +++ b/services/common/include/bundle_active_constant.h @@ -0,0 +1,126 @@ +/* + * 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 BundleActive { + +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 DAY_IN_MILLIS_MAX = 24 * 60 * 60 * 1000; +const int64_t SIX_DAY_IN_MILLIS_MAX = 6 * 24 * 60 * 60 * 1000; +const int64_t DAY_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 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 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 BundleActive +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_CONSTANT_H \ 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..00e3e8bf77e04ae616fc1f386d7e080ddb0f8abc --- /dev/null +++ b/services/common/include/bundle_active_core.h @@ -0,0 +1,92 @@ +/* + * 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 "bundle_active_iservice.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" + +namespace OHOS { +namespace BundleActive { +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 = 1 * 60 * 1000; + static const int64_t TIME_CHANGE_THRESHOLD_MILLIS = 2000; + 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_iservice.h b/services/common/include/bundle_active_iservice.h similarity index 54% rename from services/include/bundle_active_iservice.h rename to services/common/include/bundle_active_iservice.h index 910166efc7e616f86c16ea9a40e4ebaed6835c50..508a9dcc8574de62260bbd6da310a33fce9bceda 100644 --- a/services/include/bundle_active_iservice.h +++ b/services/common/include/bundle_active_iservice.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,30 +22,47 @@ #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 { - + +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 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/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..d7423a2bd46a9f80992f13ec76444903fabf8ca1 --- /dev/null +++ b/services/common/include/bundle_active_open_callback.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_OPEN_CALLBACK_H +#define BUNDLE_ACTIVE_OPEN_CALLBACK_H + +#include + +#include "rdb_open_callback.h" +#include "rdb_errno.h" + +namespace OHOS { +namespace BundleActive { +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; +}; +} // namespace BundleActive +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_OPEN_CALLBACK_H \ 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 44% rename from services/include/bundle_active_service.h rename to services/common/include/bundle_active_refresh_database_handler.h index 343eada3285315504bc0492af0be634af09e401c..56bceca354a5dc92af4f2fabf8c5923bb05fbdf4 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,8 +13,10 @@ * 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 "bundle_active_iservice.h" #include "bundle_active_stub.h" @@ -22,21 +24,21 @@ namespace OHOS { namespace BundleActive { -class BundleActiveService : public SystemAbility, public BundleActiveStub { - DECLARE_SYSTEM_ABILITY(BundleActiveService); +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() {} - -protected: - void OnStart() override; - void OnStop() override; + explicit RefreshDatabaseHandler(const std::shared_ptr &runner); + ~RefreshDatabaseHandler() = default; + + /** + * Process the event. Developers should override this method. + * + * @param event The event should be processed. + */ + void ProcessEvent(const InnerEvent::Pointer &event) override; }; -} -} -#endif \ No newline at end of file +} // namespace BundleActive +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_REFRESH_DATABASE_HANDLER_H \ No newline at end of file diff --git a/services/common/include/bundle_active_service.h b/services/common/include/bundle_active_service.h new file mode 100644 index 0000000000000000000000000000000000000000..dd170dc448f98acd5ac19fa680cd2269ea6f1fe6 --- /dev/null +++ b/services/common/include/bundle_active_service.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_SERVICE_H +#define BUNDLE_ACTIVE_SERVICE_H + +#include "bundle_mgr_interface.h" +#include "os_account_manager.h" + +#include "bundle_active_iservice.h" +#include "bundle_active_stub.h" +#include "bundle_active_core.h" +#include "bundle_active_report_handler.h" +#include "bundle_active_shutdown_callback_service.h" + +namespace OHOS { +namespace BundleActive { +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 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_; + sptr sptrBundleMgr_; + sptr shutdownCallback_; + int ConvertIntervalType(const int& intervalType); + bool GetBundleMgrProxy(); +}; +} +} + +#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 40% rename from services/common/include/bundle_active_user_service.h rename to services/common/include/bundle_active_shutdown_callback_proxy.h index e26f22a118e37e01d01ae9355a046a020966cef8..a144530469fcf603da29780f06e3ecb4a1dd8f1b 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,32 +13,27 @@ * 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 "bundle_active_iservice.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 { +using IShutdownCallback = OHOS::PowerMgr::IShutdownCallback; +class BundleActiveShutdownCallbackProxy : public IRemoteProxy { public: - BundleActiveUserService(int userId);//,/*database定义待补充*/ BundleActiveService listener/*刷数据库监听器接口实现类*/); + 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_; }; } } + #endif \ No newline at end of file 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..14ad029a7c7690e32f609baf295294c2f80a060f --- /dev/null +++ b/services/common/include/bundle_active_shutdown_callback_service.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_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 BundleActive { +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..20ffcb21dc1627ea1f748c0dc64e99d275d44f79 --- /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 "bundle_active_iservice.h" + +namespace OHOS { +namespace BundleActive { +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 94% rename from services/include/bundle_active_stub.h rename to services/common/include/bundle_active_stub.h index 5b1843da9510199ede9f49117cacfd7912973e53..665b2e96fc91daa64842910a767b2ba0f0a31b32 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 @@ -24,11 +24,10 @@ namespace BundleActive { class BundleActiveStub : public IRemoteStub { public: virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, MessageOption &option) override; - -public: BundleActiveStub() {}; ~BundleActiveStub() {}; }; } } + #endif 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..50989787a895ff4a4421bc035accce11a2b33dde --- /dev/null +++ b/services/common/include/bundle_active_usage_database.h @@ -0,0 +1,94 @@ +/* + * 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 BundleActive { +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_; +}; +} // namespace BundleActive +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_USAGE_DATABASE_H \ 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..a5f771eed52550bdbfec6c914d11360996dff3e2 --- /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 BundleActive { +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; +} +} // namespace BundleActive +} // namespace OHOS \ No newline at end of file diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eaa77960a0b8f35292746af0c82c6a87de95d7c7 --- /dev/null +++ b/services/common/src/bundle_active_core.cpp @@ -0,0 +1,380 @@ +/* + * 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_core.h" +#include "bundle_active_event.h" +#include "bundle_active_report_handler.h" +#include "bundle_active_group_common.h" +#include "bundle_active_constant.h" + +namespace OHOS { +namespace BundleActive { +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("m_userservice 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) { + //时区变换逻辑 + for (std::map>::iterator it = userStatServices_.begin(); it != userStatServices_.begin(); it++) { + 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..44faa254865180705a863001bab2b1a5e5bc132c --- /dev/null +++ b/services/common/src/bundle_active_open_callback.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_open_callback.h" +#include "bundle_active_log.h" +#include "bundle_active_constant.h" + +namespace OHOS { +namespace BundleActive { +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 BundleActive +} // 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..769c1a8308400851f527c26fdfb891cc23aaa581 --- /dev/null +++ b/services/common/src/bundle_active_refresh_database_handler.cpp @@ -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. + */ + +#include "bundle_active_refresh_database_handler.h" + +namespace OHOS { +namespace BundleActive { +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 BundleActive +} // 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..32ddd458f6acf7fbacaccfe4b351a13a10d37ad0 --- /dev/null +++ b/services/common/src/bundle_active_service.cpp @@ -0,0 +1,282 @@ +/* + * 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 "bundle_active_service.h" +#include "bundle_active_event.h" +#include "bundle_active_package_stats.h" + +namespace OHOS { +namespace BundleActive { +static const int PERIOD_BEST_JS = 0; +static const int PERIOD_YEARLY_JS = 4; +REGISTER_SYSTEM_ABILITY_BY_ID(BundleActiveService, DEVICE_UASAGE_STATISTICS_SYS_ABILITY_ID, true); + +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); + 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_); + } + if (systemAbilityId == BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) { + bundleActiveCore_->InitBundleGroupController(); + } +} + +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 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.userId_ = userId; + BUNDLE_ACTIVE_LOGI("BundleActiveService::ReportEvent user id is %{public}d", tmpHandlerObject.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); + 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 user id is %{public}d", userId); + 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 ret = ""; + std::string bundleName = ""; + //get bundle name + ret = sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + if (!ret.empty() && !bundleName.empty()) { + 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 ret = ""; + std::string bundleName = ""; + ret = sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + if (!ret.empty() && !bundleName.empty()) { + 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 ret = ""; + std::string bundleName = ""; + //get bundle name + ret = sptrBundleMgr_->GetBundleNameForUid(callingUid, bundleName); + BUNDLE_ACTIVE_LOGI("BundleActiveService::QueryPackageGroup bundlename is %{public}s", bundleName.c_str()); + if (!ret.empty() && !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 4; + } else if (intervalType > PERIOD_BEST_JS && intervalType <= PERIOD_YEARLY_JS) { + return intervalType - 1; + } + return -1; +} +} +} \ 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..8d278c43f02be5931e934912b71d730a8f5dcfa3 --- /dev/null +++ b/services/common/src/bundle_active_shutdown_callback_proxy.cpp @@ -0,0 +1,37 @@ +/* + * 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 BundleActive { +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..6161b606b9600fb9f50125f14642ce6e01cc7698 --- /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 BundleActive { +BundleActiveShutdownCallbackService::BundleActiveShutdownCallbackService(std::shared_ptr bundleActiveCore) { + if (bundleActiveCore != nullptr) { + BUNDLE_ACTIVE_LOGI("BundleActiveShutdownCallbackService::BundleActiveShutdownCallbackService called and bundleActiveCore not null"); + bundleActiveCore_ = bundleActiveCore; + } +} + +void BundleActiveShutdownCallbackService::ShutdownCallback() { + BUNDLE_ACTIVE_LOGI("BundleActiveShutdownCallbackService::ShutdownCallback called"); + bundleActiveCore_->ShutDown(); + BUNDLE_ACTIVE_LOGI("BundleActiveShutdownCallbackService::ShutdownCallback end"); +} +} +} 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..c0ce9447cc2defa546bb6798092b67dfcf71aa05 --- /dev/null +++ b/services/common/src/bundle_active_shutdown_callback_stub.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bundle_active_shutdown_callback_stub.h" + +namespace OHOS { +namespace BundleActive { +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..d22b7f2a5e40cf251da42fa0e3c5621c04b95ce7 --- /dev/null +++ b/services/common/src/bundle_active_stub.cpp @@ -0,0 +1,127 @@ +/* + * 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 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(); + std::string abilityId = data.ReadString(); + 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(); + 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..4b00439643cca7815d29c9fad0304c42cf479340 --- /dev/null +++ b/services/common/src/bundle_active_usage_database.cpp @@ -0,0 +1,1167 @@ +/* + * 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_usage_database.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" + +namespace OHOS { +namespace BundleActive { + +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()); + } + } + 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()); + } + } + 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; + } + 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); + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase PutBundleHistoryData Insert SUCCESS, outRowId = %{public}lld", outRowId); + outRowId = BUNDLE_ACTIVE_FAIL; + } else { + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase PutBundleHistoryData Update SUCCESS, changeRow = %{public}d", changeRow); + 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) { + 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); + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase FlushPackageInfo Insert SUCCESS, outRowId = %{public}lld", outRowId); + outRowId = BUNDLE_ACTIVE_FAIL; + } else { + BUNDLE_ACTIVE_LOGI("BundleActiveUsageDatabase FlushPackageInfo Update SUCCESS, changeRow = %{public}d", changeRow); + 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 { + 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(DAY_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(DAY_IN_MILLIS_MIN)); + } + queryCondition.push_back(std::to_string(DAY_IN_MILLIS_MAX)); + queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime >= ? and lastTime <= ?"; + } else if (i == endIndex) { + queryCondition.push_back(std::to_string(DAY_IN_MILLIS_MIN)); + queryCondition.push_back(std::to_string(endTime - packageTableTime)); + queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime >= ? 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); +} + +} // namespace BundleActive +} // namespace OHOS \ 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 3c0f90cc3b1bef3237cfd459ea082207fed28f98..0000000000000000000000000000000000000000 --- a/services/common/src/bundle_active_user_service.cpp +++ /dev/null @@ -1,69 +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){//,/*database定义待补充*/ BundleActiveService listener/*刷数据库监听器接口实现类*/) { - currentStats_.reserve(BundleActivePeriodStats::PERIOD_COUNT); - //m_listener = listener; - 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; - } - } -} -} -} \ No newline at end of file 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..abed3f343a21d1499d722a28d334cefb5908c9df --- /dev/null +++ b/services/packagegroup/include/bundle_active_group_common.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_GROUP_COMMON_H +#define BUNDLE_ACTIVE_GROUP_COMMON_H + +namespace OHOS { +namespace BundleActive { +namespace BundleActiveGroupConst { + +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 ONE_HOUR = 60 * ONE_MINUTE; +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..6024b5f9ed295af1f59ddf4c82c9506e1cec3c42 --- /dev/null +++ b/services/packagegroup/include/bundle_active_group_controller.h @@ -0,0 +1,102 @@ +/* + * 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 "bundle_active_iservice.h" +#include "bundle_active_event.h" +#include "bundle_active_user_history.h" +#include "bundle_mgr_interface.h" + +namespace OHOS { +namespace BundleActive { + +using namespace BundleActiveGroupConst; + +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_ ? 120 * 1000 : 1 * ONE_HOUR, + debug_ ? 240 * 1000 : 2 * ONE_HOUR + }; + const int64_t BOOT_TIME_LEVEL[4] = { + 0, + debug_ ? 1 * ONE_MINUTE : 12 * ONE_HOUR, + debug_ ? 4 * ONE_MINUTE : 24 * ONE_HOUR, + debug_ ? 16 * ONE_MINUTE : 48 * ONE_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(std::string bundleName); + 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_ ? 12 * ONE_MINUTE : 12 * ONE_HOUR; + int64_t timeoutForSystemInteraction_ = debug_ ? ONE_MINUTE : 10 * ONE_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..4ef2819f4ecb43b7d0dfb64ca8efdd0a534bb66a --- /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 "bundle_active_iservice.h" +#include "bundle_active_group_controller.h" + +namespace OHOS { +namespace BundleActive { +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 = 120 * 1000; + +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..fa3d071be14a31edb2fbd7f5ccb5e6b0eba97242 --- /dev/null +++ b/services/packagegroup/include/bundle_active_package_history.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_USAGE_HISTORY_H +#define BUNDLE_ACTIVE_USAGE_HISTORY_H + +#include "bundle_active_iservice.h" + +namespace OHOS { +namespace BundleActive { +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..9710173dc5168028b6cbc56d3f1acd8f513f6d84 --- /dev/null +++ b/services/packagegroup/include/bundle_active_user_history.h @@ -0,0 +1,59 @@ +/* + * 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 BundleActive { + +using namespace BundleActiveGroupConst; + +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..ed3f3a1a85be1797037edc815ececda4971b54c4 --- /dev/null +++ b/services/packagegroup/src/bundle_active_group_controller.cpp @@ -0,0 +1,318 @@ +/* + * 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_group_controller.h" +#include "bundle_active_user_history.h" +#include "bundle_active_group_handler.h" +#include "bundle_active_iservice.h" + +namespace OHOS { +namespace BundleActive { + +using namespace BundleActiveGroupConst; + +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()) { + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::PeriodCheckBundleState will send MSG_CHECK_IDLE_STATE event, useId is %{public}d", userId); + 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"); + std::vector allBundlesForUser; + if (!GetBundleMgrProxy()) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState get bundle manager proxy failed!"); + return false; + } + sptrBundleMgr_->GetApplicationInfos(flag, userId, allBundlesForUser); + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState size of bundles is %{public}d", allBundlesForUser.size()); + std::vector bundleNamesOfUser; + for (auto oneBundle : allBundlesForUser) { + bundleNamesOfUser.push_back(oneBundle.bundleName); + } + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + int64_t bootBasedTimeStamp = timer->GetBootTimeMs(); + BUNDLE_ACTIVE_LOGE("BundleActiveGroupController::CheckEachBundleState time of check is %{public}lld", bootBasedTimeStamp); + for (auto oneBundleName : bundleNamesOfUser) { + CheckAndUpdateGroup(oneBundleName, userId, bootBasedTimeStamp); + } + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::CheckEachBundleState print data"); + bundleUserHistory_->printdata(userId); + BUNDLE_ACTIVE_LOGI("BundleActiveGroupController::CheckEachBundleState boottimestamp for user history is %{public}lld, screenonstamp for user history is %{public}lld, bootfrom duration is %{public}lld, screenon duration is %{public}lld", + bundleUserHistory_->bootBasedTimeStamp_, bundleUserHistory_->screenOnTimeStamp_, bundleUserHistory_->bootBasedDuration_, bundleUserHistory_->ScreenOnDuration_); + 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_) == 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) == 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) == 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) { + return 1; + } else { + return 0; + } +} + +int BundleActiveGroupController::QueryPackageGroup(const int& userId, const std::string& bundleName) { + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + if (IsBundleInstalled(bundleName) == 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(std::string bundleName) { + ApplicationInfo bundleInfo; + int userId = 100; + 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..05a387d804a9d7ec13155b927fb465232adc22a0 --- /dev/null +++ b/services/packagegroup/src/bundle_active_group_handler.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service_client.h" +#include "os_account_manager.h" + +#include "bundle_active_group_handler.h" + +namespace OHOS { +namespace BundleActive { +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..4eeb965b416d6e97babca7bae52dc3cae28b2eb4 --- /dev/null +++ b/services/packagegroup/src/bundle_active_user_history.cpp @@ -0,0 +1,193 @@ +/* + * 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 BundleActive { + +using namespace BundleActiveGroupConst; + +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) { + 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) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::UpdateBootBasedAndScreenTime called"); + if (isScreenOn_ == isScreenOn && isShutdown == false) { + return; + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::UpdateBootBasedAndScreenTime called screen status change"); + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::UpdateBootBasedAndScreenTime before screenOnTimeStamp_ is %{public}lld, bootBasedTimeStamp_ is %{public}lld, ScreenOnDuration_ is %{public}lld, bootBasedDuration_ is %{public}lld", + screenOnTimeStamp_, bootBasedTimeStamp_, ScreenOnDuration_, bootBasedDuration_); + isScreenOn_ = isScreenOn; + if (isScreenOn_) { + screenOnTimeStamp_ = bootBasedTimeStamp; + } else { + ScreenOnDuration_ += bootBasedTimeStamp - screenOnTimeStamp_; + bootBasedDuration_ += bootBasedTimeStamp - bootBasedTimeStamp_; + bootBasedTimeStamp_ = bootBasedTimeStamp; + } + database_.PutDurationData(bootBasedDuration_, ScreenOnDuration_); + BUNDLE_ACTIVE_LOGI("BundleActiveUserHistory::UpdateBootBasedAndScreenTime after bootBasedTimeStamp is %{public}lld, screenOnTimeStamp_ is %{public}lld, bootBasedTimeStamp_ is %{public}lld, ScreenOnDuration_ is %{public}lld, bootBasedDuration_ is %{public}lld", + bootBasedTimeStamp, screenOnTimeStamp_, bootBasedTimeStamp_, ScreenOnDuration_, bootBasedDuration_); +} + +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..54f6956df1dfe7d6e4e27c1f86e98afb013f248c --- /dev/null +++ b/services/packageusage/include/bundle_active_calendar.h @@ -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. + */ + +#ifndef BUNDLE_ACTIVE_CALENDER_H +#define BUNDLE_ACTIVE_CALENDER_H + +#include + +namespace OHOS { +namespace BundleActive { +class BundleActiveCalendar { +private: + int64_t time_; + +public: + static const int64_t DAY_MILLISECONDS = (int64_t)1 * 24 * 60 * 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); +}; +} +} + +#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 74% rename from services/common/include/bundle_active_event.h rename to services/packageusage/include/bundle_active_event.h index 4f5f2d9d3c601327bf05527d3eb544cac752440b..2c18995f7f5f2e318c272829c946c84c0fb63b93 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 @@ -20,42 +20,48 @@ namespace OHOS { namespace BundleActive { -class BundleActiveEvent { +class BundleActiveEvent : public Parcelable { public: //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 FRONT_SERVICE_CONTINUED = 11; + 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); }; } } diff --git a/services/common/include/bundle_active_event_list.h b/services/packageusage/include/bundle_active_event_list.h similarity index 88% rename from services/common/include/bundle_active_event_list.h rename to services/packageusage/include/bundle_active_event_list.h index 1ac946e744b58f1eceb6b8f4fccfff3d9dfbc552..e120573d8990ddd1910f31b872a24e61b900f47a 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 @@ -24,14 +24,15 @@ namespace BundleActive { 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_; }; } } + #endif \ No newline at end of file diff --git a/services/common/include/bundle_active_event_stats.h b/services/packageusage/include/bundle_active_event_stats.h similarity index 96% rename from services/common/include/bundle_active_event_stats.h rename to services/packageusage/include/bundle_active_event_stats.h index e4469854d4833cbbab825145bb253225c01bc470..0fd60ddf68b7dbd7d26bccc2ce6925ed2a668fd6 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 @@ -40,4 +40,5 @@ public: }; } } + #endif \ No newline at end of file diff --git a/services/common/include/bundle_active_event_tracker.h b/services/packageusage/include/bundle_active_event_tracker.h similarity index 82% rename from services/common/include/bundle_active_event_tracker.h rename to services/packageusage/include/bundle_active_event_tracker.h index 19af858521c5e1a4804173bf26804643847e06bb..f1bfa6848bb9ec4122780062fac384133f6f1498 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 @@ -27,11 +27,12 @@ public: 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(); }; } } + #endif \ No newline at end of file diff --git a/services/common/include/bundle_active_package_stats.h b/services/packageusage/include/bundle_active_package_stats.h similarity index 52% rename from services/common/include/bundle_active_package_stats.h rename to services/packageusage/include/bundle_active_package_stats.h index 9d0c9f3d34c996a69e79fc06fb11a1146cca1d9e..f77f7ba81c32372b61b19366aff65138bd788f53 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,30 +13,30 @@ * 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 "bundle_active_iservice.h" #include "bundle_active_event.h" namespace OHOS { namespace BundleActive { -//bundles statistics, including Abilityies and frontservices. -class BundleActivePackageStats { +class BundleActivePackageStats : public Parcelable { public: std::string bundleName_; int64_t beginTimeStamp_; //start time of counting int64_t endTimeStamp_; //stop time of counting int64_t lastTimeUsed_; //the timestamp of last launch - int64_t totalTimeInFront_; // the total time of using the bundle - int64_t lastTimeLongTimeTaskUsed_; - int64_t totalTimeLongTimeTaskUsed_; - int launchedCount_; - int bundleLaunchedCount_; + 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_; // key is abilityId, value is the last event of this ability. Restore all abilities' last event of bundle. - std::map frontServices_; // restore the frontservices' names using by bundle. - BundleActivePackageStats() {}; + std::map abilities_; // key is abilityId, value is the last event of this ability. Restore all abilities' last event of bundle. + std::map longTimeTasks_; // restore the frontservices' names using by bundle. + BundleActivePackageStats(); + ~BundleActivePackageStats() {}; BundleActivePackageStats(const BundleActivePackageStats& orig); std::string GetBundleName(); int64_t GetBeginTimeStamp(); @@ -47,20 +47,23 @@ 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); }; } } + #endif diff --git a/services/common/include/bundle_active_period_stats.h b/services/packageusage/include/bundle_active_period_stats.h similarity index 62% rename from services/common/include/bundle_active_period_stats.h rename to services/packageusage/include/bundle_active_period_stats.h index 29952ad4fb9a06276b720daf84e165b060598455..cf3db40df3356f2b036761695ceb7030148d29ee 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 "bundle_active_iservice.h" #include "bundle_active_event.h" @@ -22,6 +24,7 @@ #include "bundle_active_event_list.h" #include "bundle_active_event_tracker.h" + namespace OHOS { namespace BundleActive { class BundleActivePeriodStats { @@ -32,35 +35,31 @@ 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); - }; } } + #endif \ No newline at end of file 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..70a74e3da8373213aff9d3a1d2b9e9541b8949bc --- /dev/null +++ b/services/packageusage/include/bundle_active_report_handler.h @@ -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. + */ + +#ifndef BUNDLE_ACTIVE_REPORT_HANDLER_H +#define BUNDLE_ACTIVE_REPORT_HANDLER_H + +#include "event_handler.h" +#include "event_runner.h" + +#include "bundle_active_iservice.h" +#include "bundle_active_core.h" + +namespace OHOS { +namespace BundleActive { +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..4cb8e7df65e2398998f89557096434a0937cfe49 --- /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 BundleActive { + +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..d42f71fd7ae16aed675dbc94a89d0eed8287fc55 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 BundleActive { +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..ceffad73bd03d982415d82b0c6a06189096290c9 --- /dev/null +++ b/services/packageusage/include/bundle_active_user_service.h @@ -0,0 +1,75 @@ +/* + * 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 "bundle_active_iservice.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 BundleActive { + +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..e955173eed19e237b69c6f7f2f99dd38a76f56c6 --- /dev/null +++ b/services/packageusage/src/bundle_active_calendar.cpp @@ -0,0 +1,85 @@ +/* + * 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 BundleActive { +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 59% rename from services/common/src/bundle_active_event.cpp rename to services/packageusage/src/bundle_active_event.cpp index 592544512c3befd838365fabcc942d0046840063..098208757413a41afa97e44f2097b988101eb89e 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,6 +13,8 @@ * limitations under the License. */ +#include + #include "bundle_active_event.h" namespace OHOS { @@ -23,10 +25,13 @@ 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; } @@ -39,7 +44,7 @@ std::string BundleActiveEvent::GetAbilityName() { return abilityName_; } -int BundleActiveEvent::GetAbilityId() { +std::string BundleActiveEvent::GetAbilityId() { return abilityId_; } @@ -52,7 +57,24 @@ 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 93% rename from services/common/src/bundle_active_event_list.cpp rename to services/packageusage/src/bundle_active_event_list.cpp index 1604dcc2caeac1c6c24007c5925f530ef58121b7..89098d393e85dabc1e1bfb7b6975cf02678bdf34 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 @@ -39,7 +39,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; int lo = 0; diff --git a/services/common/src/bundle_active_event_stats.cpp b/services/packageusage/src/bundle_active_event_stats.cpp similarity index 97% rename from services/common/src/bundle_active_event_stats.cpp rename to services/packageusage/src/bundle_active_event_stats.cpp index f484b8dc04d2b0735e94faef44439cea66b85aa6..bc9941060b28a5a3c5a84a628ec07989089da1db 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 diff --git a/services/common/src/bundle_active_event_tracker.cpp b/services/packageusage/src/bundle_active_event_tracker.cpp similarity index 80% rename from services/common/src/bundle_active_event_tracker.cpp rename to services/packageusage/src/bundle_active_event_tracker.cpp index b0afe2e94708284e89efd912323cb4d6a2191caa..e377c43cfc49e859cf9c915ce84727587d7af446 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 @@ -17,7 +17,14 @@ namespace OHOS { namespace BundleActive { -void BundleActiveEventTracker::CommitTime(const int64_t timeStamp) { +BundleActiveEventTracker::BundleActiveEventTracker() { + curStartTime_ = 0; + lastEventTime_ = 0; + duration_ = 0; + count_ =0; +} + +void BundleActiveEventTracker::CommitTime(const int64_t& timeStamp) { if (curStartTime_ != 0) { duration_ += timeStamp - curStartTime_; curStartTime_ = 0; @@ -33,7 +40,7 @@ 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; newEvent.eventId_ = eventId; diff --git a/services/common/src/bundle_active_package_stats.cpp b/services/packageusage/src/bundle_active_package_stats.cpp similarity index 54% rename from services/common/src/bundle_active_package_stats.cpp rename to services/packageusage/src/bundle_active_package_stats.cpp index 1b2005aa865ef3c968ef8a10a2e9f5b31bae6e0b..25d41cc094d27835fc31233aabd22ce6aa5c2a2a 100644 --- a/services/common/src/bundle_active_package_stats.cpp +++ b/services/packageusage/src/bundle_active_package_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,18 +17,31 @@ namespace OHOS { namespace BundleActive { +BundleActivePackageStats::BundleActivePackageStats() { + bundleName_.clear(); + beginTimeStamp_ = 0; + endTimeStamp_ = 0; //stop time of counting + lastTimeUsed_ = 0; //the timestamp of last launch + totalInFrontTime_ = 0; // the total time of using the bundle + lastContiniousTaskUsed_ = 0; + totalContiniousTaskUsedTime_ = 0; + startCount_ = 0; + bundleStartedCount_ = 0; + lastEvent_ = 0; +} + BundleActivePackageStats::BundleActivePackageStats (const BundleActivePackageStats& orig) { bundleName_ = orig.bundleName_; beginTimeStamp_ = orig.beginTimeStamp_; endTimeStamp_ = orig.endTimeStamp_; lastTimeUsed_ = orig.lastTimeUsed_; - lastTimeLongTimeTaskUsed_ = orig.lastTimeLongTimeTaskUsed_; - totalTimeLongTimeTaskUsed_ = orig.totalTimeLongTimeTaskUsed_; - totalTimeInFront_ = orig.totalTimeInFront_; - launchedCount_ = orig.launchedCount_; - bundleLaunchedCount_ = orig.bundleLaunchedCount_; + lastContiniousTaskUsed_ = orig.lastContiniousTaskUsed_; + totalContiniousTaskUsedTime_ = orig.totalContiniousTaskUsedTime_; + totalInFrontTime_ = orig.totalInFrontTime_; + startCount_ = orig.startCount_; + bundleStartedCount_ = orig.bundleStartedCount_; abilities_ = orig.abilities_; - frontServices_ = orig.frontServices_; + longTimeTasks_ = orig.longTimeTasks_; lastEvent_ = orig.lastEvent_; } @@ -49,23 +62,23 @@ int64_t BundleActivePackageStats::GetLastTimeUsed() { } int64_t BundleActivePackageStats::GetTotalTimeInFront() { - return totalTimeInFront_; + return totalInFrontTime_; } int64_t BundleActivePackageStats::GetLastTimeFrontServiceUsed() { - return lastTimeLongTimeTaskUsed_; + return lastContiniousTaskUsed_; } int64_t BundleActivePackageStats::GetTotalTimeFrontServiceUsed() { - return totalTimeLongTimeTaskUsed_; + return totalContiniousTaskUsedTime_; } int BundleActivePackageStats::GetLaunchedCount() { - return launchedCount_; + return startCount_; } int BundleActivePackageStats::GetBundleLaunchedCount() { - return bundleLaunchedCount_; + return bundleStartedCount_; } bool BundleActivePackageStats::HasFrontAbility() { @@ -77,34 +90,37 @@ bool BundleActivePackageStats::HasFrontAbility() { return false; } -bool BundleActivePackageStats::AnyFrontServiceStarted() { - return !frontServices_.empty(); +bool BundleActivePackageStats::AnyLongTimeTaskStarted() { + return !longTimeTasks_.empty(); } -void BundleActivePackageStats::IncrementTimeUsed(const int64_t timeStamp) { +void BundleActivePackageStats::IncrementTimeUsed(const int64_t& timeStamp) { if (timeStamp > lastTimeUsed_) { - totalTimeInFront_ += timeStamp - lastTimeUsed_; + totalInFrontTime_ += timeStamp - lastTimeUsed_; lastTimeUsed_ = timeStamp; } } -void BundleActivePackageStats::IncrementLongTimeTaskTimeUsed(const int64_t timeStamp) { - if (timeStamp > lastTimeLongTimeTaskUsed_) { - totalTimeLongTimeTaskUsed_ += timeStamp - lastTimeLongTimeTaskUsed_; - lastTimeLongTimeTaskUsed_ = timeStamp; +void BundleActivePackageStats::IncrementServiceTimeUsed(const int64_t& 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; + std::map::iterator it; + if (abilities_.empty() && eventId == BundleActiveEvent::ABILITY_FOREGROUND) { + beginTimeStamp_ = timeStamp; + } it = abilities_.find(abilityId); if (it != abilities_.end()) { int lastEventId = it->second; @@ -135,20 +151,19 @@ void BundleActivePackageStats::UpdateAbility(const int64_t timeStamp, const int } } -void BundleActivePackageStats::UpdateLongTimeTask(std::string longTimeTaskName, - const int64_t timeStamp, const int eventId) { - if (eventId != BundleActiveEvent::LONG_TIME_TASK_STARTTED && eventId != BundleActiveEvent::LONG_TIME_TASK_STOPPED) { +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_ENDED) { return; } //When we recieve a new event, first update the time stats according to the last service event in map. std::map::iterator it; - it = frontServices_.find(longTimeTaskName); - if (it != frontServices_.end()) { + 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; } @@ -156,19 +171,19 @@ 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: case BundleActiveEvent::ABILITY_BACKGROUND: @@ -179,17 +194,20 @@ void BundleActivePackageStats::Update(std::string longTimeTaskName, const int64_ if (HasFrontAbility()) { IncrementTimeUsed(timeStamp); } + if (AnyLongTimeTaskStarted()) { + IncrementServiceTimeUsed(timeStamp); + } 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: @@ -197,8 +215,31 @@ 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 59% rename from services/common/src/bundle_active_period_stats.cpp rename to services/packageusage/src/bundle_active_period_stats.cpp index 57a408e23b0d1141761436217deae069f600ac9a..a22142b342f3292f08636309092e7b254db36f2d 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 @@ -18,27 +18,49 @@ namespace OHOS { namespace BundleActive { -BundleActivePackageStats& BundleActivePeriodStats::GetOrCreateUsageStats(std::string bundleName) { - std::map::iterator it; +BundleActivePeriodStats::BundleActivePeriodStats() { + 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->beginTimeStamp_ = beginTime_; + 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) { - if (eventId == BundleActiveEvent::DEVICE_SHUTDOWN || eventId == BundleActiveEvent::FLUSH_TO_DISK) { - for (auto usageStatsPair : bundleStats_) { - usageStatsPair.second.Update("", timeStamp, eventId, 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::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; @@ -56,29 +78,29 @@ 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); keyguardShownTracker_.CommitTime(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); } @@ -99,6 +121,5 @@ 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..0a112f76993250ca5692961e7cc4f9cdd7967794 --- /dev/null +++ b/services/packageusage/src/bundle_active_report_handler.cpp @@ -0,0 +1,72 @@ +/* + * 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 BundleActive { +BundleActiveReportHandler::BundleActiveReportHandler(const std::shared_ptr &runner) : AppExecFwk::EventHandler(runner) { +} + +void BundleActiveReportHandler::Init(const std::shared_ptr& bundleActiveCore) { + BUNDLE_ACTIVE_LOGI("handler event called"); + bundleActiveCore_ = bundleActiveCore; + BUNDLE_ACTIVE_LOGI("handler event down"); +} + +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 35% rename from services/src/bundle_active_service.cpp rename to services/packageusage/src/bundle_active_stats_combiner.cpp index 84c9d3d17124d0a3b4e91b63b19bfee4dae78f2a..4c75c543674d2b532ec9db67fb4e4c7f8dc21765 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,40 +13,26 @@ * 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() -{ - int ret = Publish(this); - if (!ret) { - BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1906] FAIL."); - return; +void BundleActiveStatsCombiner::combine(const std::shared_ptr& stats, std::vector& accumulatedResult, int64_t beginTime) { + 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 111; -} - -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) { - BUNDLE_ACTIVE_LOGI("Query called"); - return 222; +void BundleActiveStatsCombiner::combine(const std::shared_ptr& stats, std::vector& accumulatedResult, int64_t beginTime) { + 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..c4f6ca869ddb91a947d1edcb491f61b309225c3e --- /dev/null +++ b/services/packageusage/src/bundle_active_user_service.cpp @@ -0,0 +1,376 @@ +/* + * 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 BundleActive { +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) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::Init current daily stat not null, last time saved is %{public}lld", currentDailyStats->lastTimeSaved_); + 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() { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::NotifyStatsChanged() CALLED, m_statschanged is %{public}d", statsChanged_); + if (!statsChanged_) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::NotifyStatsChanged() set stats changed to true"); + statsChanged_ = true; + listener_.OnStatsChanged(); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::NotifyStatsChanged() CALLED after stats changed, m_statschanged is %{public}d", statsChanged_); +} + +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); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats tmpCalendar time is %{public}lld before truncate", tmpCalendar.GetMilliseconds()); + tmpCalendar.TruncateTo( BundleActivePeriodStats::PERIOD_DAILY); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::LoadActiveStats tmpCalendar time is %{public}lld after truncate", tmpCalendar.GetMilliseconds()); + 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 stats in database is NOT null"); + 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; + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory bundle usage stats size is %{public}d", (*it)->bundleStats_.size()); + 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_); + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory CALLED call notify"); + NotifyStatsChanged(); + } + (*it)->CommitTime(dailyExpiryDate_.GetMilliseconds() - 1); + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory print user stats after update yesterday data"); + printstat(); + 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); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory after load CALLED call notify"); + NotifyStatsChanged(); + } + } + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::RenewStatsInMemory print user stats after update today data"); + printstat(); + + 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"); + printstat(); + for (auto it : currentStats->bundleStats_) { + if (bundleName.empty()) { + if (it.second->totalInFrontTime_ != 0 || it.second->totalContiniousTaskUsedTime_ != 0) { + result.push_back(*(it.second)); + } + } else { + if ((it.second->totalInFrontTime_ != 0 || it.second->totalContiniousTaskUsedTime_ != 0) && it.second->bundleName_ == bundleName) { + 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 (!bundleName.empty()) { + BUNDLE_ACTIVE_LOGI("BundleActiveUserService::QueryEvents need in memory stats"); + int startIndex = currentStats->events_.FindBestIndex(beginTime); + int size = currentStats->events_.Size(); + if (size != 0) { + for (int i = startIndex; i < size; i++) { + if (currentStats->events_.events_[i].bundleName_ == bundleName) { + result.push_back(currentStats->events_.events_[i]); + } + } + } + } else 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) { + 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 f1caeecbb585055fd27c168aff2c7943efc8277f..0000000000000000000000000000000000000000 --- a/services/src/bundle_active_stub.cpp +++ /dev/null @@ -1,54 +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); - } -} -} -} \ No newline at end of file diff --git a/test/bundle_active_test.cpp b/test/bundle_active_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..598d2f7b78034dcf3dd097e5a56c4ea121b1c782 --- /dev/null +++ b/test/bundle_active_test.cpp @@ -0,0 +1,127 @@ +/* + * 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::BundleActive; +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 == 7) { + std::string bundleName(argv[2]); + std::string abilityName(argv[3]); + std::string abilityId(argv[4]); + int userId = atoi(argv[5]); + int eventId = atoi(argv[6]); + BundleActiveClient::GetInstance().ReportEvent(bundleName, abilityName, abilityId, 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..1151843ae00cafc5575ef2bc370d0ba84201ad00 --- /dev/null +++ b/test/unittest/device_usage_statistics_test.cpp @@ -0,0 +1,151 @@ +/* + * 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 BundleActive { +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: querycurrentevents + * @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: querycurrentevents + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_IsBundleIdle_001, Function | MediumTest | Level0) +{ + bool result = BundleActiveClient::GetInstance().IsBundleIdle(DEFAULT_BUNDLENAME); + EXPECT_NE(result, false); +} + +/* + * @tc.name: BundleActiveTest_QueryPackageGroup_001 + * @tc.desc: querycurrentevents + * @tc.type FUNC + * @tc.require + */ +HWTEST_F(BundleActiveTest, BundleActiveTest_QueryPackageGroup_001, Function | MediumTest | Level0) +{ + bool result = BundleActiveClient::GetInstance().QueryPackageGroup(); + EXPECT_EQ(result, -1); +} +} +}