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 "InputFilter"
18
19 #include "InputFilter.h"
20
21 namespace android {
22
23 using aidl::com::android::server::inputflinger::IInputFilter;
24 using AidlKeyEvent = aidl::com::android::server::inputflinger::KeyEvent;
25 using aidl::com::android::server::inputflinger::KeyEventAction;
26 using AidlDeviceInfo = aidl::com::android::server::inputflinger::DeviceInfo;
27 using aidl::android::hardware::input::common::Source;
28
notifyKeyArgsToKeyEvent(const NotifyKeyArgs & args)29 AidlKeyEvent notifyKeyArgsToKeyEvent(const NotifyKeyArgs& args) {
30 AidlKeyEvent event;
31 event.id = args.id;
32 event.eventTime = args.eventTime;
33 event.deviceId = args.deviceId;
34 event.source = static_cast<Source>(args.source);
35 event.displayId = args.displayId.val();
36 event.policyFlags = args.policyFlags;
37 event.action = static_cast<KeyEventAction>(args.action);
38 event.flags = args.flags;
39 event.keyCode = args.keyCode;
40 event.scanCode = args.scanCode;
41 event.metaState = args.metaState;
42 event.downTime = args.downTime;
43 event.readTime = args.readTime;
44 return event;
45 }
46
InputFilter(InputListenerInterface & listener,IInputFlingerRust & rust,InputFilterPolicyInterface & policy)47 InputFilter::InputFilter(InputListenerInterface& listener, IInputFlingerRust& rust,
48 InputFilterPolicyInterface& policy)
49 : mNextListener(listener),
50 mCallbacks(ndk::SharedRefBase::make<InputFilterCallbacks>(listener, policy)),
51 mPolicy(policy) {
52 LOG_ALWAYS_FATAL_IF(!rust.createInputFilter(mCallbacks, &mInputFilterRust).isOk());
53 LOG_ALWAYS_FATAL_IF(!mInputFilterRust);
54 }
55
notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs & args)56 void InputFilter::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
57 mDeviceInfos.clear();
58 mDeviceInfos.reserve(args.inputDeviceInfos.size());
59 for (auto info : args.inputDeviceInfos) {
60 AidlDeviceInfo& aidlInfo = mDeviceInfos.emplace_back();
61 aidlInfo.deviceId = info.getId();
62 aidlInfo.external = info.isExternal();
63 aidlInfo.keyboardType = info.getKeyboardType();
64 }
65 if (isFilterEnabled()) {
66 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyInputDevicesChanged(mDeviceInfos).isOk());
67 }
68 mNextListener.notify(args);
69 }
70
notifyKey(const NotifyKeyArgs & args)71 void InputFilter::notifyKey(const NotifyKeyArgs& args) {
72 if (isFilterEnabled()) {
73 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyKey(notifyKeyArgsToKeyEvent(args)).isOk());
74 return;
75 }
76 mNextListener.notify(args);
77 }
78
notifyMotion(const NotifyMotionArgs & args)79 void InputFilter::notifyMotion(const NotifyMotionArgs& args) {
80 mNextListener.notify(args);
81 }
82
notifySwitch(const NotifySwitchArgs & args)83 void InputFilter::notifySwitch(const NotifySwitchArgs& args) {
84 mNextListener.notify(args);
85 }
86
notifySensor(const NotifySensorArgs & args)87 void InputFilter::notifySensor(const NotifySensorArgs& args) {
88 mNextListener.notify(args);
89 }
90
notifyVibratorState(const NotifyVibratorStateArgs & args)91 void InputFilter::notifyVibratorState(const NotifyVibratorStateArgs& args) {
92 mNextListener.notify(args);
93 }
94
notifyDeviceReset(const NotifyDeviceResetArgs & args)95 void InputFilter::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
96 mNextListener.notify(args);
97 }
98
notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs & args)99 void InputFilter::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
100 mNextListener.notify(args);
101 }
102
isFilterEnabled()103 bool InputFilter::isFilterEnabled() {
104 bool result;
105 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->isEnabled(&result).isOk());
106 return result;
107 }
108
setAccessibilityBounceKeysThreshold(nsecs_t threshold)109 void InputFilter::setAccessibilityBounceKeysThreshold(nsecs_t threshold) {
110 std::scoped_lock _l(mLock);
111
112 if (mConfig.bounceKeysThresholdNs != threshold) {
113 mConfig.bounceKeysThresholdNs = threshold;
114 notifyConfigurationChangedLocked();
115 }
116 }
117
setAccessibilitySlowKeysThreshold(nsecs_t threshold)118 void InputFilter::setAccessibilitySlowKeysThreshold(nsecs_t threshold) {
119 std::scoped_lock _l(mLock);
120
121 if (mConfig.slowKeysThresholdNs != threshold) {
122 mConfig.slowKeysThresholdNs = threshold;
123 notifyConfigurationChangedLocked();
124 }
125 }
126
setAccessibilityStickyKeysEnabled(bool enabled)127 void InputFilter::setAccessibilityStickyKeysEnabled(bool enabled) {
128 std::scoped_lock _l(mLock);
129
130 if (mConfig.stickyKeysEnabled != enabled) {
131 mConfig.stickyKeysEnabled = enabled;
132 notifyConfigurationChangedLocked();
133 if (!enabled) {
134 // When Sticky keys is disabled, send callback to clear any saved sticky state.
135 mPolicy.notifyStickyModifierStateChanged(0, 0);
136 }
137 }
138 }
139
notifyConfigurationChangedLocked()140 void InputFilter::notifyConfigurationChangedLocked() {
141 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyConfigurationChanged(mConfig).isOk());
142 if (isFilterEnabled()) {
143 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyInputDevicesChanged(mDeviceInfos).isOk());
144 }
145 }
146
dump(std::string & dump)147 void InputFilter::dump(std::string& dump) {
148 dump += "InputFilter:\n";
149 if (isFilterEnabled()) {
150 std::string result;
151 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->dumpFilter(&result).isOk());
152 dump += result;
153 dump += "\n";
154 }
155 }
156
157 } // namespace android
158