1 /*
2 * Copyright (c) 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 #include "window_info_helper.h"
16
17 #include <vector>
18 #include "sec_comp_info_helper.h"
19 #include "sec_comp_log.h"
20 #include "window_manager.h"
21
22 namespace OHOS {
23 namespace Security {
24 namespace SecurityComponent {
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "WindowInfoHelper"};
27 constexpr int32_t INVALID_WINDOW_LAYER = -1;
28 constexpr uint32_t UI_EXTENSION_MASK = 0x40000000;
29 }
30
GetWindowScale(int32_t windowId,bool & isCompatScaleMode)31 float WindowInfoHelper::GetWindowScale(int32_t windowId, bool& isCompatScaleMode)
32 {
33 float scale = FULL_SCREEN_SCALE;
34 std::vector<sptr<Rosen::AccessibilityWindowInfo>> infos;
35 if (Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(infos) != Rosen::WMError::WM_OK) {
36 SC_LOG_ERROR(LABEL, "Get AccessibilityWindowInfo failed");
37 return scale;
38 }
39 auto iter = std::find_if(infos.begin(), infos.end(), [windowId](const sptr<Rosen::AccessibilityWindowInfo> info) {
40 return windowId == info->wid_;
41 });
42 if ((iter == infos.end()) || (*iter == nullptr)) {
43 SC_LOG_WARN(LABEL, "Cannot find AccessibilityWindowInfo, return default scale");
44 return scale;
45 }
46 isCompatScaleMode = (*iter)->isCompatScaleMode_;
47 scale = (*iter)->scaleVal_;
48 SC_LOG_INFO(LABEL, "Get scale = %{public}f, isCompatScaleMode = %{public}d", scale, isCompatScaleMode);
49 return scale;
50 }
51
GetSecCompWindowMsg(int32_t compWinId,const SecCompRect & secRect,int32_t coverWindowId)52 std::string GetSecCompWindowMsg(int32_t compWinId, const SecCompRect& secRect,
53 int32_t coverWindowId)
54 {
55 std::string message = ", the id of the window where the security component is located is " +
56 std::to_string(compWinId) + ", security component is covered by the window(id = " +
57 std::to_string(coverWindowId) + "), the size of security component is (x = " +
58 std::to_string(secRect.x_) + ", y = " + std::to_string(secRect.y_) +
59 ", width = " + std::to_string(secRect.width_) +
60 ", height = " + std::to_string(secRect.height_) + ")";
61 return message;
62 }
63
GetCoveredWindowMsg(const Rosen::Rect & windowRect)64 std::string GetCoveredWindowMsg(const Rosen::Rect& windowRect)
65 {
66 std::string coveredWindowMessage = ", the size of window covering security component is (x = " +
67 std::to_string(windowRect.posX_) + ", y = " + std::to_string(windowRect.posY_) +
68 ", width = " + std::to_string(windowRect.width_) + ", height = " + std::to_string(windowRect.height_) + ")";
69 return coveredWindowMessage;
70 }
71
IsRectInWindRect(const Rosen::Rect & windRect,const SecCompRect & secRect)72 static bool IsRectInWindRect(const Rosen::Rect& windRect, const SecCompRect& secRect)
73 {
74 // left or right
75 if ((secRect.x_ + secRect.width_ <= windRect.posX_) ||
76 (secRect.x_ >= windRect.posX_ + static_cast<int32_t>(windRect.width_))) {
77 return false;
78 }
79 // top or bottom
80 if ((secRect.y_ + secRect.height_ <= windRect.posY_) ||
81 (secRect.y_ >= windRect.posY_ + static_cast<int32_t>(windRect.height_))) {
82 return false;
83 }
84 if ((GreatOrEqual(windRect.posX_, secRect.x_ + secRect.width_ - secRect.borderRadius_.rightBottom) &&
85 GreatOrEqual(windRect.posY_, secRect.y_ + secRect.height_ - secRect.borderRadius_.rightBottom))) {
86 auto distance = SecCompInfoHelper::GetDistance(secRect.x_ + secRect.width_ - secRect.borderRadius_.rightBottom,
87 secRect.y_ + secRect.height_ - secRect.borderRadius_.rightBottom, windRect.posX_, windRect.posY_);
88 return !GreatNotEqual(distance, secRect.borderRadius_.rightBottom - 1.0);
89 }
90 if ((GreatOrEqual(secRect.x_ + secRect.borderRadius_.leftBottom, windRect.posX_ + windRect.width_) &&
91 GreatOrEqual(windRect.posY_, secRect.y_ + secRect.height_ - secRect.borderRadius_.leftBottom))) {
92 auto distance = SecCompInfoHelper::GetDistance(secRect.x_ + secRect.borderRadius_.leftBottom,
93 secRect.y_ + secRect.height_ - secRect.borderRadius_.leftBottom, windRect.posX_ + windRect.width_,
94 windRect.posY_);
95 return !GreatNotEqual(distance, secRect.borderRadius_.leftBottom - 1.0);
96 }
97 if ((GreatOrEqual(windRect.posX_, secRect.x_ + secRect.width_ - secRect.borderRadius_.rightTop) &&
98 GreatOrEqual(secRect.y_ + secRect.borderRadius_.rightTop, windRect.posY_ + windRect.height_))) {
99 auto distance = SecCompInfoHelper::GetDistance(secRect.x_ + secRect.width_ - secRect.borderRadius_.rightTop,
100 secRect.y_ + secRect.borderRadius_.rightTop, windRect.posX_, windRect.posY_ + windRect.height_);
101 return !GreatNotEqual(distance, secRect.borderRadius_.rightTop - 1.0);
102 }
103 if ((GreatOrEqual(secRect.x_ + secRect.borderRadius_.leftTop, windRect.posX_ + windRect.width_) &&
104 GreatOrEqual(secRect.y_ + secRect.borderRadius_.leftTop, windRect.posY_ + windRect.height_))) {
105 auto distance = SecCompInfoHelper::GetDistance(secRect.x_ + secRect.borderRadius_.leftTop,
106 secRect.y_ + secRect.borderRadius_.leftTop, windRect.posX_ + windRect.width_,
107 windRect.posY_ + windRect.height_);
108 return !GreatNotEqual(distance, secRect.borderRadius_.leftTop - 1.0);
109 }
110
111 return true;
112 }
113
IsOtherWindowCoverComp(int32_t compWinId,const SecCompRect & secRect,int32_t compLayer,std::string & message,const std::vector<std::pair<int32_t,int32_t>> & layerList)114 static bool IsOtherWindowCoverComp(int32_t compWinId, const SecCompRect& secRect, int32_t compLayer,
115 std::string& message, const std::vector<std::pair<int32_t, int32_t>>& layerList)
116 {
117 if (compLayer == INVALID_WINDOW_LAYER) {
118 SC_LOG_ERROR(LABEL, "windId %{public}d component layer is wrong", compWinId);
119 return false;
120 }
121
122 if (layerList.size() == static_cast<size_t>(0)) {
123 return true;
124 }
125
126 auto iter = std::find_if(layerList.begin(), layerList.end(), [compLayer](const std::pair<int32_t, int32_t> layer) {
127 return layer.second >= compLayer;
128 });
129 if (iter != layerList.end()) {
130 SC_LOG_ERROR(LABEL, "component window %{public}d is covered by %{public}d, click check failed",
131 compWinId, iter->first);
132 message = GetSecCompWindowMsg(compWinId, secRect, iter->first);
133 return false;
134 }
135 return true;
136 }
CheckOtherWindowCoverComp(int32_t compWinId,const SecCompRect & secRect,std::string & message)137 bool WindowInfoHelper::CheckOtherWindowCoverComp(int32_t compWinId, const SecCompRect& secRect, std::string& message)
138 {
139 if ((static_cast<uint32_t>(compWinId) & UI_EXTENSION_MASK) == UI_EXTENSION_MASK) {
140 SC_LOG_INFO(LABEL, "UI extension can not check");
141 return true;
142 }
143 std::vector<sptr<Rosen::UnreliableWindowInfo>> infos;
144 if (Rosen::WindowManager::GetInstance().GetUnreliableWindowInfo(compWinId, infos) != Rosen::WMError::WM_OK) {
145 SC_LOG_ERROR(LABEL, "Get AccessibilityWindowInfo failed");
146 return false;
147 }
148
149 int32_t compLayer = INVALID_WINDOW_LAYER;
150 std::string coveredWindowMsg;
151 // {windowId, zOrder}
152 std::vector<std::pair<int32_t, int32_t>> layerList;
153 for (auto& info : infos) {
154 if (info == nullptr) {
155 continue;
156 }
157
158 if (info->windowId_ == compWinId) {
159 compLayer = static_cast<int32_t>(info->zOrder_);
160 continue;
161 }
162 if (info->floatingScale_ != 0.0) {
163 info->windowRect_.width_ *= info->floatingScale_;
164 info->windowRect_.height_ *= info->floatingScale_;
165 }
166 if (IsRectInWindRect(info->windowRect_, secRect)) {
167 layerList.emplace_back(std::make_pair(info->windowId_, info->zOrder_));
168 if (compLayer != INVALID_WINDOW_LAYER && static_cast<int32_t>(info->zOrder_) >= compLayer) {
169 coveredWindowMsg = GetCoveredWindowMsg(info->windowRect_);
170 break;
171 }
172 }
173 }
174
175 bool res = IsOtherWindowCoverComp(compWinId, secRect, compLayer, message, layerList);
176 if (!message.empty()) {
177 message += coveredWindowMsg;
178 }
179 return res;
180 }
181 } // namespace SecurityComponent
182 } // namespace Security
183 } // namespace OHOS
184