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 #include "keys_input_device.h"
16
17 #include <thread>
18 #include "log/log.h"
19 #include "updater_event.h"
20
21 namespace Updater {
22 enum KeyUpDownEvent {
23 EVENT_KEY_UP_VALUE,
24 EVENT_KEY_DOWN_VALUE
25 };
26
GetInstance()27 KeysInputDevice &KeysInputDevice::GetInstance()
28 {
29 static KeysInputDevice instance;
30 return instance;
31 }
32
Read(OHOS::DeviceData & data)33 bool KeysInputDevice::Read(OHOS::DeviceData& data)
34 {
35 data.keyId = lastKeyId_;
36 data.state = keyState_;
37 keyState_ = OHOS::INVALID_KEY_STATE;
38 return false;
39 }
40
OnLongKeyPressDown()41 void KeysInputDevice::OnLongKeyPressDown()
42 {
43 static int downCount = 0;
44 ++downCount;
45 timerStop_ = false;
46 using namespace std::literals::chrono_literals;
47 std::thread t { [this, lastdownCount = downCount] () {
48 constexpr auto threshold = 2s;
49 std::this_thread::sleep_for(threshold);
50 // When the downCount of the last power key press changes,
51 // it means that the last press has been released before
52 // the timeout, then you can exit the callback directly
53 if (timerStop_ || lastdownCount != downCount) {
54 return;
55 }
56 UpdaterEvent::Invoke(UPDATER_POWER_VOLUME_DOWN_EVENT);
57 }};
58 t.detach();
59 }
60
OnLongKeyPressUp()61 void KeysInputDevice::OnLongKeyPressUp()
62 {
63 // no need to judge whether in progress page,
64 // because may press power key in progress
65 // page and release power key in other page
66 timerStop_ = true;
67 UpdaterEvent::Invoke(UPDATER_POWER_VOLUME_UP_EVENT);
68 }
69
PowerVolumeDownPress(const input_event & ev)70 void KeysInputDevice::PowerVolumeDownPress(const input_event &ev)
71 {
72 static bool powerDown = false;
73 static bool volumeDown = false;
74 bool down = ev.value == EVENT_KEY_DOWN_VALUE;
75 if (ev.code == KEY_POWER) {
76 powerDown = down;
77 } else if (ev.code == KEY_VOLUMEDOWN) {
78 volumeDown = down;
79 }
80 if (powerDown && volumeDown) {
81 OnLongKeyPressDown();
82 } else if (!down && (ev.code == KEY_POWER || ev.code == KEY_VOLUMEDOWN)) {
83 OnLongKeyPressUp();
84 }
85 }
86
HandleKeyEvent(const input_event & ev,uint32_t type)87 int KeysInputDevice::HandleKeyEvent(const input_event &ev, uint32_t type)
88 {
89 if (ev.type != EV_KEY || ev.code > KEY_MAX) {
90 return 0;
91 }
92 if (ev.code == BTN_TOUCH || ev.code == BTN_TOOL_FINGER) {
93 return 0;
94 }
95 if (ev.code == BTN_MOUSE || ev.code == BTN_LEFT || ev.code == BTN_RIGHT || ev.code == BTN_MIDDLE) {
96 return 0;
97 }
98
99 // KEY_VOLUMEDOWN = 114, KEY_VOLUMEUP = 115, KEY_POWER = 116
100 if (ev.code == KEY_VOLUMEDOWN || ev.code == KEY_VOLUMEUP || ev.code == KEY_POWER) {
101 keyState_ = (ev.value == EVENT_KEY_DOWN_VALUE) ?
102 OHOS::InputDevice::STATE_PRESS : OHOS::InputDevice::STATE_RELEASE;
103 } else {
104 keyState_ = ev.value;
105 }
106
107 lastKeyId_ = ev.code;
108 PowerVolumeDownPress(ev);
109 return 0;
110 }
111 } // namespace Updater
112