1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/*
* Copyright (C) 2019 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 "InputDispatcherConfiguration.h"
#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>
namespace android {
/*
* Input dispatcher policy interface.
*
* The input dispatcher policy is used by the input dispatcher to interact with the Window Manager
* and other system components.
*
* The actual implementation is partially supported by callbacks into the DVM
* via JNI. This interface is also mocked in the unit tests.
*/
class InputDispatcherPolicyInterface {
public:
InputDispatcherPolicyInterface() = default;
virtual ~InputDispatcherPolicyInterface() = default;
/* Notifies the system that a configuration change has occurred. */
virtual void notifyConfigurationChanged(nsecs_t when) = 0;
/* Notifies the system that an application does not have a focused window.
*/
virtual void notifyNoFocusedWindowAnr(
const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) = 0;
/* Notifies the system that a window just became unresponsive. This indicates that ANR
* should be raised for this window. The window can be identified via its input token and the
* pid of the owner. The string reason contains information about the input event that we
* haven't received a response for.
*/
virtual void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid,
const std::string& reason) = 0;
/* Notifies the system that a window just became responsive. This is only called after the
* window was first marked "unresponsive". This indicates that ANR dialog (if any) should
* no longer should be shown to the user. The window is eligible to cause a new ANR in the
* future.
*/
virtual void notifyWindowResponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid) = 0;
/* Notifies the system that an input channel is unrecoverably broken. */
virtual void notifyInputChannelBroken(const sp<IBinder>& token) = 0;
virtual void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) = 0;
virtual void notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
const std::vector<float>& values) = 0;
virtual void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
InputDeviceSensorAccuracy accuracy) = 0;
virtual void notifyVibratorState(int32_t deviceId, bool isOn) = 0;
/* Filters an input event.
* Return true to dispatch the event unmodified, false to consume the event.
* A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
* to injectInputEvent.
*/
virtual bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) = 0;
/* Intercepts a key event immediately before queueing it.
* The policy can use this method as an opportunity to perform power management functions
* and early event preprocessing such as updating policy flags.
*
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
virtual void interceptKeyBeforeQueueing(const KeyEvent& keyEvent, uint32_t& policyFlags) = 0;
/* Intercepts a touch, trackball or other motion event before queueing it.
* The policy can use this method as an opportunity to perform power management functions
* and early event preprocessing such as updating policy flags.
*
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
virtual void interceptMotionBeforeQueueing(int32_t displayId, uint32_t source, int32_t action,
nsecs_t when, uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
const KeyEvent& keyEvent,
uint32_t policyFlags) = 0;
/* Allows the policy a chance to perform default processing for an unhandled key.
* Returns an alternate key event to redispatch as a fallback, if needed. */
virtual std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>& token,
const KeyEvent& keyEvent,
uint32_t policyFlags) = 0;
/* Notifies the policy about switch events.
*/
virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
uint32_t policyFlags) = 0;
/* Poke user activity for an event dispatched to a window. */
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) = 0;
/*
* Return true if the provided event is stale, and false otherwise. Used for determining
* whether the dispatcher should drop the event.
*/
virtual bool isStaleEvent(nsecs_t currentTime, nsecs_t eventTime) {
static const std::chrono::duration STALE_EVENT_TIMEOUT =
std::chrono::seconds(10) * android::base::HwTimeoutMultiplier();
return std::chrono::nanoseconds(currentTime - eventTime) >= STALE_EVENT_TIMEOUT;
}
/**
* Get the additional latency to add while waiting for other input events to process before
* dispatching the pending key.
* If there are unprocessed events, the pending key will not be dispatched immediately. Instead,
* the dispatcher will wait for this timeout, to account for the possibility that the focus
* might change due to touch or other events (such as another app getting launched by keys).
* This would give the pending key the opportunity to go to a newly focused window instead.
*/
virtual std::chrono::nanoseconds getKeyWaitingForEventsTimeout() {
return KEY_WAITING_FOR_EVENTS_TIMEOUT;
}
/* Notifies the policy that a pointer down event has occurred outside the current focused
* window.
*
* The touchedToken passed as an argument is the window that received the input event.
*/
virtual void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) = 0;
/* Change the Pointer Capture state in InputReader.
*
* InputDispatcher is solely responsible for updating the Pointer Capture state.
*/
virtual void setPointerCapture(const PointerCaptureRequest&) = 0;
/* Notifies the policy that the drag window has moved over to another window */
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(DeviceId deviceId, nsecs_t timestamp,
const std::set<gui::Uid>& uids) = 0;
private:
// Additional key latency in case a connection is still processing some motion events.
// This will help with the case when a user touched a button that opens a new window,
// and gives us the chance to dispatch the key to this new window.
static constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT =
std::chrono::milliseconds(500);
};
} // namespace android
|