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