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