1 /*
2 * Copyright (c) 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
16 #include "fingerprint_event_processor.h"
17
18 #include "ability_manager_client.h"
19 #include "dfx_hisysevent.h"
20 #include "event_log_helper.h"
21 #include "ffrt.h"
22 #include "input_event_handler.h"
23 #include "pointer_event.h"
24 #include "res_sched_client.h"
25 #include "res_type.h"
26 #include "setting_datashare.h"
27 #include "system_ability_definition.h"
28
29 #undef MMI_LOG_DOMAIN
30 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
31 #undef MMI_LOG_TAG
32 #define MMI_LOG_TAG "FingerprintEventProcessor"
33
34 namespace OHOS {
35 namespace MMI {
36 #ifdef OHOS_BUILD_ENABLE_FINGERPRINT
37 namespace {
38 constexpr int32_t MUTE_KEY_INIT { 0 };
39 constexpr int32_t MUTE_KEY_DOWN { 1 };
40 constexpr int32_t MUTE_KEY_UP { 2 };
41 constexpr int32_t POWER_KEY_UP_TIME { 1000 }; // 1000ms
42 constexpr int32_t VOLUME_KEY_UP_TIME { 500 }; // 500ms
43 const char* IS_START_SMART_KEY = "close_fingerprint_nav_event_key";
44 const char* IS_SMART_KEY_USE = "close_fingerprint_event_key";
45 const char* NEED_SHOW_DIALOG = "1";
46 const char* SMART_KEY_IS_OPEN = "1";
47 const char* SMART_KEY_IS_CLOSE = "0";
48 constexpr int32_t IS_SHOW_DIALOG = 1;
49 }
FingerprintEventProcessor()50 FingerprintEventProcessor::FingerprintEventProcessor()
51 {}
52
~FingerprintEventProcessor()53 FingerprintEventProcessor::~FingerprintEventProcessor()
54 {}
55
IsFingerprintEvent(struct libinput_event * event)56 bool FingerprintEventProcessor::IsFingerprintEvent(struct libinput_event* event)
57 {
58 CALL_DEBUG_ENTER;
59 CHKPR(event, false);
60 if (!isStartedSmartKey_) {
61 StartSmartKeyIfNeeded();
62 isStartedSmartKey_ = true;
63 }
64 if (!isCreatedObserver_) {
65 smartKeySwitch_.keyString = IS_START_SMART_KEY;
66 CreateStatusConfigObserver(smartKeySwitch_);
67 isCreatedObserver_ = true;
68 }
69 auto device = libinput_event_get_device(event);
70 CHKPR(device, false);
71 std::string name = libinput_device_get_name(device);
72 if (name != FINGERPRINT_SOURCE_KEY && name != FINGERPRINT_SOURCE_POINT) {
73 MMI_HILOGD("Not FingerprintEvent");
74 return false;
75 }
76 if (name == FINGERPRINT_SOURCE_KEY) {
77 struct libinput_event_keyboard* keyBoard = libinput_event_get_keyboard_event(event);
78 CHKPR(keyBoard, false);
79 auto key = libinput_event_keyboard_get_key(keyBoard);
80 if (key != FINGERPRINT_CODE_DOWN && key != FINGERPRINT_CODE_UP
81 && key != FINGERPRINT_CODE_CLICK && key != FINGERPRINT_CODE_RETOUCH
82 && key != FINGERPRINT_CODE_CANCEL
83 ) {
84 MMI_HILOGD("Not FingerprintEvent event");
85 return false;
86 }
87 }
88 return true;
89 }
90
SetPowerAndVolumeKeyState(struct libinput_event * event)91 void FingerprintEventProcessor::SetPowerAndVolumeKeyState(struct libinput_event* event)
92 {
93 CALL_DEBUG_ENTER;
94 CHKPV(event);
95 auto device = libinput_event_get_device(event);
96 CHKPV(device);
97 auto data = libinput_event_get_keyboard_event(event);
98 CHKPV(data);
99 int32_t keyCode = static_cast<int32_t>(libinput_event_keyboard_get_key(data));
100 auto iter = keyStateMap_.find(keyCode);
101 if (iter == keyStateMap_.end()) {
102 MMI_HILOGD("current keycode is not mistouch key, keycode is %{private}d", keyCode);
103 return;
104 }
105 int32_t keyAction = (libinput_event_keyboard_get_key_state(data) == 0) ?
106 (KeyEvent::KEY_ACTION_UP) : (KeyEvent::KEY_ACTION_DOWN);
107 MMI_HILOGD("current keycode is %{private}d, keyaction is %{private}d", keyCode, keyAction);
108 if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
109 iter->second.first = MUTE_KEY_DOWN;
110 SendFingerprintCancelEvent();
111 } else {
112 iter->second.first = MUTE_KEY_UP;
113 iter->second.second = std::chrono::steady_clock::now();
114 }
115 }
116
SetScreenState(struct libinput_event * event)117 void FingerprintEventProcessor::SetScreenState(struct libinput_event* event)
118 {
119 CALL_DEBUG_ENTER;
120 CHKPV(event);
121 auto type = libinput_event_get_type(event);
122 MMI_HILOGD("smart key screen state is %{public}d", type);
123 switch (type) {
124 case LIBINPUT_EVENT_TOUCH_DOWN: {
125 screenState_ = true;
126 break;
127 }
128 case LIBINPUT_EVENT_TOUCH_UP: {
129 screenState_ = false;
130 break;
131 }
132 default: {
133 MMI_HILOGD("Unknown event type, touchType:%{public}d", type);
134 return;
135 }
136 }
137 ChangeScreenMissTouchFlag(screenState_, cancelState_);
138 }
139
140
141 /*
142 * This is a poorly designed state machine for handling screen touch errors, SAD :(
143 */
ChangeScreenMissTouchFlag(bool screen,bool cancel)144 void FingerprintEventProcessor::ChangeScreenMissTouchFlag(bool screen, bool cancel)
145 {
146 int32_t flag = screenMissTouchFlag_ ? 1 : 0;
147 MMI_HILOGD("screenMissTouchFlag_ :%{private}d, screen:%{private}d, cancel:%{private}d", flag, screen, screen);
148 if (screenMissTouchFlag_ == false) {
149 if (screen == true) {
150 screenMissTouchFlag_ = true;
151 if (!fingerprintFlag_) {
152 return;
153 }
154 SendFingerprintCancelEvent();
155 return;
156 }
157 } else {
158 if (screen == false && cancel == true) {
159 screenMissTouchFlag_ = false;
160 return;
161 }
162 }
163 }
164
CheckMisTouchState()165 bool FingerprintEventProcessor::CheckMisTouchState()
166 {
167 if (CheckKeyMisTouchState() || CheckScreenMisTouchState()) {
168 return true;
169 }
170 return false;
171 }
172
CheckScreenMisTouchState()173 bool FingerprintEventProcessor::CheckScreenMisTouchState()
174 {
175 int32_t flag = screenMissTouchFlag_ ? 1 : 0;
176 MMI_HILOGI("The screenMissTouchFlag_ is %{public}d", flag);
177 return screenMissTouchFlag_;
178 }
179
CheckKeyMisTouchState()180 bool FingerprintEventProcessor::CheckKeyMisTouchState()
181 {
182 CALL_DEBUG_ENTER;
183 bool ret = false;
184 for (auto &[key, value] : keyStateMap_) {
185 auto keystate = value.first;
186 MMI_HILOGD("keycode:%{private}d, state:%{public}d", key, value.first);
187 if (keystate == MUTE_KEY_DOWN) {
188 ret = true;
189 } else if (keystate == MUTE_KEY_UP) {
190 auto currentTime = std::chrono::steady_clock::now();
191 auto duration = currentTime - value.second;
192 auto durationMs = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
193 int32_t time = POWER_KEY_UP_TIME;
194 if (key != KEY_POWER) {
195 time = VOLUME_KEY_UP_TIME;
196 }
197 if (durationMs < time) {
198 MMI_HILOGD("Dont report because time diff < threshold, keycode:%{private}d, state:%{public}d",
199 key, value.first);
200 ret = true;
201 } else {
202 value.first = MUTE_KEY_INIT;
203 }
204 }
205 }
206 MMI_HILOGI("KeyMisTouchState is %{public}d", ret);
207 return ret;
208 }
209
SendFingerprintCancelEvent()210 int32_t FingerprintEventProcessor::SendFingerprintCancelEvent()
211 {
212 CALL_DEBUG_ENTER;
213 auto pointerEvent = PointerEvent::Create();
214 CHKPR(pointerEvent, ERROR_NULL_POINTER);
215 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL);
216 int64_t time = GetSysClockTime();
217 pointerEvent->SetActionTime(time);
218 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_FINGERPRINT);
219 pointerEvent->SetPointerId(0);
220 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
221 MMI_HILOGD("Fingerprint key:%{public}d", pointerEvent->GetPointerAction());
222 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
223 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
224 if (eventMonitorHandler_ != nullptr) {
225 eventMonitorHandler_->OnHandleEvent(pointerEvent);
226 }
227 #endif
228 return ERR_OK;
229 }
230
HandleFingerprintEvent(struct libinput_event * event)231 int32_t FingerprintEventProcessor::HandleFingerprintEvent(struct libinput_event* event)
232 {
233 CALL_DEBUG_ENTER;
234 CHKPR(event, ERROR_NULL_POINTER);
235 auto device = libinput_event_get_device(event);
236 CHKPR(device, PARAM_INPUT_INVALID);
237 std::string name = libinput_device_get_name(device);
238 size_t pos = name.find("hand_status_dev");
239 if (name == FINGERPRINT_SOURCE_KEY) {
240 return AnalyseKeyEvent(event);
241 } else if (name == FINGERPRINT_SOURCE_POINT) {
242 ProcessSlideEvent();
243 return AnalysePointEvent(event);
244 } else if (pos != std::string::npos) { // 设备名称包含hand_status_dev的即为合法设备
245 return AnalyseMsdpPointEvent(event);
246 } else {
247 MMI_HILOGI("Unknown input device name:%{public}s", name.c_str());
248 return PARAM_INPUT_INVALID;
249 }
250 }
251
AnalyseKeyEvent(struct libinput_event * event)252 int32_t FingerprintEventProcessor::AnalyseKeyEvent(struct libinput_event *event)
253 {
254 CALL_DEBUG_ENTER;
255 CHKPR(event, ERROR_NULL_POINTER);
256 struct libinput_event_keyboard* keyEvent = libinput_event_get_keyboard_event(event);
257 CHKPR(keyEvent, ERROR_NULL_POINTER);
258 auto key = libinput_event_keyboard_get_key(keyEvent);
259 enum libinput_key_state state = libinput_event_keyboard_get_key_state(keyEvent);
260 if (state == LIBINPUT_KEY_STATE_PRESSED) {
261 MMI_HILOGI("Dont analyse the press status for %{public}d", key);
262 return ERR_OK;
263 }
264 auto pointerEvent = PointerEvent::Create();
265 CHKPR(pointerEvent, ERROR_NULL_POINTER);
266 isStartedSmartKeyBySlide_ = false;
267 switch (key) {
268 case FINGERPRINT_CODE_DOWN: {
269 fingerprintFlag_ = true;
270 cancelState_ = false;
271 ChangeScreenMissTouchFlag(screenState_, true);
272 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_DOWN);
273 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
274 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
275 break;
276 }
277 case FINGERPRINT_CODE_CANCEL: {
278 cancelState_ = true;
279 ChangeScreenMissTouchFlag(screenState_, cancelState_);
280 MMI_HILOGI("Change cancel state and dont send point event");
281 return RET_OK;
282 }
283 case FINGERPRINT_CODE_UP: {
284 fingerprintFlag_ = false;
285 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_UP);
286 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
287 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_UP);
288 break;
289 }
290 case FINGERPRINT_CODE_RETOUCH: {
291 fingerprintFlag_ = true;
292 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_RETOUCH);
293 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
294 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
295 break;
296 }
297 case FINGERPRINT_CODE_CLICK: {
298 fingerprintFlag_ = false;
299 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_CLICK);
300 ProcessClickEvent();
301 break;
302 }
303 default:
304 MMI_HILOGW("Unknown key event:%{public}d", key);
305 return UNKNOWN_EVENT;
306 }
307 int64_t time = GetSysClockTime();
308 pointerEvent->SetActionTime(time);
309 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_FINGERPRINT);
310 pointerEvent->SetPointerId(0);
311 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
312 MMI_HILOGI("Fingerprint key:%{public}d", pointerEvent->GetPointerAction());
313 if (CheckMisTouchState()) {
314 MMI_HILOGD("In mistouch state, dont report event");
315 return ERR_OK;
316 }
317 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
318 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
319 if (eventMonitorHandler_ != nullptr) {
320 eventMonitorHandler_->OnHandleEvent(pointerEvent);
321 }
322 #endif // (OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH) && OHOS_BUILD_ENABLE_MONITOR
323 return RET_OK;
324 }
325
AnalysePointEvent(libinput_event * event)326 int32_t FingerprintEventProcessor::AnalysePointEvent(libinput_event * event)
327 {
328 CALL_DEBUG_ENTER;
329 struct libinput_event_pointer* rawPointerEvent = libinput_event_get_pointer_event(event);
330 CHKPR(rawPointerEvent, ERROR_NULL_POINTER);
331 double ux = libinput_event_pointer_get_dx_unaccelerated(rawPointerEvent);
332 double uy = libinput_event_pointer_get_dy_unaccelerated(rawPointerEvent);
333 auto pointerEvent = PointerEvent::Create();
334 CHKPR(pointerEvent, ERROR_NULL_POINTER);
335 int64_t time = GetSysClockTime();
336 pointerEvent->SetActionTime(time);
337 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_SLIDE);
338 pointerEvent->SetFingerprintDistanceX(ux);
339 pointerEvent->SetFingerprintDistanceY(uy);
340 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_FINGERPRINT);
341 pointerEvent->SetPointerId(0);
342 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
343 MMI_HILOGI("Fingerprint key:%{public}d, ux:%f, uy:%f", pointerEvent->GetPointerAction(), ux, uy);
344 if (CheckMisTouchState()) {
345 MMI_HILOGD("In mistouch state, dont report event");
346 return ERR_OK;
347 }
348 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
349 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
350 if (eventMonitorHandler_ != nullptr) {
351 eventMonitorHandler_->OnHandleEvent(pointerEvent);
352 }
353 #endif // (OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH) && OHOS_BUILD_ENABLE_MONITOR
354 return RET_OK;
355 }
356
AnalyseMsdpPointEvent(libinput_event * event)357 int32_t FingerprintEventProcessor::AnalyseMsdpPointEvent(libinput_event * event)
358 {
359 CALL_DEBUG_ENTER;
360 int32_t value = libinput_event_get_hand_feature(event);
361 auto pointerEvent = PointerEvent::Create();
362 CHKPR(pointerEvent, ERROR_NULL_POINTER);
363 pointerEvent->SetHandOption(value);
364 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_MSDP_HAND_OPTINON);
365 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
366
367 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
368 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
369 if (eventMonitorHandler_ != nullptr) {
370 eventMonitorHandler_->OnHandleEvent(pointerEvent);
371 }
372 #endif // (OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH) && OHOS_BUILD_ENABLE_MONITOR
373 return RET_OK;
374 }
375
376 template <class T>
CreateStatusConfigObserver(T & item)377 void FingerprintEventProcessor::CreateStatusConfigObserver(T& item)
378 {
379 CALL_DEBUG_ENTER;
380 SettingObserver::UpdateFunc updateFunc = [&item](const std::string& key) {
381 std::string value = NEED_SHOW_DIALOG;
382 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
383 .GetStringValue(key, value);
384 if (ret != RET_OK) {
385 MMI_HILOGE("Get value from settings db failed, ret:%{public}d", ret);
386 return;
387 }
388 MMI_HILOGI("Config changed, key:%{public}s, value:%{public}s", key.c_str(), value.c_str());
389 item.valueString = value;
390 };
391
392 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
393 .CreateObserver(item.keyString, updateFunc);
394 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
395 if (ret != RET_OK) {
396 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
397 statusObserver = nullptr;
398 }
399
400 std::string value = NEED_SHOW_DIALOG;
401 ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
402 .SettingDataShare::GetStringValue(item.keyString, value);
403 if (ret != RET_OK) {
404 MMI_HILOGE("Get value from settings db failed, ret:%{public}d", ret);
405 return;
406 }
407 MMI_HILOGI("Get value success, key:%{public}s, value:%{public}s", item.keyString.c_str(), value.c_str());
408 item.valueString = value;
409 }
410
StartSmartKeyIfNeeded()411 void FingerprintEventProcessor::StartSmartKeyIfNeeded()
412 {
413 std::string isStartSmartKey = SMART_KEY_IS_CLOSE;
414 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
415 .SettingDataShare::GetStringValue(IS_SMART_KEY_USE, isStartSmartKey);
416 if (ret != RET_OK) {
417 MMI_HILOGE("Get value from settings db failed, ret:%{public}d", ret);
418 return;
419 }
420 if (isStartSmartKey == SMART_KEY_IS_OPEN) {
421 MMI_HILOGI("Before start smart-key");
422 StartSmartKey(false);
423 }
424 }
425
StartSmartKey(bool isShowDialog)426 void FingerprintEventProcessor::StartSmartKey(bool isShowDialog)
427 {
428 ffrt::submit([isShowDialog] {
429 MMI_HILOGI("StartServiceExtAbility start");
430 std::shared_ptr<AAFwk::AbilityManagerClient> abmc = AAFwk::AbilityManagerClient::GetInstance();
431 CHKPF(abmc);
432 const std::string smartKeyBundleName = "";
433 const std::string smartKeyAbilityName = "";
434 AAFwk::Want want;
435 want.SetElementName(smartKeyBundleName, smartKeyAbilityName);
436 if (isShowDialog) {
437 want.SetParam("isShowDialog", IS_SHOW_DIALOG);
438 }
439 auto begin = std::chrono::high_resolution_clock::now();
440 auto ret = abmc->StartExtensionAbility(want, nullptr, -1, AppExecFwk::ExtensionAbilityType::SERVICE);
441 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
442 std::chrono::high_resolution_clock::now() - begin).count();
443 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
444 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::ABILITY_MGR_START_EXT_ABILITY, durationMS);
445 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
446 if (ret != RET_OK) {
447 MMI_HILOGE("StartExtensionAbility failed, ret:%{public}d", ret);
448 return false;
449 }
450 MMI_HILOGI("StartServiceExtAbility finished");
451 return true;
452 });
453 return;
454 }
455
ProcessSlideEvent()456 void FingerprintEventProcessor::ProcessSlideEvent()
457 {
458 if ((smartKeySwitch_.valueString == NEED_SHOW_DIALOG || smartKeySwitch_.valueString.empty()) &&
459 !isStartedSmartKeyBySlide_) {
460 isStartedSmartKeyBySlide_ = true;
461 StartSmartKey(true);
462 }
463 }
464
ProcessClickEvent()465 void FingerprintEventProcessor::ProcessClickEvent()
466 {
467 if (smartKeySwitch_.valueString == NEED_SHOW_DIALOG || smartKeySwitch_.valueString.empty()) {
468 StartSmartKey(true);
469 }
470 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
471 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
472 }
473
ReportResSched(uint32_t resType,int64_t value)474 void FingerprintEventProcessor::ReportResSched(uint32_t resType, int64_t value)
475 {
476 std::unordered_map<std::string, std::string> payload { {"msg", ""} };
477 auto begin = std::chrono::high_resolution_clock::now();
478 ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, value, payload);
479 auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
480 std::chrono::high_resolution_clock::now() - begin).count();
481 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
482 DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::RESOURCE_SCHEDULE_REPORT_DATA, durationMS);
483 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
484 }
485 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
486 } // namespace MMI
487 } // namespace OHOS
488