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