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_FOCUS, "ZOrderCheck err, zorder 0");
41             ReportZOrderException("check zorder 0", session);
42         }
43         // repetitive zorder
44         if (session->GetZOrder() == curZOrder) {
45             TLOGE(WmsLogTag::WMS_FOCUS, "ZOrderCheck err, repetitive zorder %{public}d", session->GetZOrder());
46             ReportZOrderException("check repetitive zorder", session);
47         }
48         curZOrder = session->GetZOrder();
49         // callingSession check for input method
50         if (session->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
51             uint32_t callingWindowId = session->GetCallingSessionId();
52             const auto& callingSession =
53                 SceneSessionManager::GetInstance().GetSceneSession(static_cast<int32_t>(callingWindowId));
54             if ((callingSession != nullptr) && (callingSession->GetZOrder() > session->GetZOrder())) {
55                 TLOGE(WmsLogTag::WMS_FOCUS, "ZOrderCheck err, callingSession: %{public}d curSession: %{public}d",
56                     callingSession->GetZOrder(), session->GetZOrder());
57                 ReportZOrderException("check callingSession check for input", session);
58             }
59         }
60         // subWindow/dialogWindow
61         if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
62             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
63             auto mainSession = session->GetParentSession();
64             if ((mainSession != nullptr) && (session->GetZOrder() < mainSession->GetZOrder())) {
65                 TLOGE(WmsLogTag::WMS_FOCUS, "ZOrderCheck err, subSession %{public}d mainSession %{public}d",
66                     session->GetZOrder(), mainSession->GetZOrder());
67                 ReportZOrderException("check subWindow and dialogWindow", session);
68             }
69         }
70         if (session->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
71             keyGuardFlag = true;
72             return false;
73         }
74         if (keyGuardFlag && (!session->IsShowWhenLocked()) && (session->IsAppSession())) {
75             TLOGE(WmsLogTag::WMS_FOCUS, "ZOrderCheck err %{public}d IsShowWhenLocked", session->GetZOrder());
76             ReportZOrderException("check isShowWhenLocked", session);
77         }
78         return false;
79     };
80     SceneSessionManager::GetInstance().TraverseSessionTree(func, false);
81 }
82 
FocusCheckProcess(int32_t focusedId,int32_t nextId)83 void AnomalyDetection::FocusCheckProcess(int32_t focusedId, int32_t nextId)
84 {
85     if (nextId == INVALID_SESSION_ID) {
86         TLOGE(WmsLogTag::WMS_FOCUS, "FocusCheck err: invalid id, focusedId:%{public}d nextId:%{public}d",
87             focusedId, nextId);
88         ReportFocusException("invalid id", focusedId, nextId, nullptr);
89     }
90 }
91 
ReportZOrderException(const std::string & errorReason,sptr<SceneSession> session)92 void AnomalyDetection::ReportZOrderException(const std::string& errorReason, sptr<SceneSession> session)
93 {
94     if (session == nullptr) {
95         return;
96     }
97     std::ostringstream oss;
98     oss << " ZOrderCheck err " << errorReason;
99     oss << " cur persistentId: " << session->GetPersistentId() << ",";
100     oss << " windowType: " << static_cast<uint32_t>(session->GetWindowType()) << ",";
101     oss << " cur ZOrder: " << session->GetZOrder() << ";";
102     WindowInfoReporter::GetInstance().ReportWindowException(
103         static_cast<int32_t>(WindowDFXHelperType::WINDOW_ZORDER_CHECK), getpid(), oss.str());
104 }
105 
ReportFocusException(const std::string & errorReason,int32_t focusedId,int32_t nextId,sptr<SceneSession> session)106 void AnomalyDetection::ReportFocusException(const std::string& errorReason, int32_t focusedId, int32_t nextId,
107     sptr<SceneSession> session)
108 {
109     std::ostringstream oss;
110     oss << " FocusCheck err " << errorReason;
111     if (session != nullptr) {
112         oss << " cur persistentId: " << session->GetPersistentId() << ",";
113         oss << " windowType: " << static_cast<uint32_t>(session->GetWindowType()) << ",";
114     }
115     oss << " focusedId: " << focusedId << ",";
116     oss << " nextId: " << nextId << ";";
117     WindowInfoReporter::GetInstance().ReportWindowException(
118         static_cast<int32_t>(WindowDFXHelperType::WINDOW_FOCUS_CHECK), getpid(), oss.str());
119 }
120 } // namespace Rosen
121 } // namespace OHOS