• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 
16 #include "fold_event_cacher.h"
17 
18 #include "app_mgr_client.h"
19 #include "display_manager.h"
20 #include "hiview_logger.h"
21 #include "time_util.h"
22 #include "usage_event_common.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 DEFINE_LOG_TAG("FoldEventCacher");
27 namespace {
28 constexpr int UNKNOWN_FOLD_STATUS = -1;
29 constexpr int MILLISEC_TO_MICROSEC = 1000;
30 constexpr int SYSTEM_WINDOW_BASE = 2000;
31 
GetFocusedApp()32 std::string GetFocusedApp()
33 {
34     std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos;
35     std::unique_ptr<AppExecFwk::AppMgrClient> appMgrClient = std::make_unique<AppExecFwk::AppMgrClient>();
36     appMgrClient->GetAllRunningProcesses(allAppProcessInfos);
37     std::string packageName;
38     for (const auto &process : allAppProcessInfos) {
39         if (process.isFocused) {
40             packageName = process.processName_;
41             break;
42         }
43     }
44     return packageName;
45 }
46 
GetCombineScreenStatus(int foldStatus,int vhMode)47 int GetCombineScreenStatus(int foldStatus, int vhMode)
48 {
49     if (foldStatus == 1 && vhMode == 1) { // foldStatus: 1-expand status
50         return ScreenFoldStatus::EXPAND_LANDSCAPE_STATUS;
51     }
52     if (foldStatus == 1 && vhMode == 0) {
53         return ScreenFoldStatus::EXPAND_PORTRAIT_STATUS;
54     }
55     if ((foldStatus == 2 || foldStatus == 3) && vhMode == 1) { // foldStatus: 2-fold status 3- half fold status
56         return ScreenFoldStatus::FOLD_LANDSCAPE_STATUS;
57     }
58     if ((foldStatus == 2 || foldStatus == 3) && vhMode == 0) { // foldStatus: 2-fold status 3- half fold status
59         return ScreenFoldStatus::FOLD_PORTRAIT_STATUS;
60     }
61     return UNKNOWN_FOLD_STATUS;
62 }
63 } // namespace
64 
FoldEventCacher(const std::string & workPath)65 FoldEventCacher::FoldEventCacher(const std::string& workPath)
66 {
67     timelyStart_ = TimeUtil::GetBootTimeMs();
68     dbHelper_ = std::make_unique<FoldAppUsageDbHelper>(workPath);
69 
70     foldStatus_ = static_cast<int>(OHOS::Rosen::DisplayManager::GetInstance().GetFoldStatus());
71     auto display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
72     if (display != nullptr) {
73         int orientation = static_cast<int>(display->GetRotation());
74         if (orientation == 0 || orientation == 2) { // 0-Portrait 2-portrait_inverted
75             vhMode_ = 0; // 0-Portrait
76         } else {
77             vhMode_ = 1; // 1-landscape
78         }
79     }
80     auto focusedAppName = GetFocusedApp();
81     focusedAppPair_ = std::make_pair(focusedAppName, false);
82     HIVIEW_LOGI("focusedApp=%{public}s, foldStatus=%{public}d, vhMode=%{public}d",
83         focusedAppName.c_str(), foldStatus_, vhMode_);
84 }
85 
ProcessEvent(std::shared_ptr<SysEvent> event)86 void FoldEventCacher::ProcessEvent(std::shared_ptr<SysEvent> event)
87 {
88     if (dbHelper_ == nullptr) {
89         HIVIEW_LOGI("dbHelper is nulptr");
90         return;
91     }
92     std::string eventName = event->eventName_;
93     if (eventName == AppEventSpace::FOCUS_WINDOW) {
94         ProcessFocusWindowEvent(event);
95     }
96     if ((eventName == FoldStateChangeEventSpace::EVENT_NAME) || (eventName == VhModeChangeEventSpace::EVENT_NAME)) {
97         ProcessSceenStatusChangedEvent(event);
98     }
99 }
100 
ProcessFocusWindowEvent(std::shared_ptr<SysEvent> event)101 void FoldEventCacher::ProcessFocusWindowEvent(std::shared_ptr<SysEvent> event)
102 {
103     if (focusedAppPair_.second) {
104         ProcessBackgroundEvent(event);
105     }
106     bool shouldCount = (event->GetEventIntValue(AppEventSpace::KEY_OF_WINDOW_TYPE) < SYSTEM_WINDOW_BASE);
107     if (shouldCount) {
108         ProcessForegroundEvent(event);
109     }
110     std::string bundleName = event->GetEventValue(AppEventSpace::KEY_OF_BUNDLE_NAME);
111     focusedAppPair_ = std::make_pair(bundleName, shouldCount);
112 }
113 
ProcessForegroundEvent(std::shared_ptr<SysEvent> event)114 void FoldEventCacher::ProcessForegroundEvent(std::shared_ptr<SysEvent> event)
115 {
116     AppEventRecord appEventRecord;
117     appEventRecord.rawid = FoldEventId::EVENT_APP_START;
118     appEventRecord.ts = static_cast<int64_t>(TimeUtil::GetBootTimeMs());
119     appEventRecord.bundleName = event->GetEventValue(AppEventSpace::KEY_OF_BUNDLE_NAME);
120     int combineScreenStatus = GetCombineScreenStatus(foldStatus_, vhMode_);
121     appEventRecord.preFoldStatus = combineScreenStatus;
122     appEventRecord.foldStatus = combineScreenStatus;
123     appEventRecord.happenTime = static_cast<int64_t>(event->happenTime_);
124 
125     if (combineScreenStatus != UNKNOWN_FOLD_STATUS) {
126         dbHelper_->AddAppEvent(appEventRecord);
127     }
128 }
129 
ProcessBackgroundEvent(std::shared_ptr<SysEvent> event)130 void FoldEventCacher::ProcessBackgroundEvent(std::shared_ptr<SysEvent> event)
131 {
132     AppEventRecord appEventRecord;
133     appEventRecord.rawid = FoldEventId::EVENT_APP_EXIT;
134     appEventRecord.ts = static_cast<int64_t>(TimeUtil::GetBootTimeMs());
135     appEventRecord.bundleName = focusedAppPair_.first;
136     int combineScreenStatus = GetCombineScreenStatus(foldStatus_, vhMode_);
137     appEventRecord.preFoldStatus = combineScreenStatus;
138     appEventRecord.foldStatus = combineScreenStatus;
139     appEventRecord.happenTime = static_cast<int64_t>(event->happenTime_);
140 
141     if (combineScreenStatus != UNKNOWN_FOLD_STATUS) {
142         dbHelper_->AddAppEvent(appEventRecord);
143         CountLifeCycleDuration(appEventRecord);
144     }
145 }
146 
ProcessSceenStatusChangedEvent(std::shared_ptr<SysEvent> event)147 void FoldEventCacher::ProcessSceenStatusChangedEvent(std::shared_ptr<SysEvent> event)
148 {
149     int preFoldStatus = GetCombineScreenStatus(foldStatus_, vhMode_);
150     std::string eventName = event->eventName_;
151     if (eventName == FoldStateChangeEventSpace::EVENT_NAME) {
152         UpdateFoldStatus(event->GetEventIntValue(FoldStateChangeEventSpace::KEY_OF_NEXT_STATUS));
153     } else {
154         UpdateVhMode(event->GetEventIntValue(VhModeChangeEventSpace::KEY_OF_MODE));
155     }
156     if (!focusedAppPair_.second) {
157         return;
158     }
159     AppEventRecord appEventRecord;
160     appEventRecord.rawid = FoldEventId::EVENT_SCREEN_STATUS_CHANGED;
161     appEventRecord.ts = static_cast<int64_t>(TimeUtil::GetBootTimeMs());
162     appEventRecord.bundleName = focusedAppPair_.first;
163     appEventRecord.preFoldStatus = preFoldStatus;
164     appEventRecord.foldStatus = GetCombineScreenStatus(foldStatus_, vhMode_);
165     appEventRecord.happenTime = static_cast<int64_t>(event->happenTime_);
166     if ((appEventRecord.foldStatus != UNKNOWN_FOLD_STATUS)
167         && appEventRecord.preFoldStatus != appEventRecord.foldStatus) {
168         dbHelper_->AddAppEvent(appEventRecord);
169     }
170 }
171 
GetFoldStatusDuration(const int foldStatus,std::map<int,uint64_t> & durations)172 int64_t FoldEventCacher::GetFoldStatusDuration(const int foldStatus, std::map<int, uint64_t>& durations)
173 {
174     auto it = durations.find(foldStatus);
175     if (it == durations.end()) {
176         return 0;
177     }
178     return static_cast<int64_t>(it->second);
179 }
180 
ProcessCountDurationEvent(AppEventRecord & appEventRecord,std::map<int,uint64_t> & durations)181 void FoldEventCacher::ProcessCountDurationEvent(AppEventRecord& appEventRecord, std::map<int, uint64_t>& durations)
182 {
183     AppEventRecord newRecord;
184     newRecord.rawid = FoldEventId::EVENT_COUNT_DURATION;
185     newRecord.ts = static_cast<int64_t>(TimeUtil::GetBootTimeMs());
186     newRecord.bundleName = appEventRecord.bundleName;
187     newRecord.preFoldStatus = appEventRecord.preFoldStatus;
188     newRecord.foldStatus = appEventRecord.foldStatus;
189     newRecord.happenTime = static_cast<int64_t>(TimeUtil::GenerateTimestamp()) / MILLISEC_TO_MICROSEC;
190     newRecord.foldPortraitTime = GetFoldStatusDuration(ScreenFoldStatus::FOLD_PORTRAIT_STATUS, durations);
191     newRecord.foldLandscapeTime = GetFoldStatusDuration(ScreenFoldStatus::FOLD_LANDSCAPE_STATUS, durations);
192     newRecord.expandPortraitTime = GetFoldStatusDuration(ScreenFoldStatus::EXPAND_PORTRAIT_STATUS, durations);
193     newRecord.expandLandscapeTime = GetFoldStatusDuration(ScreenFoldStatus::EXPAND_LANDSCAPE_STATUS, durations);
194     dbHelper_->AddAppEvent(newRecord);
195 }
196 
CountLifeCycleDuration(AppEventRecord & appEventRecord)197 void FoldEventCacher::CountLifeCycleDuration(AppEventRecord& appEventRecord)
198 {
199     std::string bundleName = appEventRecord.bundleName;
200     int startIndex = GetStartIndex(bundleName);
201     int64_t dayStartTime = TimeUtil::Get0ClockStampMs();
202     std::vector<AppEventRecord> records;
203     dbHelper_->QueryAppEventRecords(startIndex, dayStartTime, bundleName, records);
204     std::map<int, uint64_t> durations;
205     CalCulateDuration(dayStartTime, records, durations);
206     ProcessCountDurationEvent(appEventRecord, durations);
207 }
208 
CalCulateDuration(uint64_t dayStartTime,std::vector<AppEventRecord> & records,std::map<int,uint64_t> & durations)209 void FoldEventCacher::CalCulateDuration(uint64_t dayStartTime, std::vector<AppEventRecord>& records,
210     std::map<int, uint64_t>& durations)
211 {
212     if (records.empty()) {
213         return;
214     }
215     auto it = records.begin();
216     // app cross 0 clock
217     if (it->rawid == FoldEventId::EVENT_APP_EXIT || it->rawid == FoldEventId::EVENT_SCREEN_STATUS_CHANGED) {
218         int foldStatus = (it->rawid == FoldEventId::EVENT_APP_EXIT) ? it->foldStatus : it->preFoldStatus;
219         Accumulative(foldStatus, (it->happenTime - dayStartTime), durations);
220     }
221     auto preIt = it;
222     // app running from 0 clock to current time, calculate durations
223     it++;
224     for (; it != records.end(); it++) {
225         if (CanCalcDuration(preIt->rawid, it->rawid)) {
226             uint64_t duration = (it->ts > preIt->ts) ? static_cast<uint64_t>(it->ts - preIt->ts) : 0;
227             Accumulative(preIt->foldStatus, duration, durations);
228         }
229         preIt = it;
230     }
231 }
232 
CanCalcDuration(uint32_t preId,uint32_t id)233 bool FoldEventCacher::CanCalcDuration(uint32_t preId, uint32_t id)
234 {
235     if (id == FoldEventId::EVENT_APP_EXIT && preId == FoldEventId::EVENT_APP_START) {
236         return true;
237     }
238     if (id == FoldEventId::EVENT_SCREEN_STATUS_CHANGED && preId == FoldEventId::EVENT_APP_START) {
239         return true;
240     }
241     if (id == FoldEventId::EVENT_SCREEN_STATUS_CHANGED && preId == FoldEventId::EVENT_SCREEN_STATUS_CHANGED) {
242         return true;
243     }
244     if (id == FoldEventId::EVENT_APP_EXIT && preId == FoldEventId::EVENT_SCREEN_STATUS_CHANGED) {
245         return true;
246     }
247     return false;
248 }
249 
Accumulative(int foldStatus,uint64_t duration,std::map<int,uint64_t> & durations)250 void FoldEventCacher::Accumulative(int foldStatus, uint64_t duration, std::map<int, uint64_t>& durations)
251 {
252     if (durations.find(foldStatus) == durations.end()) {
253         durations[foldStatus] = duration;
254     } else {
255         durations[foldStatus] += duration;
256     }
257 }
258 
GetStartIndex(const std::string & bundleName)259 int FoldEventCacher::GetStartIndex(const std::string& bundleName)
260 {
261     return dbHelper_->QueryRawEventIndex(bundleName, FoldEventId::EVENT_APP_START);
262 }
263 
UpdateFoldStatus(int status)264 void FoldEventCacher::UpdateFoldStatus(int status)
265 {
266     foldStatus_ = status;
267 }
268 
UpdateVhMode(int mode)269 void FoldEventCacher::UpdateVhMode(int mode)
270 {
271     vhMode_ = mode;
272 }
273 
274 } // namespace HiviewDFX
275 } // namespace OHOS
276