1 /*
2 * Copyright (c) 2021 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 * miscservices under the License is miscservices 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 "statistic_reporter.h"
16
17 #include <ctime>
18 #include <sys/prctl.h>
19 #include <thread>
20 #include <unistd.h>
21 #include <vector>
22
23 #include "hilog_wrapper.h"
24 #include "hisysevent.h"
25 #include "memory_guard.h"
26
27 using namespace OHOS::WallpaperMgrService;
28 namespace OHOS {
29 using namespace HiviewDFX;
30 namespace MiscServices {
31 constexpr const char *USER_ID = "USER_ID";
32 constexpr const char *PACKAGES_NAME = "PACKAGES_NAME";
33 constexpr const char *CUMULATIVE_TIME = "CUMULATIVE_TIME";
34 constexpr const char *USAGETIME_STATISTIC = "USAGETIME_STATISTIC";
35 constexpr const char *WALLPAPER_INFO = "WALLPAPER_INFO";
36
37 bool StatisticReporter::running_ = false;
38 std::mutex StatisticReporter::runMutex_;
39 std::mutex StatisticReporter::usageTimeMutex_;
40 std::map<int, std::vector<UsageTimeStat>> StatisticReporter::usageTimeStat_;
41
ReportUsageTimeStatistic(int userId,const UsageTimeStat & stat)42 void StatisticReporter::ReportUsageTimeStatistic(int userId, const UsageTimeStat &stat)
43 {
44 std::lock_guard<std::mutex> lock(usageTimeMutex_);
45 std::map<int, std::vector<UsageTimeStat>>::iterator iter = usageTimeStat_.find(userId);
46 if (iter != usageTimeStat_.end()) {
47 UsageTimeStat &timeStat = iter->second.back();
48 int nDiff = stat.startTime - timeStat.startTime;
49 timeStat.cumulativeTime = std::to_string(nDiff / ONE_HOUR_IN_SECONDS);
50 iter->second.push_back(stat);
51 } else {
52 std::vector<UsageTimeStat> vecUsageTime;
53 vecUsageTime.push_back(stat);
54 usageTimeStat_[userId] = vecUsageTime;
55 }
56 }
57
StartTimerThread()58 void StatisticReporter::StartTimerThread()
59 {
60 {
61 std::lock_guard<std::mutex> lock(runMutex_);
62 if (running_) {
63 return;
64 }
65 running_ = true;
66 }
67 auto fun = []() {
68 MemoryGuard cacheGuard;
69 prctl(PR_SET_NAME, "WallpaperThread");
70 while (true) {
71 time_t current = time(nullptr);
72 if (current == -1) {
73 sleep(ONE_HOUR_IN_SECONDS);
74 continue;
75 }
76 tm localTime = { 0 };
77 tm *result = localtime_r(¤t, &localTime);
78 if (result == nullptr) {
79 sleep(ONE_HOUR_IN_SECONDS);
80 continue;
81 }
82 int currentHour = localTime.tm_hour;
83 int currentMin = localTime.tm_min;
84 if ((EXEC_MIN_TIME - currentMin) != EXEC_MIN_TIME) {
85 int nHours = EXEC_HOUR_TIME - currentHour;
86 int nMin = EXEC_MIN_TIME - currentMin;
87 int nTime = (nMin)*ONE_MINUTE_IN_SECONDS + (nHours)*ONE_HOUR_IN_SECONDS;
88 HILOG_INFO("sleep nHours=%{public}d,nMin=%{public}d,nTime=%{public}d", nHours, nMin, nTime);
89 sleep(nTime);
90 current = time(nullptr);
91 if (current == -1) {
92 sleep(ONE_HOUR_IN_SECONDS);
93 continue;
94 }
95 InvokeUsageTime(current);
96 } else {
97 sleep(ONE_HOUR_IN_SECONDS * (ONE_DAY_IN_HOURS - currentHour));
98 current = time(nullptr);
99 if (current == -1) {
100 sleep(ONE_HOUR_IN_SECONDS);
101 continue;
102 }
103 InvokeUsageTime(current);
104 }
105 }
106 };
107 std::thread th = std::thread(fun);
108 th.detach();
109 }
110
InvokeUsageTime(time_t curTime)111 ReportStatus StatisticReporter::InvokeUsageTime(time_t curTime)
112 {
113 HILOG_INFO("InvokeUsageTime start.");
114 std::string statisticMsg;
115 std::lock_guard<std::mutex> lock(usageTimeMutex_);
116 for (auto const &usageTime : usageTimeStat_) {
117 statisticMsg.append(USER_ID).append(":" + std::to_string(usageTime.first) + ",");
118 std::vector<UsageTimeStat> vecUsageTime = usageTime.second;
119 for (auto const &stat : vecUsageTime) {
120 std::string cumulativeTime(stat.cumulativeTime);
121 if (cumulativeTime.empty()) {
122 int nDiff = curTime - stat.startTime;
123 cumulativeTime = std::to_string(nDiff / ONE_HOUR_IN_SECONDS);
124 }
125
126 statisticMsg.append(PACKAGES_NAME)
127 .append(":" + stat.packagesName + ",")
128 .append(CUMULATIVE_TIME)
129 .append(":" + cumulativeTime + "hours,");
130 }
131 }
132 if (statisticMsg.empty()) {
133 return ReportStatus::ERROR;
134 }
135
136 HiSysEventWrite(HiSysEvent::Domain::THEME, USAGETIME_STATISTIC, HiSysEvent::EventType::STATISTIC, WALLPAPER_INFO,
137 statisticMsg);
138 HILOG_INFO(" InvokeUsageTime end.");
139 return ReportStatus::SUCCESS;
140 }
141 } // namespace MiscServices
142 } // namespace OHOS
143