1 /*
2  * Copyright (c) 2022-2023 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 "window_state_observer.h"
17 
18 #include "cgroup_sched_log.h"
19 #include "cgroup_event_handler.h"
20 #include "res_type.h"
21 #include "sched_controller.h"
22 #include "ressched_utils.h"
23 
24 namespace OHOS {
25 namespace ResourceSchedule {
26     const uint8_t WINDOW_MODE_SPLIT_BIT = 1;
27     const uint8_t WINDOW_MODE_BIT_EXIT = 1;
OnFocused(const sptr<FocusChangeInfo> & focusChangeInfo)28 void WindowStateObserver::OnFocused(const sptr<FocusChangeInfo>& focusChangeInfo)
29 {
30     if (!focusChangeInfo) {
31         return;
32     }
33 
34     auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
35     if (cgHandler) {
36         auto windowId = focusChangeInfo->windowId_;
37         auto token = reinterpret_cast<uintptr_t>(focusChangeInfo->abilityToken_.GetRefPtr());
38         auto windowType = focusChangeInfo->windowType_;
39         auto displayId = focusChangeInfo->displayId_;
40         auto pid = focusChangeInfo->pid_;
41         auto uid = focusChangeInfo->uid_;
42 
43         cgHandler->PostTask([cgHandler, windowId, token, windowType, displayId, pid, uid] {
44             cgHandler->HandleFocusedWindow(windowId, token, windowType, displayId, pid, uid);
45         });
46     }
47 
48     nlohmann::json payload;
49     payload["pid"] = std::to_string(focusChangeInfo->pid_);
50     payload["uid"] = std::to_string(focusChangeInfo->uid_);
51     payload["windowId"] = std::to_string(focusChangeInfo->windowId_);
52     payload["windowType"] = std::to_string((int32_t)(focusChangeInfo->windowType_));
53     payload["displayId"] = std::to_string(focusChangeInfo->displayId_);
54     ResSchedUtils::GetInstance().ReportDataInProcess(
55         ResType::RES_TYPE_WINDOW_FOCUS, ResType::WindowFocusStatus::WINDOW_FOCUS, payload);
56 }
57 
OnUnfocused(const sptr<FocusChangeInfo> & focusChangeInfo)58 void WindowStateObserver::OnUnfocused(const sptr<FocusChangeInfo>& focusChangeInfo)
59 {
60     if (!focusChangeInfo) {
61         return;
62     }
63 
64     auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
65     if (cgHandler) {
66         auto windowId = focusChangeInfo->windowId_;
67         auto token = reinterpret_cast<uintptr_t>(focusChangeInfo->abilityToken_.GetRefPtr());
68         auto windowType = focusChangeInfo->windowType_;
69         auto displayId = focusChangeInfo->displayId_;
70         auto pid = focusChangeInfo->pid_;
71         auto uid = focusChangeInfo->uid_;
72 
73         cgHandler->PostTask([cgHandler, windowId, token, windowType, displayId, pid, uid] {
74             cgHandler->HandleUnfocusedWindow(windowId, token, windowType, displayId, pid, uid);
75         });
76     }
77 
78     nlohmann::json payload;
79     payload["pid"] = std::to_string(focusChangeInfo->pid_);
80     payload["uid"] = std::to_string(focusChangeInfo->uid_);
81     payload["windowId"] = std::to_string(focusChangeInfo->windowId_);
82     payload["windowType"] = std::to_string((int32_t)(focusChangeInfo->windowType_));
83     payload["displayId"] = std::to_string(focusChangeInfo->displayId_);
84     ResSchedUtils::GetInstance().ReportDataInProcess(
85         ResType::RES_TYPE_WINDOW_FOCUS, ResType::WindowFocusStatus::WINDOW_UNFOCUS, payload);
86 }
87 
MarshallingWindowVisibilityInfo(const sptr<WindowVisibilityInfo> & info,nlohmann::json & payload)88 void WindowVisibilityObserver::MarshallingWindowVisibilityInfo(const sptr<WindowVisibilityInfo>& info,
89     nlohmann::json& payload)
90 {
91     bool isVisible = info->visibilityState_ < Rosen::WindowVisibilityState::WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
92     payload["pid"] = std::to_string(info->pid_);
93     payload["uid"] = std::to_string(info->uid_);
94     payload["windowId"] = std::to_string(info->windowId_);
95     payload["windowType"] = std::to_string((int32_t)info->windowType_);
96     payload["isVisible"] = isVisible;
97     payload["visibilityState"] = std::to_string(info->visibilityState_);
98 }
99 
OnWindowVisibilityChanged(const std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfo)100 void WindowVisibilityObserver::OnWindowVisibilityChanged(
101     const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo)
102 {
103     auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
104     if (!cgHandler) {
105         return;
106     }
107     for (auto& info : windowVisibilityInfo) {
108         if (!info) {
109             continue;
110         }
111         auto windowId = info->windowId_;
112         auto visibilityState = info->visibilityState_;
113         auto windowType = info->windowType_;
114         auto pid = info->pid_;
115         auto uid = info->uid_;
116         cgHandler->PostTask([cgHandler, windowId, visibilityState, windowType, pid, uid] {
117             cgHandler->HandleWindowVisibilityChanged(windowId, visibilityState, windowType, pid, uid);
118         });
119         nlohmann::json payload;
120         MarshallingWindowVisibilityInfo(info, payload);
121         bool isVisible = visibilityState < Rosen::WindowVisibilityState::WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
122         ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_WINDOW_VISIBILITY_CHANGE,
123             isVisible ? ResType::WindowVisibilityStatus::VISIBLE : ResType::WindowVisibilityStatus::INVISIBLE, payload);
124     }
125 }
126 
MarshallingWindowDrawingContentInfo(const sptr<WindowDrawingContentInfo> & info,nlohmann::json & payload)127 void WindowDrawingContentObserver::MarshallingWindowDrawingContentInfo(const sptr<WindowDrawingContentInfo>& info,
128     nlohmann::json& payload)
129 {
130     payload["pid"] = std::to_string(info->pid_);
131     payload["uid"] = std::to_string(info->uid_);
132     payload["windowId"] = std::to_string(info->windowId_);
133     payload["windowType"] = std::to_string((int32_t)info->windowType_);
134     payload["drawingContentState"] = info->drawingContentState_;
135 }
136 
OnWindowDrawingContentChanged(const std::vector<sptr<WindowDrawingContentInfo>> & changeInfo)137 void WindowDrawingContentObserver::OnWindowDrawingContentChanged(
138     const std::vector<sptr<WindowDrawingContentInfo>>& changeInfo)
139 {
140     auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
141     if (!cgHandler) {
142         return;
143     }
144     for (const auto& info : changeInfo) {
145         if (!info) {
146             continue;
147         }
148         auto windowId = info->windowId_;
149         auto windowType = info->windowType_;
150         auto drawingContentState = info->drawingContentState_;
151         auto pid = info->pid_;
152         auto uid = info->uid_;
153         cgHandler->PostTask([cgHandler, windowId, windowType, drawingContentState, pid, uid] {
154             cgHandler->HandleDrawingContentChangeWindow(windowId, windowType, drawingContentState, pid, uid);
155         });
156         nlohmann::json payload;
157         MarshallingWindowDrawingContentInfo(info, payload);
158         ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_WINDOW_DRAWING_CONTENT_CHANGE,
159             drawingContentState ? ResType::WindowDrawingStatus::Drawing : ResType::WindowDrawingStatus::NotDrawing,
160             payload);
161     }
162 }
OnWindowModeUpdate(const WindowModeType mode)163 void WindowModeObserver::OnWindowModeUpdate(const WindowModeType mode)
164 {
165     CGS_LOGI("WindowModeObserver OnWindowModeUpdate mode: %{public}hhu ", mode);
166     uint8_t nowWindowMode = MarshallingWindowModeType(mode);
167     uint8_t windowModeChangeBit = nowWindowMode ^ lastWindowMode_;
168     nlohmann::json payload;
169     uint8_t windowModeSplitValue = (nowWindowMode >> WINDOW_MODE_SPLIT_BIT) & WINDOW_MODE_BIT_EXIT;
170     uint8_t windowModeFloatingValue = nowWindowMode & WINDOW_MODE_BIT_EXIT;
171     switch (windowModeChangeBit) {
172         case RSSWindowMode::WINDOW_MODE_FLOATING_CHANGED:
173             ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_FLOATING_WINDOW,
174                 windowModeFloatingValue, payload);
175             break;
176         case RSSWindowMode::WINDOW_MODE_SPLIT_CHANGED:
177             ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_SPLIT_SCREEN,
178                 windowModeSplitValue, payload);
179             break;
180         case RSSWindowMode::WINDOW_MODE_SPLIT_FLOATING_CHANGED:
181             ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_SPLIT_SCREEN,
182                 windowModeSplitValue, payload);
183             ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_FLOATING_WINDOW,
184                 windowModeFloatingValue, payload);
185             break;
186         default:
187             break;
188     }
189     lastWindowMode_ = nowWindowMode;
190 }
191 
MarshallingWindowModeType(const WindowModeType mode)192 uint8_t WindowModeObserver::MarshallingWindowModeType(const WindowModeType mode)
193 {
194     uint8_t nowWindowMode = RSSWindowMode::WINDOW_MODE_OTHER;
195     switch (mode) {
196         case Rosen::WindowModeType::WINDOW_MODE_SPLIT:
197             nowWindowMode = RSSWindowMode::WINDOW_MODE_SPLIT;
198             break;
199         case Rosen::WindowModeType::WINDOW_MODE_FLOATING:
200         case Rosen::WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING:
201             nowWindowMode = RSSWindowMode::WINDOW_MODE_FLOATING;
202             break;
203         case Rosen::WindowModeType::WINDOW_MODE_SPLIT_FLOATING:
204             nowWindowMode = RSSWindowMode::WINDOW_MODE_SPLIT_FLOATING;
205             break;
206         default:
207             nowWindowMode = RSSWindowMode::WINDOW_MODE_OTHER;
208             break;
209     }
210     return nowWindowMode;
211 }
212 } // namespace ResourceSchedule
213 } // namespace OHOS
214