You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
9.7 KiB
298 lines
9.7 KiB
/*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef _UI_INPUT_INPUTDISPATCHER_ENTRY_H
|
|
#define _UI_INPUT_INPUTDISPATCHER_ENTRY_H
|
|
|
|
#include "InjectionState.h"
|
|
#include "InputTarget.h"
|
|
|
|
#include <input/Input.h>
|
|
#include <input/InputApplication.h>
|
|
#include <stdint.h>
|
|
#include <utils/Timers.h>
|
|
#include <functional>
|
|
#include <string>
|
|
|
|
namespace android::inputdispatcher {
|
|
|
|
struct EventEntry {
|
|
enum class Type {
|
|
CONFIGURATION_CHANGED,
|
|
DEVICE_RESET,
|
|
FOCUS,
|
|
KEY,
|
|
MOTION,
|
|
SENSOR,
|
|
POINTER_CAPTURE_CHANGED,
|
|
DRAG,
|
|
};
|
|
|
|
int32_t id;
|
|
Type type;
|
|
nsecs_t eventTime;
|
|
uint32_t policyFlags;
|
|
InjectionState* injectionState;
|
|
|
|
bool dispatchInProgress; // initially false, set to true while dispatching
|
|
|
|
/**
|
|
* Injected keys are events from an external (probably untrusted) application
|
|
* and are not related to real hardware state. They come in via
|
|
* InputDispatcher::injectInputEvent, which sets policy flag POLICY_FLAG_INJECTED.
|
|
*/
|
|
inline bool isInjected() const { return injectionState != nullptr; }
|
|
|
|
/**
|
|
* Synthesized events are either injected events, or events that come
|
|
* from real hardware, but aren't directly attributable to a specific hardware event.
|
|
* Key repeat is a synthesized event, because it is related to an actual hardware state
|
|
* (a key is currently pressed), but the repeat itself is generated by the framework.
|
|
*/
|
|
inline bool isSynthesized() const {
|
|
return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER;
|
|
}
|
|
|
|
virtual std::string getDescription() const = 0;
|
|
|
|
EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
|
|
virtual ~EventEntry();
|
|
|
|
protected:
|
|
void releaseInjectionState();
|
|
};
|
|
|
|
struct ConfigurationChangedEntry : EventEntry {
|
|
explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
|
|
std::string getDescription() const override;
|
|
|
|
~ConfigurationChangedEntry() override;
|
|
};
|
|
|
|
struct DeviceResetEntry : EventEntry {
|
|
int32_t deviceId;
|
|
|
|
DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
|
|
std::string getDescription() const override;
|
|
|
|
~DeviceResetEntry() override;
|
|
};
|
|
|
|
struct FocusEntry : EventEntry {
|
|
sp<IBinder> connectionToken;
|
|
bool hasFocus;
|
|
std::string reason;
|
|
|
|
FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
|
|
const std::string& reason);
|
|
std::string getDescription() const override;
|
|
|
|
~FocusEntry() override;
|
|
};
|
|
|
|
struct PointerCaptureChangedEntry : EventEntry {
|
|
bool pointerCaptureEnabled;
|
|
|
|
PointerCaptureChangedEntry(int32_t id, nsecs_t eventTime, bool hasPointerCapture);
|
|
std::string getDescription() const override;
|
|
|
|
~PointerCaptureChangedEntry() override;
|
|
};
|
|
|
|
struct DragEntry : EventEntry {
|
|
sp<IBinder> connectionToken;
|
|
bool isExiting;
|
|
float x, y;
|
|
|
|
DragEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool isExiting, float x,
|
|
float y);
|
|
std::string getDescription() const override;
|
|
|
|
~DragEntry() override;
|
|
};
|
|
|
|
struct KeyEntry : EventEntry {
|
|
int32_t deviceId;
|
|
uint32_t source;
|
|
int32_t displayId;
|
|
int32_t action;
|
|
int32_t flags;
|
|
int32_t keyCode;
|
|
int32_t scanCode;
|
|
int32_t metaState;
|
|
int32_t repeatCount;
|
|
nsecs_t downTime;
|
|
|
|
bool syntheticRepeat; // set to true for synthetic key repeats
|
|
|
|
enum InterceptKeyResult {
|
|
INTERCEPT_KEY_RESULT_UNKNOWN,
|
|
INTERCEPT_KEY_RESULT_SKIP,
|
|
INTERCEPT_KEY_RESULT_CONTINUE,
|
|
INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
|
|
};
|
|
InterceptKeyResult interceptKeyResult; // set based on the interception result
|
|
nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
|
|
|
|
KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
|
|
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
|
|
int32_t metaState, int32_t repeatCount, nsecs_t downTime);
|
|
std::string getDescription() const override;
|
|
void recycle();
|
|
|
|
~KeyEntry() override;
|
|
};
|
|
|
|
struct MotionEntry : EventEntry {
|
|
int32_t deviceId;
|
|
uint32_t source;
|
|
int32_t displayId;
|
|
int32_t action;
|
|
int32_t actionButton;
|
|
int32_t flags;
|
|
int32_t metaState;
|
|
int32_t buttonState;
|
|
MotionClassification classification;
|
|
int32_t edgeFlags;
|
|
float xPrecision;
|
|
float yPrecision;
|
|
float xCursorPosition;
|
|
float yCursorPosition;
|
|
nsecs_t downTime;
|
|
uint32_t pointerCount;
|
|
PointerProperties pointerProperties[MAX_POINTERS];
|
|
PointerCoords pointerCoords[MAX_POINTERS];
|
|
|
|
MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
|
|
uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags,
|
|
int32_t metaState, int32_t buttonState, MotionClassification classification,
|
|
int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
|
|
float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
|
|
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
|
|
float xOffset, float yOffset);
|
|
std::string getDescription() const override;
|
|
|
|
virtual ~MotionEntry();
|
|
};
|
|
|
|
struct SensorEntry : EventEntry {
|
|
int32_t deviceId;
|
|
uint32_t source;
|
|
InputDeviceSensorType sensorType;
|
|
InputDeviceSensorAccuracy accuracy;
|
|
bool accuracyChanged;
|
|
nsecs_t hwTimestamp;
|
|
|
|
std::vector<float> values;
|
|
|
|
SensorEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
|
|
uint32_t policyFlags, nsecs_t hwTimestamp, InputDeviceSensorType sensorType,
|
|
InputDeviceSensorAccuracy accuracy, bool accuracyChanged,
|
|
std::vector<float> values);
|
|
std::string getDescription() const override;
|
|
|
|
~SensorEntry() override;
|
|
};
|
|
|
|
// Tracks the progress of dispatching a particular event to a particular connection.
|
|
struct DispatchEntry {
|
|
const uint32_t seq; // unique sequence number, never 0
|
|
|
|
std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
|
|
int32_t targetFlags;
|
|
ui::Transform transform;
|
|
float globalScaleFactor;
|
|
int2 displaySize;
|
|
// Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
|
|
// and will be undefined before that.
|
|
nsecs_t deliveryTime; // time when the event was actually delivered
|
|
// An ANR will be triggered if a response for this entry is not received by timeoutTime
|
|
nsecs_t timeoutTime;
|
|
|
|
// Set to the resolved ID, action and flags when the event is enqueued.
|
|
int32_t resolvedEventId;
|
|
int32_t resolvedAction;
|
|
int32_t resolvedFlags;
|
|
|
|
DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
|
|
ui::Transform transform, float globalScaleFactor, int2 displaySize);
|
|
|
|
inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
|
|
|
|
inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; }
|
|
|
|
private:
|
|
static volatile int32_t sNextSeqAtomic;
|
|
|
|
static uint32_t nextSeq();
|
|
};
|
|
|
|
VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
|
|
VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);
|
|
|
|
class InputDispatcher;
|
|
// A command entry captures state and behavior for an action to be performed in the
|
|
// dispatch loop after the initial processing has taken place. It is essentially
|
|
// a kind of continuation used to postpone sensitive policy interactions to a point
|
|
// in the dispatch loop where it is safe to release the lock (generally after finishing
|
|
// the critical parts of the dispatch cycle).
|
|
//
|
|
// The special thing about commands is that they can voluntarily release and reacquire
|
|
// the dispatcher lock at will. Initially when the command starts running, the
|
|
// dispatcher lock is held. However, if the command needs to call into the policy to
|
|
// do some work, it can release the lock, do the work, then reacquire the lock again
|
|
// before returning.
|
|
//
|
|
// This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
|
|
// never calls into the policy while holding its lock.
|
|
//
|
|
// Commands are implicitly 'LockedInterruptible'.
|
|
struct CommandEntry;
|
|
typedef std::function<void(InputDispatcher&, CommandEntry*)> Command;
|
|
|
|
class Connection;
|
|
struct CommandEntry {
|
|
explicit CommandEntry(Command command);
|
|
~CommandEntry();
|
|
|
|
Command command;
|
|
|
|
// parameters for the command (usage varies by command)
|
|
sp<Connection> connection;
|
|
nsecs_t eventTime;
|
|
std::shared_ptr<KeyEntry> keyEntry;
|
|
std::shared_ptr<SensorEntry> sensorEntry;
|
|
std::shared_ptr<InputApplicationHandle> inputApplicationHandle;
|
|
std::string reason;
|
|
int32_t userActivityEventType;
|
|
uint32_t seq;
|
|
bool handled;
|
|
sp<IBinder> connectionToken;
|
|
sp<IBinder> oldToken;
|
|
sp<IBinder> newToken;
|
|
std::string obscuringPackage;
|
|
bool enabled;
|
|
int32_t pid;
|
|
nsecs_t consumeTime; // time when the event was consumed by InputConsumer
|
|
int32_t displayId;
|
|
float x;
|
|
float y;
|
|
};
|
|
|
|
} // namespace android::inputdispatcher
|
|
|
|
#endif // _UI_INPUT_INPUTDISPATCHER_ENTRY_H
|