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 if (name == FINGERPRINT_SOURCE_KEY) {
233 return AnalyseKeyEvent(event);
234 } else if (name == FINGERPRINT_SOURCE_POINT) {
235 ProcessSlideEvent();
236 return AnalysePointEvent(event);
237 } else {
238 MMI_HILOGI("Unknown input device name:%{public}s", name.c_str());
239 return PARAM_INPUT_INVALID;
240 }
241 }
242
AnalyseKeyEvent(struct libinput_event * event)243 int32_t FingerprintEventProcessor::AnalyseKeyEvent(struct libinput_event *event)
244 {
245 CALL_DEBUG_ENTER;
246 CHKPR(event, ERROR_NULL_POINTER);
247 struct libinput_event_keyboard* keyEvent = libinput_event_get_keyboard_event(event);
248 CHKPR(keyEvent, ERROR_NULL_POINTER);
249 auto key = libinput_event_keyboard_get_key(keyEvent);
250 enum libinput_key_state state = libinput_event_keyboard_get_key_state(keyEvent);
251 if (state == LIBINPUT_KEY_STATE_PRESSED) {
252 MMI_HILOGI("Dont analyse the press status for %{public}d", key);
253 return ERR_OK;
254 }
255 auto pointerEvent = PointerEvent::Create();
256 CHKPR(pointerEvent, ERROR_NULL_POINTER);
257 isStartedSmartKeyBySlide_ = false;
258 switch (key) {
259 case FINGERPRINT_CODE_DOWN: {
260 fingerprintFlag_ = true;
261 cancelState_ = false;
262 ChangeScreenMissTouchFlag(screenState_, true);
263 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_DOWN);
264 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
265 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
266 break;
267 }
268 case FINGERPRINT_CODE_CANCEL: {
269 cancelState_ = true;
270 ChangeScreenMissTouchFlag(screenState_, cancelState_);
271 MMI_HILOGI("change cancel state and dont send point event");
272 return RET_OK;
273 }
274 case FINGERPRINT_CODE_UP: {
275 fingerprintFlag_ = false;
276 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_UP);
277 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
278 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_UP);
279 break;
280 }
281 case FINGERPRINT_CODE_RETOUCH: {
282 fingerprintFlag_ = false;
283 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_RETOUCH);
284 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
285 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
286 break;
287 }
288 case FINGERPRINT_CODE_CLICK: {
289 fingerprintFlag_ = false;
290 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_CLICK);
291 ProcessClickEvent();
292 break;
293 }
294 default:
295 MMI_HILOGW("Unknown key event:%{public}d", key);
296 return UNKNOWN_EVENT;
297 }
298 int64_t time = GetSysClockTime();
299 pointerEvent->SetActionTime(time);
300 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_FINGERPRINT);
301 pointerEvent->SetPointerId(0);
302 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
303 MMI_HILOGI("Fingerprint key:%{public}d", pointerEvent->GetPointerAction());
304 if (CheckMisTouchState()) {
305 MMI_HILOGD("in mistouch state, dont report event");
306 return ERR_OK;
307 }
308 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
309 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
310 if (eventMonitorHandler_ != nullptr) {
311 eventMonitorHandler_->OnHandleEvent(pointerEvent);
312 }
313 #endif // (OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH) && OHOS_BUILD_ENABLE_MONITOR
314 return RET_OK;
315 }
316
AnalysePointEvent(libinput_event * event)317 int32_t FingerprintEventProcessor::AnalysePointEvent(libinput_event * event)
318 {
319 CALL_DEBUG_ENTER;
320 struct libinput_event_pointer* rawPointerEvent = libinput_event_get_pointer_event(event);
321 CHKPR(rawPointerEvent, ERROR_NULL_POINTER);
322 double ux = libinput_event_pointer_get_dx_unaccelerated(rawPointerEvent);
323 double uy = libinput_event_pointer_get_dy_unaccelerated(rawPointerEvent);
324 auto pointerEvent = PointerEvent::Create();
325 CHKPR(pointerEvent, ERROR_NULL_POINTER);
326 int64_t time = GetSysClockTime();
327 pointerEvent->SetActionTime(time);
328 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_FINGERPRINT_SLIDE);
329 pointerEvent->SetFingerprintDistanceX(ux);
330 pointerEvent->SetFingerprintDistanceY(uy);
331 pointerEvent->SetSourceType(PointerEvent::SOURCE_TYPE_FINGERPRINT);
332 pointerEvent->SetPointerId(0);
333 EventLogHelper::PrintEventData(pointerEvent, MMI_LOG_HEADER);
334 MMI_HILOGI("Fingerprint key:%{public}d, ux:%f, uy:%f", pointerEvent->GetPointerAction(), ux, uy);
335 if (CheckMisTouchState()) {
336 MMI_HILOGD("in mistouch state, dont report event");
337 return ERR_OK;
338 }
339 #if (defined(OHOS_BUILD_ENABLE_POINTER) || defined(OHOS_BUILD_ENABLE_TOUCH)) && defined(OHOS_BUILD_ENABLE_MONITOR)
340 auto eventMonitorHandler_ = InputHandler->GetMonitorHandler();
341 if (eventMonitorHandler_ != nullptr) {
342 eventMonitorHandler_->OnHandleEvent(pointerEvent);
343 }
344 #endif // (OHOS_BUILD_ENABLE_POINTER || OHOS_BUILD_ENABLE_TOUCH) && OHOS_BUILD_ENABLE_MONITOR
345 return RET_OK;
346 }
347
348 template <class T>
CreateStatusConfigObserver(T & item)349 void FingerprintEventProcessor::CreateStatusConfigObserver(T& item)
350 {
351 CALL_DEBUG_ENTER;
352 SettingObserver::UpdateFunc updateFunc = [&item](const std::string& key) {
353 std::string value = NEED_SHOW_DIALOG;
354 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
355 .GetStringValue(key, value);
356 if (ret != RET_OK) {
357 MMI_HILOGE("Get value from settings db failed, ret: %{public}d", ret);
358 return;
359 }
360 MMI_HILOGI("Config changed, key: %{public}s, value: %{public}s", key.c_str(), value.c_str());
361 item.valueString = value;
362 };
363
364 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
365 .CreateObserver(item.keyString, updateFunc);
366 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
367 if (ret != RET_OK) {
368 MMI_HILOGE("Register setting observer failed, ret: %{public}d", ret);
369 statusObserver = nullptr;
370 }
371
372 std::string value = NEED_SHOW_DIALOG;
373 ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
374 .SettingDataShare::GetStringValue(item.keyString, value);
375 if (ret != RET_OK) {
376 MMI_HILOGE("Get value from settings db failed, ret: %{public}d", ret);
377 return;
378 }
379 MMI_HILOGI("Get value success, key: %{public}s, value: %{public}s", item.keyString.c_str(), value.c_str());
380 item.valueString = value;
381 }
382
StartSmartKeyIfNeeded()383 void FingerprintEventProcessor::StartSmartKeyIfNeeded()
384 {
385 std::string isStartSmartKey = SMART_KEY_IS_CLOSE;
386 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
387 .SettingDataShare::GetStringValue(IS_SMART_KEY_USE, isStartSmartKey);
388 if (ret != RET_OK) {
389 MMI_HILOGE("Get value from settings db failed, ret: %{public}d", ret);
390 return;
391 }
392 if (isStartSmartKey == SMART_KEY_IS_OPEN) {
393 MMI_HILOGI("Before start smart-key");
394 StartSmartKey(false);
395 }
396 }
397
StartSmartKey(bool isShowDialog)398 void FingerprintEventProcessor::StartSmartKey(bool isShowDialog)
399 {
400 ffrt::submit([isShowDialog] {
401 MMI_HILOGI("StartServiceExtAbility start");
402 std::shared_ptr<AAFwk::AbilityManagerClient> abmc = AAFwk::AbilityManagerClient::GetInstance();
403 CHKPV(abmc);
404 const std::string smartKeyBundleName = "com.hmos.hwquickaccessmenu";
405 const std::string smartKeyAbilityName = "ServiceAbility";
406 AAFwk::Want want;
407 want.SetElementName(smartKeyBundleName, smartKeyAbilityName);
408 if (isShowDialog) {
409 want.SetParam("isShowDialog", IS_SHOW_DIALOG);
410 }
411
412 auto ret = abmc->StartExtensionAbility(want, nullptr, -1, AppExecFwk::ExtensionAbilityType::SERVICE);
413 if (ret != RET_OK) {
414 MMI_HILOGE("StartExtensionAbility failed, ret: %{public}d", ret);
415 return;
416 }
417 MMI_HILOGI("StartServiceExtAbility finished");
418 });
419 }
420
ProcessSlideEvent()421 void FingerprintEventProcessor::ProcessSlideEvent()
422 {
423 if ((smartKeySwitch_.valueString == NEED_SHOW_DIALOG || smartKeySwitch_.valueString.empty()) &&
424 !isStartedSmartKeyBySlide_) {
425 isStartedSmartKeyBySlide_ = true;
426 StartSmartKey(true);
427 }
428 }
429
ProcessClickEvent()430 void FingerprintEventProcessor::ProcessClickEvent()
431 {
432 if (smartKeySwitch_.valueString == NEED_SHOW_DIALOG || smartKeySwitch_.valueString.empty()) {
433 StartSmartKey(true);
434 }
435 ReportResSched(ResourceSchedule::ResType::RES_TYPE_CLICK_RECOGNIZE,
436 ResourceSchedule::ResType::ClickEventType::TOUCH_EVENT_DOWN);
437 }
438
ReportResSched(uint32_t resType,int64_t value)439 void FingerprintEventProcessor::ReportResSched(uint32_t resType, int64_t value)
440 {
441 std::unordered_map<std::string, std::string> payload { {"msg", ""} };
442 ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, value, payload);
443 }
444 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
445 } // namespace MMI
446 } // namespace OHOS
447