Android P Camera2相机简单解析(一、openCamera)
openCamera
CameraManager
文件路径:/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
上层调用的API有两个,分别如下:
@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);}
@RequiresPermission(android.Manifest.permission.CAMERA)public void openCamera(@NonNull String cameraId, @NonNull @CallbackExecutor Executor executor, @NonNull final CameraDevice.StateCallback callback) throws CameraAccessException { if (executor == null) { throw new IllegalArgumentException("executor was null"); } openCameraForUid(cameraId, callback, executor, USE_CALLING_UID); }
但是两种实际都是调用了 openCameraForUid(cameraId, callback, executor, 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); }
这里做了容错性判断,紧接着调用了 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; }
这里主要关注上面的代码不仅仅23-31行中的cameraService.connectDevice,这仅仅是Connect到我们的Camera设备,并不能打开我们的Camera,所以第9行的ICameraDeviceUser cameraUser = null和第82行的deviceImpl.setRemoteDevice(cameraUser)也是非常重要的,这里对应了CameraDeviceImpl .java文件。但是这里我们还是先看cameraService.connectDevice实现,实际上是ICameraService.connectDevice,这里需要注意的是ICameraService实际上是aidl文件,也是就是说CameraManager通过通过 Binder 机制调用了 connectDevice 方法,这个connectDevice方法的实现在CameraService 中。
CameraService
文件路径:/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, /*api1CameraId*/-1, 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;}
不难发现这里第13行调用了connectHelper来实现连接相机的逻辑,具体代码如下:
Status CameraService::connectHelper(const sp& cameraCb, const String8& cameraId, int api1CameraId, 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); 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(effectiveApiLevel)); sp client = nullptr; { // Acquire mServiceLock and prevent other clients from connecting std::unique_ptr 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 clientTmp = nullptr; std::shared_ptr>> 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(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 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(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); } } // Update shim paremeters for legacy clients if (effectiveApiLevel == API_1) { // Assume we have always received a Client subclass for API1 sp shimClient = reinterpret_cast(client.get()); String8 rawParams = shimClient->getParameters(); CameraParameters params(rawParams); auto cameraState = getCameraState(cameraId); if (cameraState != nullptr) { cameraState->setShimParams(params); } else { ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.", __FUNCTION__, cameraId.string()); } } 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;}
在connectHelper中我们通过makeClient方法完成了client的生成并初始化,具体实现如下:
Status CameraService::makeClient(const sp& cameraService, const sp& 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* 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 tmp = static_cast(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 tmp = static_cast(cameraCb.get()); *client = new Camera2Client(cameraService, tmp, packageName, cameraId, api1CameraId, 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 { // 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 tmp = static_cast(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版本和Device版本来实例化Client的,在Android P 和Camera2的框架上,这里需要跟进的是38-39行,这里CameraDeviceClient方法是由CameraDeviceClient.cpp实现的。
CameraDeviceClient.cpp
文件路径:/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, /*API1 camera ID*/ -1, cameraFacing, clientPid, clientUid, servicePid), mInputStream(), mStreamingRequestId(REQUEST_ID_NONE), mRequestIdCounter(0) { ATRACE_CALL(); ALOGI("CameraDeviceClient %s: Opened", cameraId.string());}
这里关注第9行,发现又调用了Camera2ClientBase方法,实现代码如下:
Camera2ClientBase::Camera2ClientBase( const sp& cameraService, const sp& 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.");}
好吧,第21行mDevice = new Camera3Device(cameraId)才是重点,是由Camera3Device.cpp实现的。
Camera3Device.cpp
文件路径:/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), 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());}
到此CameraService.cpp中的makeClient工作就已经完成了并构造了"CameraDeviceClient",接下来就是connectHelper中的client->initialize这块儿了,从上面分析我们知道这里的client 指的对象就是Camera3Device了,所以我们继续找到Camera3Device中的initialize方法,代码如下:
status_t Camera3Device::initialize(sp 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 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; } res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo); if (res != OK) { SET_ERR_L("Could not retrive camera characteristics: %s (%d)", strerror(-res), res); session->close(); return res; } std::shared_ptr queue; auto requestQueueRet = session->getCaptureRequestMetadataQueue( [&queue](const auto& descriptor) { queue = std::make_shared(descriptor); if (!queue->isValid() || queue->availableToWrite() <= 0) { ALOGE("HAL returns empty request metadata fmq, not use it"); queue = nullptr; // don't use the queue onwards. } }); if (!requestQueueRet.isOk()) { ALOGE("Transaction error when getting request metadata fmq: %s, not use it", requestQueueRet.description().c_str()); return DEAD_OBJECT; } std::unique_ptr& resQueue = mResultMetadataQueue; auto resultQueueRet = session->getCaptureResultMetadataQueue( [&resQueue](const auto& descriptor) { resQueue = std::make_unique(descriptor); if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) { ALOGE("HAL returns empty result metadata fmq, not use it"); resQueue = nullptr; // Don't use the resQueue onwards. } }); if (!resultQueueRet.isOk()) { ALOGE("Transaction error when getting result metadata queue from camera session: %s", resultQueueRet.description().c_str()); return DEAD_OBJECT; } IF_ALOGV() { session->interfaceChain([]( ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { ALOGV("Session interface chain:"); for (auto iface : interfaceChain) { ALOGV(" %s", iface.c_str()); } }); } mInterface = new HalInterface(session, queue); //新建硬件抽象层接口实例 std::string providerType; mVendorTagId = manager->getProviderTagIdLocked(mId.string()); mTagMonitor.initialize(mVendorTagId); if (!monitorTags.isEmpty()) { mTagMonitor.parseTagsToMonitor(String8(monitorTags)); } return initializeCommonLocked();}
代码中第15行 res = manager->openSession 就是走向open的地方了,但是还是需要继续到一个方法,不难发现openSession方法由CameraProviderManager.cpp实现。此外在这里我们还需要注意第31和47行,第31行是请求队列,47行是结果队列在下一篇中将使用到。
CameraProviderManager.cpp
文件路径:***/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);}
其中第16行ret = deviceInfo3->mInterface->open 实际上通过Hidl指向了CameraDevice::open(),该方法由CameraDevice.cpp实现。
CameraDevice.cpp
文件路径:***/hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp***
代码如下:
Return CameraDevice::open(const sp& callback, open_cb _hidl_cb) { Status status = initStatus(); sp session = nullptr; if (callback == nullptr) { ALOGE("%s: cannot open camera %s. callback is null!", __FUNCTION__, mCameraId.c_str()); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } if (status != Status::OK) { // Provider will never pass initFailed device to client, so // this must be a disconnected camera ALOGE("%s: cannot open camera %s. camera is disconnected!", __FUNCTION__, mCameraId.c_str()); _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr); return Void(); } else { mLock.lock(); ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt); session = mSession.promote(); if (session != nullptr && !session->isClosed()) { ALOGE("%s: cannot open an already opened camera!", __FUNCTION__); mLock.unlock(); _hidl_cb(Status::CAMERA_IN_USE, nullptr); return Void(); } /** Open HAL device */ status_t res; camera3_device_t *device; ATRACE_BEGIN("camera3->open"); res = mModule->open(mCameraId.c_str(), reinterpret_cast(&device)); ATRACE_END(); if (res != OK) { ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str()); mLock.unlock(); _hidl_cb(getHidlStatus(res), nullptr); return Void(); } /** Cross-check device version */ if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) { ALOGE("%s: Could not open camera: " "Camera device should be at least %x, reports %x instead", __FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2, device->common.version); device->common.close(&device->common); mLock.unlock(); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } struct camera_info info; res = mModule->getCameraInfo(mCameraIdInt, &info); if (res != OK) { ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__); device->common.close(&device->common); mLock.unlock(); _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); } session = createSession( device, info.static_camera_characteristics, callback); if (session == nullptr) { ALOGE("%s: camera device session allocation failed", __FUNCTION__); mLock.unlock(); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } if (session->isInitFailed()) { ALOGE("%s: camera device session init failed", __FUNCTION__); session = nullptr; mLock.unlock(); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } mSession = session; IF_ALOGV() { session->getInterface()->interfaceChain([]( ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { ALOGV("Session interface chain:"); for (auto iface : interfaceChain) { ALOGV(" %s", iface.c_str()); } }); } mLock.unlock(); } _hidl_cb(status, session->getInterface()); return Void();}
其中36-37行的res = mModule->open(mCameraId.c_str(), reinterpret_cast
CameraModule.cpp
文件路径:***/hardware/interfaces/camera/common/1.0/default/CameraModule.cpp***
代码如下:
int CameraModule::open(const char* id, struct hw_device_t** device) { int res; ATRACE_BEGIN("camera_module->open"); res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device)); ATRACE_END(); return res;}
不难发现,mModule->common.methods->open紧接着就是Hal层了,在这里我们需要先把Hal层启动流程弄清楚。在系统启动后,CameraService服务跑起来就是就会启动Hal层。
CameraService
文件路径:***/frameworks/av/services/camera/libcameraservice/CameraService.cpp***
代码如下:
void CameraService::onFirstRef(){ ALOGI("CameraService process starting"); BnCameraService::onFirstRef(); // Update battery life tracking if service is restarting BatteryNotifier& notifier(BatteryNotifier::getInstance()); notifier.noteResetCamera(); notifier.noteResetFlashlight(); status_t res = INVALID_OPERATION; res = enumerateProviders(); if (res == OK) { mInitialized = true; } CameraService::pingCameraServiceProxy(); mUidPolicy = new UidPolicy(this); mUidPolicy->registerSelf();}
这里第14行res = enumerateProviders()说明CameraService在初始化时,要先枚举Provider,实现代码如下:
status_t CameraService::enumerateProviders() { status_t res; std::vector deviceIds; { Mutex::Autolock l(mServiceLock); if (nullptr == mCameraProviderManager.get()) { mCameraProviderManager = new CameraProviderManager(); res = mCameraProviderManager->initialize(this); if (res != OK) { ALOGE("%s: Unable to initialize camera provider manager: %s (%d)", __FUNCTION__, strerror(-res), res); return res; } } // Setup vendor tags before we call get_camera_info the first time // because HAL might need to setup static vendor keys in get_camera_info // TODO: maybe put this into CameraProviderManager::initialize()? mCameraProviderManager->setUpVendorTags(); if (nullptr == mFlashlight.get()) { mFlashlight = new CameraFlashlight(mCameraProviderManager, this); } res = mFlashlight->findFlashUnits(); if (res != OK) { ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res); } deviceIds = mCameraProviderManager->getCameraDeviceIds(); } for (auto& cameraId : deviceIds) { String8 id8 = String8(cameraId.c_str()); onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT); } return OK;}
这里又先初始化CameraProviderManager,并获取第三方厂家TAG,获取闪光灯,获取相机设备数,其中CameraProviderManager的初始化实现如下。
CameraProviderManager.cpp
文件路径:***/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp***
具体代码如下:
status_t CameraProviderManager::initialize(wp listener, ServiceInteractionProxy* proxy) { std::lock_guard lock(mInterfaceMutex); if (proxy == nullptr) { ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__); return BAD_VALUE; } mListener = listener; mServiceProxy = proxy; // Registering will trigger notifications for all already-known providers bool success = mServiceProxy->registerForNotifications( /* instance name, empty means no filter */ "", this); if (!success) { ALOGE("%s: Unable to register with hardware service manager for notifications " "about camera providers", __FUNCTION__); return INVALID_OPERATION; } // See if there's a passthrough HAL, but let's not complain if there's not addProviderLocked(kLegacyProviderName, /*expected*/ false); addProviderLocked(kExternalProviderName, /*expected*/ false); return OK;}
CameraProviderManager初始化中做的事情很明了,这里我们需要关注的是addProviderLocked这里进行查找并保存Provider,实现如下:
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) { for (const auto& providerInfo : mProviders) { if (providerInfo->mProviderName == newProvider) { ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__, newProvider.c_str()); return ALREADY_EXISTS; } } sp interface; interface = mServiceProxy->getService(newProvider); //获取服务 if (interface == nullptr) { if (expected) { ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__, newProvider.c_str()); return BAD_VALUE; } else { return OK; } } sp providerInfo = new ProviderInfo(newProvider, interface, this); //构建 status_t res = providerInfo->initialize(); //初始化 if (res != OK) { return res; } mProviders.push_back(providerInfo); //备份 return OK;}
这里需要关注 spprovider::V2_4::ICameraProvider interface这里的interface,最终指向了CameraProvider.cpp,不过我们需要先关注上面的构建和初始化providerInfo->initialize(),代码如下:
status_t CameraProviderManager::ProviderInfo::initialize() { status_t res = parseProviderName(mProviderName, &mType, &mId); if (res != OK) { ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__); return BAD_VALUE; } ALOGI("Connecting to new camera provider: %s, isRemote? %d", mProviderName.c_str(), mInterface->isRemote()); // cameraDeviceStatusChange callbacks may be called (and causing new devices added) // before setCallback returns hardware::Return status = mInterface->setCallback(this); if (!status.isOk()) { ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s", __FUNCTION__, mProviderName.c_str(), status.description().c_str()); return DEAD_OBJECT; } if (status != Status::OK) { ALOGE("%s: Unable to register callbacks with camera provider '%s'", __FUNCTION__, mProviderName.c_str()); return mapToStatusT(status); } hardware::Return linked = mInterface->linkToDeath(this, /*cookie*/ mId); if (!linked.isOk()) { ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s", __FUNCTION__, mProviderName.c_str(), linked.description().c_str()); return DEAD_OBJECT; } else if (!linked) { ALOGW("%s: Unable to link to provider '%s' death notifications", __FUNCTION__, mProviderName.c_str()); } // Get initial list of camera devices, if any std::vector devices; hardware::Return ret = mInterface->getCameraIdList([&status, &devices]( Status idStatus, const hardware::hidl_vec& cameraDeviceNames) { status = idStatus; if (status == Status::OK) { for (size_t i = 0; i < cameraDeviceNames.size(); i++) { devices.push_back(cameraDeviceNames[i]); } } }); if (!ret.isOk()) { ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s", __FUNCTION__, mProviderName.c_str(), linked.description().c_str()); return DEAD_OBJECT; } if (status != Status::OK) { ALOGE("%s: Unable to query for camera devices from provider '%s'", __FUNCTION__, mProviderName.c_str()); return mapToStatusT(status); } sp listener = mManager->getStatusListener(); for (auto& device : devices) { std::string id; status_t res = addDevice(device, hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);//添加device if (res != OK) { ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)", __FUNCTION__, device.c_str(), strerror(-res), res); continue; } } ALOGI("Camera provider %s ready with %zu camera devices", mProviderName.c_str(), mDevices.size()); mInitialized = true; return OK;}
这里主要关注上面的添加设备这块儿
status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name, CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) { ALOGI("Enumerating new camera device: %s", name.c_str()); uint16_t major, minor; std::string type, id; status_t res = parseDeviceName(name, &major, &minor, &type, &id); if (res != OK) { return res; } if (type != mType) { ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__, type.c_str(), mType.c_str()); return BAD_VALUE; } if (mManager->isValidDeviceLocked(id, major)) { ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__, name.c_str(), id.c_str(), major); return BAD_VALUE; } std::unique_ptr deviceInfo; switch (major) { //实例化 case 1: deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor); break; case 3: deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor); break; default: ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__, name.c_str(), major); return BAD_VALUE; } if (deviceInfo == nullptr) return BAD_VALUE; deviceInfo->mStatus = initialStatus; bool isAPI1Compatible = deviceInfo->isAPI1Compatible(); mDevices.push_back(std::move(deviceInfo)); mUniqueCameraIds.insert(id); if (isAPI1Compatible) { mUniqueAPI1CompatibleCameraIds.push_back(id); } if (parsedId != nullptr) { *parsedId = id; } return OK;}
其中实例化device代码如下:
templatestd::unique_ptr CameraProviderManager::ProviderInfo::initializeDeviceInfo( const std::string &name, const metadata_vendor_id_t tagId, const std::string &id, uint16_t minorVersion) const { Status status; auto cameraInterface = getDeviceInterface(name); //获取HAL层远程接口 if (cameraInterface == nullptr) return nullptr; CameraResourceCost resourceCost; cameraInterface->getResourceCost([&status, &resourceCost]( Status s, CameraResourceCost cost) { status = s; resourceCost = cost; }); if (status != Status::OK) { ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__, name.c_str(), statusToString(status)); return nullptr; } for (auto& conflictName : resourceCost.conflictingDevices) { uint16_t major, minor; std::string type, id; status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id); if (res != OK) { ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str()); return nullptr; } conflictName = id; } return std::unique_ptr( new DeviceInfoT(name, tagId, id, minorVersion, resourceCost, cameraInterface));}
其中获取HAL远程接口代码如下:
template<>spCameraProviderManager::ProviderInfo::getDeviceInterface (const std::string &name) const { Status status; sp cameraInterface; hardware::Return ret; ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface]( Status s, sp interface) { status = s; cameraInterface = interface; }); if (!ret.isOk()) { ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s", __FUNCTION__, name.c_str(), ret.description().c_str()); return nullptr; } if (status != Status::OK) { ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__, name.c_str(), statusToString(status)); return nullptr; } return cameraInterface;}
到了这里,可以看出ICameraDevice关联到了CameraDevice.cpp,那么providerInfo->initialize()就分析得差不多了,下面的就到了硬件层,回头来我们需要继续分析CameraProvider.cpp这里了,在这里就关注其初始化就可以了。
CameraProvider.cpp
文件路径:***/hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp***
代码如下:
bool CameraProvider::initialize() { camera_module_t *rawModule; int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule); if (err < 0) { ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err)); return true; } mModule = new CameraModule(rawModule); err = mModule->init(); if (err != OK) { ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err)); mModule.clear(); return true; } ALOGI("Loaded \"%s\" camera module", mModule->getModuleName()); // Setup vendor tags here so HAL can setup vendor keys in camera characteristics VendorTagDescriptor::clearGlobalVendorTagDescriptor(); if (!setUpVendorTags()) { ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__); } // Setup callback now because we are going to try openLegacy next err = mModule->setCallbacks(this); if (err != OK) { ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err)); mModule.clear(); return true; } mPreferredHal3MinorVersion = property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3); ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion); switch(mPreferredHal3MinorVersion) { case 2: case 3: // OK break; default: ALOGW("Unknown minor camera device HAL version %d in property " "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion); mPreferredHal3MinorVersion = 3; } mNumberOfLegacyCameras = mModule->getNumberOfCameras(); for (int i = 0; i < mNumberOfLegacyCameras; i++) { struct camera_info info; auto rc = mModule->getCameraInfo(i, &info); if (rc != NO_ERROR) { ALOGE("%s: Camera info query failed!", __func__); mModule.clear(); return true; } if (checkCameraVersion(i, info) != OK) { ALOGE("%s: Camera version check failed!", __func__); mModule.clear(); return true; } char cameraId[kMaxCameraIdLen]; snprintf(cameraId, sizeof(cameraId), "%d", i); std::string cameraIdStr(cameraId); mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT; addDeviceNames(i); } return false; // mInitFailed}
这里就初始化了CameraMoudle。
更多相关文章
- android sql 批量处理插入/修改/删除 操作通用代码
- Android之文件搜索工具类
- Android写sys文件节点
- Android 7.0以上和7.0以下获取USB,sdcard路径的方法
- android 图片处理方法(整理)
- android XML文件常用字符转义
- Android 方法调用堆栈信息显示
- Android查看电池电量的方法(基于BroadcastReceiver)
- Android功能代码