文件CameraManager.java 入手

    private CameraDevice openCameraDeviceUserAsync(String cameraId,

            CameraDevice.StateCallback callback, Handler handler, final int uid)

            throws CameraAccessException {

        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);

        CameraDevice device = null;

        synchronized (mLock) {

            ICameraDeviceUser cameraUser = null;

            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =

                    new android.hardware.camera2.impl.CameraDeviceImpl(

                        cameraId,

                        callback,

                        handler,

                        characteristics,

                        mContext.getApplicationInfo().targetSdkVersion);

            ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

            try {

                if (supportsCamera2ApiLocked(cameraId)) {

                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices

                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

                    if (cameraService == null) {

                        throw new ServiceSpecificException(

                            ICameraService.ERROR_DISCONNECTED,

                            "Camera service is currently unavailable");

                    }

                    cameraUser = cameraService.connectDevice(callbacks, cameraId,

                            mContext.getOpPackageName(), uid);

                } else {

                    // Use legacy camera implementation for HAL1 devices

                    int id;

                    try {

                        id = Integer.parseInt(cameraId);

                    } catch (NumberFormatException e) {

                        throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "

                                + cameraId);

                    }

                    Log.i(TAG, "Using legacy camera HAL.");

                    cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);

                }

            } catch (ServiceSpecificException e) {

                if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {

                    throw new AssertionError("Should've gone down the shim path");

                } else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE ||

                        e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE ||

                        e.errorCode == ICameraService.ERROR_DISABLED ||

                        e.errorCode == ICameraService.ERROR_DISCONNECTED ||

                        e.errorCode == ICameraService.ERROR_INVALID_OPERATION) {

                    // Received one of the known connection errors

                    // The remote camera device cannot be connected to, so

                    // set the local camera to the startup error state

                    deviceImpl.setRemoteFailure(e);

                    if (e.errorCode == ICameraService.ERROR_DISABLED ||

                            e.errorCode == ICameraService.ERROR_DISCONNECTED ||

                            e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {

                        // Per API docs, these failures call onError and throw

                        throwAsPublicException(e);

                    }

                } else {

                    // Unexpected failure - rethrow

                    throwAsPublicException(e);

                }

            } catch (RemoteException e) {

                // Camera service died - act as if it's a CAMERA_DISCONNECTED case

                ServiceSpecificException sse = new ServiceSpecificException(

                    ICameraService.ERROR_DISCONNECTED,

                    "Camera service is currently unavailable");

                deviceImpl.setRemoteFailure(sse);

                throwAsPublicException(sse);

            }

            // TODO: factor out callback to be non-nested, then move setter to constructor

            // For now, calling setRemoteDevice will fire initial

            // onOpened/onUnconfigured callbacks.

            // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if

            // cameraUser dies during setup.

            deviceImpl.setRemoteDevice(cameraUser);

            device = deviceImpl;

        }

        return device;

    }

 

继续往下看

 public ICameraService getCameraService() {

            synchronized(mLock) {

                connectCameraServiceLocked();

                if (mCameraService == null && !sCameraServiceDisabled) {

                    Log.e(TAG, "Camera service is unavailable");

                }

                return mCameraService;

            }

        }

 

 private void connectCameraServiceLocked() {

            // Only reconnect if necessary

            if (mCameraService != null || sCameraServiceDisabled) return;

            Log.i(TAG, "Connecting to camera service");

            IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);

            if (cameraServiceBinder == null) {

                // Camera service is now down, leave mCameraService as null

                return;

            }

            try {

                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);

            } catch (RemoteException e) {

                // Camera service is now down, leave mCameraService as null

                return;

            }

            ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);

            try {

                CameraMetadataNative.setupGlobalVendorTagDescriptor();

            } catch (ServiceSpecificException e) {

                handleRecoverableSetupErrors(e);

            }

            try {

                CameraStatus[] cameraStatuses = cameraService.addListener(this);

                for (CameraStatus c : cameraStatuses) {

                    onStatusChangedLocked(c.status, c.cameraId);

                }

                mCameraService = cameraService;

            } catch(ServiceSpecificException e) {

                // Unexpected failure

                throw new IllegalStateException("Failed to register a camera service listener", e);

            } catch (RemoteException e) {

                // Camera service is now down, leave mCameraService as null

            }

        }

 

继续往下看ServiceManager.getService方法

public static IBinder getService(String name) {

        try {

            IBinder service = sCache.get(name);

            if (service != null) {

                return service;

            } else {

                return Binder.allowBlocking(getIServiceManager().getService(name));

            }

        } catch (RemoteException e) {

            Log.e(TAG, "error in getService", e);

        }

        return null;

    }

 

往下看getIServiceManager()

private static IServiceManager getIServiceManager() {

        if (sServiceManager != null) {

            return sServiceManager;

        }

        // Find the service manager

        sServiceManager = ServiceManagerNative

                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

        return sServiceManager;

    }

往下看 ServiceManagerNative.asInterface

static public IServiceManager asInterface(IBinder obj)

    {

        if (obj == null) {

            return null;

        }

        IServiceManager in =

            (IServiceManager)obj.queryLocalInterface(descriptor);

        if (in != null) {

            return in;

        }

        

        return new ServiceManagerProxy(obj);

    }

回到getIServiceManager()方法,分析BinderInternal.getContextObject()

这个方法调用,触发jni,来到文件android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)

{

    sp

继续往下javaObjectForIBinder 该方法返回BinderProxy

jobject javaObjectForIBinder(JNIEnv* env, const sp

    if (val->checkSubclass(&gBinderOffsets)) {

        // One of our own!

        jobject object = static_cast

    // For the rest of the function we will hold this lock, to serialize

    // looking/creation/destruction of Java proxies for native Binder proxies.

    AutoMutex _l(mProxyLock);

    // Someone else's...  do we know about it?

    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);

    if (object != NULL) {

        jobject res = jniGetReferent(env, object);

        if (res != NULL) {

            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);

            return res;

        }

        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());

        android_atomic_dec(&gNumProxyRefs);

        val->detachObject(&gBinderProxyOffsets);

        env->DeleteGlobalRef(object);

    }

    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);

    if (object != NULL) {

        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);

        // The proxy holds a reference to the native object.

        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());

        val->incStrong((void*)javaObjectForIBinder);

        // The native object needs to hold a weak reference back to the

        // proxy, so we can retrieve the same proxy if it is still active.

        jobject refObject = env->NewGlobalRef(

                env->GetObjectField(object, gBinderProxyOffsets.mSelf));

        val->attachObject(&gBinderProxyOffsets, refObject,

                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy

        sp

        // Note that a new object reference has been created.

        android_atomic_inc(&gNumProxyRefs);

        incRefsCreated(env);

    }

    return object;

}

回到方法 ServiceManager.getService方法

调用 

 getIServiceManager()最终得到new ServiceManagerProxy(obj)//obj就是BinderProxy

继续看

getIServiceManager().getService(name) 这行最终来到ServiceManagerProxy下的getService方法。

 public IBinder getService(String name) throws RemoteException {

        Parcel data = Parcel.obtain();

        Parcel reply = Parcel.obtain();

        data.writeInterfaceToken(IServiceManager.descriptor);

        data.writeString(name);

        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

        IBinder binder = reply.readStrongBinder();

        reply.recycle();

        data.recycle();

        return binder;

    }

mRemote就是 BinderProxy ,然后调用下面的transact方法

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {

        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

        if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {

            // For now, avoid spamming the log by disabling after we've logged

            // about this interface at least once

            mWarnOnBlocking = false;

            Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",

                    new Throwable());

        }

        final boolean tracingEnabled = Binder.isTracingEnabled();

        if (tracingEnabled) {

            final Throwable tr = new Throwable();

            Binder.getTransactionTracker().addTrace(tr);

            StackTraceElement stackTraceElement = tr.getStackTrace()[1];

            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,

                    stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());

        }

        try {

            return transactNative(code, data, reply, flags);

        } finally {

            if (tracingEnabled) {

                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);

            }

        }

    }

trancactNative是jni方法,通过转换来到c++文件下的

android_util_Binder.cpp

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();

   //gBinderProxyOffseets.mObject中保存的是new BpBinder(0) 对象

    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*/, data->dataSize());

    return JNI_FALSE;

}

注意,

status_t err = target->transact(code, *data, reply, flags);  可以参照下面这个链接的分析,基本上差不多,target就是BpBinder

下面回到CameraManager.java文件的openCameraDeviceUserAsync方法

分析调用

cameraService.connectDevice(callbacks, cameraId, mContext.getOpPackageName(), uid);

虽然大家都知道connectDevice最终会调用到CameraService.cpp文件下的connectDevice,但是到底是如何周转过来的呢?

实际上是通过aidl

见文件frameworks/av/camera/aidl/android/hardware/ICameraService.aidl有下面的定义

 ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks,

            String cameraId,

            String opPackageName,

            int clientUid);

这段话最终会自动编译生成一个中间文件ICameraService.java,在这个文件中,connectDevice方法中会进行binder调用

类似这样的写法

mRemote.transact(CONNECT_DEVICE, data, reply, 0);//mRemote是类BinderProxy

在Binder.java下面有个类BinderProxy

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {

        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

        if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {

            // For now, avoid spamming the log by disabling after we've logged

            // about this interface at least once

            mWarnOnBlocking = false;

            Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",

                    new Throwable());

        }

        final boolean tracingEnabled = Binder.isTracingEnabled();

        if (tracingEnabled) {

            final Throwable tr = new Throwable();

            Binder.getTransactionTracker().addTrace(tr);

            StackTraceElement stackTraceElement = tr.getStackTrace()[1];

            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,

                    stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());

        }

        try {

            return transactNative(code, data, reply, flags);

        } finally {

            if (tracingEnabled) {

                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);

            }

        }

    }

transactNative方法然后通过jni来到android_util_Binder.cpp文件下面的android_os_BinderProxy_transact方法,最终,这里实现Binder调用,实现了夸进程通信

在android 8上找不到文件ICameraService.cpp,其实在这个文件中有onTransact方法

status_t BnCameraService::onTransact(

    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

    switch(code) {

        。。。

        。。。

        case CONNECT_DEVICE: {

            CHECK_INTERFACE(ICameraService, data, reply);

            sp

来到CameraService.cpp文件 的connectDevice方法

Status CameraService::connectDevice(

        const sp

    ATRACE_CALL();

    Status ret = Status::ok();

    String8 id = String8(cameraId);

    sp

    if(!ret.isOk()) {

        logRejected(id, getCallingPid(), String8(clientPackageName),

                ret.toString8());

        return ret;

    }

    *device = client;

    return ret;

}

在connectHelper方法中,调用关键方法makeClient

sp

    err = client->initialize(mCameraProviderManager);//下一章节会谈到

往下看makeClient方法

Status CameraService::makeClient(const sp

    if (halVersion < 0 || halVersion == deviceVersion) {

        // Default path: HAL version is unspecified by caller, create CameraClient

        // based on device version reported by the HAL.

        switch(deviceVersion) {

          case CAMERA_DEVICE_API_VERSION_1_0:

            if (effectiveApiLevel == API_1) {  // Camera1 API route

                sp