1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci#include "keys_input_device.h"
16fb299fa2Sopenharmony_ci
17fb299fa2Sopenharmony_ci#include <thread>
18fb299fa2Sopenharmony_ci#include "log/log.h"
19fb299fa2Sopenharmony_ci#include "updater_event.h"
20fb299fa2Sopenharmony_ci
21fb299fa2Sopenharmony_cinamespace Updater {
22fb299fa2Sopenharmony_cienum KeyUpDownEvent {
23fb299fa2Sopenharmony_ci    EVENT_KEY_UP_VALUE,
24fb299fa2Sopenharmony_ci    EVENT_KEY_DOWN_VALUE
25fb299fa2Sopenharmony_ci};
26fb299fa2Sopenharmony_ci
27fb299fa2Sopenharmony_ciKeysInputDevice &KeysInputDevice::GetInstance()
28fb299fa2Sopenharmony_ci{
29fb299fa2Sopenharmony_ci    static KeysInputDevice instance;
30fb299fa2Sopenharmony_ci    return instance;
31fb299fa2Sopenharmony_ci}
32fb299fa2Sopenharmony_ci
33fb299fa2Sopenharmony_cibool KeysInputDevice::Read(OHOS::DeviceData& data)
34fb299fa2Sopenharmony_ci{
35fb299fa2Sopenharmony_ci    data.keyId = lastKeyId_;
36fb299fa2Sopenharmony_ci    data.state = keyState_;
37fb299fa2Sopenharmony_ci    keyState_ = OHOS::INVALID_KEY_STATE;
38fb299fa2Sopenharmony_ci    return false;
39fb299fa2Sopenharmony_ci}
40fb299fa2Sopenharmony_ci
41fb299fa2Sopenharmony_civoid KeysInputDevice::OnLongKeyPressDown()
42fb299fa2Sopenharmony_ci{
43fb299fa2Sopenharmony_ci    static int downCount = 0;
44fb299fa2Sopenharmony_ci    ++downCount;
45fb299fa2Sopenharmony_ci    timerStop_ = false;
46fb299fa2Sopenharmony_ci    using namespace std::literals::chrono_literals;
47fb299fa2Sopenharmony_ci    std::thread t { [this, lastdownCount = downCount] () {
48fb299fa2Sopenharmony_ci        constexpr auto threshold = 2s;
49fb299fa2Sopenharmony_ci        std::this_thread::sleep_for(threshold);
50fb299fa2Sopenharmony_ci        // When the downCount of the last power key press changes,
51fb299fa2Sopenharmony_ci        // it means that the last press has been released before
52fb299fa2Sopenharmony_ci        // the timeout, then you can exit the callback directly
53fb299fa2Sopenharmony_ci        if (timerStop_ || lastdownCount != downCount) {
54fb299fa2Sopenharmony_ci            return;
55fb299fa2Sopenharmony_ci        }
56fb299fa2Sopenharmony_ci        UpdaterEvent::Invoke(UPDATER_POWER_VOLUME_DOWN_EVENT);
57fb299fa2Sopenharmony_ci    }};
58fb299fa2Sopenharmony_ci    t.detach();
59fb299fa2Sopenharmony_ci}
60fb299fa2Sopenharmony_ci
61fb299fa2Sopenharmony_civoid KeysInputDevice::OnLongKeyPressUp()
62fb299fa2Sopenharmony_ci{
63fb299fa2Sopenharmony_ci    // no need to judge whether in progress page,
64fb299fa2Sopenharmony_ci    // because may press power key in progress
65fb299fa2Sopenharmony_ci    // page and release power key in other page
66fb299fa2Sopenharmony_ci    timerStop_ = true;
67fb299fa2Sopenharmony_ci    UpdaterEvent::Invoke(UPDATER_POWER_VOLUME_UP_EVENT);
68fb299fa2Sopenharmony_ci}
69fb299fa2Sopenharmony_ci
70fb299fa2Sopenharmony_ci/*
71fb299fa2Sopenharmony_ci * LONG_PRESS_POWER_ONLY_TYPE : press power key to show long press warning
72fb299fa2Sopenharmony_ci * others : press power key and volume key to show long press warning
73fb299fa2Sopenharmony_ci */
74fb299fa2Sopenharmony_civoid KeysInputDevice::SetLongPressType(const std::string &type)
75fb299fa2Sopenharmony_ci{
76fb299fa2Sopenharmony_ci    type_ = type;
77fb299fa2Sopenharmony_ci}
78fb299fa2Sopenharmony_ci
79fb299fa2Sopenharmony_civoid KeysInputDevice::PowerDownPress(const input_event &ev)
80fb299fa2Sopenharmony_ci{
81fb299fa2Sopenharmony_ci    if (ev.code != KEY_POWER) {
82fb299fa2Sopenharmony_ci        return;
83fb299fa2Sopenharmony_ci    }
84fb299fa2Sopenharmony_ci    bool down = ev.value == EVENT_KEY_DOWN_VALUE;
85fb299fa2Sopenharmony_ci    LOG(INFO) << "power down " << ev.code;
86fb299fa2Sopenharmony_ci    if (down) {
87fb299fa2Sopenharmony_ci        OnLongKeyPressDown();
88fb299fa2Sopenharmony_ci    } else {
89fb299fa2Sopenharmony_ci        OnLongKeyPressUp();
90fb299fa2Sopenharmony_ci    }
91fb299fa2Sopenharmony_ci}
92fb299fa2Sopenharmony_ci
93fb299fa2Sopenharmony_civoid KeysInputDevice::PowerVolumeDownPress(const input_event &ev)
94fb299fa2Sopenharmony_ci{
95fb299fa2Sopenharmony_ci    static bool powerDown = false;
96fb299fa2Sopenharmony_ci    static bool volumeDown = false;
97fb299fa2Sopenharmony_ci    bool down = ev.value == EVENT_KEY_DOWN_VALUE;
98fb299fa2Sopenharmony_ci    if (ev.code == KEY_POWER) {
99fb299fa2Sopenharmony_ci        powerDown = down;
100fb299fa2Sopenharmony_ci    } else if (ev.code == KEY_VOLUMEDOWN) {
101fb299fa2Sopenharmony_ci        volumeDown = down;
102fb299fa2Sopenharmony_ci    }
103fb299fa2Sopenharmony_ci    if (powerDown && volumeDown) {
104fb299fa2Sopenharmony_ci        OnLongKeyPressDown();
105fb299fa2Sopenharmony_ci    } else if (!down && (ev.code == KEY_POWER || ev.code == KEY_VOLUMEDOWN)) {
106fb299fa2Sopenharmony_ci        OnLongKeyPressUp();
107fb299fa2Sopenharmony_ci    }
108fb299fa2Sopenharmony_ci}
109fb299fa2Sopenharmony_ci
110fb299fa2Sopenharmony_ciint KeysInputDevice::HandleKeyEvent(const input_event &ev, uint32_t type)
111fb299fa2Sopenharmony_ci{
112fb299fa2Sopenharmony_ci    if (ev.type != EV_KEY || ev.code > KEY_MAX) {
113fb299fa2Sopenharmony_ci        return 0;
114fb299fa2Sopenharmony_ci    }
115fb299fa2Sopenharmony_ci    if (ev.code == BTN_TOUCH || ev.code == BTN_TOOL_FINGER) {
116fb299fa2Sopenharmony_ci        return 0;
117fb299fa2Sopenharmony_ci    }
118fb299fa2Sopenharmony_ci    if (ev.code == BTN_MOUSE || ev.code == BTN_LEFT || ev.code == BTN_RIGHT || ev.code == BTN_MIDDLE) {
119fb299fa2Sopenharmony_ci        return 0;
120fb299fa2Sopenharmony_ci    }
121fb299fa2Sopenharmony_ci
122fb299fa2Sopenharmony_ci    // KEY_VOLUMEDOWN = 114, KEY_VOLUMEUP = 115, KEY_POWER = 116
123fb299fa2Sopenharmony_ci    if (ev.code == KEY_VOLUMEDOWN || ev.code == KEY_VOLUMEUP || ev.code == KEY_POWER) {
124fb299fa2Sopenharmony_ci        keyState_ = (ev.value == EVENT_KEY_DOWN_VALUE) ?
125fb299fa2Sopenharmony_ci            OHOS::InputDevice::STATE_PRESS : OHOS::InputDevice::STATE_RELEASE;
126fb299fa2Sopenharmony_ci    } else {
127fb299fa2Sopenharmony_ci        keyState_ = ev.value;
128fb299fa2Sopenharmony_ci    }
129fb299fa2Sopenharmony_ci
130fb299fa2Sopenharmony_ci    lastKeyId_ = ev.code;
131fb299fa2Sopenharmony_ci    if (type_ == LONG_PRESS_POWER_ONLY_TYPE) {
132fb299fa2Sopenharmony_ci        PowerDownPress(ev);
133fb299fa2Sopenharmony_ci    } else {
134fb299fa2Sopenharmony_ci        PowerVolumeDownPress(ev);
135fb299fa2Sopenharmony_ci    }
136fb299fa2Sopenharmony_ci    return 0;
137fb299fa2Sopenharmony_ci}
138fb299fa2Sopenharmony_ci} // namespace Updater
139