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

Commit 1736868f authored by Marco Ballesio's avatar Marco Ballesio Committed by Automerger Merge Worker
Browse files

Merge "binder: adopt BINDER_FREEZE api" am: 171cac1b am: c83049d9 am:...

Merge "binder: adopt BINDER_FREEZE api" am: 171cac1b am: c83049d9 am: 6248a87d am: 6d912f8d am: fb4fb461

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1421693

Change-Id: Ib0b3339c065a0df4924c67ec304acf97c202ec3f
parents da54cfc5 fb4fb461
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -860,6 +860,10 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
            err = FAILED_TRANSACTION;
            goto finish;

        case BR_FROZEN_REPLY:
            err = FAILED_TRANSACTION;
            goto finish;

        case BR_ACQUIRE_RESULT:
            {
                ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
@@ -1316,6 +1320,26 @@ void IPCThreadState::threadDestructor(void *st)
        }
}

status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
    struct binder_freeze_info info;
    int ret = 0;

    info.pid = pid;
    info.enable = enable;
    info.timeout_ms = timeout_ms;


#if defined(__ANDROID__)
    if (ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0)
        ret = -errno;
#endif

    //
    // ret==-EAGAIN indicates that transactions have not drained.
    // Call again to poll for completion.
    //
    return ret;
}

void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
                                size_t /*dataSize*/,
+15 −1
Original line number Diff line number Diff line
@@ -35,6 +35,20 @@ public:
    static  IPCThreadState*     self();
    static  IPCThreadState*     selfOrNull();  // self(), but won't instantiate

    // Freeze or unfreeze the binder interface to a specific process. When freezing, this method
    // will block up to timeout_ms to process pending transactions directed to pid. Unfreeze
    // is immediate. Transactions to processes frozen via this method won't be delivered and the
    // driver will return BR_FROZEN_REPLY to the client sending them. After unfreeze,
    // transactions will be delivered normally.
    //
    // pid: id for the process for which the binder interface is to be frozen
    // enable: freeze (true) or unfreeze (false)
    // timeout_ms: maximum time this function is allowed to block the caller waiting for pending
    // binder transactions to be processed.
    //
    // returns: 0 in case of success, a value < 0 in case of error
    static  status_t            freeze(pid_t pid, bool enabled, uint32_t timeout_ms);

            sp<ProcessState>    process();
            
            status_t            clearLastError();
+31 −0
Original line number Diff line number Diff line
@@ -36,6 +36,37 @@ namespace android {
#include <sys/ioctl.h>
#include <linux/android/binder.h>

#ifndef BR_FROZEN_REPLY
// Temporary definition of BR_FROZEN_REPLY. For production
// this will come from UAPI binder.h
#define BR_FROZEN_REPLY _IO('r', 18)
#endif //BR_FROZEN_REPLY

#ifndef BINDER_FREEZE
/*
 * Temporary definitions for freeze support. For the final version
 * these will be defined in the UAPI binder.h file from upstream kernel.
 */
#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)

struct binder_freeze_info {
    //
    // Group-leader PID of process to be frozen
    //
    uint32_t            pid;
    //
    // Enable(1) / Disable(0) freeze for given PID
    //
    uint32_t            enable;
    //
    // Timeout to wait for transactions to drain.
    // 0: don't wait (ioctl will return EAGAIN if not drained)
    // N: number of ms to wait
    uint32_t            timeout_ms;
};
#endif //BINDER_FREEZE


#ifdef __cplusplus
}   // namespace android
#endif
+43 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>
#include <stdio.h>
@@ -79,6 +80,8 @@ enum BinderLibTestTranscationCode {
    BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
    BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
    BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
    BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
    BINDER_LIB_TEST_GETPID,
    BINDER_LIB_TEST_ECHO_VECTOR,
    BINDER_LIB_TEST_REJECT_BUF,
};
@@ -399,6 +402,40 @@ TEST_F(BinderLibTest, NopTransaction) {
    EXPECT_EQ(NO_ERROR, ret);
}

TEST_F(BinderLibTest, Freeze) {
    status_t ret;
    Parcel data, reply, replypid;
    std::ifstream freezer_file("/sys/fs/cgroup/freezer/cgroup.freeze");

    //Pass test on devices where the freezer is not supported
    if (freezer_file.fail()) {
        GTEST_SKIP();
        return;
    }

    std::string freezer_enabled;
    std::getline(freezer_file, freezer_enabled);

    //Pass test on devices where the freezer is disabled
    if (freezer_enabled != "1") {
        GTEST_SKIP();
        return;
    }

    ret = m_server->transact(BINDER_LIB_TEST_GETPID, data, &replypid);
    int32_t pid = replypid.readInt32();
    EXPECT_EQ(NO_ERROR, ret);
    for (int i = 0; i < 10; i++) {
        EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION_WAIT, data, &reply, TF_ONE_WAY));
    }
    EXPECT_EQ(-EAGAIN, IPCThreadState::self()->freeze(pid, 1, 0));
    EXPECT_EQ(-EAGAIN, IPCThreadState::self()->freeze(pid, 1, 0));
    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 1, 1000));
    EXPECT_EQ(FAILED_TRANSACTION, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 0, 0));
    EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
}

TEST_F(BinderLibTest, SetError) {
    int32_t testValue[] = { 0, -123, 123 };
    for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
@@ -1178,6 +1215,12 @@ class BinderLibTestService : public BBinder
                pthread_mutex_unlock(&m_serverWaitMutex);
                return ret;
            }
            case BINDER_LIB_TEST_GETPID:
                reply->writeInt32(getpid());
                return NO_ERROR;
            case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT:
                usleep(5000);
                return NO_ERROR;
            case BINDER_LIB_TEST_NOP_TRANSACTION:
                return NO_ERROR;
            case BINDER_LIB_TEST_DELAYED_CALL_BACK: {