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