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_log.h"
19 #include "window_manager.h"
20 
21 namespace OHOS {
22 namespace Security {
23 namespace SecurityComponent {
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "WindowInfoHelper"};
26 constexpr int32_t INVALID_WINDOW_LAYER = -1;
27 constexpr uint32_t UI_EXTENSION_MASK = 0x40000000;
28 }
29 
GetWindowScale(int32_t windowId)30 float WindowInfoHelper::GetWindowScale(int32_t windowId)
31 {
32     float scale = FULL_SCREEN_SCALE;
33     std::vector<sptr<Rosen::AccessibilityWindowInfo>> infos;
34     if (Rosen::WindowManager::GetInstance().GetAccessibilityWindowInfo(infos) != Rosen::WMError::WM_OK) {
35         SC_LOG_ERROR(LABEL, "Get AccessibilityWindowInfo failed");
36         return scale;
37     }
38     auto iter = std::find_if(infos.begin(), infos.end(), [windowId](const sptr<Rosen::AccessibilityWindowInfo> info) {
39         return windowId == info->wid_;
40     });
41     if ((iter == infos.end()) || (*iter == nullptr)) {
42         SC_LOG_WARN(LABEL, "Cannot find AccessibilityWindowInfo, return default scale");
43         return scale;
44     }
45     scale = (*iter)->scaleVal_;
46     SC_LOG_INFO(LABEL, "Get scale %{public}f", scale);
47     return scale;
48 }
49 
IsRectInWindRect(const Rosen::Rect & windRect,const SecCompRect & secRect)50 static bool IsRectInWindRect(const Rosen::Rect& windRect, const SecCompRect& secRect)
51 {
52     // left or right
53     if ((secRect.x_ + secRect.width_ <= windRect.posX_) || (secRect.x_ >= windRect.posX_ + windRect.width_)) {
54         return false;
55     }
56     // top or bottom
57     if ((secRect.y_ + secRect.height_ <= windRect.posY_) || (secRect.y_ >= windRect.posY_ + windRect.height_)) {
58         return false;
59     }
60 
61     return true;
62 }
63 
CheckOtherWindowCoverComp(int32_t compWinId,const SecCompRect & secRect)64 bool WindowInfoHelper::CheckOtherWindowCoverComp(int32_t compWinId, const SecCompRect& secRect)
65 {
66     if ((static_cast<uint32_t>(compWinId) & UI_EXTENSION_MASK) == UI_EXTENSION_MASK) {
67         SC_LOG_INFO(LABEL, "UI extension can not check");
68         return true;
69     }
70     std::vector<sptr<Rosen::UnreliableWindowInfo>> infos;
71     if (Rosen::WindowManager::GetInstance().GetUnreliableWindowInfo(compWinId, infos) != Rosen::WMError::WM_OK) {
72         SC_LOG_ERROR(LABEL, "Get AccessibilityWindowInfo failed");
73         return false;
74     }
75 
76     int32_t compLayer = INVALID_WINDOW_LAYER;
77     // {windowId, zOrder}
78     std::vector<std::pair<int32_t, int32_t>> layerList;
79     for (auto& info : infos) {
80         if (info == nullptr) {
81             continue;
82         }
83 
84         if (info->windowId_ == compWinId) {
85             compLayer = static_cast<int32_t>(info->zOrder_);
86             continue;
87         }
88         if (info->floatingScale_ != 0.0) {
89             info->windowRect_.width_ *= info->floatingScale_;
90             info->windowRect_.height_ *= info->floatingScale_;
91         }
92         if (IsRectInWindRect(info->windowRect_, secRect)) {
93             layerList.emplace_back(std::make_pair(info->windowId_, info->zOrder_));
94         }
95     }
96 
97     if (compLayer == INVALID_WINDOW_LAYER) {
98         SC_LOG_ERROR(LABEL, "windId %{public}d component layer is wrong", compWinId);
99         return false;
100     }
101 
102     if (layerList.size() == static_cast<size_t>(0)) {
103         return true;
104     }
105 
106     auto iter = std::find_if(layerList.begin(), layerList.end(),
107         [compLayer](const std::pair<int32_t, int32_t> layer) {
108         return layer.second >= compLayer;
109     });
110     if (iter != layerList.end()) {
111         SC_LOG_ERROR(LABEL, "component window %{public}d is covered by %{public}d, click check failed",
112             compWinId, iter->first);
113         return false;
114     }
115     return true;
116 }
117 }  // namespace SecurityComponent
118 }  // namespace Security
119 }  // namespace OHOS
120