Loading libs/binder/OS_unix_base.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ ssize_t sendMessageOnSocket(const RpcTransportFd& socket, iovec* iovs, int niovs memcpy(CMSG_DATA(cmsg), fds, fdsByteSize); msg.msg_controllen = CMSG_SPACE(fdsByteSize); return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC)); return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL)); } msghdr msg{ Loading @@ -125,7 +125,8 @@ ssize_t receiveMessageFromSocket(const RpcTransportFd& socket, iovec* iovs, int .msg_control = msgControlBuf, .msg_controllen = sizeof(msgControlBuf), }; ssize_t processSize = TEMP_FAILURE_RETRY(recvmsg(socket.fd.get(), &msg, MSG_NOSIGNAL)); ssize_t processSize = TEMP_FAILURE_RETRY(recvmsg(socket.fd.get(), &msg, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC)); if (processSize < 0) { return -1; } Loading libs/binder/RpcState.cpp +55 −12 Original line number Diff line number Diff line Loading @@ -373,6 +373,7 @@ RpcState::CommandData::CommandData(size_t size) : mSize(size) { mData.reset(data); } // MUST ALWAYS SHUTDOWN ON ERROR, DUE TO CALLER CONSTRAITS status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs, const std::optional<SmallFunction<status_t()>>& altPoll, Loading @@ -397,6 +398,7 @@ status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection, return OK; } // MUST ALWAYS SHUTDOWN ON ERROR, DUE TO CALLER CONSTRAITS status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs, std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) { Loading Loading @@ -568,6 +570,11 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti LOG_ALWAYS_FATAL_IF(!data.isForRpc()); LOG_ALWAYS_FATAL_IF(data.objectsCount() != 0); if (!(flags & IBinder::FLAG_ONEWAY)) { LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction."); } uint64_t asyncNumber = 0; if (address != 0) { Loading Loading @@ -659,8 +666,8 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti return OK; } LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction."); // b/416734088 // NOW THAT WE'VE SENT TRANSACTION, WE MUST READ FULL RESULT FOR PROTOCOL TO BE IN SYNC return waitForReply(connection, session, reply); } Loading @@ -683,14 +690,14 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, ? &ancillaryFds : nullptr); status != OK) return status; return status; // rpcRec failure calls shutdown if (command.command == RPC_COMMAND_REPLY) break; if (status_t status = processCommand(connection, session, command, CommandType::ANY, std::move(ancillaryFds)); status != OK) return status; return status; // processCommand must shutdown on failure // Reset to avoid spurious use-after-move warning from clang-tidy. ancillaryFds = decltype(ancillaryFds)(); Loading Loading @@ -722,8 +729,12 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, {data.data(), data.size()}, }; if (status_t status = rpcRec(connection, session, "reply body", iovs, countof(iovs), nullptr); status != OK) status != OK) { // rpcRec shuts down connection on failure return status; } // NOW THAT WE'VE READ RESPONSE, WE CAN RETURN WITHOUT SHUTTING DOWN THE CONNECTION. if (rpcReply.status != OK) return rpcReply.status; Loading Loading @@ -806,9 +817,13 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con rpcRec(connection, session, "command header (for server)", &iov, 1, enableAncillaryFds(session->getFileDescriptorTransportMode()) ? &ancillaryFds : nullptr); status != OK) status != OK) { return status; } // b/416734088 // NOW THAT WE'VE READ HEADER WE MUST READ THE REST AND WRITE FULL RESPONSE, OR OTHERWISE // SHUTDOWN THE SERVICE return processCommand(connection, session, command, type, std::move(ancillaryFds)); } Loading @@ -825,6 +840,9 @@ status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection return OK; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO waitForReply. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO getAndExecuteCommand and // waitForReply. status_t RpcState::processCommand( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command, CommandType type, Loading Loading @@ -867,6 +885,9 @@ status_t RpcState::processCommand( (void)session->shutdownAndWait(false); return DEAD_OBJECT; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processTransact( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command, Loading @@ -883,9 +904,13 @@ status_t RpcState::processTransact( } iovec iov{transactionData.data(), transactionData.size()}; if (status_t status = rpcRec(connection, session, "transaction body", &iov, 1, nullptr); status != OK) return status; status != OK) { return status; // rpcRec always shuts down on error } // ACCORDING TO RPC BINDER PROTOCOL: // - if the transaction is oneway, we must not write a response // - if the transaction is twoway, we must ALWAYS write a response return processTransactInternal(connection, session, std::move(transactionData), std::move(ancillaryFds)); } Loading @@ -898,6 +923,11 @@ static void do_nothing_to_transact_data(const uint8_t* data, size_t dataSize, (void)objectsCount; } // ACCORDING TO RPC BINDER PROTOCOL: // - if the transaction is oneway, we must not write a response // - if the transaction is twoway, we must ALWAYS write a response // DUE TO CLIENT CONSTRAINTS, WE CANNOT RETURN AN ERROR WITHOUT SHUTTING DOWN THE CONNECTION // UNTIL THE FULL RESPONSE HAS BEEN WRITTEN. status_t RpcState::processTransactInternal( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, CommandData transactionData, Loading Loading @@ -982,6 +1012,8 @@ processTransactInternalTailCall: target.get(), numPending); } } // This is a oneway transaction (scheduled later), no response is required. return OK; } } Loading Loading @@ -1013,6 +1045,7 @@ processTransactInternalTailCall: " objectTableBytesSize=%zu. Terminating!", transactionData.size(), sizeof(RpcWireTransaction), transaction->parcelDataSize, objectTableBytes->size); (void)session->shutdownAndWait(false); return BAD_VALUE; } objectTableSpan = *maybeSpan; Loading Loading @@ -1186,6 +1219,8 @@ processTransactInternalTailCall: rpcFields->mFds.get()); } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command) { LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_DEC_STRONG, "command: %d", command.command); Loading @@ -1200,15 +1235,23 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect RpcDecStrong body; iovec iov{&body, sizeof(RpcDecStrong)}; if (status_t status = rpcRec(connection, session, "dec ref body", &iov, 1, nullptr); status != OK) return status; status != OK) { return status; // rpcRec shutsdown if it fails } // AT THIS POINT, WE HAVE READ THE FULL TRANSACTION, SO WE CAN RETURN WITHOUT MESSING // UP THE PROTOCOL uint64_t addr = RpcWireAddress::toRaw(body.address); RpcMutexUniqueLock _l(mNodeMutex); if (mTerminated) return DEAD_OBJECT; auto it = mNodeForAddress.find(addr); if (it == mNodeForAddress.end()) { ALOGE("Unknown binder address %" PRIu64 " for dec strong.", addr); return OK; ALOGE("Unknown binder address %" PRIu64 " for dec strong. Terminating!", addr); (void)session->shutdownAndWait(false); return BAD_VALUE; } sp<IBinder> target = it->second.binder.promote(); Loading libs/gui/Choreographer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,13 @@ void Choreographer::dispatchHotplugConnectionError(nsecs_t, int32_t connectionEr this, connectionError); } void Choreographer::dispatchModeChangedWithFrameRateOverrides(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t, nsecs_t, nsecs_t, std::vector<FrameRateOverride>) { LOG_ALWAYS_FATAL( "dispatchModeChangedWithFrameRateOverrides was called but was never registered"); } void Choreographer::dispatchModeChanged(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t, nsecs_t, nsecs_t) { LOG_ALWAYS_FATAL("dispatchModeChanged was called but was never registered"); Loading libs/gui/DisplayEventDispatcher.cpp +17 −2 Original line number Diff line number Diff line Loading @@ -27,10 +27,10 @@ #include <utils/Timers.h> #include <utils/Trace.h> #include <com_android_graphics_libgui_flags.h> #include <com_android_graphics_surfaceflinger_flags.h> namespace android { using namespace com::android::graphics::libgui; using namespace com::android::graphics::surfaceflinger; // Number of events to read at a time from the DisplayEventDispatcher pipe. // The value should be large enough that we can quickly drain the pipe Loading Loading @@ -193,11 +193,23 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, } break; case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: LOG_ALWAYS_FATAL_IF(flags::unify_refresh_rate_callbacks(), "dispatchModeChanged should not be sent when" " refresh rate callbacks are unified"); dispatchModeChanged(ev.header.timestamp, ev.header.displayId, ev.modeChange.modeId, ev.modeChange.vsyncPeriod, ev.modeChange.appVsyncOffset, ev.modeChange.presentationDeadline); break; case DisplayEventType::DISPLAY_EVENT_MODE_AND_FRAME_RATE_CHANGE: dispatchModeChangedWithFrameRateOverrides(ev.header.timestamp, ev.header.displayId, ev.modeChange.modeId, ev.modeChange.vsyncPeriod, ev.modeChange.appVsyncOffset, ev.modeChange.presentationDeadline, std::move(mFrameRateOverrides)); break; case DisplayEventType::DISPLAY_EVENT_NULL: dispatchNullEvent(ev.header.timestamp, ev.header.displayId); break; Loading @@ -205,6 +217,9 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, mFrameRateOverrides.emplace_back(ev.frameRateOverride); break; case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: LOG_ALWAYS_FATAL_IF(flags::unify_refresh_rate_callbacks(), "dispatchFrameRateOverrides should not be sent when" " refresh rate callbacks are unified"); dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId, std::move(mFrameRateOverrides)); break; Loading libs/gui/ISurfaceComposer.cpp +23 −59 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <gui/SchedulingPolicy.h> #include <gui/SimpleTransactionState.h> #include <gui/TransactionState.h> #include <private/gui/ParcelUtils.h> #include <stdint.h> #include <sys/types.h> Loading @@ -50,22 +52,17 @@ using gui::IWindowInfosListener; using gui::LayerCaptureArgs; using ui::ColorMode; class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { public: explicit BpSurfaceComposer(const sp<IBinder>& impl) : BpInterface<ISurfaceComposer>(impl) { } explicit BpSurfaceComposer(const sp<IBinder>& impl) : BpInterface<ISurfaceComposer>(impl) {} virtual ~BpSurfaceComposer(); status_t setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, const SimpleTransactionState simpleState, const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, Vector<DisplayState>& displays, const sp<IBinder>& applyToken, const std::vector<client_cache_t>& uncacheBuffers, const TransactionListenerCallbacks& listenerCallbacks, const std::vector<uint64_t>& mergedTransactionIds, const std::vector<gui::EarlyWakeupInfo>& earlyWakeupInfos) override { Parcel data, reply; Loading @@ -83,25 +80,15 @@ public: SAFE_PARCEL(d.write, data); } SAFE_PARCEL(data.writeUint32, flags); SAFE_PARCEL(simpleState.writeToParcel, &data); SAFE_PARCEL(data.writeStrongBinder, applyToken); SAFE_PARCEL(commands.write, data); SAFE_PARCEL(data.writeInt64, desiredPresentTime); SAFE_PARCEL(data.writeBool, isAutoTimestamp); SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size())); for (const client_cache_t& uncacheBuffer : uncacheBuffers) { SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote()); SAFE_PARCEL(data.writeUint64, uncacheBuffer.id); } SAFE_PARCEL(data.writeBool, hasListenerCallbacks); SAFE_PARCEL(data.writeVectorSize, listenerCallbacks); for (const auto& [listener, callbackIds] : listenerCallbacks) { SAFE_PARCEL(data.writeStrongBinder, listener); SAFE_PARCEL(data.writeParcelableVector, callbackIds); } SAFE_PARCEL(data.writeUint64, transactionId); SAFE_PARCEL(listenerCallbacks.writeToParcel, &data); SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(mergedTransactionIds.size())); for (auto mergedTransactionId : mergedTransactionIds) { Loading @@ -113,12 +100,11 @@ public: e.writeToParcel(&data); } if (flags & ISurfaceComposer::eOneWay) { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply, IBinder::FLAG_ONEWAY); if (simpleState.mFlags & ISurfaceComposer::eOneWay) { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply, IBinder::FLAG_ONEWAY); } else { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } } }; Loading @@ -131,9 +117,8 @@ IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); // ---------------------------------------------------------------------- status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t BnSurfaceComposer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); Loading @@ -160,17 +145,11 @@ status_t BnSurfaceComposer::onTransact( displays.add(d); } uint32_t stateFlags = 0; SAFE_PARCEL(data.readUint32, &stateFlags); SimpleTransactionState simpleState; SAFE_PARCEL(simpleState.readFromParcel, &data); sp<IBinder> applyToken; SAFE_PARCEL(data.readStrongBinder, &applyToken); InputWindowCommands inputWindowCommands; SAFE_PARCEL(inputWindowCommands.read, data); int64_t desiredPresentTime = 0; bool isAutoTimestamp = true; SAFE_PARCEL(data.readInt64, &desiredPresentTime); SAFE_PARCEL(data.readBool, &isAutoTimestamp); SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); std::vector<client_cache_t> uncacheBuffers(count); Loading @@ -181,21 +160,8 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id); } bool hasListenerCallbacks = false; SAFE_PARCEL(data.readBool, &hasListenerCallbacks); std::vector<ListenerCallbacks> listenerCallbacks; int32_t listenersSize = 0; SAFE_PARCEL_READ_SIZE(data.readInt32, &listenersSize, data.dataSize()); for (int32_t i = 0; i < listenersSize; i++) { SAFE_PARCEL(data.readStrongBinder, &tmpBinder); std::vector<CallbackId> callbackIds; SAFE_PARCEL(data.readParcelableVector, &callbackIds); listenerCallbacks.emplace_back(tmpBinder, callbackIds); } uint64_t transactionId = -1; SAFE_PARCEL(data.readUint64, &transactionId); TransactionListenerCallbacks listenerCallbacks; SAFE_PARCEL(listenerCallbacks.readFromParcel, &data); SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); std::vector<uint64_t> mergedTransactions(count); Loading @@ -213,10 +179,8 @@ status_t BnSurfaceComposer::onTransact( earlyWakeupInfos.push_back(std::move(e)); } return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken, std::move(inputWindowCommands), desiredPresentTime, isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, listenerCallbacks, transactionId, mergedTransactions, return setTransactionState(simpleState, frameTimelineInfo, state, displays, applyToken, uncacheBuffers, listenerCallbacks, mergedTransactions, earlyWakeupInfos); } case GET_SCHEDULING_POLICY: { Loading Loading
libs/binder/OS_unix_base.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ ssize_t sendMessageOnSocket(const RpcTransportFd& socket, iovec* iovs, int niovs memcpy(CMSG_DATA(cmsg), fds, fdsByteSize); msg.msg_controllen = CMSG_SPACE(fdsByteSize); return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC)); return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL)); } msghdr msg{ Loading @@ -125,7 +125,8 @@ ssize_t receiveMessageFromSocket(const RpcTransportFd& socket, iovec* iovs, int .msg_control = msgControlBuf, .msg_controllen = sizeof(msgControlBuf), }; ssize_t processSize = TEMP_FAILURE_RETRY(recvmsg(socket.fd.get(), &msg, MSG_NOSIGNAL)); ssize_t processSize = TEMP_FAILURE_RETRY(recvmsg(socket.fd.get(), &msg, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC)); if (processSize < 0) { return -1; } Loading
libs/binder/RpcState.cpp +55 −12 Original line number Diff line number Diff line Loading @@ -373,6 +373,7 @@ RpcState::CommandData::CommandData(size_t size) : mSize(size) { mData.reset(data); } // MUST ALWAYS SHUTDOWN ON ERROR, DUE TO CALLER CONSTRAITS status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs, const std::optional<SmallFunction<status_t()>>& altPoll, Loading @@ -397,6 +398,7 @@ status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection, return OK; } // MUST ALWAYS SHUTDOWN ON ERROR, DUE TO CALLER CONSTRAITS status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs, std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) { Loading Loading @@ -568,6 +570,11 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti LOG_ALWAYS_FATAL_IF(!data.isForRpc()); LOG_ALWAYS_FATAL_IF(data.objectsCount() != 0); if (!(flags & IBinder::FLAG_ONEWAY)) { LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction."); } uint64_t asyncNumber = 0; if (address != 0) { Loading Loading @@ -659,8 +666,8 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti return OK; } LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction."); // b/416734088 // NOW THAT WE'VE SENT TRANSACTION, WE MUST READ FULL RESULT FOR PROTOCOL TO BE IN SYNC return waitForReply(connection, session, reply); } Loading @@ -683,14 +690,14 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, ? &ancillaryFds : nullptr); status != OK) return status; return status; // rpcRec failure calls shutdown if (command.command == RPC_COMMAND_REPLY) break; if (status_t status = processCommand(connection, session, command, CommandType::ANY, std::move(ancillaryFds)); status != OK) return status; return status; // processCommand must shutdown on failure // Reset to avoid spurious use-after-move warning from clang-tidy. ancillaryFds = decltype(ancillaryFds)(); Loading Loading @@ -722,8 +729,12 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, {data.data(), data.size()}, }; if (status_t status = rpcRec(connection, session, "reply body", iovs, countof(iovs), nullptr); status != OK) status != OK) { // rpcRec shuts down connection on failure return status; } // NOW THAT WE'VE READ RESPONSE, WE CAN RETURN WITHOUT SHUTTING DOWN THE CONNECTION. if (rpcReply.status != OK) return rpcReply.status; Loading Loading @@ -806,9 +817,13 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con rpcRec(connection, session, "command header (for server)", &iov, 1, enableAncillaryFds(session->getFileDescriptorTransportMode()) ? &ancillaryFds : nullptr); status != OK) status != OK) { return status; } // b/416734088 // NOW THAT WE'VE READ HEADER WE MUST READ THE REST AND WRITE FULL RESPONSE, OR OTHERWISE // SHUTDOWN THE SERVICE return processCommand(connection, session, command, type, std::move(ancillaryFds)); } Loading @@ -825,6 +840,9 @@ status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection return OK; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO waitForReply. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO getAndExecuteCommand and // waitForReply. status_t RpcState::processCommand( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command, CommandType type, Loading Loading @@ -867,6 +885,9 @@ status_t RpcState::processCommand( (void)session->shutdownAndWait(false); return DEAD_OBJECT; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processTransact( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command, Loading @@ -883,9 +904,13 @@ status_t RpcState::processTransact( } iovec iov{transactionData.data(), transactionData.size()}; if (status_t status = rpcRec(connection, session, "transaction body", &iov, 1, nullptr); status != OK) return status; status != OK) { return status; // rpcRec always shuts down on error } // ACCORDING TO RPC BINDER PROTOCOL: // - if the transaction is oneway, we must not write a response // - if the transaction is twoway, we must ALWAYS write a response return processTransactInternal(connection, session, std::move(transactionData), std::move(ancillaryFds)); } Loading @@ -898,6 +923,11 @@ static void do_nothing_to_transact_data(const uint8_t* data, size_t dataSize, (void)objectsCount; } // ACCORDING TO RPC BINDER PROTOCOL: // - if the transaction is oneway, we must not write a response // - if the transaction is twoway, we must ALWAYS write a response // DUE TO CLIENT CONSTRAINTS, WE CANNOT RETURN AN ERROR WITHOUT SHUTTING DOWN THE CONNECTION // UNTIL THE FULL RESPONSE HAS BEEN WRITTEN. status_t RpcState::processTransactInternal( const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, CommandData transactionData, Loading Loading @@ -982,6 +1012,8 @@ processTransactInternalTailCall: target.get(), numPending); } } // This is a oneway transaction (scheduled later), no response is required. return OK; } } Loading Loading @@ -1013,6 +1045,7 @@ processTransactInternalTailCall: " objectTableBytesSize=%zu. Terminating!", transactionData.size(), sizeof(RpcWireTransaction), transaction->parcelDataSize, objectTableBytes->size); (void)session->shutdownAndWait(false); return BAD_VALUE; } objectTableSpan = *maybeSpan; Loading Loading @@ -1186,6 +1219,8 @@ processTransactInternalTailCall: rpcFields->mFds.get()); } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, const RpcWireHeader& command) { LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_DEC_STRONG, "command: %d", command.command); Loading @@ -1200,15 +1235,23 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect RpcDecStrong body; iovec iov{&body, sizeof(RpcDecStrong)}; if (status_t status = rpcRec(connection, session, "dec ref body", &iov, 1, nullptr); status != OK) return status; status != OK) { return status; // rpcRec shutsdown if it fails } // AT THIS POINT, WE HAVE READ THE FULL TRANSACTION, SO WE CAN RETURN WITHOUT MESSING // UP THE PROTOCOL uint64_t addr = RpcWireAddress::toRaw(body.address); RpcMutexUniqueLock _l(mNodeMutex); if (mTerminated) return DEAD_OBJECT; auto it = mNodeForAddress.find(addr); if (it == mNodeForAddress.end()) { ALOGE("Unknown binder address %" PRIu64 " for dec strong.", addr); return OK; ALOGE("Unknown binder address %" PRIu64 " for dec strong. Terminating!", addr); (void)session->shutdownAndWait(false); return BAD_VALUE; } sp<IBinder> target = it->second.binder.promote(); Loading
libs/gui/Choreographer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,13 @@ void Choreographer::dispatchHotplugConnectionError(nsecs_t, int32_t connectionEr this, connectionError); } void Choreographer::dispatchModeChangedWithFrameRateOverrides(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t, nsecs_t, nsecs_t, std::vector<FrameRateOverride>) { LOG_ALWAYS_FATAL( "dispatchModeChangedWithFrameRateOverrides was called but was never registered"); } void Choreographer::dispatchModeChanged(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t, nsecs_t, nsecs_t) { LOG_ALWAYS_FATAL("dispatchModeChanged was called but was never registered"); Loading
libs/gui/DisplayEventDispatcher.cpp +17 −2 Original line number Diff line number Diff line Loading @@ -27,10 +27,10 @@ #include <utils/Timers.h> #include <utils/Trace.h> #include <com_android_graphics_libgui_flags.h> #include <com_android_graphics_surfaceflinger_flags.h> namespace android { using namespace com::android::graphics::libgui; using namespace com::android::graphics::surfaceflinger; // Number of events to read at a time from the DisplayEventDispatcher pipe. // The value should be large enough that we can quickly drain the pipe Loading Loading @@ -193,11 +193,23 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, } break; case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: LOG_ALWAYS_FATAL_IF(flags::unify_refresh_rate_callbacks(), "dispatchModeChanged should not be sent when" " refresh rate callbacks are unified"); dispatchModeChanged(ev.header.timestamp, ev.header.displayId, ev.modeChange.modeId, ev.modeChange.vsyncPeriod, ev.modeChange.appVsyncOffset, ev.modeChange.presentationDeadline); break; case DisplayEventType::DISPLAY_EVENT_MODE_AND_FRAME_RATE_CHANGE: dispatchModeChangedWithFrameRateOverrides(ev.header.timestamp, ev.header.displayId, ev.modeChange.modeId, ev.modeChange.vsyncPeriod, ev.modeChange.appVsyncOffset, ev.modeChange.presentationDeadline, std::move(mFrameRateOverrides)); break; case DisplayEventType::DISPLAY_EVENT_NULL: dispatchNullEvent(ev.header.timestamp, ev.header.displayId); break; Loading @@ -205,6 +217,9 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, mFrameRateOverrides.emplace_back(ev.frameRateOverride); break; case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: LOG_ALWAYS_FATAL_IF(flags::unify_refresh_rate_callbacks(), "dispatchFrameRateOverrides should not be sent when" " refresh rate callbacks are unified"); dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId, std::move(mFrameRateOverrides)); break; Loading
libs/gui/ISurfaceComposer.cpp +23 −59 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <gui/SchedulingPolicy.h> #include <gui/SimpleTransactionState.h> #include <gui/TransactionState.h> #include <private/gui/ParcelUtils.h> #include <stdint.h> #include <sys/types.h> Loading @@ -50,22 +52,17 @@ using gui::IWindowInfosListener; using gui::LayerCaptureArgs; using ui::ColorMode; class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { public: explicit BpSurfaceComposer(const sp<IBinder>& impl) : BpInterface<ISurfaceComposer>(impl) { } explicit BpSurfaceComposer(const sp<IBinder>& impl) : BpInterface<ISurfaceComposer>(impl) {} virtual ~BpSurfaceComposer(); status_t setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, const SimpleTransactionState simpleState, const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, Vector<DisplayState>& displays, const sp<IBinder>& applyToken, const std::vector<client_cache_t>& uncacheBuffers, const TransactionListenerCallbacks& listenerCallbacks, const std::vector<uint64_t>& mergedTransactionIds, const std::vector<gui::EarlyWakeupInfo>& earlyWakeupInfos) override { Parcel data, reply; Loading @@ -83,25 +80,15 @@ public: SAFE_PARCEL(d.write, data); } SAFE_PARCEL(data.writeUint32, flags); SAFE_PARCEL(simpleState.writeToParcel, &data); SAFE_PARCEL(data.writeStrongBinder, applyToken); SAFE_PARCEL(commands.write, data); SAFE_PARCEL(data.writeInt64, desiredPresentTime); SAFE_PARCEL(data.writeBool, isAutoTimestamp); SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size())); for (const client_cache_t& uncacheBuffer : uncacheBuffers) { SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote()); SAFE_PARCEL(data.writeUint64, uncacheBuffer.id); } SAFE_PARCEL(data.writeBool, hasListenerCallbacks); SAFE_PARCEL(data.writeVectorSize, listenerCallbacks); for (const auto& [listener, callbackIds] : listenerCallbacks) { SAFE_PARCEL(data.writeStrongBinder, listener); SAFE_PARCEL(data.writeParcelableVector, callbackIds); } SAFE_PARCEL(data.writeUint64, transactionId); SAFE_PARCEL(listenerCallbacks.writeToParcel, &data); SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(mergedTransactionIds.size())); for (auto mergedTransactionId : mergedTransactionIds) { Loading @@ -113,12 +100,11 @@ public: e.writeToParcel(&data); } if (flags & ISurfaceComposer::eOneWay) { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply, IBinder::FLAG_ONEWAY); if (simpleState.mFlags & ISurfaceComposer::eOneWay) { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply, IBinder::FLAG_ONEWAY); } else { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } } }; Loading @@ -131,9 +117,8 @@ IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); // ---------------------------------------------------------------------- status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t BnSurfaceComposer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); Loading @@ -160,17 +145,11 @@ status_t BnSurfaceComposer::onTransact( displays.add(d); } uint32_t stateFlags = 0; SAFE_PARCEL(data.readUint32, &stateFlags); SimpleTransactionState simpleState; SAFE_PARCEL(simpleState.readFromParcel, &data); sp<IBinder> applyToken; SAFE_PARCEL(data.readStrongBinder, &applyToken); InputWindowCommands inputWindowCommands; SAFE_PARCEL(inputWindowCommands.read, data); int64_t desiredPresentTime = 0; bool isAutoTimestamp = true; SAFE_PARCEL(data.readInt64, &desiredPresentTime); SAFE_PARCEL(data.readBool, &isAutoTimestamp); SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); std::vector<client_cache_t> uncacheBuffers(count); Loading @@ -181,21 +160,8 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id); } bool hasListenerCallbacks = false; SAFE_PARCEL(data.readBool, &hasListenerCallbacks); std::vector<ListenerCallbacks> listenerCallbacks; int32_t listenersSize = 0; SAFE_PARCEL_READ_SIZE(data.readInt32, &listenersSize, data.dataSize()); for (int32_t i = 0; i < listenersSize; i++) { SAFE_PARCEL(data.readStrongBinder, &tmpBinder); std::vector<CallbackId> callbackIds; SAFE_PARCEL(data.readParcelableVector, &callbackIds); listenerCallbacks.emplace_back(tmpBinder, callbackIds); } uint64_t transactionId = -1; SAFE_PARCEL(data.readUint64, &transactionId); TransactionListenerCallbacks listenerCallbacks; SAFE_PARCEL(listenerCallbacks.readFromParcel, &data); SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); std::vector<uint64_t> mergedTransactions(count); Loading @@ -213,10 +179,8 @@ status_t BnSurfaceComposer::onTransact( earlyWakeupInfos.push_back(std::move(e)); } return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken, std::move(inputWindowCommands), desiredPresentTime, isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, listenerCallbacks, transactionId, mergedTransactions, return setTransactionState(simpleState, frameTimelineInfo, state, displays, applyToken, uncacheBuffers, listenerCallbacks, mergedTransactions, earlyWakeupInfos); } case GET_SCHEDULING_POLICY: { Loading