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 }
64 if (isFilterEnabled()) {
65 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyInputDevicesChanged(mDeviceInfos).isOk());
66 }
67 mNextListener.notify(args);
68 }
69
notifyConfigurationChanged(const NotifyConfigurationChangedArgs & args)70 void InputFilter::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
71 mNextListener.notify(args);
72 }
73
notifyKey(const NotifyKeyArgs & args)74 void InputFilter::notifyKey(const NotifyKeyArgs& args) {
75 if (isFilterEnabled()) {
76 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyKey(notifyKeyArgsToKeyEvent(args)).isOk());
77 return;
78 }
79 mNextListener.notify(args);
80 }
81
notifyMotion(const NotifyMotionArgs & args)82 void InputFilter::notifyMotion(const NotifyMotionArgs& args) {
83 mNextListener.notify(args);
84 }
85
notifySwitch(const NotifySwitchArgs & args)86 void InputFilter::notifySwitch(const NotifySwitchArgs& args) {
87 mNextListener.notify(args);
88 }
89
notifySensor(const NotifySensorArgs & args)90 void InputFilter::notifySensor(const NotifySensorArgs& args) {
91 mNextListener.notify(args);
92 }
93
notifyVibratorState(const NotifyVibratorStateArgs & args)94 void InputFilter::notifyVibratorState(const NotifyVibratorStateArgs& args) {
95 mNextListener.notify(args);
96 }
97
notifyDeviceReset(const NotifyDeviceResetArgs & args)98 void InputFilter::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
99 mNextListener.notify(args);
100 }
101
notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs & args)102 void InputFilter::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
103 mNextListener.notify(args);
104 }
105
isFilterEnabled()106 bool InputFilter::isFilterEnabled() {
107 bool result;
108 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->isEnabled(&result).isOk());
109 return result;
110 }
111
setAccessibilityBounceKeysThreshold(nsecs_t threshold)112 void InputFilter::setAccessibilityBounceKeysThreshold(nsecs_t threshold) {
113 std::scoped_lock _l(mLock);
114
115 if (mConfig.bounceKeysThresholdNs != threshold) {
116 mConfig.bounceKeysThresholdNs = threshold;
117 notifyConfigurationChangedLocked();
118 }
119 }
120
setAccessibilitySlowKeysThreshold(nsecs_t threshold)121 void InputFilter::setAccessibilitySlowKeysThreshold(nsecs_t threshold) {
122 std::scoped_lock _l(mLock);
123
124 if (mConfig.slowKeysThresholdNs != threshold) {
125 mConfig.slowKeysThresholdNs = threshold;
126 notifyConfigurationChangedLocked();
127 }
128 }
129
setAccessibilityStickyKeysEnabled(bool enabled)130 void InputFilter::setAccessibilityStickyKeysEnabled(bool enabled) {
131 std::scoped_lock _l(mLock);
132
133 if (mConfig.stickyKeysEnabled != enabled) {
134 mConfig.stickyKeysEnabled = enabled;
135 notifyConfigurationChangedLocked();
136 if (!enabled) {
137 // When Sticky keys is disabled, send callback to clear any saved sticky state.
138 mPolicy.notifyStickyModifierStateChanged(0, 0);
139 }
140 }
141 }
142
notifyConfigurationChangedLocked()143 void InputFilter::notifyConfigurationChangedLocked() {
144 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyConfigurationChanged(mConfig).isOk());
145 if (isFilterEnabled()) {
146 LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyInputDevicesChanged(mDeviceInfos).isOk());
147 }
148 }
149
dump(std::string & dump)150 void InputFilter::dump(std::string& dump) {
151 dump += "InputFilter:\n";
152 }
153
154 } // namespace android
155