zoukankan      html  css  js  c++  java
  • android binder 机制三(匿名Service)

    什么是匿名Service?凡是没有到ServiceManager上注冊的Service,都是匿名Service。

    还是拿上一篇的样例来举例,看代码:

    status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
    {
        status_t err = UNKNOWN_ERROR;
        const sp<IMediaPlayerService>& service(getMediaPlayerService());
        if (service != 0) {
            sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
            if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
                (NO_ERROR != player->setDataSource(fd, offset, length))) {
                player.clear();
            }
            err = attachNewPlayer(player);
        }
        return err;
    }
    

    在BpMediaPlayerService中。create的实现例如以下:

    virtual sp<IMediaPlayer> create(
            const sp<IMediaPlayerClient>& client, int audioSessionId) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeStrongBinder(client->asBinder());
        data.writeInt32(audioSessionId);
    
        remote()->transact(CREATE, data, &reply);
        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
    }
    
    直接跳到服务端MediaPlayerService,看create的真正实现:

    sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
            int audioSessionId)
    {
        pid_t pid = IPCThreadState::self()->getCallingPid();
        int32_t connId = android_atomic_inc(&mNextConnId);
    
        sp<Client> c = new Client(
                this, pid, connId, client, audioSessionId,
                IPCThreadState::self()->getCallingUid());
    
        ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
             IPCThreadState::self()->getCallingUid());
        /* add by Gary. start {{----------------------------------- */
        c->setScreen(mScreen);
        /* add by Gary. end   -----------------------------------}} */
        c->setSubGate(mGlobalSubGate);  // 2012-03-12, add the global interfaces to control the subtitle gate
    
        wp<Client> w = c;
        {
            Mutex::Autolock lock(mLock);
            mClients.add(w);
        }
        return c;
    }
    

    从代码中,我们能够看出,service->create(this, mAudioSessionId)是返回了一个參数为Client类型的BpMediaPlayer对象,当中Client为MediaPlayerService的私有内部类,其声明为:class Client : publicBnMediaPlayer。

    这样,Binder通信的服务端和client就建立起来了。Client端BpMediaPlayer由MediaPlayer使用,Server端BnMediaPlayer由MediaPlayerService使用。

    BpMediaPlayer是怎样获得BnMediaPlayer的handle值的呢?答案在MediaPlayerService返回这个binder的引用的时候,binder驱动保存了这个binder实体的各种数据。创建了节点,看以下的代码:

    status_t BnMediaPlayerService::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        switch (code) {
            case CREATE: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                sp<IMediaPlayerClient> client =
                    interface_cast<IMediaPlayerClient>(data.readStrongBinder());
                int audioSessionId = data.readInt32();
                sp<IMediaPlayer> player = create(client, audioSessionId);
                reply->writeStrongBinder(player->asBinder());
                return NO_ERROR;
            } break;
    	……
    	}
    }
    

    答案就在这句话中:reply->writeStrongBinder(player->asBinder());

    当这个reply写到Binder驱动时,驱动会特殊处理这样的IBinder类型的数据,为Bbinder建立一个handle。

    通信的通路建立后,就能够进行通信了:player->setDataSource(fd, offset, length)

    之后的实现,和上一篇讲的普通Service就一样了。
  • 相关阅读:
    1031.查询-集合操作
    1030.查询-select子句
    1029.查询-复杂分组grouping子句
    1028.查询-group by和having子句
    1027.查询-where子句
    1026.查询-from子句2
    1025.查询-from子句
    1024.查询-概述
    1023.表-数据操作
    图片隐写之stegsolve使用(转载)
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6869700.html
Copyright © 2011-2022 走看看