Camera2 FrameWork层分析

在Camera2 App中我们去打开相机时,最终是调用了mCameraManager.openCamera(cameraId)。我们就从这里开始分析Camera2 的FrameWork层。openCamera()最终是调用了CameraManager.openCameraDeviceUserAsync()我们直接来看这个函数

/**frameworks/base/core/java/android/hardware/camera2/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;
}

在这段代码中我们新建了一个android.hardware.camera2.impl.CameraDeviceImpl对象,并且向其中保存了远端设备并把它返回了。我们先来分析下远端设备cameraUser的获取。在HAL3.2+的时候

/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
cameraUser = cameraService.connectDevice(callbacks, cameraId,
                        mContext.getOpPackageName(), uid);

这里第一句很容易知道这是通过了Android的Binder机制来获取了远端CameraService的一个代理。关于CameraService的启动时机以及初始化,下节会详细介绍。下面分析CameraService.connectDevice()

/**/frameworks/av/services/camera/libcameraservice/CameraService.cpp**/
Status CameraService::connectDevice(
        const sp& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        int clientUid,
        /*out*/
        sp* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp client = nullptr;
    ret = connectHelper(cameraCb, id,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
            clientUid, USE_CALLING_PID, API_2,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client);

    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }

    *device = client;
    return ret;

这里可以看到connectDevice()函数实际返回了一个CameraDeviceCilent对象,而这个对象是由函数connectHelper()返回的,函数如下:

/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
template
Status CameraService::connectHelper(const sp& cameraCb, const String8& cameraId,
        int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp& device) {
    binder::Status ret = binder::Status::ok();

    String8 clientName8(clientPackageName);

    /* Do something in */
    ......
    /* Do something out */

        sp tmp = nullptr;
        if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast(tmp.get());

        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);

        err = client->initialize(mCameraProviderManager);

    /* Do something in */
    ......
    /* Do something out */

    // Important: release the mutex here so the client can call back into the service from its
    // destructor (can be at the end of the call)
    device = client;
    return ret;
}

这里先是调用了makeCilent()函数返回一个BaseClient对象,然后将这个BaseClient对象转型为了一个CameraDeviceCilent对象,然后执行它的初始化函数,最后将这个对象返回。

/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
Status CameraService::makeClient(const sp& cameraService,
        const sp& cameraCb, const String16& packageName, const String8& cameraId,
        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp* client) {

    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:
            /* Do something in */
            ......
            /* Do something out */
          case CAMERA_DEVICE_API_VERSION_3_0:
          case CAMERA_DEVICE_API_VERSION_3_1:
          case CAMERA_DEVICE_API_VERSION_3_2:
          case CAMERA_DEVICE_API_VERSION_3_3:
          case CAMERA_DEVICE_API_VERSION_3_4:
            if (effectiveApiLevel == API_1) { // Camera1 API route
                sp tmp = static_cast(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
                        facing, clientPid, clientUid, servicePid, legacyMode);
            } else { // Camera2 API route
                sp tmp =
                        static_cast(cameraCb.get());
                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
                        facing, clientPid, clientUid, servicePid);
            }
            break;
          default:
            // Should not be reachable
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                    "Camera device \"%s\" has unknown HAL version %d",
                    cameraId.string(), deviceVersion);
        }
    } else {
        /* Do something in */
        ......
        /* Do something out */
    }
    return Status::ok();
}

可以看到在Camera2 API时,最终创建了一个CameraDeviceCilent对象并一路向上返回,最终被保存在CameraManager中新建的CameraDeviceImpl对象的mRemoteDevice中。知道了deviceImpl.setRemoteDevice(cameraUser);中的cameraUser到底是什么,我们再来看看这个方法做了什么

/**/frameworks/base/core/java/android/hardware/camera2/Impl/CameraDeviceImpl.java**/
 public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
        synchronized(mInterfaceLock) {
            // TODO: Move from decorator to direct binder-mediated exceptions
            // If setRemoteFailure already called, do nothing
            if (mInError) return;

            mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);

            IBinder remoteDeviceBinder = remoteDevice.asBinder();
            // For legacy camera device, remoteDevice is in the same process, and
            // asBinder returns NULL.
            if (remoteDeviceBinder != null) {
                try {
                    remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
                } catch (RemoteException e) {
                    CameraDeviceImpl.this.mDeviceHandler.post(mCallOnDisconnected);

                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "The camera device has encountered a serious error");
                }
            }

            mDeviceHandler.post(mCallOnOpened);
            mDeviceHandler.post(mCallOnUnconfigured);
        }
    }

private final Runnable mCallOnOpened = new Runnable() {
        @Override
        public void run() {
            StateCallbackKK sessionCallback = null;
            synchronized(mInterfaceLock) {
                if (mRemoteDevice == null) return; // Camera already closed

                sessionCallback = mSessionStateCallback;
            }
            if (sessionCallback != null) {
                sessionCallback.onOpened(CameraDeviceImpl.this);
            }
            mDeviceCallback.onOpened(CameraDeviceImpl.this);
        }
    };

这里mDeviceHandler就是我们创建deviceImpl传入的handlermDeviceCallback就是我们自己callback也就是我们自己打开相机时写的那个回调。这里就明白了当CameraDeviceCilent创建成功并且通过CameraDeviceImpl.setRemoteDevice()设置给CameraDeviceImpl的时候就会回调相机打开成功的函数,而函数中的CameraDevice实际就是CameraDeviceImpl,可以看到CameraDeviceImpl确实继承了CameraDevice
下图总结了这一段的流程。

返回CameraDeviceClient.png

接着我们看CameraDeviceCilent的构造函数:

/**frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp**/
CameraDeviceClient::CameraDeviceClient(const sp& cameraService,
        const sp& remoteCallback,
        const String16& clientPackageName,
        const String8& cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid) :
    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
                cameraId, cameraFacing, clientPid, clientUid, servicePid),
    mInputStream(),
    mStreamingRequestId(REQUEST_ID_NONE),
    mRequestIdCounter(0) {

    ATRACE_CALL();
    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}

可以看到这里就是调用了父类的构造函数,和一些初始化。CameraDeviceClient新建完成后在CameraService.connectHelper中执行了client->initialize(mCameraProviderManager);

/**frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp**/
status_t CameraDeviceClient::initialize(sp manager) {
    return initializeImpl(manager);
}

template
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
    ATRACE_CALL();
    status_t res;

    res = Camera2ClientBase::initialize(providerPtr);
    if (res != OK) {
        return res;
    }

    String8 threadName;
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
    mFrameProcessor->run(threadName.string());

    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
                                      /*listener*/this,
                                      /*sendPartials*/true);

    return OK;
}

这里执行了父类的初始化函数,然后进行了FrameProcessor 的创建与初始化配置等等,这个东西可能是用于处理上传的每帧数据的。上面执行了父类也就是Camera2ClientBase的构造函数,这里又执行了它的初始化函数,接下来着重分析类Camera2ClientBase。先看构造函数:

/**frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp**/
template 
Camera2ClientBase::Camera2ClientBase(
        const sp& cameraService,
        const sp& remoteCallback,
        const String16& clientPackageName,
        const String8& cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid):
        TClientBase(cameraService, remoteCallback, clientPackageName,
                cameraId, cameraFacing, clientPid, clientUid, servicePid),
        mSharedCameraCallbacks(remoteCallback),
        mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
        mDeviceActive(false)
{
    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
            String8(clientPackageName).string(), clientPid, clientUid);

    mInitialClientPid = clientPid;
    mDevice = new Camera3Device(cameraId);
    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}

这里就是需要注意创建了一个Camera3Device对象,接着分析Camera2ClientBase的初始化函数:

/**frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp**/
template 
status_t Camera2ClientBase::initialize(sp manager) {
    return initializeImpl(manager);
}

template 
template 
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr) {
    ATRACE_CALL();
    ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
          TClientBase::mCameraIdStr.string());
    status_t res;

    // Verify ops permissions
    res = TClientBase::startCameraOps();
    if (res != OK) {
        return res;
    }

    if (mDevice == NULL) {
        ALOGE("%s: Camera %s: No device connected",
                __FUNCTION__, TClientBase::mCameraIdStr.string());
        return NO_INIT;
    }

    res = mDevice->initialize(providerPtr);
    if (res != OK) {
        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }

    wp weakThis(this);
    res = mDevice->setNotifyCallback(weakThis);

    return OK;
}

注意此处,TClientBase 对应 CameraDeviceClientBase,而 TProviderPtr对应的是 CameraProviderManager。这里调用了Camera3Device的初始化函数,此前我们已经新建了Camera3Device对象,调用了构造函数。

/**frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp*/
Camera3Device::Camera3Device(const String8 &id):
        mId(id),
        mOperatingMode(NO_MODE),
        mIsConstrainedHighSpeedConfiguration(false),
        mStatus(STATUS_UNINITIALIZED),
        mStatusWaiters(0),
        mUsePartialResult(false),
        mNumPartialResults(1),
        mTimestampOffset(0),
        mNextResultFrameNumber(0),
        mNextReprocessResultFrameNumber(0),
        mNextShutterFrameNumber(0),
        mNextReprocessShutterFrameNumber(0),
        mListener(NULL),
        mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID)
{
    ATRACE_CALL();
    camera3_callback_ops::notify = &sNotify;
    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}

这里主要进行了参数的初始化以及两个回调接口的设置。

/**frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp*/
status_t Camera3Device::initialize(sp manager) {
    ATRACE_CALL();
    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);

    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
    if (mStatus != STATUS_UNINITIALIZED) {
        CLOGE("Already initialized!");
        return INVALID_OPERATION;
    }
    if (manager == nullptr) return INVALID_OPERATION;

    sp session;
    ATRACE_BEGIN("CameraHal::openSession");
    status_t res = manager->openSession(mId.string(), this,
            /*out*/ &session);
    ATRACE_END();
    if (res != OK) {
        SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
        return res;
    }

    /* Do something in */
    ......
    /* Do something out */

    return initializeCommonLocked();
}

这里可以看到通过CameraProviderManager开启了远端session

/**frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp**/
status_t CameraProviderManager::openSession(const std::string &id,
        const sp& callback,
        /*out*/
        sp *session) {

    std::lock_guard lock(mInterfaceMutex);

    auto deviceInfo = findDeviceInfoLocked(id,
            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
    if (deviceInfo == nullptr) return NAME_NOT_FOUND;

    auto *deviceInfo3 = static_cast(deviceInfo);

    Status status;
    hardware::Return ret;
    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
            (Status s, const sp& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    *session = cameraSession;
                }
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                __FUNCTION__, id.c_str(), ret.description().c_str());
        return DEAD_OBJECT;
    }
    return mapToStatusT(status);
}

首先调用findDeviceInfoLocked(),获取 HAL3 相关的 DeviceInfo3,这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。通过远端调用 CameraDeviceopen() 方法,创建 CameraDeviceSession实例并将其本地调用接口通过入参session返回。 (DeviceInfo3这个类的 mInterface成员类型是 ICameraDevice,通过它可以调用远端 CameraDevice 中的方法。)这里就进入了HAL层了,CameraDevice.open()中最终调用了CameraDevice.createDeviceSession()创建了一个CameraDeviceSession
这一段的流程图如下:

Framework流程图.png

Camera2架构.png

你可能感兴趣的:(Camera2 FrameWork层分析)