Loading include/input/Input.h +18 −0 Original line number Diff line number Diff line Loading @@ -1138,6 +1138,24 @@ private: std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEventPool; }; /** * An input event factory implementation that simply creates the input events on the heap, when * needed. The caller is responsible for destroying the returned references. * It is recommended that the caller wrap these return values into std::unique_ptr. */ class DynamicInputEventFactory : public InputEventFactoryInterface { public: explicit DynamicInputEventFactory(){}; ~DynamicInputEventFactory(){}; KeyEvent* createKeyEvent() override { return new KeyEvent(); }; MotionEvent* createMotionEvent() override { return new MotionEvent(); }; FocusEvent* createFocusEvent() override { return new FocusEvent(); }; CaptureEvent* createCaptureEvent() override { return new CaptureEvent(); }; DragEvent* createDragEvent() override { return new DragEvent(); }; TouchModeEvent* createTouchModeEvent() override { return new TouchModeEvent(); }; }; /* * Describes a unique request to enable or disable Pointer Capture. */ Loading services/inputflinger/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,7 @@ phony { "inputflinger_input_reader_fuzzer", "inputflinger_blocking_queue_fuzzer", "inputflinger_input_classifier_fuzzer", "inputflinger_input_dispatcher_fuzzer", // Java/Kotlin targets "CtsWindowManagerDeviceWindow", Loading services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp +13 −165 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ #include <binder/Binder.h> #include <gui/constants.h> #include "../dispatcher/InputDispatcher.h" #include "../tests/FakeApplicationHandle.h" #include "../tests/FakeInputDispatcherPolicy.h" #include "../tests/FakeWindowHandle.h" using android::base::Result; using android::gui::WindowInfo; using android::gui::WindowInfoHandle; using android::os::IInputConstants; using android::os::InputEventInjectionResult; using android::os::InputEventInjectionSync; Loading @@ -33,171 +35,17 @@ namespace android::inputdispatcher { namespace { // An arbitrary device id. constexpr int32_t DEVICE_ID = 1; constexpr DeviceId DEVICE_ID = 1; // The default pid and uid for windows created by the test. constexpr gui::Pid WINDOW_PID{999}; constexpr gui::Uid WINDOW_UID{1001}; // An arbitrary display id constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 5s; static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 100ms; static nsecs_t now() { return systemTime(SYSTEM_TIME_MONOTONIC); } // --- FakeInputDispatcherPolicy --- class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface { public: FakeInputDispatcherPolicy() = default; virtual ~FakeInputDispatcherPolicy() = default; private: void notifyConfigurationChanged(nsecs_t) override {} void notifyNoFocusedWindowAnr( const std::shared_ptr<InputApplicationHandle>& applicationHandle) override { ALOGE("There is no focused window for %s", applicationHandle->getName().c_str()); } void notifyWindowUnresponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid, const std::string& reason) override { ALOGE("Window is not responding: %s", reason.c_str()); } void notifyWindowResponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid) override {} void notifyInputChannelBroken(const sp<IBinder>&) override {} void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {} void notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy, nsecs_t timestamp, const std::vector<float>& values) override {} void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy) override {} void notifyVibratorState(int32_t deviceId, bool isOn) override {} bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) override { return true; // dispatch event normally } void interceptKeyBeforeQueueing(const KeyEvent&, uint32_t&) override {} void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {} nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override { return 0; } std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent&, uint32_t) override { return {}; } void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) override {} void pokeUserActivity(nsecs_t, int32_t, int32_t) override {} void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {} void setPointerCapture(const PointerCaptureRequest&) override {} void notifyDropWindow(const sp<IBinder>&, float x, float y) override {} void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp, const std::set<gui::Uid>& uids) override {} InputDispatcherConfiguration mConfig; }; class FakeApplicationHandle : public InputApplicationHandle { public: FakeApplicationHandle() {} virtual ~FakeApplicationHandle() {} virtual bool updateInfo() { mInfo.dispatchingTimeoutMillis = std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count(); return true; } }; class FakeInputReceiver { public: void consumeEvent() { uint32_t consumeSeq = 0; InputEvent* event; std::chrono::time_point start = std::chrono::steady_clock::now(); status_t result = WOULD_BLOCK; while (result == WOULD_BLOCK) { std::chrono::duration elapsed = std::chrono::steady_clock::now() - start; if (elapsed > 10ms) { ALOGE("Waited too long for consumer to produce an event, giving up"); break; } result = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event); } if (result != OK) { ALOGE("Received result = %d from consume()", result); } result = mConsumer->sendFinishedSignal(consumeSeq, true); if (result != OK) { ALOGE("Received result = %d from sendFinishedSignal", result); } } protected: explicit FakeInputReceiver(InputDispatcher& dispatcher, const std::string name) { Result<std::unique_ptr<InputChannel>> channelResult = dispatcher.createInputChannel(name); LOG_ALWAYS_FATAL_IF(!channelResult.ok()); mClientChannel = std::move(*channelResult); mConsumer = std::make_unique<InputConsumer>(mClientChannel); } virtual ~FakeInputReceiver() {} std::shared_ptr<InputChannel> mClientChannel; std::unique_ptr<InputConsumer> mConsumer; PreallocatedInputEventFactory mEventFactory; }; class FakeWindowHandle : public WindowInfoHandle, public FakeInputReceiver { public: static const int32_t WIDTH = 200; static const int32_t HEIGHT = 200; FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle, InputDispatcher& dispatcher, const std::string name) : FakeInputReceiver(dispatcher, name), mFrame(Rect(0, 0, WIDTH, HEIGHT)) { inputApplicationHandle->updateInfo(); updateInfo(); mInfo.applicationInfo = *inputApplicationHandle->getInfo(); } void updateInfo() { mInfo.token = mClientChannel->getConnectionToken(); mInfo.name = "FakeWindowHandle"; mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT; mInfo.frame = mFrame; mInfo.globalScaleFactor = 1.0; mInfo.touchableRegion.clear(); mInfo.addTouchableRegion(mFrame); mInfo.ownerPid = WINDOW_PID; mInfo.ownerUid = WINDOW_UID; mInfo.displayId = ADISPLAY_ID_DEFAULT; } protected: Rect mFrame; }; static MotionEvent generateMotionEvent() { PointerProperties pointerProperties[1]; PointerCoords pointerCoords[1]; Loading Loading @@ -263,7 +111,7 @@ static void benchmarkNotifyMotion(benchmark::State& state) { // Create a window that will receive motion events std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); dispatcher.onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); Loading @@ -281,8 +129,8 @@ static void benchmarkNotifyMotion(benchmark::State& state) { motionArgs.eventTime = now(); dispatcher.notifyMotion(motionArgs); window->consumeEvent(); window->consumeEvent(); window->consumeMotion(); window->consumeMotion(); } dispatcher.stop(); Loading @@ -298,7 +146,7 @@ static void benchmarkInjectMotion(benchmark::State& state) { // Create a window that will receive motion events std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); dispatcher.onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); Loading @@ -315,8 +163,8 @@ static void benchmarkInjectMotion(benchmark::State& state) { INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER); window->consumeEvent(); window->consumeEvent(); window->consumeMotion(); window->consumeMotion(); } dispatcher.stop(); Loading @@ -332,7 +180,7 @@ static void benchmarkOnWindowInfosChanged(benchmark::State& state) { // Create a window std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); std::vector<gui::WindowInfo> windowInfos{*window->getInfo()}; gui::DisplayInfo info; Loading services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h +3 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ #include <android-base/properties.h> #include <binder/IBinder.h> #include <gui/InputApplication.h> #include <gui/PidUid.h> #include <input/Input.h> #include <input/InputDevice.h> #include <utils/RefBase.h> #include <set> Loading Loading @@ -146,7 +148,7 @@ public: virtual void notifyDropWindow(const sp<IBinder>& token, float x, float y) = 0; /* Notifies the policy that there was an input device interaction with apps. */ virtual void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp, virtual void notifyDeviceInteraction(DeviceId deviceId, nsecs_t timestamp, const std::set<gui::Uid>& uids) = 0; }; Loading services/inputflinger/tests/FakeApplicationHandle.h 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android-base/properties.h> #include <android/os/IInputConstants.h> #include <gui/InputApplication.h> namespace android { namespace inputdispatcher { class FakeApplicationHandle : public InputApplicationHandle { public: FakeApplicationHandle() { static const std::chrono::duration DISPATCHING_TIMEOUT = std::chrono::milliseconds( android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS * android::base::HwTimeoutMultiplier()); mInfo.name = "Fake Application"; mInfo.token = sp<BBinder>::make(); mInfo.dispatchingTimeoutMillis = std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count(); } virtual ~FakeApplicationHandle() {} bool updateInfo() override { return true; } void setDispatchingTimeout(std::chrono::milliseconds timeout) { mInfo.dispatchingTimeoutMillis = timeout.count(); } }; } // namespace inputdispatcher } // namespace android Loading
include/input/Input.h +18 −0 Original line number Diff line number Diff line Loading @@ -1138,6 +1138,24 @@ private: std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEventPool; }; /** * An input event factory implementation that simply creates the input events on the heap, when * needed. The caller is responsible for destroying the returned references. * It is recommended that the caller wrap these return values into std::unique_ptr. */ class DynamicInputEventFactory : public InputEventFactoryInterface { public: explicit DynamicInputEventFactory(){}; ~DynamicInputEventFactory(){}; KeyEvent* createKeyEvent() override { return new KeyEvent(); }; MotionEvent* createMotionEvent() override { return new MotionEvent(); }; FocusEvent* createFocusEvent() override { return new FocusEvent(); }; CaptureEvent* createCaptureEvent() override { return new CaptureEvent(); }; DragEvent* createDragEvent() override { return new DragEvent(); }; TouchModeEvent* createTouchModeEvent() override { return new TouchModeEvent(); }; }; /* * Describes a unique request to enable or disable Pointer Capture. */ Loading
services/inputflinger/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,7 @@ phony { "inputflinger_input_reader_fuzzer", "inputflinger_blocking_queue_fuzzer", "inputflinger_input_classifier_fuzzer", "inputflinger_input_dispatcher_fuzzer", // Java/Kotlin targets "CtsWindowManagerDeviceWindow", Loading
services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp +13 −165 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ #include <binder/Binder.h> #include <gui/constants.h> #include "../dispatcher/InputDispatcher.h" #include "../tests/FakeApplicationHandle.h" #include "../tests/FakeInputDispatcherPolicy.h" #include "../tests/FakeWindowHandle.h" using android::base::Result; using android::gui::WindowInfo; using android::gui::WindowInfoHandle; using android::os::IInputConstants; using android::os::InputEventInjectionResult; using android::os::InputEventInjectionSync; Loading @@ -33,171 +35,17 @@ namespace android::inputdispatcher { namespace { // An arbitrary device id. constexpr int32_t DEVICE_ID = 1; constexpr DeviceId DEVICE_ID = 1; // The default pid and uid for windows created by the test. constexpr gui::Pid WINDOW_PID{999}; constexpr gui::Uid WINDOW_UID{1001}; // An arbitrary display id constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 5s; static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 100ms; static nsecs_t now() { return systemTime(SYSTEM_TIME_MONOTONIC); } // --- FakeInputDispatcherPolicy --- class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface { public: FakeInputDispatcherPolicy() = default; virtual ~FakeInputDispatcherPolicy() = default; private: void notifyConfigurationChanged(nsecs_t) override {} void notifyNoFocusedWindowAnr( const std::shared_ptr<InputApplicationHandle>& applicationHandle) override { ALOGE("There is no focused window for %s", applicationHandle->getName().c_str()); } void notifyWindowUnresponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid, const std::string& reason) override { ALOGE("Window is not responding: %s", reason.c_str()); } void notifyWindowResponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid) override {} void notifyInputChannelBroken(const sp<IBinder>&) override {} void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {} void notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy, nsecs_t timestamp, const std::vector<float>& values) override {} void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy) override {} void notifyVibratorState(int32_t deviceId, bool isOn) override {} bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) override { return true; // dispatch event normally } void interceptKeyBeforeQueueing(const KeyEvent&, uint32_t&) override {} void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {} nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override { return 0; } std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent&, uint32_t) override { return {}; } void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) override {} void pokeUserActivity(nsecs_t, int32_t, int32_t) override {} void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {} void setPointerCapture(const PointerCaptureRequest&) override {} void notifyDropWindow(const sp<IBinder>&, float x, float y) override {} void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp, const std::set<gui::Uid>& uids) override {} InputDispatcherConfiguration mConfig; }; class FakeApplicationHandle : public InputApplicationHandle { public: FakeApplicationHandle() {} virtual ~FakeApplicationHandle() {} virtual bool updateInfo() { mInfo.dispatchingTimeoutMillis = std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count(); return true; } }; class FakeInputReceiver { public: void consumeEvent() { uint32_t consumeSeq = 0; InputEvent* event; std::chrono::time_point start = std::chrono::steady_clock::now(); status_t result = WOULD_BLOCK; while (result == WOULD_BLOCK) { std::chrono::duration elapsed = std::chrono::steady_clock::now() - start; if (elapsed > 10ms) { ALOGE("Waited too long for consumer to produce an event, giving up"); break; } result = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event); } if (result != OK) { ALOGE("Received result = %d from consume()", result); } result = mConsumer->sendFinishedSignal(consumeSeq, true); if (result != OK) { ALOGE("Received result = %d from sendFinishedSignal", result); } } protected: explicit FakeInputReceiver(InputDispatcher& dispatcher, const std::string name) { Result<std::unique_ptr<InputChannel>> channelResult = dispatcher.createInputChannel(name); LOG_ALWAYS_FATAL_IF(!channelResult.ok()); mClientChannel = std::move(*channelResult); mConsumer = std::make_unique<InputConsumer>(mClientChannel); } virtual ~FakeInputReceiver() {} std::shared_ptr<InputChannel> mClientChannel; std::unique_ptr<InputConsumer> mConsumer; PreallocatedInputEventFactory mEventFactory; }; class FakeWindowHandle : public WindowInfoHandle, public FakeInputReceiver { public: static const int32_t WIDTH = 200; static const int32_t HEIGHT = 200; FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle, InputDispatcher& dispatcher, const std::string name) : FakeInputReceiver(dispatcher, name), mFrame(Rect(0, 0, WIDTH, HEIGHT)) { inputApplicationHandle->updateInfo(); updateInfo(); mInfo.applicationInfo = *inputApplicationHandle->getInfo(); } void updateInfo() { mInfo.token = mClientChannel->getConnectionToken(); mInfo.name = "FakeWindowHandle"; mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT; mInfo.frame = mFrame; mInfo.globalScaleFactor = 1.0; mInfo.touchableRegion.clear(); mInfo.addTouchableRegion(mFrame); mInfo.ownerPid = WINDOW_PID; mInfo.ownerUid = WINDOW_UID; mInfo.displayId = ADISPLAY_ID_DEFAULT; } protected: Rect mFrame; }; static MotionEvent generateMotionEvent() { PointerProperties pointerProperties[1]; PointerCoords pointerCoords[1]; Loading Loading @@ -263,7 +111,7 @@ static void benchmarkNotifyMotion(benchmark::State& state) { // Create a window that will receive motion events std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); dispatcher.onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); Loading @@ -281,8 +129,8 @@ static void benchmarkNotifyMotion(benchmark::State& state) { motionArgs.eventTime = now(); dispatcher.notifyMotion(motionArgs); window->consumeEvent(); window->consumeEvent(); window->consumeMotion(); window->consumeMotion(); } dispatcher.stop(); Loading @@ -298,7 +146,7 @@ static void benchmarkInjectMotion(benchmark::State& state) { // Create a window that will receive motion events std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); dispatcher.onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); Loading @@ -315,8 +163,8 @@ static void benchmarkInjectMotion(benchmark::State& state) { INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER); window->consumeEvent(); window->consumeEvent(); window->consumeMotion(); window->consumeMotion(); } dispatcher.stop(); Loading @@ -332,7 +180,7 @@ static void benchmarkOnWindowInfosChanged(benchmark::State& state) { // Create a window std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window"); sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID); std::vector<gui::WindowInfo> windowInfos{*window->getInfo()}; gui::DisplayInfo info; Loading
services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h +3 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ #include <android-base/properties.h> #include <binder/IBinder.h> #include <gui/InputApplication.h> #include <gui/PidUid.h> #include <input/Input.h> #include <input/InputDevice.h> #include <utils/RefBase.h> #include <set> Loading Loading @@ -146,7 +148,7 @@ public: virtual void notifyDropWindow(const sp<IBinder>& token, float x, float y) = 0; /* Notifies the policy that there was an input device interaction with apps. */ virtual void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp, virtual void notifyDeviceInteraction(DeviceId deviceId, nsecs_t timestamp, const std::set<gui::Uid>& uids) = 0; }; Loading
services/inputflinger/tests/FakeApplicationHandle.h 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android-base/properties.h> #include <android/os/IInputConstants.h> #include <gui/InputApplication.h> namespace android { namespace inputdispatcher { class FakeApplicationHandle : public InputApplicationHandle { public: FakeApplicationHandle() { static const std::chrono::duration DISPATCHING_TIMEOUT = std::chrono::milliseconds( android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS * android::base::HwTimeoutMultiplier()); mInfo.name = "Fake Application"; mInfo.token = sp<BBinder>::make(); mInfo.dispatchingTimeoutMillis = std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count(); } virtual ~FakeApplicationHandle() {} bool updateInfo() override { return true; } void setDispatchingTimeout(std::chrono::milliseconds timeout) { mInfo.dispatchingTimeoutMillis = timeout.count(); } }; } // namespace inputdispatcher } // namespace android