Add timestamp to RecordedTransaction
Test: `atest binderUnitTest`
Change-Id: I93bf860136ee66977391c6d2a24ebb52fb85c3cc
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 5e725a9..da5affb 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -407,8 +407,10 @@
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);
diff --git a/libs/binder/BinderRecordReplay.cpp b/libs/binder/BinderRecordReplay.cpp
index 9463785..8ba18a8 100644
--- a/libs/binder/BinderRecordReplay.cpp
+++ b/libs/binder/BinderRecordReplay.cpp
@@ -101,18 +101,24 @@
// 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.";
@@ -175,6 +181,7 @@
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: {
@@ -292,6 +299,12 @@
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;
}
diff --git a/libs/binder/include/binder/BinderRecordReplay.h b/libs/binder/include/binder/BinderRecordReplay.h
index 609e5be..ff983f0 100644
--- a/libs/binder/include/binder/BinderRecordReplay.h
+++ b/libs/binder/include/binder/BinderRecordReplay.h
@@ -34,8 +34,8 @@
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;
@@ -43,6 +43,7 @@
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;
@@ -60,9 +61,12 @@
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;
diff --git a/libs/binder/tests/binderRecordedTransactionTest.cpp b/libs/binder/tests/binderRecordedTransactionTest.cpp
index 67e482d..2ece315 100644
--- a/libs/binder/tests/binderRecordedTransactionTest.cpp
+++ b/libs/binder/tests/binderRecordedTransactionTest.cpp
@@ -28,7 +28,8 @@
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));
@@ -42,6 +43,8 @@
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);