Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43140867 authored by Fabián Cañas's avatar Fabián Cañas Committed by Automerger Merge Worker
Browse files

Merge "Add interfaceDescriptor to RecordedTransaction" am: c150630e am: 3bbd866b

parents 760147ac 3bbd866b
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -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;
+43 −21
Original line number Diff line number Diff line
@@ -106,18 +106,16 @@ 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,
    t.mData.mHeader = {code,
                       flags,
                       static_cast<int32_t>(err),
                       dataParcel.isForRpc() ? static_cast<uint32_t>(1) : static_cast<uint32_t>(0),
@@ -125,6 +123,14 @@ std::optional<RecordedTransaction> RecordedTransaction::fromDetails(uint32_t cod
                       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.";
        return std::nullopt;
@@ -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 {
+8 −2
Original line number Diff line number Diff line
@@ -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);

    struct MovableData { // movable
        TransactionHeader mHeader;
        String8 mInterfaceName;
    };
    MovableData mData;
    Parcel mSent;
    Parcel mReply;
};
+9 −3
Original line number Diff line number Diff line
@@ -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));