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
16 #include "sensor_illumination_task.h"
17
18 #include "common_event_manager.h"
19 #include "common_event_subscriber.h"
20 #include "common_event_support.h"
21 #ifdef CONFIG_USE_DISPLAY_MANAGER_COMPONENT
22 #include "display_power_mgr_client.h"
23 #endif
24 #include "iservice_registry.h"
25 #include "pipeline/rs_render_thread.h"
26 #include "system_ability_definition.h"
27 #include "system_ability_status_change_stub.h"
28 #include "transaction/rs_interfaces.h"
29 #include "transaction/rs_transaction.h"
30 #include "ui/rs_surface_extractor.h"
31
32 #include "iam_check.h"
33 #include "iam_logger.h"
34 #include "iam_ptr.h"
35
36 #include "sa_command_manager.h"
37 #include "screen_state_monitor.h"
38
39 #define LOG_TAG "FINGERPRINT_AUTH_SA"
40
41 namespace OHOS {
42 namespace UserIam {
43 namespace FingerprintAuth {
44 using namespace EventFwk;
45 using namespace AAFwk;
46 using namespace UserAuth;
47 using namespace Rosen;
48
49 namespace {
50 constexpr uint32_t MAX_DISPLAY_TIME = 1000; // ms
51 constexpr uint32_t BRIGHTNESS_INDEX = 0;
52 constexpr uint32_t ALPHA_INDEX = 1;
53 constexpr uint32_t THOUSAND = 1000l; // center X and Y in per thousand
54 constexpr float MAX_ZORDER = 100000.0f;
55 constexpr uint8_t BRIGHTNESS_AND_ALPHA[][2] = { { 4, 234 }, { 6, 229 }, { 8, 219 }, { 10, 220 }, { 12, 216 },
56 { 14, 211 }, { 16, 208 }, { 20, 205 }, { 24, 187 }, { 28, 176 }, { 30, 170 }, { 34, 163 }, { 40, 159 }, { 46, 142 },
57 { 50, 140 }, { 56, 140 }, { 64, 125 }, { 74, 121 }, { 84, 111 }, { 94, 101 }, { 104, 92 }, { 114, 81 }, { 124, 81 },
58 { 134, 69 }, { 144, 68 }, { 154, 58 }, { 164, 56 }, { 174, 46 }, { 184, 44 }, { 194, 35 }, { 204, 34 }, { 214, 30 },
59 { 224, 22 }, { 234, 23 }, { 244, 18 }, { 248, 0 }, { 255, 0 } };
GetBackgroundAlpha(int32_t currScreenBrightness, uint32_t &outAlpha)60 ResultCode GetBackgroundAlpha(int32_t currScreenBrightness, uint32_t &outAlpha)
61 {
62 for (uint32_t i = 0; i < sizeof(BRIGHTNESS_AND_ALPHA) / sizeof(BRIGHTNESS_AND_ALPHA[0]); i++) {
63 if (currScreenBrightness > BRIGHTNESS_AND_ALPHA[i][BRIGHTNESS_INDEX]) {
64 continue;
65 } else if (currScreenBrightness == BRIGHTNESS_AND_ALPHA[i][BRIGHTNESS_INDEX] || i == 0) {
66 outAlpha = BRIGHTNESS_AND_ALPHA[i][ALPHA_INDEX];
67 } else {
68 // linear interpolation
69 float gapBrightnessDiff =
70 BRIGHTNESS_AND_ALPHA[i][BRIGHTNESS_INDEX] - BRIGHTNESS_AND_ALPHA[i - 1][BRIGHTNESS_INDEX];
71 float gapAlphaDiff = BRIGHTNESS_AND_ALPHA[i][ALPHA_INDEX] - BRIGHTNESS_AND_ALPHA[i - 1][ALPHA_INDEX];
72 float slope = gapAlphaDiff / gapBrightnessDiff;
73 float currBrightnessDiff = currScreenBrightness - BRIGHTNESS_AND_ALPHA[i - 1][BRIGHTNESS_INDEX];
74 float currAlphaDiff = slope * currBrightnessDiff;
75 outAlpha = BRIGHTNESS_AND_ALPHA[i - 1][ALPHA_INDEX] + static_cast<uint32_t>(currAlphaDiff);
76 }
77 IAM_LOGI("brightness %{public}d to alpha %{public}u", currScreenBrightness, outAlpha);
78 return ResultCode::SUCCESS;
79 }
80 IAM_LOGE("brightness mismatch");
81 return ResultCode::GENERAL_ERROR;
82 }
83
84 #ifndef USE_ROSEN_DRAWING
ConvertToSkColor(uint32_t color)85 SkColor ConvertToSkColor(uint32_t color)
86 {
87 uint8_t *colorBytes = static_cast<uint8_t *>(static_cast<void *>(&color));
88 constexpr uint32_t RIndex = 0;
89 constexpr uint32_t GIndex = 1;
90 constexpr uint32_t BIndex = 2;
91 constexpr uint32_t AIndex = 3;
92 return SkColorSetARGB(colorBytes[AIndex], colorBytes[RIndex], colorBytes[GIndex], colorBytes[BIndex]);
93 }
94 #else
ConvertToDrawingColor(uint32_t color)95 Drawing::ColorQuad ConvertToDrawingColor(uint32_t color)
96 {
97 uint8_t *colorBytes = static_cast<uint8_t *>(static_cast<void *>(&color));
98 constexpr uint32_t RIndex = 0;
99 constexpr uint32_t GIndex = 1;
100 constexpr uint32_t BIndex = 2;
101 constexpr uint32_t AIndex = 3;
102 return Drawing::Color::ColorQuadSetARGB(colorBytes[RIndex], colorBytes[GIndex], colorBytes[BIndex],
103 colorBytes[AIndex]);
104 }
105 #endif
106
DrawCanvas(std::shared_ptr<RSPaintFilterCanvas> canvas, const CanvasParam ¶m)107 ResultCode DrawCanvas(std::shared_ptr<RSPaintFilterCanvas> canvas, const CanvasParam ¶m)
108 {
109 IF_FALSE_LOGE_AND_RETURN_VAL(canvas != nullptr, ResultCode::GENERAL_ERROR);
110
111 #ifndef USE_ROSEN_DRAWING
112 canvas->clear(SkColorSetARGB(param.alpha, 0x00, 0x00, 0x00));
113
114 SkPaint paint;
115 paint.setStyle(SkPaint::kFill_Style);
116 paint.setAntiAlias(true);
117 paint.setColor(ConvertToSkColor(param.color));
118
119 canvas->drawCircle(SkPoint::Make(param.centerXInPx, param.centerYInPy), param.radius, paint);
120 #else
121 canvas->Clear(Drawing::Color::ColorQuadSetARGB(0x00, 0x00, 0x00, param.alpha));
122
123 Drawing::Brush brush;
124 brush.SetAntiAlias(true);
125 brush.SetColor(ConvertToDrawingColor(param.color));
126
127 canvas->AttachBrush(brush);
128 canvas->DrawCircle(Drawing::Point(param.centerXInPx, param.centerYInPy), param.radius);
129 canvas->DetachBrush();
130 #endif
131 return ResultCode::SUCCESS;
132 }
133
convertThousandthToPx(uint32_t relativeLength, uint32_t fullLength, uint32_t &pxLength)134 bool convertThousandthToPx(uint32_t relativeLength, uint32_t fullLength, uint32_t &pxLength)
135 {
136 uint64_t pxLengthUint64 = static_cast<uint64_t>(relativeLength) * static_cast<uint64_t>(fullLength) / THOUSAND;
137 if (pxLengthUint64 > std::numeric_limits<uint32_t>::max()) {
138 IAM_LOGE("pxLengthUint64 is more than UINT32_MAX");
139 return false;
140 }
141 pxLength = static_cast<uint32_t>(pxLengthUint64);
142 return true;
143 }
144 } // namespace
145
SensorIlluminationTask()146 SensorIlluminationTask::SensorIlluminationTask() : timer_("sensor_illumination_timer")
147 {
148 ScreenStateMonitor::GetInstance().Subscribe();
149 timer_.Setup();
150 }
151
~SensorIlluminationTask()152 SensorIlluminationTask::~SensorIlluminationTask()
153 {
154 ScreenStateMonitor::GetInstance().Unsubscribe();
155 timer_.Unregister(currTimerId_);
156 timer_.Shutdown();
157 if (destructCallback_ != nullptr) {
158 destructCallback_();
159 }
160 }
161
EnableSensorIllumination(uint32_t centerX, uint32_t centerY, uint32_t radius, uint32_t color)162 ResultCode SensorIlluminationTask::EnableSensorIllumination(uint32_t centerX, uint32_t centerY, uint32_t radius,
163 uint32_t color)
164 {
165 std::lock_guard<std::recursive_mutex> lock(recursiveMutex_);
166 IAM_LOGI("start");
167
168 RSSurfaceNodeConfig config = { .SurfaceNodeName = "FingerprintSenor" };
169
170 auto rsSurfaceNode = RSSurfaceNode::Create(config, RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE);
171 IF_FALSE_LOGE_AND_RETURN_VAL(rsSurfaceNode != nullptr, ResultCode::GENERAL_ERROR);
172
173 auto defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
174 IF_FALSE_LOGE_AND_RETURN_VAL(defaultDisplay != nullptr, ResultCode::GENERAL_ERROR);
175
176 int32_t width = defaultDisplay->GetWidth();
177 int32_t height = defaultDisplay->GetHeight();
178 rsSurfaceNode->SetBounds(0, 0, width, height);
179 rsSurfaceNode->SetFingerprint(true);
180
181 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(rsSurfaceNode);
182 IF_FALSE_LOGE_AND_RETURN_VAL(rsSurface != nullptr, ResultCode::GENERAL_ERROR);
183
184 auto renderContext = Common::MakeShared<RenderContext>();
185 IF_FALSE_LOGE_AND_RETURN_VAL(renderContext != nullptr, ResultCode::GENERAL_ERROR);
186 renderContext->InitializeEglContext();
187 rsSurface->SetRenderContext(renderContext.get());
188
189 uint32_t centerXInPx = 0;
190 bool convertRetX = convertThousandthToPx(centerX, defaultDisplay->GetWidth(), centerXInPx);
191 IF_FALSE_LOGE_AND_RETURN_VAL(convertRetX == true, ResultCode::GENERAL_ERROR);
192 uint32_t centerYInPx = 0;
193 bool convertRetY = convertThousandthToPx(centerY, defaultDisplay->GetHeight(), centerYInPx);
194 IF_FALSE_LOGE_AND_RETURN_VAL(convertRetY == true, ResultCode::GENERAL_ERROR);
195
196 canvasParam_ = (CanvasParam) { .centerXInPx = centerXInPx,
197 .centerYInPy = centerYInPx,
198 .radius = radius,
199 .color = color,
200 .alpha = 0,
201 .frameWidth = width,
202 .frameHeight = height };
203
204 defaultScreenId_ = Rosen::RSInterfaces::GetInstance().GetDefaultScreenId();
205 defaultDisplayId_ = defaultDisplay->GetId();
206 rsSurfaceNode_ = rsSurfaceNode;
207 rsSurface_ = rsSurface;
208 renderContext_ = renderContext;
209
210 ResultCode drawResult = DrawSurfaceNode();
211 IF_FALSE_LOGE_AND_RETURN_VAL(drawResult == ResultCode::SUCCESS, ResultCode::GENERAL_ERROR);
212
213 IAM_LOGI("success");
214 return ResultCode::SUCCESS;
215 }
216
DisableSensorIllumination()217 ResultCode SensorIlluminationTask::DisableSensorIllumination()
218 {
219 std::lock_guard<std::recursive_mutex> lock(recursiveMutex_);
220 IAM_LOGI("start");
221
222 TurnOffSensorIllumination();
223 rsSurfaceNode_ = nullptr;
224
225 ScreenStateMonitor::GetInstance().Unsubscribe();
226 IAM_LOGI("success");
227 return ResultCode::SUCCESS;
228 }
229
DrawSurfaceNode()230 ResultCode SensorIlluminationTask::DrawSurfaceNode()
231 {
232 IF_FALSE_LOGE_AND_RETURN_VAL(rsSurface_ != nullptr, ResultCode::GENERAL_ERROR);
233
234 IAM_LOGI("start");
235
236 #ifdef CONFIG_USE_DISPLAY_MANAGER_COMPONENT
237 uint32_t brightness = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDeviceBrightness();
238 #else
239 uint32_t brightness = INVALID_BRIGHTNESS;
240 #endif
241 IF_FALSE_LOGE_AND_RETURN_VAL(brightness != INVALID_BRIGHTNESS, ResultCode::GENERAL_ERROR);
242 IAM_LOGI("get device brightness %{public}u", brightness);
243
244 if (brightness == brightness_) {
245 IAM_LOGI("brightness is same, no need redraw");
246 return ResultCode::SUCCESS;
247 }
248 brightness_ = brightness;
249
250 uint32_t alpha;
251 ResultCode result = GetBackgroundAlpha(brightness_, alpha);
252 IF_FALSE_LOGE_AND_RETURN_VAL(result == ResultCode::SUCCESS, ResultCode::GENERAL_ERROR);
253 canvasParam_.alpha = alpha;
254
255 auto surfaceFrame = rsSurface_->RequestFrame(canvasParam_.frameWidth, canvasParam_.frameHeight);
256 IF_FALSE_LOGE_AND_RETURN_VAL(surfaceFrame != nullptr, ResultCode::GENERAL_ERROR);
257 auto skSurface = surfaceFrame->GetSurface();
258 IF_FALSE_LOGE_AND_RETURN_VAL(skSurface != nullptr, ResultCode::GENERAL_ERROR);
259
260 auto canvas = Common::MakeShared<RSPaintFilterCanvas>(skSurface.get());
261 IF_FALSE_LOGE_AND_RETURN_VAL(canvas != nullptr, ResultCode::GENERAL_ERROR);
262 auto drawCanvasResult = DrawCanvas(canvas, canvasParam_);
263 IF_FALSE_LOGE_AND_RETURN_VAL(drawCanvasResult == ResultCode::SUCCESS, ResultCode::GENERAL_ERROR);
264
265 rsSurface_->FlushFrame(surfaceFrame);
266 auto transactionPolicy = RSTransactionProxy::GetInstance();
267 transactionPolicy->FlushImplicitTransaction();
268
269 IAM_LOGI("success");
270 return ResultCode::SUCCESS;
271 }
272
TurnOnSensorIllumination()273 ResultCode SensorIlluminationTask::TurnOnSensorIllumination()
274 {
275 std::lock_guard<std::recursive_mutex> lock(recursiveMutex_);
276 IAM_LOGI("start");
277
278 IF_FALSE_LOGE_AND_RETURN_VAL(rsSurfaceNode_ != nullptr, ResultCode::GENERAL_ERROR);
279
280 if (ScreenStateMonitor::GetInstance().GetScreenOn() == false) {
281 IAM_LOGI("screen is not on, no need turn on display");
282 return ResultCode::SUCCESS;
283 }
284
285 if (isIlluminationOn_) {
286 IAM_LOGI("illumination already on");
287 return ResultCode::SUCCESS;
288 }
289
290 ResultCode drawResult = DrawSurfaceNode();
291 IF_FALSE_LOGE_AND_RETURN_VAL(drawResult == ResultCode::SUCCESS, ResultCode::GENERAL_ERROR);
292
293 timer_.Unregister(currTimerId_);
294 currTimerId_ = timer_.Register(
295 [weak_self = weak_from_this()]() {
296 auto self = weak_self.lock();
297 if (self == nullptr) {
298 IAM_LOGE("object is released");
299 return;
300 }
301 self->OnDisplayTimeOut();
302 },
303 MAX_DISPLAY_TIME, true);
304
305 IF_FALSE_LOGE_AND_RETURN_VAL(defaultScreenId_ != Rosen::INVALID_SCREEN_ID, ResultCode::GENERAL_ERROR);
306 rsSurfaceNode_->SetPositionZ(MAX_ZORDER);
307 rsSurfaceNode_->AttachToDisplay(defaultScreenId_);
308 OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
309
310 isIlluminationOn_ = true;
311
312 IAM_LOGI("success");
313 return ResultCode::SUCCESS;
314 }
315
TurnOffSensorIllumination()316 ResultCode SensorIlluminationTask::TurnOffSensorIllumination()
317 {
318 std::lock_guard<std::recursive_mutex> lock(recursiveMutex_);
319 IAM_LOGI("start");
320
321 IF_FALSE_LOGE_AND_RETURN_VAL(rsSurfaceNode_ != nullptr, ResultCode::GENERAL_ERROR);
322
323 if (!isIlluminationOn_) {
324 IAM_LOGI("illumination already off");
325 return ResultCode::SUCCESS;
326 }
327
328 timer_.Unregister(currTimerId_);
329
330 IF_FALSE_LOGE_AND_RETURN_VAL(defaultScreenId_ != Rosen::INVALID_SCREEN_ID, ResultCode::GENERAL_ERROR);
331 rsSurfaceNode_->DetachToDisplay(defaultScreenId_);
332 OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
333
334 isIlluminationOn_ = false;
335
336 IAM_LOGI("success");
337 return ResultCode::SUCCESS;
338 }
339
OnDisplayTimeOut()340 void SensorIlluminationTask::OnDisplayTimeOut()
341 {
342 IAM_LOGI("start");
343 TurnOffSensorIllumination();
344 }
345
RegisterDestructCallback(DestructCallback destructCallback)346 void SensorIlluminationTask::RegisterDestructCallback(DestructCallback destructCallback)
347 {
348 destructCallback_ = destructCallback;
349 }
350
GetSensorIlluminationTask()351 std::shared_ptr<ISensorIlluminationTask> GetSensorIlluminationTask()
352 {
353 return Common::MakeShared<SensorIlluminationTask>();
354 }
355 } // namespace FingerprintAuth
356 } // namespace UserIam
357 } // namespace OHOS