1 /*
2 * Copyright (c) 2024 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 "anomaly_detection.h"
17 #include <hitrace_meter.h>
18
19 #include "session_manager/include/scene_session_manager.h"
20 #include "window_helper.h"
21 #include "perform_reporter.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "AnomalyDetection" };
27 }
28
SceneZOrderCheckProcess()29 void AnomalyDetection::SceneZOrderCheckProcess()
30 {
31 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::SceneZOrderCheckProcess");
32 bool keyGuardFlag = false;
33 uint32_t curZOrder = 0;
34 auto func = [&curZOrder, &keyGuardFlag](sptr<SceneSession> session) {
35 if ((session == nullptr) || (!SceneSessionManager::GetInstance().IsSessionVisibleForeground(session))) {
36 return false;
37 }
38 // check zorder = 0
39 if (session->GetZOrder() == 0) {
40 TLOGE(WmsLogTag::WMS_HIERARCHY, "ZOrderCheck err, zorder 0");
41 ReportZOrderException("check zorder 0", session);
42 }
43 // repetitive zorder
44 if (session->GetZOrder() == curZOrder) {
45 TLOGND(WmsLogTag::WMS_HIERARCHY, "ZOrderCheck err, zorder %{public}d", session->GetZOrder());
46 ReportZOrderException("check repetitive zorder", session);
47 }
48 curZOrder = session->GetZOrder();
49 // callingSession check for input method
50 CheckCallingSession(session);
51 // subWindow/dialogWindow
52 CheckSubWindow(session);
53 // check app session showWhenLocked
54 CheckShowWhenLocked(session, keyGuardFlag);
55 // wallpaper zOrder check
56 CheckWallpaper(session);
57 return false;
58 };
59 SceneSessionManager::GetInstance().TraverseSessionTree(func, false);
60 }
61
CheckCallingSession(sptr<SceneSession> & session)62 void AnomalyDetection::CheckCallingSession(sptr<SceneSession>& session)
63 {
64 if (session->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
65 uint32_t callingWindowId = session->GetCallingSessionId();
66 const auto& callingSession =
67 SceneSessionManager::GetInstance().GetSceneSession(static_cast<int32_t>(callingWindowId));
68 if ((callingSession != nullptr) && (callingSession->GetZOrder() > session->GetZOrder())) {
69 TLOGE(WmsLogTag::WMS_HIERARCHY,
70 "ZOrderCheck err, callingSession: %{public}d curSession: %{public}d",
71 callingSession->GetZOrder(),
72 session->GetZOrder());
73 ReportZOrderException("check callingSession check for input", session);
74 }
75 }
76 }
77
CheckSubWindow(sptr<SceneSession> & session)78 void AnomalyDetection::CheckSubWindow(sptr<SceneSession>& session)
79 {
80 if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
81 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
82 auto mainSession = session->GetParentSession();
83 if ((mainSession != nullptr) && (session->GetZOrder() < mainSession->GetZOrder())) {
84 TLOGE(WmsLogTag::WMS_HIERARCHY,
85 "ZOrderCheck err, subSession %{public}d mainSession %{public}d",
86 session->GetZOrder(),
87 mainSession->GetZOrder());
88 ReportZOrderException("check subWindow and dialogWindow", session);
89 }
90 }
91 }
92
CheckShowWhenLocked(sptr<SceneSession> & session,bool & keyGuardFlag)93 void AnomalyDetection::CheckShowWhenLocked(sptr<SceneSession>& session, bool& keyGuardFlag)
94 {
95 if (session->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
96 keyGuardFlag = true;
97 return;
98 }
99 if (keyGuardFlag && (!session->IsShowWhenLocked()) && (session->IsAppSession())) {
100 TLOGE(WmsLogTag::WMS_HIERARCHY, "ZOrderCheck err %{public}d IsShowWhenLocked", session->GetZOrder());
101 ReportZOrderException("check isShowWhenLocked", session);
102 }
103 }
104
CheckWallpaper(sptr<SceneSession> & session)105 void AnomalyDetection::CheckWallpaper(sptr<SceneSession>& session)
106 {
107 if (session->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
108 constexpr uint32_t defaultWallpaperZOrder = 1;
109 if (!SceneSessionManager::GetInstance().IsScreenLocked() && session->GetZOrder() != defaultWallpaperZOrder) {
110 TLOGE(
111 WmsLogTag::WMS_HIERARCHY, "ZOrderCheck err %{public}d wallpaper zOrder abnormal", session->GetZOrder());
112 ReportZOrderException("check wallpaperWhenLocked", session);
113 }
114 }
115 }
116
FocusCheckProcess(int32_t focusedId,int32_t nextId)117 void AnomalyDetection::FocusCheckProcess(int32_t focusedId, int32_t nextId)
118 {
119 if (nextId == INVALID_SESSION_ID) {
120 TLOGE(WmsLogTag::WMS_FOCUS, "FocusCheck err: invalid id, focusedId:%{public}d nextId:%{public}d",
121 focusedId, nextId);
122 ReportFocusException("invalid id", focusedId, nextId, nullptr);
123 }
124 }
125
ReportZOrderException(const std::string & errorReason,sptr<SceneSession> session)126 void AnomalyDetection::ReportZOrderException(const std::string& errorReason, sptr<SceneSession> session)
127 {
128 if (session == nullptr) {
129 return;
130 }
131 std::ostringstream oss;
132 oss << " ZOrderCheck err " << errorReason;
133 oss << " cur persistentId: " << session->GetPersistentId() << ",";
134 oss << " windowType: " << static_cast<uint32_t>(session->GetWindowType()) << ",";
135 oss << " cur ZOrder: " << session->GetZOrder() << ";";
136 WindowInfoReporter::GetInstance().ReportWindowException(
137 static_cast<int32_t>(WindowDFXHelperType::WINDOW_ZORDER_CHECK), getpid(), oss.str());
138 }
139
ReportFocusException(const std::string & errorReason,int32_t focusedId,int32_t nextId,sptr<SceneSession> session)140 void AnomalyDetection::ReportFocusException(const std::string& errorReason, int32_t focusedId, int32_t nextId,
141 sptr<SceneSession> session)
142 {
143 std::ostringstream oss;
144 oss << " FocusCheck err " << errorReason;
145 if (session != nullptr) {
146 oss << " cur persistentId: " << session->GetPersistentId() << ",";
147 oss << " windowType: " << static_cast<uint32_t>(session->GetWindowType()) << ",";
148 }
149 oss << " focusedId: " << focusedId << ",";
150 oss << " nextId: " << nextId << ";";
151 WindowInfoReporter::GetInstance().ReportWindowException(
152 static_cast<int32_t>(WindowDFXHelperType::WINDOW_FOCUS_CHECK), getpid(), oss.str());
153 }
154 } // namespace Rosen
155 } // namespace OHOS