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