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