camera framework open流程

一、camera app连接cameraservice
1. framework/core/java/android/hardware/camera2/CameraManager.java
@RequiresPermission(android.Manifest.permission.CAMERA)
    public void openCamera(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
        throws CameraAccessException {
        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
                USE_CALLING_UID);
    }
    public void openCameraForUid(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
            int clientUid)
            throws CameraAccessException {
        if (cameraId == null) {
            throw new IllegalArgumentException("cameraId was null");
        } else if (callback == null) {
            throw new IllegalArgumentException("callback was null");
        }
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No cameras available on device");
        }
        openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
    }
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, 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,
                        executor,
                        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;
    }

29行 实例化CameraDeviceImpl对象,该类主要是对相机实例的一些操作,提供给app调用;
36行 CameraDeviceCallbacks是CameraDeviceImpl的内部类,通过getCallbacks方法可以获取CameraDeviceCallbacks的实例mCallbacks,这是提供给远端连接到CameraDeviceImpl的接口。CameraDeviceImpl主要是实现captureSession一些方法,如提交/停止预览请求等,CameraDeviceCallbacks是返回给上层的回调,如onCaptureStarted,onResultReceived,notifyError,onDeviceError(当A相机应用被高优先级的B相机应用抢占camera的时候会调用该方法)等;
40行 通过CameraManagerGlobal拿到CameraService的本地接口。调用过程:CameraManagerGlobal::getCameraService->connectCameraServiceLocked(ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder)),其中connectCameraServiceLocked这个函数在CameraManager中经常用到,用于拿到cameraservice的实例。
46行 通过connectDevice方法(binder机制)连接到相机设备,cameraUser实际上指的就是远端CameraDeviceClient的本地接口。
72行 若没有拿到远端相机设备,就会触发收到失败的回调(如未抢占成功抢占摄像头会返回-EBUSY)。
98行 拿到相机设备了,将其塞到CameraDeviceImpl中,进行管理,然后就可以从CameraDeviceImpl调用到ICameraDeviceUserWrapper->AIDL->ICameraDeviceUser->BpCameraDeviceUser->CameraDeviceClient中。

2. /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.mDeviceExecutor.execute(mCallOnDisconnected);
                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                        "The camera device has encountered a serious error");
            }
        }
        mDeviceExecutor.execute(mCallOnOpened);
        mDeviceExecutor.execute(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);
    }
};         

setRemoteDevice方法就是将远端设备保存起来:
6行 通过ICameraDeviceUserWrapper给远端实例添加一层封装;
20-21行 既然成功连接上了相机设备,那此时就会触发两个回调,来让上层知道camera状态,其中callOnOpened比较关键,通知app层camera已经是opened状态,让app可以执行下一步动作;
34行 实际上mDeviceCallback就是StateCallback类型变量,StateCallback是CameraDevice的内部抽象类。注意看执行onOpened时传入的对象为CameraDeviceImpl.this(继承自CameraDevice)。在app层,我们需要初始化StateCallback对象,将其作为参数传入到openCamera中并重写其onOpened方法,从而执行打开camera后的configure等,如下:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        // This method is called when the camera is opened.  We start camera preview here.
        mCameraOpenCloseLock.release();
        mCameraDevice = cameraDevice;
        createCameraPreviewSession();
    }
}
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);

第6行很重要,这里是保存了opencamerauser返回的cameraDevice对象,也就是打开的具体设备,然后在createCameraPreviewSession开启会话时执行mCameraDevice.createCaptureSession进行configure。

3. framework/av/services/camra/libcameraservice/CameraService.cpp
camera2在opencamera的时候会通过connectDevice连接到相机设备;
camera1在open的时候会通过connect连接到相机设备用;
camera1和camera2连接相机设备不一样,但是在connect和connectDevice方法中都会调用connectHelper方法:
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();
    String8 clientName8(clientPackageName);
    int originalClientPid = 0;
    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
            "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
            (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
            static_cast<int>(effectiveApiLevel));
    sp<CLIENT> client = nullptr;
    {
        // Acquire mServiceLock and prevent other clients from connecting
        std::unique_ptr<AutoConditionLock> lock =
                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);

        if (lock == nullptr) {
            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
                    , clientPid);
            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
                    cameraId.string(), clientName8.string(), clientPid);
        }
        // Enforce client permissions and do basic sanity checks
        if(!(ret = validateConnectLocked(cameraId, clientName8,
                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
            return ret;
        }
        // Check the shim parameters after acquiring lock, if they have already been updated and
        // we were doing a shim update, return immediately
        if (shimUpdateOnly) {
            auto cameraState = getCameraState(cameraId);
            if (cameraState != nullptr) {
                if (!cameraState->getShimParams().isEmpty()) return ret;
            }
        }
        status_t err;
        sp<BasicClient> clientTmp = nullptr;
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
                /*out*/&partial)) != NO_ERROR) {
            switch (err) {
                case -ENODEV:
                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                            "No camera device with ID \"%s\" currently available",
                            cameraId.string());
                case -EBUSY:
                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
                            cameraId.string());
                default:
                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                            "Unexpected error %s (%d) opening camera \"%s\"",
                            strerror(-err), err, cameraId.string());
            }
        }
        if (clientTmp.get() != nullptr) {
            // Handle special case for API1 MediaRecorder where the existing client is returned
            device = static_cast<CLIENT*>(clientTmp.get());
            return ret;
        }
        // give flashlight a chance to close devices if necessary.
        mFlashlight->prepareDeviceOpen(cameraId);
        int facing = -1;
        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
        if (facing == -1) {
            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                    "Unable to get camera device \"%s\" facing", cameraId.string());
        }
        sp<BasicClient> tmp = nullptr;
        if(!(ret = makeClient(this, cameraCb, clientPackageName,
                cameraId, api1CameraId, facing,
                clientPid, clientUid, getpid(), legacyMode,
                halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());
        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);
        err = client->initialize(mCameraProviderManager, mMonitorTags);
        if (err != OK) {
            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
            // Errors could be from the HAL module open call or from AppOpsManager
            switch(err) {
                case BAD_VALUE:
                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
                case -EBUSY:
                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                            "Camera \"%s\" is already open", cameraId.string());
                case -EUSERS:
                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                            "Too many cameras already open, cannot open camera \"%s\"",
                            cameraId.string());
                case PERMISSION_DENIED:
                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                            "No permission to open camera \"%s\"", cameraId.string());
                case -EACCES:
                    return STATUS_ERROR_FMT(ERROR_DISABLED,
                            "Camera \"%s\" disabled by policy", cameraId.string());
                case -ENODEV:
                default:
                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
                            strerror(-err), err);
            }
        }
        if (shimUpdateOnly) {
            // If only updating legacy shim parameters, immediately disconnect client
            mServiceLock.unlock();
            client->disconnect();
            mServiceLock.lock();
        } else {
            // Otherwise, add client to active clients list
            finishConnectLocked(client, partial);
        }
    } // lock is destroyed, allow further connect calls
    // 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;
}

17行 waitAndAcquire去获取连接cameraService的锁,获取不到就没法连接cameraService;
26行 validateConnectLocked去查询连接cameraServicede的应用的权限,即查看是否是有效连接;
41行 handleEvictionsLocked去解决各个应用连接camera时的冲突,让优先级高的应用连接相机,并让优先级低的相机退出连接;
74行 makeClient生成cameraDeviceClient实例;
84行 initialize方法是去往camra hal的第一步。
先看下makeclient中干了啥:
Status CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
        int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp<BasicClient>* 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:
            if (effectiveApiLevel == API_1) {  // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new CameraClient(cameraService, tmp, packageName,
                        api1CameraId, facing, clientPid, clientUid,
                        getpid(), legacyMode);
            } else { // Camera2 API route
                ALOGW("Camera using old HAL version: %d", deviceVersion);
                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                        "Camera device \"%s\" HAL version %d does not support camera2 API",
                        cameraId.string(), deviceVersion);
            }
            break;
          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<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName,
                        cameraId, api1CameraId,
                        facing, clientPid, clientUid,
                        servicePid, legacyMode);
            } else { // Camera2 API route
                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(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 {
        // A particular HAL version is requested by caller. Create CameraClient
        // based on the requested HAL version.
        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
            // Only support higher HAL version device opened as HAL1.0 device.
            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
            *client = new CameraClient(cameraService, tmp, packageName,
                    api1CameraId, facing, clientPid, clientUid,
                    servicePid, legacyMode);
        } else {
            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
                    " opened as HAL %x device", halVersion, deviceVersion,
                    CAMERA_DEVICE_API_VERSION_1_0);
            return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
                    "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
                    cameraId.string(), deviceVersion, halVersion);
        }
    }
    return Status::ok();
}

如果使用的是API 1 + HAL 1,则构建一个CameraClient对象
如果使用的是API 1 + HAL 3,则构建一个Camera2Client对象
否则,如果使用API 2 + HAL 3,构建一个CameraDeviceClient对象
36-38行 new了一个CameraDeviceClient实例,并在CameraDeviceClient构造中传入了ICameraDeviceCallbacks,这是连接到CameraDeviceImpl的远端回调。
至此app通过cameraservice拿到远端设备的通路就打开了。


二、cameraservice连接到camera hal
1. framework/av/services/camra/libcameraservice/api2/CameraDeviceClient.cpp
在cameraService的makeClient中new了一个CameraDeviceClient实例,并调用了CameraDeviceClient中的initialize方法:
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
    ATRACE_CALL();
    status_t res;
    res = Camera2ClientBase::initialize(providerPtr, monitorTags);
    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);
    auto deviceInfo = mDevice->info();
    camera_metadata_entry_t physicalKeysEntry = deviceInfo.find(
            ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
    if (physicalKeysEntry.count > 0) {
        mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
                physicalKeysEntry.data.i32,
                physicalKeysEntry.data.i32 + physicalKeysEntry.count);
    }
    return OK;
}

15-18行 实例化了FrameProcessBase对象,并且将mDevice(下文可知是Camera3Device对象)传入其中,并且让内部的ThreadLoop跑起来,实际上就是在阻塞等待ProcessCaptureResult 返回的frame;
10行 可以看出最终调用到了Camera2ClientBase::initialize的方法中,先看下CameraDeviceClient的继承关系:
class CameraDeviceClient :
        public Camera2ClientBase<CameraDeviceClientBase>,
        public camera2::FrameProcessorBase::FilteredListener

可以看出CameraDeviceClient是Camera2ClientBase的子类,因此在构造CameraDeviceClient的时候,先调用其父类Camera2ClientBase的构造函数:
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
        const sp<CameraService>& cameraService,
        const sp<TCamCallbacks>& remoteCallback,
        const String16& clientPackageName,
        const String8& cameraId,
        int api1CameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid):
        TClientBase(cameraService, remoteCallback, clientPackageName,
                cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
        mSharedCameraCallbacks(remoteCallback),
        mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
        mDeviceActive(false), mApi1CameraId(api1CameraId)
 {
    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.");
}
//看下CameraDeviceClientBase的继承关系:
struct CameraDeviceClientBase :
         public CameraService::BasicClient,
         public hardware::camera2::BnCameraDeviceUser

1行 可以看出TClientBase就是CameraDeviceClientBase。
25行 可以看出CameraDeviceClientBase是CameraService::BasicClient的子类,这个很重要。
22行 初始化了一个Camera3Device类型变量,这是通往Camera3Device的关键:

status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {
    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, monitorTags);
    if (res != OK) {
        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }
    wp<CameraDeviceBase::NotificationListener> weakThis(this);
    res = mDevice->setNotifyCallback(weakThis);
    return OK;
}

16行 这句函数很重要,TClientBase实际上就是CameraDeviceClientBase,而startCameraOps的实现在CameraDeviceClientBase父类CameraService::BasicClient中,主要是执行对camera的一些操作,比如检测相机的权限是否被AppOpsManager禁用,返回相机的状态给CameraManager等等。既然有startCameraOps那就有相应的finishCameraOps来执行一些相对的动作,发现在CameraSercvice::finishCameraOps中调用;
25行 可以看出最终会执行到Camera3Device的initialize中:
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),
        mLastTemplateId(-1)
{
    ATRACE_CALL();
    camera3_callback_ops::notify = &sNotify;
    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}

status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
    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<ICameraDeviceSession> 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;
    }
    .....
    mInterface = new HalInterface(session, queue);
    .....
    return initializeCommonLocked();
}
status_t Camera3Device::initializeCommonLocked() {
    /** Start up status tracker thread */
    mStatusTracker = new StatusTracker(this);
    status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
    if (res != OK) {
        SET_ERR_L("Unable to start status tracking thread: %s (%d)",
                strerror(-res), res);
        mInterface->close();
        mStatusTracker.clear();
        return res;
    }
    /** Create buffer manager */
    mBufferManager = new Camera3BufferManager();
    ........
    /** Start up request queue thread */
    mRequestThread = new RequestThread(this, mStatusTracker, mInterface, sessionParamKeys);
    res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
    if (res != OK) {
        SET_ERR_L("Unable to start request queue thread: %s (%d)",
                strerror(-res), res);
        mInterface->close();
        mRequestThread.clear();
        return res;
    }
    mPreparerThread = new PreparerThread();
    .....
}

18-19行 设定了两个回调接口;
38行 通过调用CameraProviderManager的openSession(this就是callback回调)方法,接下来就会调用MtkExternalDevice::open->MtkExternalDeviceSession::createSession,获取一个Provider中的ICameraDeviceSession代理。
45行 实例化一个HalInterface对象mHalInterface(构造中会执行mHidlSession(session)),实际上就是ICameraDeviceSession代理的套壳,接下来在调用configure和request请求时直接使用mHidlSession即可。除此之外,还在HalInterface构造函数中创建了一个CameraDeviceSession对象(3.4版本:mHidlSession_3_4),这里非常关键,因为接下来request和configure都会通过这个对象进到camera hal层;
63行 new了一个RequestThread实例,并将其中的ThreadLoop以阻塞的方式运行起来。当传来request请求时,Camera3Device::setRepeatingRequests->unpauseForNewRequests发送信号,让RequestThread::ThreadLoop继续运行起来。

上面的流程有几个关键的点:
1.在CameraDeviceClient::initialize中让FrameProcessBase::threadLoop跑起来,阻塞等待result中的frame,当hal层有result返回的时候,就会通过Camera3Device::processCaptureResult->sendCaptureResult->insertResultLocked(mResultSignal.signal())来让FrameProcessBase::threadLoop继续跑起来,然后再一步步返回上层。
在Camera3Device::initial中让Camera3Device::RequestThread::threadLoop跑起来,并阻塞等待上层发送的request请求,当app端发送request请求时,就会一路到Camera3Device::RequestThread::unpauseForNewRequests,发送信号让Camera3Device::RequestThread::threadLoop继续跑起来。

上述板书有点问题,可以移至我的有道云笔记观看~

文档:camera open流程.note
链接:http://note.youdao.com/noteshare?id=e093157f6c840cf45c1939c91b3079cd&sub=WEB6653a8479b9c5141b98c524abd33e4a4

文档:CameraService启动流程.note
链接:http://note.youdao.com/noteshare?id=293fd9d8dd76721f8bbb8e3d8b999750&sub=WEB7eef16176b59c1929c9105ccb5727a22

至此framework camera open流程就结束了,后续再来补充,bye~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值