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