Fix drag and drop (1/3)
Added ability to send different InputWindowCommands to SurfaceFlinger. Also
added transferTouchFocus function from client so it can be translated to an
InputWindowCommand and passed to SF.
Bug: 120463595
Test: Builds, no uses of new function
Change-Id: I17deaf4a96d5a5bf6b14795d66419acffdb10882
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 799151a..2f6ef79 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -75,7 +75,8 @@
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) {
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& commands) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -91,6 +92,7 @@
data.writeUint32(flags);
data.writeStrongBinder(applyToken);
+ commands.write(data);
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
@@ -750,7 +752,9 @@
uint32_t stateFlags = data.readUint32();
sp<IBinder> applyToken = data.readStrongBinder();
- setTransactionState(state, displays, stateFlags, applyToken);
+ InputWindowCommands inputWindowCommands;
+ inputWindowCommands.read(data);
+ setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands);
return NO_ERROR;
}
case BOOT_FINISHED: {
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 35ce6e3..e5170ab 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -379,4 +379,36 @@
}
}
+// ------------------------------- InputWindowCommands ----------------------------------------
+
+void InputWindowCommands::merge(const InputWindowCommands& other) {
+ transferTouchFocusCommands
+ .insert(transferTouchFocusCommands.end(),
+ std::make_move_iterator(other.transferTouchFocusCommands.begin()),
+ std::make_move_iterator(other.transferTouchFocusCommands.end()));
+}
+
+void InputWindowCommands::clear() {
+ transferTouchFocusCommands.clear();
+}
+
+void InputWindowCommands::write(Parcel& output) const {
+ output.writeUint32(static_cast<uint32_t>(transferTouchFocusCommands.size()));
+ for (const auto& transferTouchFocusCommand : transferTouchFocusCommands) {
+ output.writeStrongBinder(transferTouchFocusCommand.fromToken);
+ output.writeStrongBinder(transferTouchFocusCommand.toToken);
+ }
+}
+
+void InputWindowCommands::read(const Parcel& input) {
+ size_t count = input.readUint32();
+ transferTouchFocusCommands.clear();
+ for (size_t i = 0; i < count; i++) {
+ TransferTouchFocusCommand transferTouchFocusCommand;
+ transferTouchFocusCommand.fromToken = input.readStrongBinder();
+ transferTouchFocusCommand.toToken = input.readStrongBinder();
+ transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+ }
+}
+
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5b004e2..e043762 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -166,6 +166,7 @@
mEarlyWakeup(other.mEarlyWakeup) {
mDisplayStates = other.mDisplayStates;
mComposerStates = other.mComposerStates;
+ mInputWindowCommands = other.mInputWindowCommands;
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
@@ -199,6 +200,8 @@
}
other.mListenerCallbacks.clear();
+ mInputWindowCommands.merge(other.mInputWindowCommands);
+
return *this;
}
@@ -265,8 +268,8 @@
mEarlyWakeup = false;
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
-
- sf->setTransactionState(composerStates, displayStates, flags, applyToken);
+ sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands);
+ mInputWindowCommands.clear();
mStatus = NO_ERROR;
return NO_ERROR;
}
@@ -804,6 +807,16 @@
s->what |= layer_state_t::eInputInfoChanged;
return *this;
}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::transferTouchFocus(
+ const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+ InputWindowCommands::TransferTouchFocusCommand transferTouchFocusCommand;
+ transferTouchFocusCommand.fromToken = fromToken;
+ transferTouchFocusCommand.toToken = toToken;
+ mInputWindowCommands.transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+ return *this;
+}
+
#endif
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8cb40e7..e0ff410 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -42,6 +42,7 @@
struct DisplayState;
struct DisplayInfo;
struct DisplayStatInfo;
+struct InputWindowCommands;
class LayerDebugInfo;
class HdrCapabilities;
class IDisplayEventConnection;
@@ -125,7 +126,8 @@
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) = 0;
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 02c6be2..e7564f5 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -228,6 +228,20 @@
status_t read(const Parcel& input);
};
+struct InputWindowCommands {
+ struct TransferTouchFocusCommand {
+ sp<IBinder> fromToken;
+ sp<IBinder> toToken;
+ };
+
+ std::vector<TransferTouchFocusCommand> transferTouchFocusCommands;
+
+ void merge(const InputWindowCommands& other);
+ void clear();
+ void write(Parcel& output) const;
+ void read(const Parcel& input);
+};
+
static inline int compare_type(const ComposerState& lhs, const ComposerState& rhs) {
if (lhs.client < rhs.client) return -1;
if (lhs.client > rhs.client) return 1;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8e3ba78..9765cdd 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -219,6 +219,7 @@
bool mAnimation = false;
bool mEarlyWakeup = false;
+ InputWindowCommands mInputWindowCommands;
int mStatus = NO_ERROR;
layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -335,6 +336,7 @@
#ifndef NO_INPUT
Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
+ Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
#endif
Transaction& destroySurface(const sp<SurfaceControl>& sc);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index c56304f..13fac7f 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -559,7 +559,8 @@
sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; }
void setTransactionState(const Vector<ComposerState>& /*state*/,
const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
- const sp<IBinder>& /*applyToken*/) override {}
+ const sp<IBinder>& /*applyToken*/,
+ const InputWindowCommands& /*inputWindowCommands*/) override {}
void bootFinished() override {}
bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& /*surface*/) const override {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02cd9d9..4d68559 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3337,7 +3337,7 @@
if (composerStateContainsUnsignaledFences(states)) {
break;
}
- applyTransactionState(states, displays, flags);
+ applyTransactionState(states, displays, flags, mInputWindowCommands);
transactionQueue.pop();
}
@@ -3383,7 +3383,8 @@
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) {
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands) {
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
@@ -3399,11 +3400,12 @@
return;
}
- applyTransactionState(states, displays, flags);
+ applyTransactionState(states, displays, flags, inputWindowCommands);
}
void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
- const Vector<DisplayState>& displays, uint32_t flags) {
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const InputWindowCommands& inputWindowCommands) {
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
@@ -3444,6 +3446,8 @@
setDestroyStateLocked(state);
}
+ transactionFlags |= addInputWindowCommands(inputWindowCommands);
+
// If a synchronous transaction is explicitly requested without any changes, force a transaction
// anyway. This can be used as a flush mechanism for previous async transactions.
// Empty animation transaction can be used to simulate back-pressure, so also force a
@@ -3781,6 +3785,16 @@
}
}
+uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
+ uint32_t flags = 0;
+ if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
+ flags |= eTraversalNeeded;
+ }
+
+ mInputWindowCommands.merge(inputWindowCommands);
+ return flags;
+}
+
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
@@ -3995,7 +4009,7 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0, nullptr);
+ setTransactionState(state, displays, 0, nullptr, mInputWindowCommands);
const auto display = getDisplayDevice(displayToken);
if (!display) return;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 822bb18..c37f159 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -443,7 +443,8 @@
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken);
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands);
virtual void bootFinished();
virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -555,8 +556,8 @@
* Transactions
*/
void applyTransactionState(const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags)
- REQUIRES(mStateLock);
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock);
bool flushTransactionQueues();
uint32_t getTransactionFlags(uint32_t flags);
uint32_t peekTransactionFlags();
@@ -570,6 +571,7 @@
uint32_t setClientStateLocked(const ComposerState& composerState);
uint32_t setDisplayStateLocked(const DisplayState& s);
void setDestroyStateLocked(const ComposerState& composerState);
+ uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
/* ------------------------------------------------------------------------
* Layer management
@@ -1020,6 +1022,8 @@
sp<Scheduler::ConnectionHandle> mSfConnectionHandle;
sp<IInputFlinger> mInputFlinger;
+
+ InputWindowCommands mInputWindowCommands;
};
}; // namespace android