Merge "Release buffers early after GL comp"
diff --git a/include/input/Input.h b/include/input/Input.h
index d397313..5015e68 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -801,6 +801,8 @@
static std::string actionToString(int32_t action);
+ static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
+
protected:
int32_t mAction;
int32_t mActionButton;
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 65f6bc6..4465b8e 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -28,6 +28,7 @@
#include <android-base/hex.h>
#include <android-base/macros.h>
+#include <android-base/scopeguard.h>
#include <android_runtime/vm.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>
@@ -54,13 +55,13 @@
RpcSession::RpcSession(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {
LOG_RPC_DETAIL("RpcSession created %p", this);
- mState = std::make_unique<RpcState>();
+ mRpcBinderState = std::make_unique<RpcState>();
}
RpcSession::~RpcSession() {
LOG_RPC_DETAIL("RpcSession destroyed %p", this);
std::lock_guard<std::mutex> _l(mMutex);
- LOG_ALWAYS_FATAL_IF(mIncomingConnections.size() != 0,
+ LOG_ALWAYS_FATAL_IF(mThreadState.mIncomingConnections.size() != 0,
"Should not be able to destroy a session with servers in use.");
}
@@ -77,10 +78,12 @@
void RpcSession::setMaxThreads(size_t threads) {
std::lock_guard<std::mutex> _l(mMutex);
- LOG_ALWAYS_FATAL_IF(!mOutgoingConnections.empty() || !mIncomingConnections.empty(),
+ LOG_ALWAYS_FATAL_IF(!mThreadState.mOutgoingConnections.empty() ||
+ !mThreadState.mIncomingConnections.empty(),
"Must set max threads before setting up connections, but has %zu client(s) "
"and %zu server(s)",
- mOutgoingConnections.size(), mIncomingConnections.size());
+ mThreadState.mOutgoingConnections.size(),
+ mThreadState.mIncomingConnections.size());
mMaxThreads = threads;
}
@@ -194,11 +197,11 @@
LOG_ALWAYS_FATAL_IF(mShutdownListener == nullptr, "Shutdown listener not installed");
mShutdownListener->waitForShutdown(_l, sp<RpcSession>::fromExisting(this));
- LOG_ALWAYS_FATAL_IF(!mThreads.empty(), "Shutdown failed");
+ LOG_ALWAYS_FATAL_IF(!mThreadState.mThreads.empty(), "Shutdown failed");
}
_l.unlock();
- mState->clear();
+ mRpcBinderState->clear();
return true;
}
@@ -260,11 +263,11 @@
void RpcSession::WaitForShutdownListener::waitForShutdown(std::unique_lock<std::mutex>& lock,
const sp<RpcSession>& session) {
- while (session->mIncomingConnections.size() > 0) {
+ while (session->mThreadState.mIncomingConnections.size() > 0) {
if (std::cv_status::timeout == mCv.wait_for(lock, std::chrono::seconds(1))) {
ALOGE("Waiting for RpcSession to shut down (1s w/o progress): %zu incoming connections "
"still.",
- session->mIncomingConnections.size());
+ session->mThreadState.mIncomingConnections.size());
}
}
}
@@ -274,7 +277,7 @@
{
std::lock_guard<std::mutex> _l(mMutex);
- mThreads[thread.get_id()] = std::move(thread);
+ mThreadState.mThreads[thread.get_id()] = std::move(thread);
}
}
@@ -289,7 +292,8 @@
if (connection == nullptr) {
status = DEAD_OBJECT;
} else {
- status = mState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+ status =
+ mRpcBinderState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
}
return PreJoinSetupResult{
@@ -376,10 +380,10 @@
sp<RpcSession::EventListener> listener;
{
std::lock_guard<std::mutex> _l(session->mMutex);
- auto it = session->mThreads.find(std::this_thread::get_id());
- LOG_ALWAYS_FATAL_IF(it == session->mThreads.end());
+ auto it = session->mThreadState.mThreads.find(std::this_thread::get_id());
+ LOG_ALWAYS_FATAL_IF(it == session->mThreadState.mThreads.end());
it->second.detach();
- session->mThreads.erase(it);
+ session->mThreadState.mThreads.erase(it);
listener = session->mEventListener.promote();
}
@@ -410,12 +414,34 @@
bool incoming)>& connectAndInit) {
{
std::lock_guard<std::mutex> _l(mMutex);
- LOG_ALWAYS_FATAL_IF(mOutgoingConnections.size() != 0,
+ LOG_ALWAYS_FATAL_IF(mThreadState.mOutgoingConnections.size() != 0,
"Must only setup session once, but already has %zu clients",
- mOutgoingConnections.size());
+ mThreadState.mOutgoingConnections.size());
}
+
if (auto status = initShutdownTrigger(); status != OK) return status;
+ auto oldProtocolVersion = mProtocolVersion;
+ auto cleanup = base::ScopeGuard([&] {
+ // if any threads are started, shut them down
+ (void)shutdownAndWait(true);
+
+ mShutdownListener = nullptr;
+ mEventListener.clear();
+
+ mId.clear();
+
+ mShutdownTrigger = nullptr;
+ mRpcBinderState = std::make_unique<RpcState>();
+
+ // protocol version may have been downgraded - if we reuse this object
+ // to connect to another server, force that server to request a
+ // downgrade again
+ mProtocolVersion = oldProtocolVersion;
+
+ mThreadState = {};
+ });
+
if (status_t status = connectAndInit({}, false /*incoming*/); status != OK) return status;
{
@@ -464,6 +490,8 @@
if (status_t status = connectAndInit(mId, true /*incoming*/); status != OK) return status;
}
+ cleanup.Disable();
+
return OK;
}
@@ -634,12 +662,12 @@
std::lock_guard<std::mutex> _l(mMutex);
connection->rpcTransport = std::move(rpcTransport);
connection->exclusiveTid = gettid();
- mOutgoingConnections.push_back(connection);
+ mThreadState.mOutgoingConnections.push_back(connection);
}
status_t status = OK;
if (init) {
- mState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+ mRpcBinderState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
}
{
@@ -671,9 +699,9 @@
std::unique_ptr<RpcTransport> rpcTransport) {
std::lock_guard<std::mutex> _l(mMutex);
- if (mIncomingConnections.size() >= mMaxThreads) {
+ if (mThreadState.mIncomingConnections.size() >= mMaxThreads) {
ALOGE("Cannot add thread to session with %zu threads (max is set to %zu)",
- mIncomingConnections.size(), mMaxThreads);
+ mThreadState.mIncomingConnections.size(), mMaxThreads);
return nullptr;
}
@@ -681,7 +709,7 @@
// happens when new connections are still being established as part of a
// very short-lived session which shuts down after it already started
// accepting new connections.
- if (mIncomingConnections.size() < mMaxIncomingConnections) {
+ if (mThreadState.mIncomingConnections.size() < mThreadState.mMaxIncomingConnections) {
return nullptr;
}
@@ -689,18 +717,19 @@
session->rpcTransport = std::move(rpcTransport);
session->exclusiveTid = gettid();
- mIncomingConnections.push_back(session);
- mMaxIncomingConnections = mIncomingConnections.size();
+ mThreadState.mIncomingConnections.push_back(session);
+ mThreadState.mMaxIncomingConnections = mThreadState.mIncomingConnections.size();
return session;
}
bool RpcSession::removeIncomingConnection(const sp<RpcConnection>& connection) {
std::unique_lock<std::mutex> _l(mMutex);
- if (auto it = std::find(mIncomingConnections.begin(), mIncomingConnections.end(), connection);
- it != mIncomingConnections.end()) {
- mIncomingConnections.erase(it);
- if (mIncomingConnections.size() == 0) {
+ if (auto it = std::find(mThreadState.mIncomingConnections.begin(),
+ mThreadState.mIncomingConnections.end(), connection);
+ it != mThreadState.mIncomingConnections.end()) {
+ mThreadState.mIncomingConnections.erase(it);
+ if (mThreadState.mIncomingConnections.size() == 0) {
sp<EventListener> listener = mEventListener.promote();
if (listener) {
_l.unlock();
@@ -725,7 +754,7 @@
pid_t tid = gettid();
std::unique_lock<std::mutex> _l(session->mMutex);
- session->mWaitingThreads++;
+ session->mThreadState.mWaitingThreads++;
while (true) {
sp<RpcConnection> exclusive;
sp<RpcConnection> available;
@@ -733,8 +762,8 @@
// CHECK FOR DEDICATED CLIENT SOCKET
//
// A server/looper should always use a dedicated connection if available
- findConnection(tid, &exclusive, &available, session->mOutgoingConnections,
- session->mOutgoingConnectionsOffset);
+ findConnection(tid, &exclusive, &available, session->mThreadState.mOutgoingConnections,
+ session->mThreadState.mOutgoingConnectionsOffset);
// WARNING: this assumes a server cannot request its client to send
// a transaction, as mIncomingConnections is excluded below.
@@ -747,8 +776,9 @@
// command. So, we move to considering the second available thread
// for subsequent calls.
if (use == ConnectionUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
- session->mOutgoingConnectionsOffset = (session->mOutgoingConnectionsOffset + 1) %
- session->mOutgoingConnections.size();
+ session->mThreadState.mOutgoingConnectionsOffset =
+ (session->mThreadState.mOutgoingConnectionsOffset + 1) %
+ session->mThreadState.mOutgoingConnections.size();
}
// USE SERVING SOCKET (e.g. nested transaction)
@@ -756,7 +786,7 @@
sp<RpcConnection> exclusiveIncoming;
// server connections are always assigned to a thread
findConnection(tid, &exclusiveIncoming, nullptr /*available*/,
- session->mIncomingConnections, 0 /* index hint */);
+ session->mThreadState.mIncomingConnections, 0 /* index hint */);
// asynchronous calls cannot be nested, we currently allow ref count
// calls to be nested (so that you can use this without having extra
@@ -785,19 +815,20 @@
break;
}
- if (session->mOutgoingConnections.size() == 0) {
+ if (session->mThreadState.mOutgoingConnections.size() == 0) {
ALOGE("Session has no client connections. This is required for an RPC server to make "
"any non-nested (e.g. oneway or on another thread) calls. Use: %d. Server "
"connections: %zu",
- static_cast<int>(use), session->mIncomingConnections.size());
+ static_cast<int>(use), session->mThreadState.mIncomingConnections.size());
return WOULD_BLOCK;
}
LOG_RPC_DETAIL("No available connections (have %zu clients and %zu servers). Waiting...",
- session->mOutgoingConnections.size(), session->mIncomingConnections.size());
+ session->mThreadState.mOutgoingConnections.size(),
+ session->mThreadState.mIncomingConnections.size());
session->mAvailableConnectionCv.wait(_l);
}
- session->mWaitingThreads--;
+ session->mThreadState.mWaitingThreads--;
return OK;
}
@@ -836,7 +867,7 @@
if (!mReentrant && mConnection != nullptr) {
std::unique_lock<std::mutex> _l(mSession->mMutex);
mConnection->exclusiveTid = std::nullopt;
- if (mSession->mWaitingThreads > 0) {
+ if (mSession->mThreadState.mWaitingThreads > 0) {
_l.unlock();
mSession->mAvailableConnectionCv.notify_one();
}
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index e727772..3f7dd11 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -36,7 +36,6 @@
uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
virtual sp<IMemory> allocate(size_t size);
- virtual void deallocate(size_t offset);
virtual void dump(const char* what) const;
// allocations are aligned to some value. return that value so clients can account for it.
@@ -48,6 +47,8 @@
virtual ~MemoryDealer();
private:
+ friend class Allocation;
+ virtual void deallocate(size_t offset);
const sp<IMemoryHeap>& heap() const;
SimpleBestFitAllocator* allocator() const;
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 12d448d..19888b7 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -168,7 +168,7 @@
sp<RpcServer> server();
// internal only
- const std::unique_ptr<RpcState>& state() { return mState; }
+ const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
private:
friend sp<RpcSession>;
@@ -303,7 +303,7 @@
std::unique_ptr<FdTrigger> mShutdownTrigger;
- std::unique_ptr<RpcState> mState;
+ std::unique_ptr<RpcState> mRpcBinderState;
std::mutex mMutex; // for all below
@@ -311,13 +311,16 @@
std::optional<uint32_t> mProtocolVersion;
std::condition_variable mAvailableConnectionCv; // for mWaitingThreads
- size_t mWaitingThreads = 0;
- // hint index into clients, ++ when sending an async transaction
- size_t mOutgoingConnectionsOffset = 0;
- std::vector<sp<RpcConnection>> mOutgoingConnections;
- size_t mMaxIncomingConnections = 0;
- std::vector<sp<RpcConnection>> mIncomingConnections;
- std::map<std::thread::id, std::thread> mThreads;
+
+ struct ThreadState {
+ size_t mWaitingThreads = 0;
+ // hint index into clients, ++ when sending an async transaction
+ size_t mOutgoingConnectionsOffset = 0;
+ std::vector<sp<RpcConnection>> mOutgoingConnections;
+ size_t mMaxIncomingConnections = 0;
+ std::vector<sp<RpcConnection>> mIncomingConnections;
+ std::map<std::thread::id, std::thread> mThreads;
+ } mThreadState;
};
} // namespace android
diff --git a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
index f9dda8c..f5e3af5 100644
--- a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
@@ -46,15 +46,6 @@
[&]() -> void { dealer->getAllocationAlignment(); },
[&]() -> void { dealer->getMemoryHeap(); },
[&]() -> void {
- size_t offset = fdp.ConsumeIntegral<size_t>();
-
- // Offset has already been freed, so return instead.
- if (free_list.find(offset) != free_list.end()) return;
-
- dealer->deallocate(offset);
- free_list.insert(offset);
- },
- [&]() -> void {
std::string randString = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
dealer->dump(randString.c_str());
},
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 14ec948..2b17616 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -747,14 +747,26 @@
std::unique_lock<std::mutex> lock(mMutex);
while (!mDone) {
while (!mRunnables.empty()) {
- std::function<void()> runnable = mRunnables.front();
- mRunnables.pop_front();
- runnable();
+ std::deque<std::function<void()>> runnables = std::move(mRunnables);
+ mRunnables.clear();
+ lock.unlock();
+ // Run outside the lock since the runnable might trigger another
+ // post to the async worker.
+ execute(runnables);
+ lock.lock();
}
mCv.wait(lock);
}
}
+ void execute(std::deque<std::function<void()>>& runnables) {
+ while (!runnables.empty()) {
+ std::function<void()> runnable = runnables.front();
+ runnables.pop_front();
+ runnable();
+ }
+ }
+
public:
AsyncWorker() : Singleton<AsyncWorker>() { mThread = std::thread(&AsyncWorker::run, this); }
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index cf61209..f848e4f 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -50,7 +50,6 @@
transform(0),
transformToDisplayInverse(false),
crop(Rect::INVALID_RECT),
- orientedDisplaySpaceRect(Rect::INVALID_RECT),
dataspace(ui::Dataspace::UNKNOWN),
surfaceDamageRegion(),
api(-1),
@@ -100,7 +99,6 @@
SAFE_PARCEL(output.write, transparentRegion);
SAFE_PARCEL(output.writeUint32, transform);
SAFE_PARCEL(output.writeBool, transformToDisplayInverse);
- SAFE_PARCEL(output.write, orientedDisplaySpaceRect);
SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dataspace));
SAFE_PARCEL(output.write, hdrMetadata);
@@ -195,7 +193,6 @@
SAFE_PARCEL(input.read, transparentRegion);
SAFE_PARCEL(input.readUint32, &transform);
SAFE_PARCEL(input.readBool, &transformToDisplayInverse);
- SAFE_PARCEL(input.read, orientedDisplaySpaceRect);
uint32_t tmpUint32 = 0;
SAFE_PARCEL(input.readUint32, &tmpUint32);
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 1f5d289..b01eed4 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -206,7 +206,6 @@
uint32_t transform;
bool transformToDisplayInverse;
Rect crop;
- Rect orientedDisplaySpaceRect;
BufferData bufferData;
ui::Dataspace dataspace;
HdrMetadata hdrMetadata;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index a1542c8..390ff96 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -65,8 +65,8 @@
return result;
}
-vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
- const vec2 transformedXy = transform.transform(x, y);
+vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) {
+ const vec2 transformedXy = transform.transform(xy);
const vec2 transformedOrigin = transform.transform(0, 0);
return transformedXy - transformedOrigin;
}
@@ -501,21 +501,16 @@
const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- // For compatibility, convert raw coordinates into logical display space.
- const vec2 xy = shouldDisregardTranslation(mSource)
- ? transformWithoutTranslation(mRawTransform, coords->getX(), coords->getY())
- : mRawTransform.transform(coords->getX(), coords->getY());
+ const vec2 xy = calculateTransformedXY(mSource, mRawTransform, coords->getXYValue());
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
- // For compatibility, since we report raw coordinates in logical display space, we
- // need to convert the relative axes into the same orientation for consistency.
const vec2 relativeXy =
transformWithoutTranslation(mRawTransform,
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
}
@@ -527,9 +522,7 @@
const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- const vec2 xy = shouldDisregardTranslation(mSource)
- ? transformWithoutTranslation(mTransform, coords->getX(), coords->getY())
- : mTransform.transform(coords->getXYValue());
+ const vec2 xy = calculateTransformedXY(mSource, mTransform, coords->getXYValue());
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
@@ -537,8 +530,8 @@
if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
const vec2 relativeXy =
transformWithoutTranslation(mTransform,
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
}
@@ -815,6 +808,12 @@
return android::base::StringPrintf("%" PRId32, action);
}
+vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& transform,
+ const vec2& xy) {
+ return shouldDisregardTranslation(source) ? transformWithoutTranslation(transform, xy)
+ : transform.transform(xy);
+}
+
// --- FocusEvent ---
void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
@@ -969,6 +968,13 @@
return;
}
break;
+ case AINPUT_EVENT_TYPE_TOUCH_MODE:
+ if (mTouchModeEventPool.size() < mMaxPoolSize) {
+ mTouchModeEventPool.push(
+ std::unique_ptr<TouchModeEvent>(static_cast<TouchModeEvent*>(event)));
+ return;
+ }
+ break;
}
delete event;
}
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index bcb0071..c03581d 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -40,14 +40,15 @@
entry.repeatCount};
}
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
- const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
- const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+ const ui::Transform& rawTransform) {
+ const vec2 rawXY = MotionEvent::calculateTransformedXY(entry.source, rawTransform,
+ entry.pointerCoords[0].getXYValue());
const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
entry.displayId},
- rawX,
- rawY,
+ rawXY.x,
+ rawXY.y,
actionMasked,
entry.downTime,
entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 7a121ce..477781a 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -254,7 +254,8 @@
};
VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+ const ui::Transform& rawTransform);
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 695dd17..1baa100 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -915,7 +915,7 @@
*/
bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
- (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
+ isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
// Optimize case where the current application is unresponsive and the user
// decides to touch a window in a different application.
@@ -1609,7 +1609,7 @@
return true;
}
- bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
+ const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
// Identify targets.
std::vector<InputTarget> inputTargets;
@@ -1995,7 +1995,7 @@
maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
- const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
+ const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
bool wrongDevice = false;
if (newGesture) {
bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
@@ -3360,16 +3360,18 @@
const std::array<uint8_t, 32> InputDispatcher::getSignature(
const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
- int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
- if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
+ const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
+ if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
// Only sign events up and down events as the purely move events
// are tied to their up/down counterparts so signing would be redundant.
- VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
- verifiedEvent.actionMasked = actionMasked;
- verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
- return sign(verifiedEvent);
+ return INVALID_HMAC;
}
- return INVALID_HMAC;
+
+ VerifiedMotionEvent verifiedEvent =
+ verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
+ verifiedEvent.actionMasked = actionMasked;
+ verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
+ return sign(verifiedEvent);
}
const std::array<uint8_t, 32> InputDispatcher::getSignature(
@@ -4190,12 +4192,17 @@
case AINPUT_EVENT_TYPE_MOTION: {
const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
- int32_t action = motionEvent.getAction();
- size_t pointerCount = motionEvent.getPointerCount();
+ const int32_t action = motionEvent.getAction();
+ const bool isPointerEvent =
+ isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
+ // If a pointer event has no displayId specified, inject it to the default display.
+ const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
+ ? ADISPLAY_ID_DEFAULT
+ : event->getDisplayId();
+ const size_t pointerCount = motionEvent.getPointerCount();
const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
- int32_t actionButton = motionEvent.getActionButton();
+ const int32_t actionButton = motionEvent.getActionButton();
int32_t flags = motionEvent.getFlags();
- int32_t displayId = motionEvent.getDisplayId();
if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
return InputEventInjectionResult::FAILED;
}
@@ -4220,8 +4227,8 @@
std::unique_ptr<MotionEntry> injectedEntry =
std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
resolvedDeviceId, motionEvent.getSource(),
- motionEvent.getDisplayId(), policyFlags, action,
- actionButton, flags, motionEvent.getMetaState(),
+ displayId, policyFlags, action, actionButton,
+ flags, motionEvent.getMetaState(),
motionEvent.getButtonState(),
motionEvent.getClassification(),
motionEvent.getEdgeFlags(),
@@ -4241,9 +4248,8 @@
std::unique_ptr<MotionEntry> nextInjectedEntry =
std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
resolvedDeviceId, motionEvent.getSource(),
- motionEvent.getDisplayId(), policyFlags,
- action, actionButton, flags,
- motionEvent.getMetaState(),
+ displayId, policyFlags, action, actionButton,
+ flags, motionEvent.getMetaState(),
motionEvent.getButtonState(),
motionEvent.getClassification(),
motionEvent.getEdgeFlags(),
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 42d3e58..ca77d7a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2801,7 +2801,14 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+ ui::Transform transform;
+ transform.set({1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0, 0, 1});
+
+ gui::DisplayInfo displayInfo;
+ displayInfo.displayId = ADISPLAY_ID_DEFAULT;
+ displayInfo.transform = transform;
+
+ mDispatcher->onWindowInfosChanged({*window->getInfo()}, {displayInfo});
NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -2822,8 +2829,11 @@
const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
- EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
- EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
+ const vec2 rawXY =
+ MotionEvent::calculateTransformedXY(motionArgs.source, transform,
+ motionArgs.pointerCoords[0].getXYValue());
+ EXPECT_EQ(rawXY.x, verifiedMotion.rawX);
+ EXPECT_EQ(rawXY.y, verifiedMotion.rawY);
EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);