• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 #include "sec_comp_info_helper.h"
16 
17 #include <iomanip>
18 #include <sstream>
19 
20 #include "accesstoken_kit.h"
21 #include "display.h"
22 #include "display_info.h"
23 #include "display_manager.h"
24 #include "location_button.h"
25 #include "paste_button.h"
26 #include "save_button.h"
27 #include "sec_comp_err.h"
28 #include "sec_comp_info.h"
29 #include "sec_comp_log.h"
30 #include "sec_comp_tool.h"
31 #include "window_info_helper.h"
32 
33 namespace OHOS {
34 namespace Security {
35 namespace SecurityComponent {
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompInfoHelper"};
38 static constexpr double MAX_RECT_PERCENT = 0.3F; // 30%
39 static constexpr double ZERO_OFFSET = 0.0F;
40 const std::string OUT_OF_SCREEN = ", security component is out of screen, security component(x = ";
41 const std::string OUT_OF_WINDOW = ", security component is out of window, security component(x = ";
42 const std::string SECURITY_COMPONENT_IS_TOO_LARGER =
43     ", security component is too larger, security component(width = ";
44 const int HEX_FIELD_WIDTH = 2;
45 const int NUMBER_TWO = 2;
46 const char HEX_FILL_CHAR = '0';
47 }
48 
AdjustSecCompRect(SecCompBase * comp,float scale)49 void SecCompInfoHelper::AdjustSecCompRect(SecCompBase* comp, float scale)
50 {
51     comp->rect_.width_ *= scale;
52     comp->rect_.height_ *= scale;
53     comp->rect_.x_ = comp->windowRect_.x_ + (comp->rect_.x_ - comp->windowRect_.x_) * scale;
54     comp->rect_.y_ = comp->windowRect_.y_ + (comp->rect_.y_ - comp->windowRect_.y_) * scale;
55 
56     SC_LOG_DEBUG(LABEL, "After adjust x %{public}f, y %{public}f, width %{public}f, height %{public}f",
57         comp->rect_.x_, comp->rect_.y_, comp->rect_.width_, comp->rect_.height_);
58 
59     comp->windowRect_.width_ *= scale;
60     comp->windowRect_.height_ *= scale;
61 }
62 
ParseComponent(SecCompType type,const nlohmann::json & jsonComponent,std::string & message,bool isClicked)63 SecCompBase* SecCompInfoHelper::ParseComponent(SecCompType type, const nlohmann::json& jsonComponent,
64     std::string& message, bool isClicked)
65 {
66     SecCompBase* comp = nullptr;
67     switch (type) {
68         case LOCATION_COMPONENT:
69             comp = ConstructComponent<LocationButton>(jsonComponent, message, isClicked);
70             break;
71         case PASTE_COMPONENT:
72             comp = ConstructComponent<PasteButton>(jsonComponent, message, isClicked);
73             break;
74         case SAVE_COMPONENT:
75             comp = ConstructComponent<SaveButton>(jsonComponent, message, isClicked);
76             break;
77         default:
78             SC_LOG_ERROR(LABEL, "Parse component type unknown");
79             break;
80     }
81     if (comp == nullptr) {
82         SC_LOG_ERROR(LABEL, "Parse component failed");
83         return comp;
84     }
85 
86     comp->SetValid(CheckComponentValid(comp, message));
87     return comp;
88 }
89 
GetScreenSize(double & width,double & height,const uint64_t displayId,const CrossAxisState crossAxisState)90 static bool GetScreenSize(double& width, double& height, const uint64_t displayId, const CrossAxisState crossAxisState)
91 {
92     sptr<OHOS::Rosen::Display> display =
93         OHOS::Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
94     if (display == nullptr) {
95         SC_LOG_ERROR(LABEL, "Get display manager failed");
96         return false;
97     }
98 
99     auto info = display->GetDisplayInfo();
100     if (info == nullptr) {
101         SC_LOG_ERROR(LABEL, "Get display info failed");
102         return false;
103     }
104 
105     width = static_cast<double>(info->GetWidth());
106     if (crossAxisState == CrossAxisState::STATE_CROSS) {
107         height = static_cast<double>(info->GetPhysicalHeight());
108     } else {
109         height = static_cast<double>(info->GetHeight());
110     }
111     SC_LOG_DEBUG(LABEL, "display manager Screen width %{public}f height %{public}f",
112         width, height);
113     return true;
114 }
115 
GetDistance(DimensionT x1,DimensionT y1,DimensionT x2,DimensionT y2)116 double SecCompInfoHelper::GetDistance(DimensionT x1, DimensionT y1, DimensionT x2, DimensionT y2)
117 {
118     return sqrt(pow(x1 - x2, NUMBER_TWO) + pow(y1 -y2, NUMBER_TWO));
119 }
120 
IsOutOfWatchScreen(const SecCompRect & rect,double radius,std::string & message)121 bool SecCompInfoHelper::IsOutOfWatchScreen(const SecCompRect& rect, double radius, std::string& message)
122 {
123     double leftTop = GetDistance(rect.x_ + rect.borderRadius_.leftTop,
124         rect.y_ + rect.borderRadius_.leftTop, radius, radius);
125     double leftBottom = GetDistance(rect.x_ + rect.borderRadius_.leftBottom,
126         rect.y_ + rect.height_ - rect.borderRadius_.leftBottom, radius, radius);
127     double rightTop = GetDistance(rect.x_ + rect.width_ - rect.borderRadius_.rightTop,
128         rect.y_ + rect.borderRadius_.rightTop, radius, radius);
129     double rightBottom = GetDistance(rect.x_ + rect.width_ - rect.borderRadius_.rightBottom,
130         rect.y_ + rect.height_ - rect.borderRadius_.rightBottom, radius, radius);
131     if (GreatNotEqual(leftTop, radius - rect.borderRadius_.leftTop + 1.0) ||
132         GreatNotEqual(leftBottom, radius - rect.borderRadius_.leftBottom + 1.0) ||
133         GreatNotEqual(rightTop, radius - rect.borderRadius_.rightTop + 1.0) ||
134         GreatNotEqual(rightBottom, radius - rect.borderRadius_.rightBottom + 1.0)) {
135         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of screen");
136         message = OUT_OF_SCREEN + std::to_string(rect.x_) + ", y = " + std::to_string(rect.y_) +
137             ", width = " + std::to_string(rect.width_) + ", height = " + std::to_string(rect.height_) +
138             "), current screen(width = " + std::to_string(radius * NUMBER_TWO) +
139             ", height = " + std::to_string(radius * NUMBER_TWO) + ")";
140         return true;
141     }
142     return false;
143 }
144 
IsOutOfScreen(const SecCompRect & rect,double curScreenWidth,double curScreenHeight,std::string & message,bool isWearable)145 bool SecCompInfoHelper::IsOutOfScreen(const SecCompRect& rect, double curScreenWidth, double curScreenHeight,
146     std::string& message, bool isWearable)
147 {
148     if (isWearable) {
149         if (IsOutOfWatchScreen(rect, curScreenHeight / NUMBER_TWO, message)) {
150             return true;
151         }
152     } else {
153         if (GreatNotEqual(ZERO_OFFSET, rect.x_) || GreatNotEqual(ZERO_OFFSET, rect.y_) ||
154             GreatNotEqual(rect.x_, curScreenWidth) || GreatNotEqual(rect.y_, curScreenHeight)) {
155             SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of screen");
156             message = OUT_OF_SCREEN + std::to_string(rect.x_) + ", y = " + std::to_string(rect.y_) +
157                 ", width = " + std::to_string(rect.width_) + ", height = " + std::to_string(rect.height_) +
158                 "), current screen(width = " + std::to_string(curScreenWidth) +
159                 ", height = " + std::to_string(curScreenHeight) + ")";
160             return true;
161         }
162 
163         if (GreatOrEqual((rect.x_ + rect.width_), curScreenWidth + 1.0) ||
164             GreatOrEqual((rect.y_ + rect.height_), curScreenHeight + 1.0)) {
165             SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of screen");
166             message = OUT_OF_SCREEN + std::to_string(rect.x_) + ", y = " + std::to_string(rect.y_) +
167                 ", width = " + std::to_string(rect.width_) + ", height = " + std::to_string(rect.height_) +
168                 "), current screen(width = " + std::to_string(curScreenWidth) +
169                 ", height = " + std::to_string(curScreenHeight) + ")";
170             return true;
171         }
172     }
173 
174     return false;
175 }
176 
CheckRectValid(const SecCompRect & rect,const SecCompRect & windowRect,const ScreenInfo & screenInfo,std::string & message)177 bool SecCompInfoHelper::CheckRectValid(const SecCompRect& rect, const SecCompRect& windowRect,
178     const ScreenInfo& screenInfo, std::string& message)
179 {
180     double curScreenWidth = 0.0F;
181     double curScreenHeight = 0.0F;
182     if (!GetScreenSize(curScreenWidth, curScreenHeight, screenInfo.displayId, screenInfo.crossAxisState)) {
183         SC_LOG_ERROR(LABEL, "Get screen size is invalid");
184         return false;
185     }
186 
187     if (GreatOrEqual(0.0, rect.width_) || GreatOrEqual(0.0, rect.height_)) {
188         SC_LOG_ERROR(LABEL, "width or height is <= 0");
189         return false;
190     }
191 
192     if (IsOutOfScreen(rect, curScreenWidth, curScreenHeight, message, screenInfo.isWearable)) {
193         return false;
194     }
195 
196     if (GreatNotEqual(windowRect.x_, rect.x_ + 1.0) || GreatNotEqual(windowRect.y_, rect.y_ + 1.0) ||
197         GreatNotEqual(rect.x_ + rect.width_, windowRect.x_ + windowRect.width_ + 1.0) ||
198         GreatNotEqual(rect.y_ + rect.height_, windowRect.y_ + windowRect.height_ + 1.0)) {
199         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of window");
200         message = OUT_OF_WINDOW + std::to_string(rect.x_) + ", y = " + std::to_string(rect.y_) +
201             ", width = " + std::to_string(rect.width_) + ", height = " + std::to_string(rect.height_) +
202             "), current window(x = " + std::to_string(windowRect.x_) + ", y = " + std::to_string(windowRect.y_) +
203             ", width = " + std::to_string(windowRect.width_) + ", height = " +
204             std::to_string(windowRect.height_) + ")";
205         return false;
206     }
207 
208     // check rect > 30%
209     if (GreatOrEqual((rect.width_ * rect.height_), (curScreenWidth * curScreenHeight * MAX_RECT_PERCENT))) {
210         SC_LOG_INFO(LABEL, "security component is larger than 30 percent of screen");
211     }
212     SC_LOG_DEBUG(LABEL, "check component rect success.");
213     return true;
214 }
215 
ColorToHexString(const SecCompColor & color)216 std::string ColorToHexString(const SecCompColor& color)
217 {
218     std::stringstream ss;
219     ss << std::hex;
220     ss << std::setw(HEX_FIELD_WIDTH) << std::setfill(HEX_FILL_CHAR) << static_cast<int>(color.argb.alpha);
221     ss << std::setw(HEX_FIELD_WIDTH) << std::setfill(HEX_FILL_CHAR) << static_cast<int>(color.argb.red);
222     ss << std::setw(HEX_FIELD_WIDTH) << std::setfill(HEX_FILL_CHAR) << static_cast<int>(color.argb.green);
223     ss << std::setw(HEX_FIELD_WIDTH) << std::setfill(HEX_FILL_CHAR) << static_cast<int>(color.argb.blue);
224 
225     return "#" + ss.str();
226 }
227 
CheckSecCompBaseButtonColorsimilar(const SecCompBase * comp,std::string & message)228 static bool CheckSecCompBaseButtonColorsimilar(const SecCompBase* comp, std::string& message)
229 {
230     if ((comp->bg_ != SecCompBackground::NO_BG_TYPE) && !IsColorFullTransparent(comp->bgColor_) &&
231         (comp->icon_ != NO_ICON) && IsColorSimilar(comp->iconColor_, comp->bgColor_)) {
232         SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: iconColor is similar with backgroundColor.");
233         message = ", icon color is similar with background color, icon color = " +
234             ColorToHexString(comp->iconColor_) + ", background color = " + ColorToHexString(comp->bgColor_);
235         return false;
236     }
237 
238     if ((comp->bg_ != SecCompBackground::NO_BG_TYPE) && !IsColorFullTransparent(comp->bgColor_) &&
239         (comp->text_ != NO_TEXT) && IsColorSimilar(comp->fontColor_, comp->bgColor_)) {
240         SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: fontColor is similar with backgroundColor.");
241         message = ", font color is similar with background color, font color = " +
242             ColorToHexString(comp->fontColor_) + ", background color = " + ColorToHexString(comp->bgColor_);
243         return false;
244     }
245 
246     if (comp->bg_ == SecCompBackground::NO_BG_TYPE &&
247         ((comp->padding_.top != MIN_PADDING_WITHOUT_BG) || (comp->padding_.right != MIN_PADDING_WITHOUT_BG) ||
248         (comp->padding_.bottom != MIN_PADDING_WITHOUT_BG) || (comp->padding_.left != MIN_PADDING_WITHOUT_BG))) {
249         SC_LOG_INFO(LABEL, "padding can not change without background.");
250         message = ", padding can not change without background";
251         return false;
252     }
253 
254     return true;
255 }
256 
CheckSecCompBaseButton(const SecCompBase * comp,std::string & message)257 static bool CheckSecCompBaseButton(const SecCompBase* comp, std::string& message)
258 {
259     if ((comp->text_ < 0) && (comp->icon_ < 0)) {
260         SC_LOG_INFO(LABEL, "both text and icon do not exist.");
261         return false;
262     }
263     if (comp->text_ >= 0) {
264         DimensionT minFontSize;
265         if (comp->icon_ >= 0) {
266             minFontSize = MIN_FONT_SIZE_WITH_ICON;
267         } else {
268             minFontSize = MIN_FONT_SIZE_WITHOUT_ICON;
269         }
270 
271         if (comp->fontSize_ < minFontSize) {
272             SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: fontSize is too small.");
273             message = ", font size is too small, font size = " +
274                 std::to_string(comp->fontSize_);
275             return false;
276         }
277     }
278     if ((comp->icon_ >= 0) && comp->iconSize_ < MIN_ICON_SIZE) {
279         SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: iconSize is too small.");
280         message = ", icon size is too small, icon size = " +
281             std::to_string(comp->iconSize_);
282         return false;
283     }
284 
285     return CheckSecCompBaseButtonColorsimilar(comp, message);
286 }
287 
CheckSecCompBase(const SecCompBase * comp,std::string & message)288 static bool CheckSecCompBase(const SecCompBase* comp, std::string& message)
289 {
290     if (comp->parentEffect_) {
291         SC_LOG_ERROR(LABEL,
292             "SecurityComponentCheckFail: the parents of security component have invalid effect.");
293         message = "PARENT_HAVE_INVALID_EFFECT";
294         return false;
295     }
296 
297     if ((comp->padding_.top < MIN_PADDING_SIZE) || (comp->padding_.right < MIN_PADDING_SIZE) ||
298         (comp->padding_.bottom < MIN_PADDING_SIZE) || (comp->padding_.left < MIN_PADDING_SIZE)) {
299         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: padding is too small.");
300         message = ", padding is too small, padding(top = " + std::to_string(comp->padding_.top) +
301             ", bottom = " + std::to_string(comp->padding_.bottom) +
302             ", left = " + std::to_string(comp->padding_.left) +
303             ", right = " + std::to_string(comp->padding_.right) + ")";
304         return false;
305     }
306 
307     if ((comp->textIconSpace_ < MIN_PADDING_SIZE)) {
308         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: textIconSpace is too small.");
309         message = ", textIconSpace is too small, textIconSpace = " + std::to_string(comp->textIconSpace_);
310         return false;
311     }
312 
313     if ((comp->text_ != NO_TEXT) && (IsColorTransparent(comp->fontColor_))) {
314         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: fontColor is too transparent.");
315         message = ", font color is too transparent, font color = " + ColorToHexString(comp->fontColor_);
316         return false;
317     }
318 
319     if ((comp->icon_ != NO_ICON) && (IsColorTransparent(comp->iconColor_))) {
320         SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: iconColor is too transparent.");
321         message = ", icon color is too transparent, icon color = " + ColorToHexString(comp->iconColor_);
322         return false;
323     }
324 
325     if (!CheckSecCompBaseButton(comp, message)) {
326         return false;
327     }
328     return true;
329 }
330 
CheckComponentValid(SecCompBase * comp,std::string & message)331 bool SecCompInfoHelper::CheckComponentValid(SecCompBase* comp, std::string& message)
332 {
333     if ((comp == nullptr) || !IsComponentTypeValid(comp->type_)) {
334         SC_LOG_INFO(LABEL, "comp is null or type is invalid.");
335         return false;
336     }
337 
338     float scale = WindowInfoHelper::GetWindowScale(comp->windowId_);
339     SC_LOG_DEBUG(LABEL, "WindowScale = %{public}f", scale);
340     if (!IsEqual(scale, WindowInfoHelper::FULL_SCREEN_SCALE) && !IsEqual(scale, 0.0)) {
341         AdjustSecCompRect(comp, scale);
342     }
343 
344     if (!CheckSecCompBase(comp, message)) {
345         SC_LOG_INFO(LABEL, "SecComp base is invalid.");
346         return false;
347     }
348 
349     return true;
350 }
351 }  // namespace SecurityComponent
352 }  // namespace Security
353 }  // namespace OHOS
354