1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "app_usage_event_factory.h"
16
17 #include <cinttypes>
18 #include <vector>
19
20 #include "app_usage_event.h"
21 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
22 #include "bundle_active_client.h"
23 #endif
24 #include "bundle_mgr_client.h"
25 #include "logger.h"
26 #include "os_account_manager.h"
27 #include "time_util.h"
28 #include "usage_event_common.h"
29
30 namespace OHOS {
31 namespace HiviewDFX {
32 DEFINE_LOG_TAG("HiView-AppUsageEventFactory");
33 namespace {
34 constexpr int32_t DEFAULT_USER_ID = 100;
35 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
36 constexpr int32_t INTERVAL_TYPE = 1;
37 constexpr int64_t MILLISEC_TO_SEC = 1000;
38 #endif
39 const std::string DATE_FORMAT = "%Y-%m-%d";
40 }
41 using namespace AppUsageEventSpace;
42 using namespace OHOS::AccountSA;
43 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
44 using namespace OHOS::DeviceUsageStats;
45 #endif
46
Create()47 std::unique_ptr<LoggerEvent> AppUsageEventFactory::Create()
48 {
49 return std::make_unique<AppUsageEvent>(EVENT_DOMAIN, EVENT_NAME, HiSysEvent::STATISTIC);
50 }
51
Create(std::vector<std::unique_ptr<LoggerEvent>> & events)52 void AppUsageEventFactory::Create(std::vector<std::unique_ptr<LoggerEvent>>& events)
53 {
54 // get user ids
55 std::vector<int32_t> userIds;
56 GetAllCreatedOsAccountIds(userIds);
57 if (userIds.empty()) {
58 HIVIEW_LOGE("the accounts obtained are empty");
59 return;
60 }
61
62 // get app usage info
63 std::vector<AppUsageInfo> appUsageInfos;
64 for (auto userId : userIds) {
65 GetAppUsageInfosByUserId(appUsageInfos, userId);
66 }
67
68 // create events
69 for (auto info : appUsageInfos) {
70 std::unique_ptr<LoggerEvent> event = Create();
71 event->Update(KEY_OF_PACKAGE, info.package_);
72 event->Update(KEY_OF_VERSION, info.version_);
73 event->Update(KEY_OF_USAGE, info.usage_);
74 event->Update(KEY_OF_DATE, info.date_);
75 events.push_back(std::move(event));
76 }
77 }
78
GetAllCreatedOsAccountIds(std::vector<int32_t> & ids)79 void AppUsageEventFactory::GetAllCreatedOsAccountIds(std::vector<int32_t>& ids)
80 {
81 std::vector<OsAccountInfo> osAccountInfos;
82 auto res = OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos);
83 if (res != ERR_OK) {
84 HIVIEW_LOGE("failed to get userId, err=%{public}d", res);
85 ids.push_back(DEFAULT_USER_ID);
86 return;
87 }
88 for (auto info : osAccountInfos) {
89 ids.push_back(info.GetLocalId());
90 }
91 }
92
GetAppUsageInfosByUserId(std::vector<AppUsageInfo> & appUsageInfos,int32_t userId)93 void AppUsageEventFactory::GetAppUsageInfosByUserId(std::vector<AppUsageInfo>& appUsageInfos, int32_t userId)
94 {
95 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
96 HIVIEW_LOGI("get app usage info by userId=%{public}d", userId);
97 int64_t today0Time = TimeUtil::Get0ClockStampMs();
98 int64_t gapTime = static_cast<int64_t>(TimeUtil::MILLISECS_PER_DAY);
99 int64_t startTime = today0Time > gapTime ? (today0Time - gapTime) : 0;
100 int64_t endTime = today0Time > MILLISEC_TO_SEC ? (today0Time - MILLISEC_TO_SEC) : 0;
101 std::vector<BundleActivePackageStats> pkgStats;
102 int32_t errCode = BundleActiveClient::GetInstance().QueryBundleStatsInfoByInterval(pkgStats, INTERVAL_TYPE,
103 startTime, endTime, userId);
104 if (errCode != ERR_OK) {
105 HIVIEW_LOGE("failed to get package stats, errCode=%{public}d", errCode);
106 return;
107 }
108
109 HIVIEW_LOGI("startTime=%{public}" PRId64 ", endTime=%{public}" PRId64 ", size=%{public}zu",
110 startTime, endTime, pkgStats.size());
111 std::string dateStr = TimeUtil::TimestampFormatToDate(startTime / MILLISEC_TO_SEC, DATE_FORMAT);
112 for (auto stat : pkgStats) {
113 std::string package = stat.bundleName_;
114 auto it = std::find_if(appUsageInfos.begin(), appUsageInfos.end(), [package](auto info) {
115 return info.package_ == package;
116 });
117 uint64_t usage = stat.totalInFrontTime_ > 0 ? static_cast<uint64_t>(stat.totalInFrontTime_) : 0;
118 if (it != appUsageInfos.end()) {
119 it->usage_ += usage;
120 } else {
121 std::string version = GetAppVersion(stat.bundleName_);
122 appUsageInfos.push_back(AppUsageInfo(stat.bundleName_, version, usage, dateStr));
123 }
124 }
125 #endif
126 }
127
GetAppVersion(const std::string & bundleName)128 std::string AppUsageEventFactory::GetAppVersion(const std::string& bundleName)
129 {
130 AppExecFwk::BundleInfo info;
131 AppExecFwk::BundleMgrClient client;
132 if (!client.GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, info,
133 AppExecFwk::Constants::ALL_USERID)) {
134 HIVIEW_LOGE("Failed to get the version of the bundle=%{public}s", bundleName.c_str());
135 return "";
136 }
137 return info.versionName;
138 }
139 } // namespace HiviewDFX
140 } // namespace OHOS
141