• 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 #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