跳转至

Binder机制03-Framework-Native

前言

Framework是一个中间层,它对接了底层实现,封装了复杂的内部逻辑,并提供供外部使用的接口。Framework层是应用程序开发的基础。Binder Framework层分为C++和Java两个部分,为了达到功能的复用,中间通过JNI进行衔接。 Binder Framework的C++部分

Binder库最终会编译成一个动态链接库:libbinder.so,供其他进程链接使用。

在上一章节中,我们了解到了ServiceManager的启动过程,注册、获取服务的细节。如果让我们开发应该Native服务,我们要怎么做呢?我们以media的服务来进行分析。在了解如何开发native服务之前我们先了解Native层的Binder架构。

Native层的Binder架构

Binder Framework Native(libbinder)中,将实现分为Proxy和Native两端。

  • Proxy对应Client端,是服务对外提供的接口。类名中带有小写字母p的(例如BpInterface),就是指Proxy端。
  • Native是服务实现的一端,对应了上文提到的Server端。类名带有小写字母n的(例如BnInterface),就是指Native端。

    Proxy代表了调用方,通常与服务的实现不在同一个进程,因此下文中,我们也称Proxy端为“远程”端。 Native端是服务实现的自身,因此下文中,我们也称Native端为“本地”端。

概念

在前面的Binder概述、Binder驱动等章节我们都聊到了BpBinder、BBinder。我们先用一个表格来列举libbinder中的主要类。

类名 说明
BpRefBase RefBase的子类,提供remote()方法获取远程Binder
IInterface Binder服务接口的基类,Binder服务通常需要同时提供本地接口和远程接口
BpInterface 远程接口的基类,远程接口是供客户端调用的接口集
BnInterface 本地接口的基类,本地接口是需要服务中真正实现的接口集
IBiner Binder对象的基类,BBinder和BpBinder都是这个类的子类
BpBinder 远程Binder,这个类提供transact方法来发送请求,BpXXX实现中会用到
BBinder 本地Binder,服务实现方的基类,提供了onTransact接口来接收请求
ProcessState 代表了使用Binder的进程
IPCThreadState 代表了使用Binder的线程,这个类中封装了与Binder驱动通信的逻辑
Parcel 在Binder上传递的数据的包装器

下图描述了Binder Framework Native(libbinder)主要类的关系。

Binder服务的实现类(图中紫色部分)通常都会遵守下面的命名规则: - 服务的接口使用I字母作为前缀 - 远程接口使用Bp作为前缀 - 本地接口使用Bn作为前缀

IBinder.h

IBinder从Refbase继承而来,一提供强弱指针计数能力。IBinder有几个方法比较重要:

  • localBinder():获取本地Binder对象
  • remoteBinder():获取远程Binder对象
  • transact():进行一次Binder操作
  • queryLocalInterface():尝试获取本地Binder,如何失败返回NULL
  • getInterfaceDescriptor():获取Binder的服务接口描述,其实就是Binder服务的唯一标识
  • isBinderAlive():查询Binder服务是否还活着
  • pingBinder():发送PING_TRANSACTION给Binder服务

IBinder.h的代码可以点链接查看。对于IBinder中的方法,基本都是没有实现的,这些方法的实现都交给继承它的子类来实现,那下面直接看BpBinder的内容。

BpBinder.h

BpBinder.h的代码比较多不贴出来了,可以点击链接自行查看代码。我们主要来分析上述提到的几个函数的具体实现。 ​

BpBinder构造函数

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
    : mHandle(handle)
    , mStability(0)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(nullptr)
    , mTrackedUid(trackedUid)
{
    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle, this);
}
  • 将传入的handle值保存到mHandle成员变量里
  • mAlive设置为1
  • extendObjectLifetime将对象改为弱引用控制
  • 通过IPCThreadState的incWeakHandle增加Binder Service的如引用计数值。
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IPCThreadState.cpp

void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
{
    LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
    mOut.writeInt32(BC_INCREFS);
    mOut.writeInt32(handle);
    // Create a temp reference until the driver has handled this command.
    proxy->getWeakRefs()->incWeak(mProcess.get());
    mPostWriteWeakDerefs.push(proxy->getWeakRefs());
}

这一步只是将BC_INCREFS请求写到mOut中,还没有发送出去。

除了incWeakHandle函数外还有decWeakHandle,incStrongHandle和decStrongHandle与Binder协议中的其他命令对应起来。

getInterfaceDescriptor()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

const String16& BpBinder::getInterfaceDescriptor() const
{
    if (isDescriptorCached() == false) {
        Parcel send, reply;
        // do the IPC without a lock held.
        //通过BpBinder的transact函数将INTERFACE_TRANSACTION请求发送出去
        status_t err = const_cast<BpBinder*>(this)->transact(
                INTERFACE_TRANSACTION, send, &reply);
        if (err == NO_ERROR) {
          //读取返回值得内容
            String16 res(reply.readString16());
            Mutex::Autolock _l(mLock);
            // mDescriptorCache could have been assigned while the lock was
            // released.
            if (mDescriptorCache.size() == 0)
                mDescriptorCache = res;
        }
    }

    // we're returning a reference to a non-static object here. Usually this
    // is not something smart to do, however, with binder objects it is
    // (usually) safe because they are reference-counted.

    return mDescriptorCache;
}

这里是通过BpBinder的transact函数将请求发送出去

transact()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

// NOLINTNEXTLINE(google-default-arguments)
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        ...
        //调用IPCThreadState的transact函数
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;

        return status;
    }

    return DEAD_OBJECT;
}

BpBinder这个代理端的数据发送其实也不是自己执行数据传输的操作,而是调用IPCThreadState的transact()函数进行数据传输。

IPCThreadState.transact()
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err;

    flags |= TF_ACCEPT_FDS;

    ...
    //调用writeTransactionData,将data中的数据打包成binder_transaction_data结构并写入到mOut中
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    if ((flags & TF_ONE_WAY) == 0) {
        if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
            if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
                ALOGE("Process making non-oneway call (code: %u) but is restricted.", code);
                CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
                    ANDROID_LOG_ERROR);
            } else /* FATAL_IF_NOT_ONEWAY */ {
                LOG_ALWAYS_FATAL("Process may not make oneway calls (code: %u).", code);
            }
        }

        ...

        if (reply) {
            //和Binder驱动通信,等待数据回复
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            //和Binder驱动通信,等待数据回复
            err = waitForResponse(&fakeReply);
        }
        ...
    } else {
        //和Binder驱动通信,等待数据回复
        err = waitForResponse(nullptr, nullptr);
    }

    return err;
}
  • 调用writeTransactionData,将Parcel类变量data打包成一个binder_transaction_data,然后将其写到mOut中
  • 调用waitForResponse,等待binder驱动处理数据
IPCThreadState.waitForResponse()
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
        //Binder驱动进行交互
        if ((err=talkWithDriver()) < NO_ERROR) break;
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;

        //拿到cmd
        cmd = (uint32_t)mIn.readInt32();

        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) goto finish;
            break;

        case BR_DEAD_REPLY:
            err = DEAD_OBJECT;
            goto finish;

        case BR_FAILED_REPLY:
            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");
                const int32_t result = mIn.readInt32();
                if (!acquireResult) continue;
                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
            }
            goto finish;

        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
                if (err != NO_ERROR) goto finish;

                if (reply) {
                    if ((tr.flags & TF_STATUS_CODE) == 0) {
                        reply->ipcSetDataReference(
                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                            tr.data_size,
                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t),
                            freeBuffer, this);
                    } else {
                        err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
                        freeBuffer(nullptr,
                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                            tr.data_size,
                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t), this);
                    }
                } else {
                    freeBuffer(nullptr,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(binder_size_t), this);
                    continue;
                }
            }
            goto finish;

        default:
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
    }

finish:
    if (err != NO_ERROR) {
        if (acquireResult) *acquireResult = err;
        if (reply) reply->setError(err);
        mLastError = err;
    }

    return err;
}
  • 调用talkWithDriver()函数跟驱动交互,在 Binder机制02-ServiceManager 章节中我们讲过talkWithDriver()函数调用binder_ioctl()跟驱动交互的细节,这里不在展开描述
  • 根据binder驱动处理后的结果做操作,BR码在 Binder机制02-ServiceManager 有描述

linkToDeath()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::linkToDeath(
    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
{
    Obituary ob;
    ob.recipient = recipient;
    ob.cookie = cookie;
    ob.flags = flags;


    {
        AutoMutex _l(mLock);

        if (!mObitsSent) {//还没有发送过死亡通知
            if (!mObituaries) {//第一次调用的话,mObituaries还没有分配内存
                mObituaries = new Vector<Obituary>;
                if (!mObituaries) {
                    return NO_MEMORY;
                }
                ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
                getWeakRefs()->incWeak(this);
                IPCThreadState* self = IPCThreadState::self();
                self->requestDeathNotification(mHandle, this);
                self->flushCommands();
            }
            ssize_t res = mObituaries->add(ob);
            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
        }
    }

    return DEAD_OBJECT;
}
  • 判断是否已经发送过死亡通知,如果没有发送过那么就分配内存
  • 调用IPCThreadState的requestDeathNotification,将自己注册到binder驱动里面
  • 将Obituary添加到vector里
IPCThreadState.requestDeathNotification()
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
{
    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
    mOut.writeInt32((int32_t)handle);
    mOut.writePointer((uintptr_t)proxy);
    return NO_ERROR;
}

将BC_REQUEST_DEATH_NOTIFICATION(请求接收死亡通知)写到mOut中。BC码在 Binder机制01-驱动 有描述

IPCThreadState.flushCommands()
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IPCThreadState.cpp

void IPCThreadState::flushCommands()
{
    if (mProcess->mDriverFD < 0)
        return;
    talkWithDriver(false);
    // The flush could have caused post-write refcount decrements to have
    // been executed, which in turn could result in BC_RELEASE/BC_DECREFS
    // being queued in mOut. So flush again, if we need to.
    if (mOut.dataSize() > 0) {
        talkWithDriver(false);
    }
    if (mOut.dataSize() > 0) {
        ALOGW("mOut.dataSize() > 0 after flushCommands()");
    }
}

调用talkWithDriver和binder驱动进行交互,在 Binder机制02-ServiceManager 章节中我们讲过talkWithDriver()函数调用binder_ioctl()跟驱动交互的细节,这里不在展开描述。

unlinkToDeath()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::unlinkToDeath(
    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
    wp<DeathRecipient>* outRecipient)
{
    AutoMutex _l(mLock);

    if (mObitsSent) {
        return DEAD_OBJECT;
    }

    const size_t N = mObituaries ? mObituaries->size() : 0;
    for (size_t i=0; i<N; i++) {
        const Obituary& obit = mObituaries->itemAt(i);
        if ((obit.recipient == recipient
                    || (recipient == nullptr && obit.cookie == cookie))
                && obit.flags == flags) {
            if (outRecipient != nullptr) {
                *outRecipient = mObituaries->itemAt(i).recipient;
            }
            mObituaries->removeAt(i);
            if (mObituaries->size() == 0) {
                ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
                IPCThreadState* self = IPCThreadState::self();
                self->clearDeathNotification(mHandle, this);
                self->flushCommands();
                delete mObituaries;
                mObituaries = nullptr;
            }
            return NO_ERROR;
        }
    }

    return NAME_NOT_FOUND;
}

unlinkToDeath()函数跟linkToDeath()函数调用流程一直,只不过是BC码变成了BC_CLEAR_DEATH_NOTIFICATION(去除接收死亡通知)。

sendObituary()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/BpBinder.cpp

void BpBinder::sendObituary()
{
    ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
        this, mHandle, mObitsSent ? "true" : "false");

    mAlive = 0;
    //如果已经发送过死亡通知了就直接返回
    if (mObitsSent) return;

    mLock.lock();
    Vector<Obituary>* obits = mObituaries;
    if(obits != nullptr) {
        ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
        IPCThreadState* self = IPCThreadState::self();
        //清除注册在binder驱动中的死亡通知
        self->clearDeathNotification(mHandle, this);
        self->flushCommands();
        mObituaries = nullptr;
    }
    mObitsSent = 1;
    mLock.unlock();

    ALOGV("Reporting death of proxy %p for %zu recipients\n",
        this, obits ? obits->size() : 0U);

    if (obits != nullptr) {
        const size_t N = obits->size();
        for (size_t i=0; i<N; i++) {
            //调用死亡通知函数
            reportOneDeath(obits->itemAt(i));
        }

        delete obits;
    }
}

void BpBinder::reportOneDeath(const Obituary& obit)
{
    sp<DeathRecipient> recipient = obit.recipient.promote();
    ALOGV("Reporting death to recipient: %p\n", recipient.get());
    if (recipient == nullptr) return;

    recipient->binderDied(this);
}

发出死亡通知。

BBinder

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/include/binder/Binder.h


class BBinder : public IBinder
{
public:
                        BBinder();

    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    virtual status_t    dump(int fd, const Vector<String16>& args);

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0) final;

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = nullptr,
                                    uint32_t flags = 0);

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = nullptr,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = nullptr);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func) final;
    virtual void*       findObject(const void* objectID) const final;
    virtual void        detachObject(const void* objectID) final;

    virtual BBinder*    localBinder();

    bool                isRequestingSid();
    // This must be called before the object is sent to another process. Not thread safe.
    void                setRequestingSid(bool requestSid);

    sp<IBinder>         getExtension();
    // This must be called before the object is sent to another process. Not thread safe.
    void                setExtension(const sp<IBinder>& extension);

    __attribute__((weak))
    void                setMinSchedulerPolicy(int policy, int priority);
    __attribute__((weak))
    int                 getMinSchedulerPolicy();
    __attribute__((weak))
    int                 getMinSchedulerPriority();

    pid_t               getDebugPid();

protected:
    virtual             ~BBinder();

    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

private:
                        BBinder(const BBinder& o);
            BBinder&    operator=(const BBinder& o);

    class Extras;

    Extras*             getOrCreateExtras();

    std::atomic<Extras*> mExtras;

    friend ::android::internal::Stability;
    union {
        int32_t mStability;
        void* mReserved0;
    };
};

BBinder类在Binder.h中定义,其方法在Binder.cpp里实现。

transact()

https://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/Binder.cpp

// NOLINTNEXTLINE(google-default-arguments)
status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            err = pingBinder();
            break;
        case EXTENSION_TRANSACTION:
            err = reply->writeStrongBinder(getExtension());
            break;
        case DEBUG_PID_TRANSACTION:
            err = reply->writeInt32(getDebugPid());
            break;
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }

    // In case this is being transacted on in the same process.
    if (reply != nullptr) {
        reply->setDataPosition(0);
    }

    return err;
}

那么接下来直接看onTransact函数好了。

https://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/Binder.cpp

// NOLINTNEXTLINE(google-default-arguments)
status_t BBinder::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
{
    switch (code) {
        case INTERFACE_TRANSACTION:
            reply->writeString16(getInterfaceDescriptor());
            return NO_ERROR;

        case DUMP_TRANSACTION: {
            int fd = data.readFileDescriptor();
            int argc = data.readInt32();
            Vector<String16> args;
            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
               args.add(data.readString16());
            }
            return dump(fd, args);
        }

        case SHELL_COMMAND_TRANSACTION: {
            int in = data.readFileDescriptor();
            int out = data.readFileDescriptor();
            int err = data.readFileDescriptor();
            int argc = data.readInt32();
            Vector<String16> args;
            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
               args.add(data.readString16());
            }
            sp<IShellCallback> shellCallback = IShellCallback::asInterface(
                    data.readStrongBinder());
            sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(
                    data.readStrongBinder());

            // XXX can't add virtuals until binaries are updated.
            //return shellCommand(in, out, err, args, resultReceiver);
            (void)in;
            (void)out;
            (void)err;

            if (resultReceiver != nullptr) {
                resultReceiver->send(INVALID_OPERATION);
            }

            return NO_ERROR;
        }

        case SYSPROPS_TRANSACTION: {
            report_sysprop_change();
            return NO_ERROR;
        }

        default:
            return UNKNOWN_TRANSACTION;
    }
}

没有什么实际的内容,在 Binder机制02-ServiceManager 章节中提到过编写实际的Binder服务端程序的时候应该是会重载这个函数,以提供实际的功能。事实是否如此呢,我们可以带着这个疑问在下文中寻找答案。

BBinder的代码不多,看样子主要还是依靠具体服务端的特性来添加相应的功能的。 还有就是像attachObject、detachObject、findObject的功能是通过BpBinder中的ObjectManager来实现的。

IInterface.h

IInterface.h的代码比较多,可以通过点链接自行查看。除了构造函数和析构函数外,IInterface类里面只带有一个实现了的类方法,两个不同的重载,就是将IInterface参数转换成IBinder对象,然后返回给调用者,这样子调用者就可以使用IBinder提供的transact、onTransact等函数进行Binder数据传输了。 ​

DECLARE_META_INTERFACE

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/include/binder/IInterface.h

#define DECLARE_META_INTERFACE(INTERFACE)                               \
public:                                                                 \
    static const ::android::String16 descriptor;                        \
    static ::android::sp<I##INTERFACE> asInterface(                     \
            const ::android::sp<::android::IBinder>& obj);              \
    virtual const ::android::String16& getInterfaceDescriptor() const;  \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \
    static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl);     \
    static const std::unique_ptr<I##INTERFACE>& getDefaultImpl();       \
private:                                                                \
    static std::unique_ptr<I##INTERFACE> default_impl;                  \
public: 

以AudioPolicyService为例

DECLARE_META_INTERFACE(AudioPolicyService)

public:
    static const ::android::String16 descriptor;
    static ::android::sp<IAudioPolicyService> asInterface(
            const ::android::sp<::android::IBinder>& obj);
    virtual const ::android::String16& getInterfaceDescriptor() const;
    IAudioPolicyService();
    virtual ~IAudioPolicyService();
    static bool setDefaultImpl(std::unique_ptr<IAudioPolicyService> impl);
    static const std::unique_ptr<IAudioPolicyService>& getDefaultImpl();
private:
    static std::unique_ptr<IAudioPolicyService> default_impl;
public:

替换之后的内容就很容易理解了,无非就是定义了一些方法。那么IMPLEMENT_META_INTERFACE应该就是实现这些方法的宏了,下面看看替换后的IMPLEMENT_META_INTERFACE的内容是什么。

IMPLEMENT_META_INTERFACE

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/include/binder/IInterface.h

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)    \

#endif

#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
    const ::android::StaticString16                                     \
        I##INTERFACE##_descriptor_static_str16(__IINTF_CONCAT(u, NAME));\
    const ::android::String16 I##INTERFACE::descriptor(                 \
        I##INTERFACE##_descriptor_static_str16);                        \
    const ::android::String16&                                          \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
            const ::android::sp<::android::IBinder>& obj)               \
    {                                                                   \
        ::android::sp<I##INTERFACE> intr;                               \
        if (obj != nullptr) {                                           \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == nullptr) {                                      \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \
    bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
    {                                                                   \
        /* Only one user of this interface can use this function     */ \
        /* at a time. This is a heuristic to detect if two different */ \
        /* users in the same process use this function.              */ \
        assert(!I##INTERFACE::default_impl);                            \
        if (impl) {                                                     \
            I##INTERFACE::default_impl = std::move(impl);               \
            return true;                                                \
        }                                                               \
        return false;                                                   \
    }                                                                   \
    const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \
    {                                                                   \
        return I##INTERFACE::default_impl;                              \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

以AudioPolicyService为例

IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService")

const ::android::String16 IAudioPolicyService::descriptor("android.media.IAudioPolicyService");
const ::android::String16&
    IAudioPolicyService::getInterfaceDescriptor() const {
    return IAudioPolicyService::descriptor;
}
::android::sp<IAudioPolicyService> IAudioPolicyService::asInterface(
    const ::android::sp<::android::IBinder>& obj)
{
    ::android::sp<IAudioPolicyService> intr;
    if (obj != nullptr) {
        intr = static_cast<IAudioPolicyService*>(
            obj->queryLocalInterface(
                IAudioPolicyService::descriptor).get());
        if (intr == nullptr) {
            intr = new BpAudioPolicyService(obj);
        }
    }
    return intr;
}
std::unique_ptr<IAudioPolicyService> IAudioPolicyService::default_impl;
bool IAudioPolicyService::setDefaultImpl(std::unique_ptr<IAudioPolicyService> impl)
{
    if (!IAudioPolicyService::default_impl && impl) {
        IAudioPolicyService::default_impl = std::move(impl);
        return true;
    }
    return false;
}
const std::unique_ptr<IAudioPolicyService>& IAudioPolicyService::getDefaultImpl()
{
    return IAudioPolicyService::default_impl;
}
IAudioPolicyService::IAudioPolicyService() { }
IAudioPolicyService::~IAudioPolicyService() { }

其实将descriptor定义为android.os.IAudioPolicyService,然后getInterfaceDescriptor函数可以获取到这个descriptor。然后在asInterface函数中,将一个IBinder对象转换为一个BpInterface类对象。下一节还有举例补充说明。

小结

每个Binder服务都是为了某个功能而实现的,因此其本身会定义一套接口集(通常是C++的一个类)来描述自己提供的所有功能。而Binder服务既有自身实现服务的类,也要有给客户端进程调用的类。为了便于开发,这两中类里面的服务接口应当是一致的,例如:假设服务实现方提供了一个接口为add(int a, int b)的服务方法,那么其远程接口中也应当有一个add(int a, int b)方法。因此为了实现方便,本地实现类和远程接口类需要有一个公共的描述服务接口的基类(即上图中的IXXXService)来继承。而这个基类通常是IInterface的子类。

BnInterface继承了BBinder类,由此可以通过复写onTransact方法来提供实现。BpInterface继承了BpRefBase,通过这个类的remote方法可以获取到指向服务实现方的句柄。在客户端接口的实现类中,每个接口在组装好参数之后,都会调用remote()->transact来发送请求,而这里其实就是调用的BpBinder的transact方法,这样请求便通过Binder到达了服务实现方的onTransact中。这个过程如下图所示:

注册Native服务(media服务)

mediaserver服务如何被拉起,后面会专门找个章节详细讲解,本章我们就默认执行到mediaserver的main()函数了。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/av/media/mediaserver/main_mediaserver.cpp


int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());//获得ProcessState实例对象
    sp<IServiceManager> sm(defaultServiceManager());//获取BpServiceManager对象
    ALOGI("ServiceManager: %p", sm.get());
    AIcu_initializeIcuOrDie();
    MediaPlayerService::instantiate();//注册多媒体服务
    ResourceManagerService::instantiate();
    registerExtensions();
    ::android::hardware::configureRpcThreadpool(16, false);//配置HwBinder的线程池
    ProcessState::self()->startThreadPool();//启动Binder线程池
    IPCThreadState::self()->joinThreadPool();//当前线程加入到线程池
    ::android::hardware::joinRpcThreadpool();//把当前的通信加入HwBinder的线程池进行循环
}
  • 获得ProcessState实例对象
  • 调用defualtServiceManager方法获取IServiceManager实例(即BpServiceManager)
  • 注册media服务
  • 启动Binder线程池
  • 把当前线程加入到线程池

打开Binder驱动

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != nullptr) {
        return gProcess;
    }
    gProcess = new ProcessState(kDefaultDriver);
    return gProcess;
}

ProcessState代表进程状态,一个进程只有一个ProcessState对象。ProcessState采用了单例的模式保存了一个ProcessState全局对象gProcess,供每个线程使用。

这里的new ProcessState(kDefaultDriver)其实就是去打开binder驱动等操作,如果看过 Binder机制02-ServiceManager 或者Ashmem简介(Android IPC传输大数据)会这流程有所了解,为了照顾没看过这两篇文档的同学,这里我们还是把之前的分析拷贝过来。

new ProcessState(driver)

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    ...

    if (mDriverFD >= 0) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        //#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
        //_SC_PAGE_SIZE表示一个page页的大小,通常情况下为4K
        //3. 通过mmap内存映射(1M-4K*2)的内存空间
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

    ...
}

这里看到了很多有用的信息,设置驱动的名字、最大线程数等等。还调用了open_driver(driver)和mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0)。

open_driver(driver)

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver)
{
    //1. 打开Binder设备驱动
    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        //2. 获取Binder的版本信息
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) {
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        }
        //2.1 比较协议版本是否相同,不同则跳出
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
            close(fd);
            fd = -1;
        }
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        //设置最大线程数,BINDER_SET_MAX_THREADS=16
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}
  • 调用open(对应内核中的binder_open)打开Binder设备驱动
  • 调用ioctl(对应内核中的binder_ioctl)获取Binder的版本信息
  • 调用ioctl(对应内核中的binder_ioctl)设置最大线程数,BINDER_SET_MAX_THREADS=16

mmap()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

//#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
//_SC_PAGE_SIZE表示一个page页的大小,通常情况下为4K
//3. 通过mmap内存映射(1M-4K*2)的内存空间
mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

调用mmap(对应内核中的binder_mmap)内存映射(1M-4K*2)的内存空间

小结

sequenceDiagram
main_mediaserver.cpp ->>+ ProcessState:self()
ProcessState ->> ProcessState:new ProcessState(driver)
ProcessState ->> ProcessState:open_driver(driver)
ProcessState ->> Binder驱动:binder_open()
ProcessState ->> Binder驱动:binder_ioctl()
ProcessState ->>- Binder驱动:binder_mmap()

ProcessState:self的工作也比较简单,分为以下几步:

  • 通过系统调用open()来打开"/dev/binder",获得一个句柄信息,在Binder驱动中对应的是函数binder_open()
  • 通过ioctl获取binder的版本信息,比较binder协议版本是否相同,不同则跳出;再次通过ioctl设置最大线程数,在Binder驱动中对应的是函数binder_ioctl()
  • 通过mmap内存映射(1M-4K*2)的内存空间,即把binder驱动文件的1016K字节映射到了内存空间,这1016K内存空间为servicemanager使用。在Binder驱动中对应的是函数binder_mmap()。
  • _SC_PAGE_SIZE表示一个page页的大小,通常情况下为4K,即(1M - 4K*2)=1016K。
  • 这个page的大小,不同厂家有时候也会调整大小,一般有1M,64K,4K,1KB,通常为4K。
  • Android11之前servicemanager映射的内存空间是128K。

获取ServiceManager代理对象

当服务进程获取到了ProcessState对象后,接下来要拿到ServiceManager的代理对象(BpServiceManager)。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IServiceManager.cpp

//AidlServiceManager其实就是IServiceManager
using AidlServiceManager = android::os::IServiceManager;

sp<IServiceManager> defaultServiceManager()
{
    std::call_once(gSmOnce, []() {
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
                sleep(1);
            }
        }

        gDefaultServiceManager = new ServiceManagerShim(sm);
    });

    return gDefaultServiceManager;
}

获取ServiceManager对象采用单例模式,当gDefaultServiceManager存在,则直接返回,否则创建一个新对象。 其创建过程分为几个步骤:

  • 调用ProcessState::self()获取ProcessState对象,上一步刚获取,所以全局对象gProcess
  • 调用ProcessState::getContextObject(nullptr)获取获取BpBinder对象
  • 调用interface_cast()获取BpServiceManager对象

getContextObject()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    sp<IBinder> context = getStrongProxyForHandle(0);

    if (context == nullptr) {
       ALOGW("Not able to get context object on %s.", mDriverName.c_str());
    }

    // The root object is special since we get it directly from the driver, it is never
    // written by Parcell::writeStrongBinder.
    internal::Stability::tryMarkCompilationUnit(context.get());

    return context;
}

getContextObject()调用getStrongProxyForHandle()进行处理,传入handle=0(系统中约定了ServiceManager的handle=0)

getStrongProxyForHandle()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);
    //查找handle对应的资源项
    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {

                Parcel data;
                //通过ping操作测试binder是否已经准备就绪
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                if (status == DEAD_OBJECT)
                   return nullptr;
            }
            //当handle值所对应的IBinder不存在或弱引用无效时,则创建BpBinder对象
            //handle=0
            //create的实现其实就是new BpBinder(0,trackedUid)
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    //当handle大于mHandleToObject的长度时,进入该分支
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = nullptr;
        e.refs = nullptr;
        //从mHandleToObject的第N个位置开始,插入(handle+1-N)个e到队列中
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return nullptr;
    }
    return &mHandleToObject.editItemAt(handle);
}
  • 当handle=0所对应的IBinder不存在或弱引用无效时,创建BpBinder
  • 通过PING_TRANSACTION来判断ServiceManager是否已经就绪
  • 创建一个BpBinder(0, trackedUid),同时将handle相对应Binder的弱引用增加1

lookupHandleLocked()方法根据handle值来查找对应的handle_entry,handle_entry是一个结构体,里面记录了IBinder和weakref_type两个指针。当handle大于mHandleToObject的Vector长度时,则向Vector中添加(handle+1-N)个handle_entry结构体,然后再返回handle向对应位置的handle_entry结构体指针。

获取BpServiceManager对象

interface_cast()
http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/include/binder/IInterface.h

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
这里采用了C++的模板函数,因为AidlServiceManager其实就是IServiceManager,interface_cast<AidlServiceManager>其实就是interface_cast<IServiceManager>,也就是调用了IServiceManager::asInterface(obj);  这里的obj就是new BpBinder(0)。

obsidian正文中用到 <> 或者在table中用到 __ 开头,就影响的md格式。 所以上面这段话如果放在正文,就影响了整个文档格式。

IServiceManager::asInterface()

但是IServiceManager中没有看到 asInterface()的实现,还记得前面我聊到DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE中实现asInterface()。

看过Android 10及之前相关源码的同学应该会对BpServiceManager这个类比较熟悉,它是ServiceManager在其它Binder线程的代理。不过这一部分代码现在已经被删除了。在此之后,BpServiceManager不再通过手动实现,而是采用AID(文件为 IServiceManager.aidl),生成IServiceManager、BnServiceManager、BpServiceManager的头文件及具体实现。

https://android-review.googlesource.com/c/platform/frameworks/native/+/1132445 https://android.googlesource.com/platform/system/tools/aidl/+/brillo-m10-dev/docs/aidl-cpp.md

生成的代码如下:

DECLARE_META_INTERFACE(ServiceManager)

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")

DECLARE_META_INTERFACE(ServiceManager)
public:
    static const ::android::String16 descriptor;
    static ::android::sp<IServiceManager> asInterface(
            const ::android::sp<::android::IBinder>& obj);
    virtual const ::android::String16& getInterfaceDescriptor() const;
    IServiceManager();
    virtual ~IServiceManager();
    static bool setDefaultImpl(std::unique_ptr<IServiceManager> impl);
    static const std::unique_ptr<IServiceManager>& getDefaultImpl();
private:
    static std::unique_ptr<IServiceManager> default_impl;
public:

该过程主要是声明asInterface()、getInterfaceDescriptor()方法。

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")
const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const ::android::String16&
    IServiceManager::getInterfaceDescriptor() const {
    return IServiceManager::descriptor;
}
::android::sp<IServiceManager> IServiceManager::asInterface(
    const ::android::sp<::android::IBinder>& obj)
{
    ::android::sp<IServiceManager> intr;
    if (obj != nullptr) {
        intr = static_cast<IServiceManager*>(
            obj->queryLocalInterface(
                IServiceManager::descriptor).get());
        if (intr == nullptr) {
            intr = new BpServiceManager(obj);
        }
    }
    return intr;
}
std::unique_ptr<IServiceManager> IServiceManager::default_impl;
bool IServiceManager::setDefaultImpl(std::unique_ptr<IServiceManager> impl)
{
    if (!IServiceManager::default_impl && impl) {
        IServiceManager::default_impl = std::move(impl);
        return true;
    }
    return false;
}
const std::unique_ptr<IServiceManager>& IServiceManager::getDefaultImpl()
{
    return IServiceManager::default_impl;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }

最终IServiceManager::asInterface()等价于new Bp##INTERFACE(obj),即new BpServiceManager(obj),所以gDefaultServiceManager = new ServiceManagerShim(sm);转换后,变成gDefaultServiceManager = new ServiceManagerShim(new BpBinder(0,trackedUid));

MediaPlayerService::instantiate()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}
  • 创建一个新的Service——BnMediaPlayerService,想把它告诉ServiceManager。然后调用BnServiceManager的addService的addService来向ServiceManager中添加一个Service,其他进程可以通过字符串"media.player"来向ServiceManager查询此服务。
  • 注册服务MediaPlayerService:由defaultServiceManager()返回的是BpServiceManager,同时会创建ProcessState对象和BpBinder对象。故此处等价于调用BpServiceManager->addService。

类图

懒得画图,复用之前的图片,把图中XXX换成MediaPlayerService即可。

MediaPlayerService继承自BnMediaPlayerService,BnMediaPlayerService继承自BnInterface,BnInterface继承自BBinder,最终转换为一个Binder实体,也就是BBinder对象。

BpServiceManager.addService()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IServiceManager.cpp

status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)
{
    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

添加Service到ServiceManager。

ServiceManager.addService()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/cmds/servicemanager/ServiceManager.h

//定义Service结构体
struct Service {
    sp<IBinder> binder; // not null
    bool allowIsolated;
    int32_t dumpPriority;
    bool hasClients = false; // notifications sent on true -> false.
    bool guaranteeClient = false; // forces the client check to true
    pid_t debugPid = 0; // the process in which this service runs

    // the number of clients of the service, including servicemanager itself
    ssize_t getNodeStrongRefCount();
};

using ServiceMap = std::map<std::string, Service>;

//用于保存添加进来的Services
ServiceMap mNameToService;


http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/cmds/servicemanager/ServiceManager.cpp

Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
    ...

    //添加 Service 到 mNameToService 中,完成 Binder Service 注册过程
    mNameToService[name] = Service {
        .binder = binder,
        .allowIsolated = allowIsolated,
        .dumpPriority = dumpPriority,
        .debugPid = ctx.debugPid,
    };

    auto it = mNameToRegistrationCallback.find(name);
    if (it != mNameToRegistrationCallback.end()) {
        for (const sp<IServiceCallback>& cb : it->second) {
            mNameToService[name].guaranteeClient = true;
            // permission checked in registerForNotifications
            cb->onRegistration(name, binder);
        }
    }

    return Status::ok();
}

这一个过程在 Binder机制02-ServiceManager 章节中有讲解,这里就不展开描述。

小结

  • 服务进程先获得一个 ProcessState()的对象
  • 获取ServiceManager的代理对象BpServiceManager,主要通过new BpBinder(0,xxx)得到
  • 调用BpServiceManager的addService,ServiceManager保存到mNameToService中
  • 通过ProcessState::startThreadPool启动线程池
  • 通过IPCThreadState::joinThreadPool将主线程加入的Binder中
  • 通过::android::hardware::joinRpcThreadpool()将主线程加入HwBinder的线程池进行循环

获取Native服务(media服务)

http://aospxref.com/android-11.0.0_r21/xref/frameworks/av/media/libmedia/IMediaDeathNotifier.cpp

IMediaDeathNotifier::getMediaPlayerService()
{
    ALOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
        //获取ServiceManager的代理对象BpServiceManager
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            //调用BpServiceManager的getService接口,来获取服务名称为“media.player”的Binder服务对象
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
            }
            ALOGW("Media player service not published, waiting...");
            //如果media的服务还没有准备好,休眠0.5秒进行等待
            usleep(500000); // 0.5 s
        } while (true);

        if (sDeathNotifier == NULL) {
            //创建死亡通知对象
            sDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(sDeathNotifier);
        //转换得到服务对象
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}
  • 获取ServiceManager的代理对象BpServiceManager
  • 调用BpServiceManager的getService接口,来获取服务名称为“media.player”的Binder服务对象
  • 创建死亡通知对象
  • 将死亡通知连接到binder
  • 得到服务对象

获取ServiceManager代理对象

其中defaultServiceManager()过程在上面已经说了。

BpServiceManager.getService()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IServiceManager.cpp

sp<IBinder> ServiceManagerShim::getService(const String16& name) const
{
    static bool gSystemBootCompleted = false;
    //检查指定服务是否存在
    sp<IBinder> svc = checkService(name);
    if (svc != nullptr) return svc;

    //如果ProcessState和Binder驱动交互的是"/dev/vndbinder",那么isVendorService为True,表明Vendor进程之间可以进行Binder通信
    const bool isVendorService =
        strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
    const long timeout = uptimeMillis() + 5000;
    // Vendor code can't access system properties
    if (!gSystemBootCompleted && !isVendorService) {
    //vendor分区的代码不能访问system的属性
#ifdef __ANDROID__
        char bootCompleted[PROPERTY_VALUE_MAX];
        property_get("sys.boot_completed", bootCompleted, "0");
        gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
#else
        gSystemBootCompleted = true;
#endif
    }
    // retry interval in millisecond; note that vendor services stay at 100ms
    //vendor分区的服务sleepTime 为100ms, system为1000ms
    const long sleepTime = gSystemBootCompleted ? 1000 : 100;

    int n = 0;
    while (uptimeMillis() < timeout) {
        n++;
        ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
            ProcessState::self()->getDriverName().c_str());
        usleep(1000*sleepTime);

        sp<IBinder> svc = checkService(name);
        if (svc != nullptr) return svc;
    }
    ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
    return nullptr;
}

getService()的核心就是调用checkService()来检查服务是否存在,如果不存在,继续等待查找。注意:vendor分区的服务等待时间为100ms,system分区的为1000ms.

BpServiceManager.checkService()

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/libs/binder/IServiceManager.cpp

sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
    sp<IBinder> ret;
    if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
        return nullptr;
    }
    return ret;
}

checkService()和前面的addService()类似,最终调到ServiceManager.cpp里。

ServiceManager.checkService()

ttp://aospxref.com/android-11.0.0_r21/xref/frameworks/native/cmds/servicemanager/ServiceManager.h

//定义Service结构体
struct Service {
    sp<IBinder> binder; // not null
    bool allowIsolated;
    int32_t dumpPriority;
    bool hasClients = false; // notifications sent on true -> false.
    bool guaranteeClient = false; // forces the client check to true
    pid_t debugPid = 0; // the process in which this service runs

    // the number of clients of the service, including servicemanager itself
    ssize_t getNodeStrongRefCount();
};

using ServiceMap = std::map<std::string, Service>;

//用于保存添加进来的Services
ServiceMap mNameToService;


http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/cmds/servicemanager/ServiceManager.cpp

Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
    *outBinder = tryGetService(name, false);
    // returns ok regardless of result for legacy reasons
    return Status::ok();
}

sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
    auto ctx = mAccess->getCallingContext();

    sp<IBinder> out;
    Service* service = nullptr;
    //查找mNameToServices是否存在名字为name的Service
    if (auto it = mNameToService.find(name); it != mNameToService.end()) {
        service = &(it->second);

        if (!service->allowIsolated) {
            uid_t appid = multiuser_get_app_id(ctx.uid);
            bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;

            if (isIsolated) {
                return nullptr;
            }
        }
        out = service->binder;
    }

    if (!mAccess->canFind(ctx, name)) {
        return nullptr;
    }

    if (!out && startIfNotFound) {
        tryStartService(name);
    }

    if (out) {
        // Setting this guarantee each time we hand out a binder ensures that the client-checking
        // loop knows about the event even if the client immediately drops the service
        service->guaranteeClient = true;
    }

    return out;
}

到此我们就拿到服务,拿到服务后可以调用linkToDeath()函数监听服务进程的状态,前面我们有聊到过如何处罚linkToDeath,这里就不再展开描述。

总结

不过是服务的注册还是获取,都是通过ServiceManager交互。说得简单一点其实就是:

  • 通过调用defaultServiceManager()获取ServiceManager的代理对象BpServiceManager
  • 调用BpServiceManager.addService()获取BpServiceManager.getService()

当然在实际coding过程中没这么简单,在后续得章节中我们会写一个native服务demo,这过程中就不难发现其实出来刚才说得,其实还需要添加seliunx、编译文件、启动脚本等等。

评论