1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "InputFilterCallbacks"
18
19 #include "InputFilterCallbacks.h"
20 #include <aidl/com/android/server/inputflinger/BnInputThread.h>
21 #include <android/binder_auto_utils.h>
22 #include <utils/Looper.h>
23 #include <utils/StrongPointer.h>
24 #include <functional>
25 #include "InputThread.h"
26
27 namespace android {
28
29 using AidlKeyEvent = aidl::com::android::server::inputflinger::KeyEvent;
30
keyEventToNotifyKeyArgs(const AidlKeyEvent & event)31 NotifyKeyArgs keyEventToNotifyKeyArgs(const AidlKeyEvent& event) {
32 return NotifyKeyArgs(event.id, event.eventTime, event.readTime, event.deviceId,
33 static_cast<uint32_t>(event.source), ui::LogicalDisplayId{event.displayId},
34 event.policyFlags, static_cast<int32_t>(event.action), event.flags,
35 event.keyCode, event.scanCode, event.metaState, event.downTime);
36 }
37
38 namespace {
39
40 using namespace aidl::com::android::server::inputflinger;
41
42 class InputFilterThread : public BnInputThread {
43 public:
InputFilterThread(std::shared_ptr<IInputThreadCallback> callback)44 InputFilterThread(std::shared_ptr<IInputThreadCallback> callback) : mCallback(callback) {
45 mLooper = sp<Looper>::make(/*allowNonCallbacks=*/false);
46 mThread = std::make_unique<InputThread>(
47 "InputFilter", [this]() { loopOnce(); }, [this]() { mLooper->wake(); });
48 }
49
finish()50 ndk::ScopedAStatus finish() override {
51 if (mThread && mThread->isCallingThread()) {
52 ALOGE("InputFilterThread cannot be stopped on itself!");
53 return ndk::ScopedAStatus::fromStatus(INVALID_OPERATION);
54 }
55 mThread.reset();
56 return ndk::ScopedAStatus::ok();
57 }
58
sleepUntil(nsecs_t when)59 ndk::ScopedAStatus sleepUntil(nsecs_t when) override {
60 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
61 mLooper->pollOnce(toMillisecondTimeoutDelay(now, when));
62 return ndk::ScopedAStatus::ok();
63 }
64
wake()65 ndk::ScopedAStatus wake() override {
66 mLooper->wake();
67 return ndk::ScopedAStatus::ok();
68 }
69
70 private:
71 sp<Looper> mLooper;
72 std::unique_ptr<InputThread> mThread;
73 std::shared_ptr<IInputThreadCallback> mCallback;
74
loopOnce()75 void loopOnce() { LOG_ALWAYS_FATAL_IF(!mCallback->loopOnce().isOk()); }
76 };
77
78 } // namespace
79
InputFilterCallbacks(InputListenerInterface & listener,InputFilterPolicyInterface & policy)80 InputFilterCallbacks::InputFilterCallbacks(InputListenerInterface& listener,
81 InputFilterPolicyInterface& policy)
82 : mNextListener(listener), mPolicy(policy) {}
83
sendKeyEvent(const AidlKeyEvent & event)84 ndk::ScopedAStatus InputFilterCallbacks::sendKeyEvent(const AidlKeyEvent& event) {
85 mNextListener.notifyKey(keyEventToNotifyKeyArgs(event));
86 return ndk::ScopedAStatus::ok();
87 }
88
onModifierStateChanged(int32_t modifierState,int32_t lockedModifierState)89 ndk::ScopedAStatus InputFilterCallbacks::onModifierStateChanged(int32_t modifierState,
90 int32_t lockedModifierState) {
91 std::scoped_lock _l(mLock);
92 mStickyModifierState.modifierState = modifierState;
93 mStickyModifierState.lockedModifierState = lockedModifierState;
94 mPolicy.notifyStickyModifierStateChanged(modifierState, lockedModifierState);
95 ALOGI("Sticky keys modifier state changed: modifierState=%d, lockedModifierState=%d",
96 modifierState, lockedModifierState);
97 return ndk::ScopedAStatus::ok();
98 }
99
createInputFilterThread(const std::shared_ptr<IInputThreadCallback> & callback,std::shared_ptr<IInputThread> * aidl_return)100 ndk::ScopedAStatus InputFilterCallbacks::createInputFilterThread(
101 const std::shared_ptr<IInputThreadCallback>& callback,
102 std::shared_ptr<IInputThread>* aidl_return) {
103 *aidl_return = ndk::SharedRefBase::make<InputFilterThread>(callback);
104 return ndk::ScopedAStatus::ok();
105 }
106
getModifierState()107 uint32_t InputFilterCallbacks::getModifierState() {
108 std::scoped_lock _l(mLock);
109 return mStickyModifierState.modifierState;
110 }
111
getLockedModifierState()112 uint32_t InputFilterCallbacks::getLockedModifierState() {
113 std::scoped_lock _l(mLock);
114 return mStickyModifierState.lockedModifierState;
115 }
116
117 } // namespace android
118