Loading libs/binder/Binder.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -407,8 +407,10 @@ status_t BBinder::transact( AutoMutex lock(e->mLock); if (mRecordingOn) { Parcel emptyReply; timespec ts; timespec_get(&ts, TIME_UTC); auto transaction = android::binder::debug::RecordedTransaction::fromDetails(code, flags, data, android::binder::debug::RecordedTransaction::fromDetails(code, flags, ts, data, reply ? *reply : emptyReply, err); Loading libs/binder/BinderRecordReplay.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -101,18 +101,24 @@ static_assert(PADDING8(8) == 0); // End Chunk may therefore produce a empty, meaningless RecordedTransaction. RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept { mHeader = {t.getCode(), t.getFlags(), t.getReturnedStatus(), t.getVersion()}; mHeader = t.mHeader; mSent.setData(t.getDataParcel().data(), t.getDataParcel().dataSize()); mReply.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize()); } std::optional<RecordedTransaction> RecordedTransaction::fromDetails(uint32_t code, uint32_t flags, timespec timestamp, const Parcel& dataParcel, const Parcel& replyParcel, status_t err) { RecordedTransaction t; t.mHeader = {code, flags, static_cast<int32_t>(err), dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0)}; t.mHeader = {code, flags, static_cast<int32_t>(err), dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0), static_cast<int64_t>(timestamp.tv_sec), static_cast<int32_t>(timestamp.tv_nsec), 0}; if (t.mSent.setData(dataParcel.data(), dataParcel.dataSize()) != android::NO_ERROR) { LOG(INFO) << "Failed to set sent parcel data."; Loading Loading @@ -175,6 +181,7 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd LOG(INFO) << "Failed to read transactionHeader from fd " << fd.get(); return std::nullopt; } lseek(fd.get(), chunk.padding, SEEK_CUR); break; } case DATA_PARCEL_CHUNK: { Loading Loading @@ -292,6 +299,12 @@ int32_t RecordedTransaction::getReturnedStatus() const { return mHeader.statusReturned; } timespec RecordedTransaction::getTimestamp() const { time_t sec = mHeader.timestampSeconds; int32_t nsec = mHeader.timestampNanoseconds; return (timespec){.tv_sec = sec, .tv_nsec = nsec}; } uint32_t RecordedTransaction::getVersion() const { return mHeader.version; } Loading libs/binder/include/binder/BinderRecordReplay.h +7 −3 Original line number Diff line number Diff line Loading @@ -34,8 +34,8 @@ public: static std::optional<RecordedTransaction> fromFile(const android::base::unique_fd& fd); // Filled with the arguments. static std::optional<RecordedTransaction> fromDetails(uint32_t code, uint32_t flags, const Parcel& data, const Parcel& reply, status_t err); timespec timestamp, const Parcel& data, const Parcel& reply, status_t err); RecordedTransaction(RecordedTransaction&& t) noexcept; [[nodiscard]] status_t dumpToFile(const android::base::unique_fd& fd) const; Loading @@ -43,6 +43,7 @@ public: uint32_t getCode() const; uint32_t getFlags() const; int32_t getReturnedStatus() const; timespec getTimestamp() const; uint32_t getVersion() const; const Parcel& getDataParcel() const; const Parcel& getReplyParcel() const; Loading @@ -60,9 +61,12 @@ private: uint32_t flags = 0; int32_t statusReturned = 0; uint32_t version = 0; // !0 iff Rpc int64_t timestampSeconds = 0; int32_t timestampNanoseconds = 0; int32_t reserved = 0; }; #pragma clang diagnostic pop static_assert(sizeof(TransactionHeader) == 16); static_assert(sizeof(TransactionHeader) == 32); static_assert(sizeof(TransactionHeader) % 8 == 0); TransactionHeader mHeader; Loading libs/binder/tests/binderRecordedTransactionTest.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,8 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { d.writeInt64(2); Parcel r; r.writeInt32(99); auto transaction = RecordedTransaction::fromDetails(1, 42, d, r, 0); timespec ts = {1232456, 567890}; auto transaction = RecordedTransaction::fromDetails(1, 42, ts, d, r, 0); auto file = std::tmpfile(); auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1)); Loading @@ -42,6 +43,8 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { EXPECT_EQ(retrievedTransaction->getCode(), 1); EXPECT_EQ(retrievedTransaction->getFlags(), 42); EXPECT_EQ(retrievedTransaction->getTimestamp().tv_sec, ts.tv_sec); EXPECT_EQ(retrievedTransaction->getTimestamp().tv_nsec, ts.tv_nsec); EXPECT_EQ(retrievedTransaction->getDataParcel().dataSize(), 12); EXPECT_EQ(retrievedTransaction->getReplyParcel().dataSize(), 4); EXPECT_EQ(retrievedTransaction->getReturnedStatus(), 0); Loading Loading
libs/binder/Binder.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -407,8 +407,10 @@ status_t BBinder::transact( AutoMutex lock(e->mLock); if (mRecordingOn) { Parcel emptyReply; timespec ts; timespec_get(&ts, TIME_UTC); auto transaction = android::binder::debug::RecordedTransaction::fromDetails(code, flags, data, android::binder::debug::RecordedTransaction::fromDetails(code, flags, ts, data, reply ? *reply : emptyReply, err); Loading
libs/binder/BinderRecordReplay.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -101,18 +101,24 @@ static_assert(PADDING8(8) == 0); // End Chunk may therefore produce a empty, meaningless RecordedTransaction. RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept { mHeader = {t.getCode(), t.getFlags(), t.getReturnedStatus(), t.getVersion()}; mHeader = t.mHeader; mSent.setData(t.getDataParcel().data(), t.getDataParcel().dataSize()); mReply.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize()); } std::optional<RecordedTransaction> RecordedTransaction::fromDetails(uint32_t code, uint32_t flags, timespec timestamp, const Parcel& dataParcel, const Parcel& replyParcel, status_t err) { RecordedTransaction t; t.mHeader = {code, flags, static_cast<int32_t>(err), dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0)}; t.mHeader = {code, flags, static_cast<int32_t>(err), dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0), static_cast<int64_t>(timestamp.tv_sec), static_cast<int32_t>(timestamp.tv_nsec), 0}; if (t.mSent.setData(dataParcel.data(), dataParcel.dataSize()) != android::NO_ERROR) { LOG(INFO) << "Failed to set sent parcel data."; Loading Loading @@ -175,6 +181,7 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd LOG(INFO) << "Failed to read transactionHeader from fd " << fd.get(); return std::nullopt; } lseek(fd.get(), chunk.padding, SEEK_CUR); break; } case DATA_PARCEL_CHUNK: { Loading Loading @@ -292,6 +299,12 @@ int32_t RecordedTransaction::getReturnedStatus() const { return mHeader.statusReturned; } timespec RecordedTransaction::getTimestamp() const { time_t sec = mHeader.timestampSeconds; int32_t nsec = mHeader.timestampNanoseconds; return (timespec){.tv_sec = sec, .tv_nsec = nsec}; } uint32_t RecordedTransaction::getVersion() const { return mHeader.version; } Loading
libs/binder/include/binder/BinderRecordReplay.h +7 −3 Original line number Diff line number Diff line Loading @@ -34,8 +34,8 @@ public: static std::optional<RecordedTransaction> fromFile(const android::base::unique_fd& fd); // Filled with the arguments. static std::optional<RecordedTransaction> fromDetails(uint32_t code, uint32_t flags, const Parcel& data, const Parcel& reply, status_t err); timespec timestamp, const Parcel& data, const Parcel& reply, status_t err); RecordedTransaction(RecordedTransaction&& t) noexcept; [[nodiscard]] status_t dumpToFile(const android::base::unique_fd& fd) const; Loading @@ -43,6 +43,7 @@ public: uint32_t getCode() const; uint32_t getFlags() const; int32_t getReturnedStatus() const; timespec getTimestamp() const; uint32_t getVersion() const; const Parcel& getDataParcel() const; const Parcel& getReplyParcel() const; Loading @@ -60,9 +61,12 @@ private: uint32_t flags = 0; int32_t statusReturned = 0; uint32_t version = 0; // !0 iff Rpc int64_t timestampSeconds = 0; int32_t timestampNanoseconds = 0; int32_t reserved = 0; }; #pragma clang diagnostic pop static_assert(sizeof(TransactionHeader) == 16); static_assert(sizeof(TransactionHeader) == 32); static_assert(sizeof(TransactionHeader) % 8 == 0); TransactionHeader mHeader; Loading
libs/binder/tests/binderRecordedTransactionTest.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,8 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { d.writeInt64(2); Parcel r; r.writeInt32(99); auto transaction = RecordedTransaction::fromDetails(1, 42, d, r, 0); timespec ts = {1232456, 567890}; auto transaction = RecordedTransaction::fromDetails(1, 42, ts, d, r, 0); auto file = std::tmpfile(); auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1)); Loading @@ -42,6 +43,8 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { EXPECT_EQ(retrievedTransaction->getCode(), 1); EXPECT_EQ(retrievedTransaction->getFlags(), 42); EXPECT_EQ(retrievedTransaction->getTimestamp().tv_sec, ts.tv_sec); EXPECT_EQ(retrievedTransaction->getTimestamp().tv_nsec, ts.tv_nsec); EXPECT_EQ(retrievedTransaction->getDataParcel().dataSize(), 12); EXPECT_EQ(retrievedTransaction->getReplyParcel().dataSize(), 4); EXPECT_EQ(retrievedTransaction->getReturnedStatus(), 0); Loading