diff options
| author | 2023-01-18 20:43:43 +0000 | |
|---|---|---|
| committer | 2023-01-18 20:43:43 +0000 | |
| commit | 3bbd866bb2739d5d12e4e0c12f7de4710bbb751a (patch) | |
| tree | fd3200ea057c1b0064548152fdf72ea8732953dd /libs | |
| parent | 637054bcee5ccebff35ccb0a429be3778bcbfc80 (diff) | |
| parent | c150630e839316f9bda6268c88102f7aa26165c1 (diff) | |
Merge "Add interfaceDescriptor to RecordedTransaction" am: c150630e83
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2389113
Change-Id: I62a1e02529bdb9e81c51a83ff76c47b1f6a701c3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/binder/Binder.cpp | 8 | ||||
| -rw-r--r-- | libs/binder/BinderRecordReplay.cpp | 64 | ||||
| -rw-r--r-- | libs/binder/include/binder/BinderRecordReplay.h | 10 | ||||
| -rw-r--r-- | libs/binder/tests/binderRecordedTransactionTest.cpp | 12 |
4 files changed, 63 insertions, 31 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index da5affb274..5fa8bfa616 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -409,11 +409,9 @@ status_t BBinder::transact( Parcel emptyReply; timespec ts; timespec_get(&ts, TIME_UTC); - auto transaction = - android::binder::debug::RecordedTransaction::fromDetails(code, flags, ts, data, - reply ? *reply - : emptyReply, - err); + auto transaction = android::binder::debug::RecordedTransaction:: + fromDetails(getInterfaceDescriptor(), code, flags, ts, data, + reply ? *reply : emptyReply, err); if (transaction) { if (status_t err = transaction->dumpToFile(e->mRecordingFd); err != NO_ERROR) { LOG(INFO) << "Failed to dump RecordedTransaction to file with error " << err; diff --git a/libs/binder/BinderRecordReplay.cpp b/libs/binder/BinderRecordReplay.cpp index 58bb106b37..389c49e36b 100644 --- a/libs/binder/BinderRecordReplay.cpp +++ b/libs/binder/BinderRecordReplay.cpp @@ -106,24 +106,30 @@ static_assert(PADDING8(8) == 0); // End Chunk may therefore produce an empty, meaningless RecordedTransaction. RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept { - mHeader = t.mHeader; + mData = t.mData; 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) { +std::optional<RecordedTransaction> RecordedTransaction::fromDetails( + const String16& interfaceName, 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), - static_cast<int64_t>(timestamp.tv_sec), - static_cast<int32_t>(timestamp.tv_nsec), - 0}; + t.mData.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}; + + t.mData.mInterfaceName = String8(interfaceName); + if (interfaceName.size() != t.mData.mInterfaceName.bytes()) { + LOG(ERROR) << "Interface Name is not valid. Contains characters that aren't single byte " + "utf-8: " + << interfaceName; + return std::nullopt; + } if (t.mSent.setData(dataParcel.data(), dataParcel.dataSize()) != android::NO_ERROR) { LOG(ERROR) << "Failed to set sent parcel data."; @@ -142,6 +148,7 @@ enum { HEADER_CHUNK = 1, DATA_PARCEL_CHUNK = 2, REPLY_PARCEL_CHUNK = 3, + INTERFACE_NAME_CHUNK = 4, END_CHUNK = 0x00ffffff, }; @@ -220,7 +227,11 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd << sizeof(TransactionHeader) << "."; return std::nullopt; } - t.mHeader = *reinterpret_cast<TransactionHeader*>(payloadMap); + t.mData.mHeader = *reinterpret_cast<TransactionHeader*>(payloadMap); + break; + } + case INTERFACE_NAME_CHUNK: { + t.mData.mInterfaceName.setTo(reinterpret_cast<char*>(payloadMap), chunk.dataSize); break; } case DATA_PARCEL_CHUNK: { @@ -291,10 +302,17 @@ android::status_t RecordedTransaction::writeChunk(borrowed_fd fd, uint32_t chunk android::status_t RecordedTransaction::dumpToFile(const unique_fd& fd) const { if (NO_ERROR != writeChunk(fd, HEADER_CHUNK, sizeof(TransactionHeader), - reinterpret_cast<const uint8_t*>(&mHeader))) { + reinterpret_cast<const uint8_t*>(&(mData.mHeader)))) { LOG(ERROR) << "Failed to write transactionHeader to fd " << fd.get(); return UNKNOWN_ERROR; } + if (NO_ERROR != + writeChunk(fd, INTERFACE_NAME_CHUNK, mData.mInterfaceName.size() * sizeof(uint8_t), + reinterpret_cast<const uint8_t*>(mData.mInterfaceName.string()))) { + LOG(INFO) << "Failed to write Interface Name Chunk to fd " << fd.get(); + return UNKNOWN_ERROR; + } + if (NO_ERROR != writeChunk(fd, DATA_PARCEL_CHUNK, mSent.dataSize(), mSent.data())) { LOG(ERROR) << "Failed to write sent Parcel to fd " << fd.get(); return UNKNOWN_ERROR; @@ -310,26 +328,30 @@ android::status_t RecordedTransaction::dumpToFile(const unique_fd& fd) const { return NO_ERROR; } +const android::String8& RecordedTransaction::getInterfaceName() const { + return mData.mInterfaceName; +} + uint32_t RecordedTransaction::getCode() const { - return mHeader.code; + return mData.mHeader.code; } uint32_t RecordedTransaction::getFlags() const { - return mHeader.flags; + return mData.mHeader.flags; } int32_t RecordedTransaction::getReturnedStatus() const { - return mHeader.statusReturned; + return mData.mHeader.statusReturned; } timespec RecordedTransaction::getTimestamp() const { - time_t sec = mHeader.timestampSeconds; - int32_t nsec = mHeader.timestampNanoseconds; + time_t sec = mData.mHeader.timestampSeconds; + int32_t nsec = mData.mHeader.timestampNanoseconds; return (timespec){.tv_sec = sec, .tv_nsec = nsec}; } uint32_t RecordedTransaction::getVersion() const { - return mHeader.version; + return mData.mHeader.version; } const Parcel& RecordedTransaction::getDataParcel() const { diff --git a/libs/binder/include/binder/BinderRecordReplay.h b/libs/binder/include/binder/BinderRecordReplay.h index ff983f08c2..9602c9f742 100644 --- a/libs/binder/include/binder/BinderRecordReplay.h +++ b/libs/binder/include/binder/BinderRecordReplay.h @@ -33,13 +33,15 @@ public: // Filled with the first transaction from fd. 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, + static std::optional<RecordedTransaction> fromDetails(const String16& interfaceName, + uint32_t code, uint32_t flags, 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; + const String8& getInterfaceName() const; uint32_t getCode() const; uint32_t getFlags() const; int32_t getReturnedStatus() const; @@ -69,7 +71,11 @@ private: static_assert(sizeof(TransactionHeader) == 32); static_assert(sizeof(TransactionHeader) % 8 == 0); - TransactionHeader mHeader; + struct MovableData { // movable + TransactionHeader mHeader; + String8 mInterfaceName; + }; + MovableData mData; Parcel mSent; Parcel mReply; }; diff --git a/libs/binder/tests/binderRecordedTransactionTest.cpp b/libs/binder/tests/binderRecordedTransactionTest.cpp index 67553fc811..d900e8634f 100644 --- a/libs/binder/tests/binderRecordedTransactionTest.cpp +++ b/libs/binder/tests/binderRecordedTransactionTest.cpp @@ -24,13 +24,16 @@ using android::base::unique_fd; using android::binder::debug::RecordedTransaction; TEST(BinderRecordedTransaction, RoundTripEncoding) { + android::String16 interfaceName("SampleInterface"); Parcel d; d.writeInt32(12); d.writeInt64(2); Parcel r; r.writeInt32(99); timespec ts = {1232456, 567890}; - auto transaction = RecordedTransaction::fromDetails(1, 42, ts, d, r, 0); + + auto transaction = RecordedTransaction::fromDetails(interfaceName, 1, 42, ts, d, r, 0); + EXPECT_TRUE(transaction.has_value()); auto file = std::tmpfile(); auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1)); @@ -42,6 +45,7 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { auto retrievedTransaction = RecordedTransaction::fromFile(fd); + EXPECT_EQ(retrievedTransaction->getInterfaceName(), android::String8(interfaceName)); EXPECT_EQ(retrievedTransaction->getCode(), 1); EXPECT_EQ(retrievedTransaction->getFlags(), 42); EXPECT_EQ(retrievedTransaction->getTimestamp().tv_sec, ts.tv_sec); @@ -57,13 +61,14 @@ TEST(BinderRecordedTransaction, RoundTripEncoding) { } TEST(BinderRecordedTransaction, Checksum) { + android::String16 interfaceName("SampleInterface"); Parcel d; d.writeInt32(12); d.writeInt64(2); Parcel r; r.writeInt32(99); timespec ts = {1232456, 567890}; - auto transaction = RecordedTransaction::fromDetails(1, 42, ts, d, r, 0); + auto transaction = RecordedTransaction::fromDetails(interfaceName, 1, 42, ts, d, r, 0); auto file = std::tmpfile(); auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1)); @@ -91,6 +96,7 @@ TEST(BinderRecordedTransaction, PayloadsExceedPageBoundaries) { std::vector<uint8_t> largePayload; uint8_t filler = 0xaa; largePayload.insert(largePayload.end(), largeDataSize, filler); + android::String16 interfaceName("SampleInterface"); Parcel d; d.writeInt32(12); d.writeInt64(2); @@ -98,7 +104,7 @@ TEST(BinderRecordedTransaction, PayloadsExceedPageBoundaries) { Parcel r; r.writeInt32(99); timespec ts = {1232456, 567890}; - auto transaction = RecordedTransaction::fromDetails(1, 42, ts, d, r, 0); + auto transaction = RecordedTransaction::fromDetails(interfaceName, 1, 42, ts, d, r, 0); auto file = std::tmpfile(); auto fd = unique_fd(fcntl(fileno(file), F_DUPFD, 1)); |