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

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  See comment
        // in getWeakProxyForHandle() for more info about this.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            b = new BpBinder(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;
}
wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
{
    wp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {        
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  The
        // attemptIncWeak() is safe because we know the BpBinder destructor will always
        // call expungeHandle(), which acquires the same lock we are holding now.
        // We need to do this because there is a race condition between someone
        // releasing a reference on this BpBinder, and a new reference on its handle
        // arriving from the driver.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            b = new BpBinder(handle);
            result = b;
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
        } else {
            result = b;
            e->refs->decWeak(this);
        }
    }

    return result;
}
示例#3
0
/******************************************************************************
 * frameworks/base/media/mediaserver/main_mediaserver.cpp
 *
 * Library:
 * LOCAL_MODULE:= mediaserver
 *
 * system/core/rootdir/init.rc
 *
 * service media /system/bin/mediaserver
    user media
    group system audio camera graphics inet net_bt net_bt_admin
 *
 */
int main(int argc, char** argv)
{
    // Get IServiceManager
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();

    AudioFlinger::instantiate();
    // void AudioFlinger::instantiate()
    {
        // AudioFlinger <-- BnAudioFlinger <-- BnInterface<IAudioFlinger> <--
        // BBinder <-- IBinder <-- RefBase
        defaultServiceManager()->addService(String16("media.audio_flinger"), new AudioFlinger());
        // status_t BpServiceManager::addService(const String16& name, const
        // sp<IBinder>& service)
        //
        // The service is IAudioFlinger as BBinder and IBinder interface.
        {
            Parcel data, reply;
            // write to IServiceManager
            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
            // write name "android.media.IAudioFlinger"
            data.writeString16(name);
            data.writeStrongBinder(service);
            // status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
            {
                flatten_binder(ProcessState::self(), val, this);
                // status_t flatten_binder(const sp<ProcessState>& proc, const
                // sp<IBinder>& binder, Parcel* out)
                {
                    flat_binder_object obj;

                    IBinder *local = binder->localBinder();
                    // BBinder* BBinder::localBinder()
                    //
                    // AudioFlinger is derived from BBinder, so it shall call
                    // BBinder::localBinder() to return itself
                    //
                    // TODO: check if the pointer will be switched to handle in
                    // binder driver
                    {
                        return this;
                    }

                    obj.type = BINDER_TYPE_BINDER;
                    obj.binder = local->getWeakRefs();
                    obj.cookie = local;

                    finish_flatten_binder(binder, obj, out);
                    // inline static status_t finish_flatten_binder(const
                    // sp<IBinder>& binder, const flat_binder_object& flat,
                    // Parcel* out)
                    {
                        out->writeObject(flat, false);
                    }

                    // After the packet for addService RPC call is made,
                    // BpServiceManager::addService will call BpBinder’s
                    // transact.
                    //

                }
            } // writeStrongBinder()
        }
    }

    MediaPlayerService::instantiate();
    // void MediaPlayerService::instantiate()
    // frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp
    // TODO: how to connect the pointer to the handle??
    {
        defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
    }


}