static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
        jobject recipient, jint flags) // throws RemoteException
{
    if (recipient == NULL) {
        jniThrowNullPointerException(env, NULL);
        return;
    }

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
        assert(false);
    }

    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);

    if (!target->localBinder()) {
        DeathRecipientList* list = (DeathRecipientList*)
                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
        status_t err = target->linkToDeath(jdr, NULL, flags);
        if (err != NO_ERROR) {
            // Failure adding the death recipient, so clear its reference
            // now.
            jdr->clearReference();
            signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
        }
    }
}
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;
}
static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
        jobject recipient, jint flags) // throws RemoteException
{
    if (recipient == NULL) {
        jniThrowNullPointerException(env, NULL);
        return;
    }

    BinderProxyNativeData *nd = getBPNativeData(env, obj);
    IBinder* target = nd->mObject.get();

    LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);

    if (!target->localBinder()) {
        DeathRecipientList* list = nd->mOrgue.get();
        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
        status_t err = target->linkToDeath(jdr, NULL, flags);
        if (err != NO_ERROR) {
            // Failure adding the death recipient, so clear its reference
            // now.
            jdr->clearReference();
            signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
        }
    }
}
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;
}
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }

    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }

    ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
            target, obj, code);


    bool time_binder_calls;
    int64_t start_millis;
    if (kEnableBinderSample) {
        // Only log the binder call duration for things on the Java-level main thread.
        // But if we don't
        time_binder_calls = should_time_binder_calls();

        if (time_binder_calls) {
            start_millis = uptimeMillis();
        }
    }

    //printf("Transact from Java code to %p sending: ", target); data->print();
    status_t err = target->transact(code, *data, reply, flags);
    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();

    if (kEnableBinderSample) {
        if (time_binder_calls) {
            conditionally_log_binder_call(start_millis, target, code);
        }
    }

    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }

    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
    return JNI_FALSE;
}
static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
{
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target == NULL) {
        return JNI_FALSE;
    }
    bool alive = target->isBinderAlive();
    return alive ? JNI_TRUE : JNI_FALSE;
}
static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
{
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target == NULL) {
        return JNI_FALSE;
    }
    status_t err = target->pingBinder();
    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
}
static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj)
{
    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        return JNI_FALSE;
    }
    bool alive = target->isBinderAlive();
    return alive ? JNI_TRUE : JNI_FALSE;
}
static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj)
{
    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        return JNI_FALSE;
    }
    status_t err = target->pingBinder();
    return err == NO_ERROR ? JNI_TRUE : JNI_FALSE;
}
static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
{
    IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
    if (target != NULL) {
        const String16& desc = target->getInterfaceDescriptor();
        return env->NewString((jchar*)desc.string(), desc.size());
    }
    jniThrowException(env, "java/lang/RuntimeException",
            "No binder found for object");
    return NULL;
}
static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj)
{
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target != NULL) {
        const String16& desc = target->getInterfaceDescriptor();
        return env->NewString(reinterpret_cast<const jchar*>(desc.string()),
                              desc.size());
    }
    jniThrowException(env, "java/lang/RuntimeException",
            "No binder found for object");
    return NULL;
}
static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
{
    IBinder* b = (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    DeathRecipientList* drl = (DeathRecipientList*)
            env->GetLongField(obj, gBinderProxyOffsets.mOrgue);

    LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
    env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
    env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
    drl->decStrong((void*)javaObjectForIBinder);
    b->decStrong((void*)javaObjectForIBinder);

    IPCThreadState::self()->flushCommands();
}
static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
                                                 jobject recipient, jint flags)
{
    jboolean res = JNI_FALSE;
    if (recipient == NULL) {
        jniThrowNullPointerException(env, NULL);
        return res;
    }

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient);
        return JNI_FALSE;
    }

    LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);

    if (!target->localBinder()) {
        status_t err = NAME_NOT_FOUND;

        // If we find the matching recipient, proceed to unlink using that
        DeathRecipientList* list = (DeathRecipientList*)
                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
        sp<JavaDeathRecipient> origJDR = list->find(recipient);
        LOGDEATH("   unlink found list %p and JDR %p", list, origJDR.get());
        if (origJDR != NULL) {
            wp<IBinder::DeathRecipient> dr;
            err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
            if (err == NO_ERROR && dr != NULL) {
                sp<IBinder::DeathRecipient> sdr = dr.promote();
                JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
                if (jdr != NULL) {
                    jdr->clearReference();
                }
            }
        }

        if (err == NO_ERROR || err == DEAD_OBJECT) {
            res = JNI_TRUE;
        } else {
            jniThrowException(env, "java/util/NoSuchElementException",
                              "Death link does not exist");
        }
    }

    return res;
}
void flatten_binder(const wptr<IBinder>& binder, flat_binder_object* out)
{
	out->length = sizeof(flat_binder_object) - sizeof(small_flat_data);
	if (binder != NULL) {
		sptr<IBinder> real = binder.promote();
		if (real != NULL) {
			IBinder *local = real->LocalBinder();
			if (!local) {
				BpBinder *proxy = real->RemoteBinder();
				ErrFatalErrorIf(!proxy, "Binder is neither local nor remote");
				const int32_t handle = proxy->Handle();
				out->type = kPackedLargeBinderWeakHandleType;
				out->handle = handle;
			} else {
				out->type = kPackedLargeBinderWeakType;
				out->binder = binder.get_weak_atom_ptr()->cookie;
				out->cookie = binder.get_weak_atom_ptr()->atom;
			}
		} else {
			// This is bad!  In order to build a SValue from a binder,
			// we need to probe it for information, which requires a primary
			// reference...  but we don't have one.  As something of a hack,
			// we will do a direct dynamic_cast<> on the binder, since we
			// know an BpBinder doesn't get destroyed until all weak references
			// are removed.
			
			SAtom::weak_atom_ptr* weak = binder.get_weak_atom_ptr();
			IBinder* local = static_cast<IBinder*>(weak->cookie);
			BpBinder* proxy = local->RemoteBinder();
			if (proxy != NULL) {
				// Found a proxy, so use it.
				const int32_t handle = proxy->Handle();
				out->type = kPackedLargeBinderWeakHandleType;
				out->handle = handle;
			} else {
				// Couldn't cast as a proxy, so assume this is a local binder.
				out->type = kPackedLargeBinderWeakType;
				out->binder = weak->cookie;
				out->cookie = weak->atom;
			}
		}
	} else {
		out->type = kPackedLargeBinderType;
		out->binder = NULL;
	}
}
AutoPtr<DisplayDevice> VirtualDisplayAdapter::CreateVirtualDisplayLocked(
    /* [in] */ IIVirtualDisplayCallback* callback,
    /* [in] */ IIMediaProjection* projection,
    /* [in] */ Int32 ownerUid,
     /* [in] */ const String& ownerPackageName,
     /* [in] */ const String& name,
    /* [in] */ Int32 width,
    /* [in] */ Int32 height,
    /* [in] */ Int32 densityDpi,
    /* [in] */ ISurface* surface,
    /* [in] */ Int32 flags)
{
    AutoPtr<ISurfaceControlHelper> helper;
    CSurfaceControlHelper::AcquireSingleton((ISurfaceControlHelper**)&helper);

    Boolean secure = (flags & IDisplayManager::VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
    IBinder* appToken = IBinder::Probe(callback);

    AutoPtr<IBinder> displayToken;
    helper->CreateDisplay(name, secure, (IBinder**)&displayToken);
    AutoPtr<Callback> cb = new Callback(callback, mHandler, this);
    AutoPtr<VirtualDisplayDevice> device = new VirtualDisplayDevice(
        displayToken, appToken, ownerUid, ownerPackageName, name,
        width, height, densityDpi, surface, flags, cb, this);

    mVirtualDisplayDevices->Put(TO_IINTERFACE(appToken), TO_IINTERFACE(device));

    // try {
    AutoPtr<IProxy> proxy = (IProxy*)appToken->Probe(EIID_IProxy);
    ECode ec = NOERROR;
    if (projection != NULL) {
        AutoPtr<IIMediaProjectionCallback> mpcb;
        assert(0 && "TODO");
        // CMediaProjectionCallback::New(appToken, IObject::Probe(this),
        //     (IIMediaProjectionCallback**)&mpcb);
        ec = projection->RegisterCallback(mpcb);
        FAIL_GOTO(ec, _EXIT_)
    }
Exemple #16
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());
    }


}