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