diff --git a/BUILD.gn b/BUILD.gn index b1802af024798d37df49321df1d18a7b70efd35e..d9881aeb7c174a00d57419abe8bd9ad9ff72fb61 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -157,3 +157,36 @@ ohos_shared_library("usagestatservice") { part_name = "${device_usage_statistics_part_name}" subsystem_name = "resourceschedule" } + +ohos_executable("deviceusagestats") { + include_dirs = [ + "services/common/include", + "services/packageusage/include", + "services/packagegroup/include", + "interfaces/innerkits/include", + "utils/dump/include", + ] + + sources = [ + "utils/dump/src/bundle_active_shell_command.cpp", + "utils/dump/src/main.cpp", + "utils/dump/src/shell_command.cpp", + ] + + deps = [ ":usagestatsinner" ] + + configs = [] + + external_deps = [ + "ability_base:want", + "ability_runtime:wantagent_innerkits", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + "utils_base:utils", + ] + + install_enable = true + part_name = "${device_usage_statistics_part_name}" +} diff --git a/bundle.json b/bundle.json index 8dbbd215bd8531f6661b327d82152234da0206f7..051e76f024005cffd1b03851c4b5bdb51d0bfb28 100644 --- a/bundle.json +++ b/bundle.json @@ -51,7 +51,8 @@ "//foundation/resourceschedule/device_usage_statistics:usagestatservice", "//foundation/resourceschedule/device_usage_statistics:device_usage_statistics_sa_profile", "//foundation/resourceschedule/device_usage_statistics:device_usage_statistics_service_init", - "//foundation/resourceschedule/device_usage_statistics:bundlestate" + "//foundation/resourceschedule/device_usage_statistics:bundlestate", + "//foundation/resourceschedule/device_usage_statistics:deviceusagestats" ], "inner_kits": [ { diff --git a/interfaces/innerkits/include/bundle_active_client.h b/interfaces/innerkits/include/bundle_active_client.h index 85a531818ec51406d21559d225699fdfe115921a..b20f8acbfb7953adee2cae52000866e770c85579 100644 --- a/interfaces/innerkits/include/bundle_active_client.h +++ b/interfaces/innerkits/include/bundle_active_client.h @@ -98,6 +98,7 @@ public: */ ~BundleActiveClient() {} + int32_t ShellDump(const std::vector &dumpOption, std::vector &dumpInfo); private: bool GetBundleActiveProxy(); sptr bundleActiveProxy_; diff --git a/interfaces/innerkits/src/bundle_active_client.cpp b/interfaces/innerkits/src/bundle_active_client.cpp index ef7bb21bcc9ae8b9082bf0efc5c03ab24b2fa032..fd581d21b1fcd63799226c8d71fce75a4d296266 100644 --- a/interfaces/innerkits/src/bundle_active_client.cpp +++ b/interfaces/innerkits/src/bundle_active_client.cpp @@ -17,6 +17,11 @@ namespace OHOS { namespace DeviceUsageStats { +namespace { + const int32_t EVENTS_PARAM = 5; + const int32_t PACKAGE_USAGE_PARAM = 6; + const int32_t MODULE_USAGE_PARAM = 4; +} BundleActiveClient& BundleActiveClient::GetInstance() { static BundleActiveClient instance; @@ -125,6 +130,56 @@ int BundleActiveClient::QueryFormStatistics(int32_t maxNum, std::vectorQueryFormStatistics(maxNum, results, userId); } + +int32_t BundleActiveClient::ShellDump(const std::vector &dumpOption, std::vector &dumpInfo) +{ + int32_t ret = -1; + + if (dumpOption[1] == "Events") { + std::vector eventResult; + if (static_cast(dumpOption.size()) != EVENTS_PARAM) { + return ret; + } + int64_t beginTime = std::stoll(dumpOption[2]); + int64_t endTime = std::stoll(dumpOption[3]); + int32_t userId = std::stoi(dumpOption[4]); + eventResult = this->QueryEvents(beginTime, endTime, ret, userId); + for (auto& oneEvent : eventResult) { + dumpInfo.emplace_back(oneEvent.ToString()); + } + } else if (dumpOption[1] == "PackageUsage") { + std::vector packageUsageResult; + if (static_cast(dumpOption.size()) != PACKAGE_USAGE_PARAM) { + return ret; + } + int32_t intervalType = std::stoi(dumpOption[2]); + int64_t beginTime = std::stoll(dumpOption[3]); + int64_t endTime = std::stoll(dumpOption[4]); + int32_t userId = std::stoi(dumpOption[5]); + packageUsageResult = this->QueryPackageStats(intervalType, beginTime, endTime, ret, userId); + for (auto& onePackageRecord : packageUsageResult) { + dumpInfo.emplace_back(onePackageRecord.ToString()); + } + } else if (dumpOption[1] == "ModuleUsage") { + std::vector moduleResult; + if (static_cast(dumpOption.size()) != MODULE_USAGE_PARAM) { + return ret; + } + int32_t maxNum = std::stoi(dumpOption[2]); + int32_t userId = std::stoi(dumpOption[3]); + BUNDLE_ACTIVE_LOGI("M is %{public}d, u is %{public}d", maxNum, userId); + ret = this->QueryFormStatistics(maxNum, moduleResult, userId); + for (auto& oneModuleRecord : moduleResult) { + dumpInfo.emplace_back(oneModuleRecord.ToString()); + for (uint32_t i = 0; i < oneModuleRecord.formRecords_.size(); i++) { + std::string oneFormInfo = "form " + std::to_string(static_cast(i) + 1) + ", "; + dumpInfo.emplace_back(oneFormInfo + oneModuleRecord.formRecords_[i].ToString()); + } + } + } + + return ret; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_event.h b/services/packageusage/include/bundle_active_event.h index 74a98edea516d5017d4ffa89964caeb95152f1c9..8d4924a5dd34741e4da5affb3a2a20169bcce9a9 100644 --- a/services/packageusage/include/bundle_active_event.h +++ b/services/packageusage/include/bundle_active_event.h @@ -106,6 +106,11 @@ public: * return: point to a BundleActiveEvent. */ std::shared_ptr UnMarshalling(Parcel &parcel); + /* + * function: ToString, change event object to string. + * return: string of bundlename, timestamp, eventid. + */ + std::string ToString(); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_form_record.h b/services/packageusage/include/bundle_active_form_record.h index ac6e07b83ec67bdb71717f8c76679ebb5df1d144..a773947ec12d6c73da4e4e9ce5d2375319e23dc9 100644 --- a/services/packageusage/include/bundle_active_form_record.h +++ b/services/packageusage/include/bundle_active_form_record.h @@ -92,6 +92,11 @@ public: * return: point to a BundleActiveFormRecord. */ std::shared_ptr UnMarshalling(Parcel &parcel); + /* + * function: ToString, change form record object to string. + * return: string of form name, form id, form dimension, last used time and touch count. + */ + std::string ToString(); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_module_record.h b/services/packageusage/include/bundle_active_module_record.h index 65f7f0993302a16d72c6abf0ba80509b088118f5..69bbf249b343c3ba82a56e3a499a4b7937aa83bc 100644 --- a/services/packageusage/include/bundle_active_module_record.h +++ b/services/packageusage/include/bundle_active_module_record.h @@ -37,6 +37,7 @@ public: static bool cmp(const BundleActiveModuleRecord& moduleRecordA, const BundleActiveModuleRecord& moduleRecordB); virtual bool Marshalling(Parcel &parcel) const override; std::shared_ptr UnMarshalling(Parcel &parcel); + std::string ToString(); public: std::string deviceId_; diff --git a/services/packageusage/include/bundle_active_package_stats.h b/services/packageusage/include/bundle_active_package_stats.h index 71ac47da6fbfed12deb8a1aa74fca503c6e094e0..5d2b2e6f29c5ac88777e127e961d87b99a97cfed 100644 --- a/services/packageusage/include/bundle_active_package_stats.h +++ b/services/packageusage/include/bundle_active_package_stats.h @@ -82,6 +82,12 @@ public: * return: point to a BundleActivePackageStats. */ std::shared_ptr UnMarshalling(Parcel &parcel); + /* + * function: ToString, change module record object to string. + * return: string of bundle name, last used time, total front time, last continuous task used time, + * total continuous task time. + */ + std::string ToString(); private: bool HasFrontAbility(); diff --git a/services/packageusage/src/bundle_active_event.cpp b/services/packageusage/src/bundle_active_event.cpp index 41130aaccbb7180f4ad937164ae4f2e2de24323f..cb1cf4dbdb38b6a7eb8cb6a4e5df6ebefab302a7 100644 --- a/services/packageusage/src/bundle_active_event.cpp +++ b/services/packageusage/src/bundle_active_event.cpp @@ -163,6 +163,12 @@ std::shared_ptr BundleActiveEvent::UnMarshalling(Parcel &parc result->eventId_ = parcel.ReadInt32(); return result; } + +std::string BundleActiveEvent::ToString() +{ + return "bundle name is " + this->bundleName_ + ", event is " + + std::to_string(this->eventId_) + ", timestamp is " + std::to_string(this->timeStamp_) + "\n"; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_form_record.cpp b/services/packageusage/src/bundle_active_form_record.cpp index 0f7de8ba0e7574aa76d2cb70b7fd5fd801ebd809..3ef3c59e2e842ba5be6ce3d3a67d09b45cfb031f 100644 --- a/services/packageusage/src/bundle_active_form_record.cpp +++ b/services/packageusage/src/bundle_active_form_record.cpp @@ -84,6 +84,15 @@ bool BundleActiveFormRecord::cmp(const BundleActiveFormRecord& formRecordA, { return formRecordA.count_ > formRecordB.count_; } + +std::string BundleActiveFormRecord::ToString() +{ + return "form name is " + this->formName_ + + ", form dimension is " + std::to_string(this->formDimension_) + + ", form id is " + std::to_string(this->formId_) + + ", last used time stamp is" + std::to_string(this->formLastUsedTime_) + + ", touch count is " + std::to_string(this->count_) + "\n"; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_module_record.cpp b/services/packageusage/src/bundle_active_module_record.cpp index 7cf83d9591325c7558bdc011589bf7d651d7e197..9032d92935671f99ffb69688d309a35ef7d8ee3e 100644 --- a/services/packageusage/src/bundle_active_module_record.cpp +++ b/services/packageusage/src/bundle_active_module_record.cpp @@ -123,6 +123,14 @@ bool BundleActiveModuleRecord::cmp(const BundleActiveModuleRecord& moduleRecordA { return moduleRecordA.lastModuleUsedTime_ > moduleRecordB.lastModuleUsedTime_; } + +std::string BundleActiveModuleRecord::ToString() +{ + return "bundle name is " + this->bundleName_ + + ", module name is " + this->moduleName_ + + ", last used time stamp is " + std::to_string(this->lastModuleUsedTime_) + + ", module is used for " + std::to_string(this->launchedCount_) + " times\n"; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/src/bundle_active_package_stats.cpp b/services/packageusage/src/bundle_active_package_stats.cpp index 6865d9faf25ffe5054095a9612e693b0a2c56620..b96064b147125fe56a7e4e08b288c85c8e10c156 100644 --- a/services/packageusage/src/bundle_active_package_stats.cpp +++ b/services/packageusage/src/bundle_active_package_stats.cpp @@ -219,6 +219,16 @@ std::shared_ptr BundleActivePackageStats::UnMarshallin result->totalContiniousTaskUsedTime_ = parcel.ReadInt64(); return result; } + +std::string BundleActivePackageStats::ToString() +{ + return "bundle name is " + this->bundleName_ + + ", last used time stamp is " + std::to_string(this->lastTimeUsed_) + + ", total time in front is " + std::to_string(this->totalInFrontTime_) + + ", last continuous task used time is " + std::to_string(this->lastContiniousTaskUsed_) + + ", total continuous task time is " + + std::to_string(this->totalContiniousTaskUsedTime_) + "\n"; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/utils/dump/include/bundle_active_shell_command.h b/utils/dump/include/bundle_active_shell_command.h new file mode 100644 index 0000000000000000000000000000000000000000..4df0b562681b63bd11466ba16899f7fbbdaea22b --- /dev/null +++ b/utils/dump/include/bundle_active_shell_command.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_SHELL_COMMAND_H +#define BUNDLE_ACTIVE_SHELL_COMMAND_H + +#include "shell_command.h" +#include "bundle_active_client.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveShellCommand : public ShellCommand { +public: + BundleActiveShellCommand(int32_t argc, char *argv[]); + +private: + int32_t CreateCommandMap() override; + int32_t CreateMessageMap() override; + int32_t init() override; + int32_t RunAsHelpCommand(); + int32_t RunAsDumpCommand(); +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_SHELL_COMMAND_H + diff --git a/utils/dump/include/shell_command.h b/utils/dump/include/shell_command.h new file mode 100644 index 0000000000000000000000000000000000000000..a6f9556ad1796ef699fb1a96141a97171b21e006 --- /dev/null +++ b/utils/dump/include/shell_command.h @@ -0,0 +1,87 @@ +/* + * 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 SHELL_COMMAND +#define SHELL_COMMAND + +#include +#include +#include + +#include "ibundle_active_service.h" + +namespace OHOS { +namespace DeviceUsageStats { +class ShellCommand { +public: + ShellCommand(int32_t argc, char *argv[], std::string name); + + /** + * @brief The OnCommand callback. + * + * @return ERR_OK on success, others on failure. + */ + int32_t OnCommand(); + /** + * @brief Exec command. + * + * @return Result receiver. + */ + std::string ExecCommand(); + /** + * @brief Get command error msg. + * + * @return Command error msg. + */ + std::string GetCommandErrorMsg() const; + + /** + * @brief Create command map. + * + * @return 0 on success, others on failure. + */ + virtual int32_t CreateCommandMap() = 0; + /** + * @brief Create message map. + * + * @return 0 on success, others on failure. + */ + virtual int32_t CreateMessageMap() = 0; + /** + * @brief Init. + * + * @return 0 on success, others on failure. + */ + virtual int32_t init() = 0; + +protected: + static constexpr int32_t MIN_ARGUMENT_NUMBER = 2; + + int32_t argc_; + char **argv_; + + std::string cmd_; + std::vector argList_; + + std::string name_; + std::map> commandMap_; + std::map messageMap_; + + std::string resultReceiver_ = ""; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // SHELL_COMMAND + diff --git a/utils/dump/src/bundle_active_shell_command.cpp b/utils/dump/src/bundle_active_shell_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d90d64a6e76fe7f8e6458f121de03a1c3e2041a2 --- /dev/null +++ b/utils/dump/src/bundle_active_shell_command.cpp @@ -0,0 +1,112 @@ +/* + * 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_shell_command.h" + +#include +#include + +#include "iservice_registry.h" +#include "singleton.h" + +#include "bundle_active_client.h" + +namespace OHOS { +namespace DeviceUsageStats { +namespace { + static constexpr int32_t MIN_BUNDLE_ACTIVE_DUMP_PARAMS_NUM = 4; + + static const struct option OPTIONS[] = { + {"help", no_argument, nullptr, 'h'}, + {"all", no_argument, nullptr, 'A'}, + }; + + static const std::string HELP_MSG = "usage: deviceusagestats []\n" + "These are common commands list:\n" + " help list available commands\n" + " dump dump the info of bundleactive\n"; + + static const std::string DUMP_HELP_MSG = + "usage: bundleactive dump []\n" + "options list:\n" + " -h help menu\n" + " -A \n" + " Events [beginTime] [endTime] [userId] get events for one user\n" + " PackageUsage [intervalType] [beginTime] [endTime] [userId] get package usage for one user\n" + " ModuleUsage [maxNum] [userId] get module usage for one user\n"; +} // namespace + +BundleActiveShellCommand::BundleActiveShellCommand(int32_t argc, char *argv[]) : ShellCommand(argc, + argv, "deviceusagestats") +{} + +int32_t BundleActiveShellCommand::CreateCommandMap() +{ + commandMap_ = { + {"help", std::bind(&BundleActiveShellCommand::RunAsHelpCommand, this)}, + {"dump", std::bind(&BundleActiveShellCommand::RunAsDumpCommand, this)}, + }; + return 0; +} + +int32_t BundleActiveShellCommand::CreateMessageMap() +{ + messageMap_ = {}; + return 0; +} + +int32_t BundleActiveShellCommand::init() +{ + return 0; +} + +int32_t BundleActiveShellCommand::RunAsHelpCommand() +{ + resultReceiver_.append(HELP_MSG); + return 0; +} + +int32_t BundleActiveShellCommand::RunAsDumpCommand() +{ + int32_t ind = 0; + int32_t option = getopt_long(argc_, argv_, "hA", OPTIONS, &ind); + int32_t ret = 0; + std::vector infos; + switch (option) { + case 'h': + resultReceiver_.append(DUMP_HELP_MSG); + break; + case 'A': + if (argc_ < MIN_BUNDLE_ACTIVE_DUMP_PARAMS_NUM) { + resultReceiver_.append("Please input correct params.\n"); + resultReceiver_.append(DUMP_HELP_MSG); + return -1; + } + ret = BundleActiveClient::GetInstance().ShellDump(argList_, infos); + break; + default: + resultReceiver_.append("Please input correct params.\n"); + resultReceiver_.append(DUMP_HELP_MSG); + ret = -1; + break; + } + for (auto info : infos) { + resultReceiver_.append(info); + } + return ret; +} +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/utils/dump/src/main.cpp b/utils/dump/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76c1c4d303a1e1b10b97c217b399d636b284a2b6 --- /dev/null +++ b/utils/dump/src/main.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "bundle_active_shell_command.h" + +int32_t main(int32_t argc, char *argv[]) +{ + OHOS::DeviceUsageStats::BundleActiveShellCommand cmd(argc, argv); + std::cout << cmd.ExecCommand(); + return 0; +} + diff --git a/utils/dump/src/shell_command.cpp b/utils/dump/src/shell_command.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54a190d3784b511f78bc753dbf3c16f5c69523cf --- /dev/null +++ b/utils/dump/src/shell_command.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 "bundle_active_log.h" +#include "shell_command.h" + +namespace OHOS { +namespace DeviceUsageStats { +ShellCommand::ShellCommand(int32_t argc, char *argv[], std::string name) +{ + argc_ = argc; + argv_ = argv; + name_ = name; + + if (argc < MIN_ARGUMENT_NUMBER) { + cmd_ = "help"; + return; + } + cmd_ = argv[1]; + for (int32_t i = 2; i < argc; i++) { + argList_.push_back(argv[i]); + } + for (const auto& arg : argList_) { + BUNDLE_ACTIVE_LOGI("arg is %{public}s", arg.c_str()); + } +} + +int32_t ShellCommand::OnCommand() +{ + int32_t result = 0; + + auto respond = commandMap_[cmd_]; + if (respond == nullptr) { + resultReceiver_.append(GetCommandErrorMsg()); + respond = commandMap_["help"]; + } + + if (init() == 0) { + respond(); + } else { + result = -1; + } + + return result; +} + +std::string ShellCommand::ExecCommand() +{ + int32_t result = CreateCommandMap(); + if (result != 0) { + BUNDLE_ACTIVE_LOGE("failed to create command map."); + } + + result = CreateMessageMap(); + if (result != 0) { + BUNDLE_ACTIVE_LOGE("failed to create message map."); + } + + result = OnCommand(); + if (result != 0) { + BUNDLE_ACTIVE_LOGE("failed to execute your command."); + resultReceiver_ = "error: failed to execute your command.\n"; + } + + return resultReceiver_; +} + +std::string ShellCommand::GetCommandErrorMsg() const +{ + std::string commandErrorMsg = + name_ + ": '" + cmd_ + "' is not a valid " + name_ + " command. See '" + name_ + " help'.\n"; + return commandErrorMsg; +} +} // namespace DeviceUsageStats +} // namespace OHOS +