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; }
/****************************************************************************** * 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()); } }