Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3935e6fa authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

Add slow_keys input filter

DD: go/pk_accessibility
‘Slow keys’ is an accessibility feature to aid users who have
physical disabilities, that allows the user to specify the
duration for which one must press-and-hold a key before the
system accepts the keypress.
Note: As part of this CL, introduced threading in input_filter
stage in RUST. Due to Jni requirements, have used the utils/Thread.h
impl to create a thread and pass it over to rust for handling.

Test: atest --host libinputflinger_rs_test
Bug: 294546335
Change-Id: Ib418c133e09f3085e5fe78991068d4be9ed09ed9
parent 98f2e04b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -118,6 +118,15 @@ void InputFilter::setAccessibilityBounceKeysThreshold(nsecs_t threshold) {
    }
}

void InputFilter::setAccessibilitySlowKeysThreshold(nsecs_t threshold) {
    std::scoped_lock _l(mLock);

    if (mConfig.slowKeysThresholdNs != threshold) {
        mConfig.slowKeysThresholdNs = threshold;
        notifyConfigurationChangedLocked();
    }
}

void InputFilter::setAccessibilityStickyKeysEnabled(bool enabled) {
    std::scoped_lock _l(mLock);

+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ public:
     */
    virtual void dump(std::string& dump) = 0;
    virtual void setAccessibilityBounceKeysThreshold(nsecs_t threshold) = 0;
    virtual void setAccessibilitySlowKeysThreshold(nsecs_t threshold) = 0;
    virtual void setAccessibilityStickyKeysEnabled(bool enabled) = 0;
};

@@ -61,6 +62,7 @@ public:
    void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
    void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;
    void setAccessibilityBounceKeysThreshold(nsecs_t threshold) override;
    void setAccessibilitySlowKeysThreshold(nsecs_t threshold) override;
    void setAccessibilityStickyKeysEnabled(bool enabled) override;
    void dump(std::string& dump) override;

+53 −0
Original line number Diff line number Diff line
@@ -17,6 +17,11 @@
#define LOG_TAG "InputFilterCallbacks"

#include "InputFilterCallbacks.h"
#include <aidl/com/android/server/inputflinger/BnInputThread.h>
#include <android/binder_auto_utils.h>
#include <utils/StrongPointer.h>
#include <utils/Thread.h>
#include <functional>

namespace android {

@@ -29,6 +34,47 @@ NotifyKeyArgs keyEventToNotifyKeyArgs(const AidlKeyEvent& event) {
                         event.scanCode, event.metaState, event.downTime);
}

namespace {

using namespace aidl::com::android::server::inputflinger;

class InputFilterThreadImpl : public Thread {
public:
    explicit InputFilterThreadImpl(std::function<void()> loop)
          : Thread(/*canCallJava=*/true), mThreadLoop(loop) {}

    ~InputFilterThreadImpl() {}

private:
    std::function<void()> mThreadLoop;

    bool threadLoop() override {
        mThreadLoop();
        return true;
    }
};

class InputFilterThread : public BnInputThread {
public:
    InputFilterThread(std::shared_ptr<IInputThreadCallback> callback) : mCallback(callback) {
        mThread = sp<InputFilterThreadImpl>::make([this]() { loopOnce(); });
        mThread->run("InputFilterThread", ANDROID_PRIORITY_URGENT_DISPLAY);
    }

    ndk::ScopedAStatus finish() override {
        mThread->requestExit();
        return ndk::ScopedAStatus::ok();
    }

private:
    sp<Thread> mThread;
    std::shared_ptr<IInputThreadCallback> mCallback;

    void loopOnce() { LOG_ALWAYS_FATAL_IF(!mCallback->loopOnce().isOk()); }
};

} // namespace

InputFilterCallbacks::InputFilterCallbacks(InputListenerInterface& listener,
                                           InputFilterPolicyInterface& policy)
      : mNextListener(listener), mPolicy(policy) {}
@@ -49,6 +95,13 @@ ndk::ScopedAStatus InputFilterCallbacks::onModifierStateChanged(int32_t modifier
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus InputFilterCallbacks::createInputFilterThread(
        const std::shared_ptr<IInputThreadCallback>& callback,
        std::shared_ptr<IInputThread>* aidl_return) {
    *aidl_return = ndk::SharedRefBase::make<InputFilterThread>(callback);
    return ndk::ScopedAStatus::ok();
}

uint32_t InputFilterCallbacks::getModifierState() {
    std::scoped_lock _l(mLock);
    return mStickyModifierState.modifierState;
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <aidl/com/android/server/inputflinger/IInputFlingerRust.h>
#include <android/binder_auto_utils.h>
#include <utils/Mutex.h>
#include <memory>
#include <mutex>
#include "InputFilterPolicyInterface.h"
#include "InputListener.h"
@@ -31,6 +32,9 @@ namespace android {

using IInputFilter = aidl::com::android::server::inputflinger::IInputFilter;
using AidlKeyEvent = aidl::com::android::server::inputflinger::KeyEvent;
using aidl::com::android::server::inputflinger::IInputThread;
using IInputThreadCallback =
        aidl::com::android::server::inputflinger::IInputThread::IInputThreadCallback;

class InputFilterCallbacks : public IInputFilter::BnInputFilterCallbacks {
public:
@@ -53,6 +57,9 @@ private:
    ndk::ScopedAStatus sendKeyEvent(const AidlKeyEvent& event) override;
    ndk::ScopedAStatus onModifierStateChanged(int32_t modifierState,
                                              int32_t lockedModifierState) override;
    ndk::ScopedAStatus createInputFilterThread(
            const std::shared_ptr<IInputThreadCallback>& callback,
            std::shared_ptr<IInputThread>* aidl_return) override;
};

} // namespace android
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.inputflinger;

import com.android.server.inputflinger.DeviceInfo;
import com.android.server.inputflinger.IInputThread;
import com.android.server.inputflinger.IInputThread.IInputThreadCallback;
import com.android.server.inputflinger.InputFilterConfiguration;
import com.android.server.inputflinger.KeyEvent;

@@ -36,6 +38,9 @@ interface IInputFilter {

        /** Sends back modifier state */
        void onModifierStateChanged(int modifierState, int lockedModifierState);

        /** Creates an Input filter thread */
        IInputThread createInputFilterThread(in IInputThreadCallback callback);
    }

    /** Returns if InputFilter is enabled */
Loading