camera open 过程涉及到 Android 架构中的三个层次:App 层,Framework 层,Runtime 层。
其中,App 层直接调用 Framework 层所封装的方法,而 Framework 层需要通过 Binder 远程调用 Runtime 中 CameraService 的函数。
(https://blog.youkuaiyun.com/qq_16775897/article/details/81537710)
从 Application 连接到 CameraService
APP
mCameraManager.openCamera(currentCameraId, stateCallback, backgroundHandler);
Framework
/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
最初的入口就是 CameraManager 的 openCamera
方法,但它也是仅仅是调用了 openCameraForUid
方法,最终主要调用了 openCameraDeviceUserAsync
方法
459 /**
460 * Helper for opening a connection to a camera with the given ID.
461 *
462 * @param cameraId The unique identifier of the camera device to open
463 * @param callback The callback for the camera. Must not be null.
464 * @param executor The executor to invoke the callback with. Must not be null.
465 * @param uid The UID of the application actually opening the camera.
466 * Must be USE_CALLING_UID unless the caller is a service
467 * that is trusted to open the device on behalf of an
468 * application and to forward the real UID.
469 *
470 * @throws CameraAccessException if the camera is disabled by device policy,
471 * too many camera devices are already open, or the cameraId does not match
472 * any currently available camera device.
473 *
474 * @throws SecurityException if the application does not have permission to
475 * access the camera
476 * @throws IllegalArgumentException if callback or handler is null.
477 * @return A handle to the newly-created camera device.
478 *
479 * @see #getCameraIdList
480 * @see android.app.admin.DevicePolicyManager#setCameraDisabled
481 */
482 private CameraDevice openCameraDeviceUserAsync(String cameraId,
483 CameraDevice.StateCallback callback, Executor executor, final int uid)
private CameraDevice openCameraDeviceUserAsync(String cameraId,
483 CameraDevice.StateCallback callback, Executor executor, final int uid)
484 throws CameraAccessException {
//获取到目标camera的特性参数
485 CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
486 CameraDevice device = null;
487
488 synchronized (mLock) {
489
490 ICameraDeviceUser cameraUser = null;
//实例化一个 CameraDeviceImpl,构造时传入了 CameraDevice.StateCallback 以及 Handler
492 android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
493 new android.hardware.camera2.impl.CameraDeviceImpl(
494 cameraId,
495 callback,
496 executor,
497 characteristics,
498 mContext.getApplicationInfo().targetSdkVersion);
//获取 CameraDeviceCallback 实例,这是提供给远端连接到 CameraDeviceImpl 的接口
500 ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
//从 CameraManagerGlobal 中获取 CameraService 的本地接口,通过它远端调用(采用 Binder 机制)
//connectDevice 方法连接到相机设备。注意返回的 cameraUser 实际上指向的是远端
//CameraDeviceClient 的本地接口。
502 try {
503 if (supportsCamera2ApiLocked(cameraId)) {
504 // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
505 ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
506 if (cameraService == null) {
507 throw new ServiceSpecificException(
508 ICameraService.ERROR_DISCONNECTED,
509 "Camera service is currently unavailable");
510 }
511 cameraUser = cameraService.connectDevice(callbacks, cameraId,
512 mContext.getOpPackageName(), mContext.getAttributionTag(), uid);
513 } else {
514 // Use legacy camera implementation for HAL1 devices
515 int id;
516 try {
517 id = Integer.parseInt(cameraId);
518 } catch (NumberFormatException e) {
519 throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
520 + cameraId);
521 }
522
523 Log.i(TAG, "Using legacy camera HAL.");
524 cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id,
525 getDisplaySize());
526 }
527 } catch (ServiceSpecificException e) {
......
......
557 }
//将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理
559 // TODO: factor out callback to be non-nested, then move setter to constructor
560 // For now, calling setRemoteDevice will fire initial
561 // onOpened/onUnconfigured callbacks.
562 // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if
563 // cameraUser dies during setup.
564 deviceImpl.setRemoteDevice(cameraUser);
565 device = deviceImpl;
566 }
567
568 return device;
569 }
CameraDeviceImpl
/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.javasetRemoteDevice
方法主要是将获取到的远端设备保存起来
283 /**
284 * Set remote device, which triggers initial onOpened/onUnconfigured callbacks
285 *
286 * <p>This function may post onDisconnected and throw CAMERA_DISCONNECTED if remoteDevice dies
287 * during setup.</p>
288 *
289 */
290 public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
291 synchronized(mInterfaceLock) {
292 // TODO: Move from decorator to direct binder-mediated exceptions
293 // If setRemoteFailure already called, do nothing
294 if (mInError) return;
//通过 ICameraDeviceUserWrapper 给远端设备实例加上一层封装
296 mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
297
298 IBinder remoteDeviceBinder = remoteDevice.asBinder();
299 // For legacy camera device, remoteDevice is in the same process, and
300 // asBinder returns NULL.
301 if (remoteDeviceBinder != null) {
302 try {
303 remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
304 } catch (RemoteException e) {
305 CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);
306
307 throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
308 "The camera device has encountered a serious error");
309 }
310 }
//需要注意这个时间节点,此处触发 onOpened 与 onUnconfigured 这两个回调
//mCallOnOpened是CameraDeviceImpl类的一个成员变量
312 mDeviceExecutor.execute(mCallOnOpened);
313 mDeviceExecutor.execute(mCallOnUnconfigured);
314 }
315 }
Runtime
通过 Binder 机制,我们远端调用了 cameraService.connectDevice方法,这个方法实现在 CameraService 类中。
CameraService
/frameworks/av/services/camera/libcameraservice/CameraService.cpp
connectDevice
调用的 connectHelper
方法才真正实现了连接逻辑
1577Status CameraService::connectDevice(
1578 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1579 const String16& cameraId,
1580 const String16& clientPackageName,
1581 const std::unique_ptr<String16>& clientFeatureId,
1582 int clientUid,
1583 /*out*/
1584 sp<hardware::camera2::ICameraDeviceUser>* device) {
1585
1586 ATRACE_CALL();
1587 Status ret = Status::ok();
1588 String8 id = String8(cameraId);
1589 sp<CameraDeviceClient> client = nullptr;
1590 String16 clientPackageNameAdj = clientPackageName;
1591
1592 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
1593 std::string vendorClient =
1594 StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
1595 clientPackageNameAdj = String16(vendorClient.c_str());
1596 }
//调用的 connectHelper 方法才真正实现了连接逻辑,
//设定的模板类型是 ICameraDeviceCallbacks 以及 CameraDeviceClient。
1597 ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1598 /*api1CameraId*/-1,
1599 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
1600 clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
1601
1602 if(!ret.isOk()) {
1603 logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
1604 ret.toString8());
1605 return ret;
1606 }
//注意 client 指向的类型是 CameraDeviceClient,其实例则是最终的返回结果
1608 *device = client;
1609 return ret;
1610}
connectHelper
调用 makeClient
生成 CameraDeviceClient 实例,
template<class CALLBACK, class CLIENT>
1613Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1614 int api1CameraId, int halVersion, const String16& clientPackageName,
1615 const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
1616 apiLevel effectiveApiLevel, bool shimUpdateOnly,
1617 /*out*/sp<CLIENT>& device) {
1618 binder::Status ret = binder::Status::ok();
1619
1620 String8 clientName8(clientPackageName);
1621
1622 int originalClientPid = 0;
1623
1624 ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1625 "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1626 (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1627 static_cast<int>(effectiveApiLevel));
1628
1629 sp<CLIENT> client = nullptr;
1630 {
1631 // Acquire mServiceLock and prevent other clients from connecting
1632 std::unique_ptr<AutoConditionLock> lock =
1633 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1634
1635 if (lock == nullptr) {
1636 ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1637 , clientPid);
1638 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1639 "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1640 cameraId.string(), clientName8.string(), clientPid);
1641 }
1642
1643 // Enforce client permissions and do basic validity checks
1644 if(!(ret = validateConnectLocked(cameraId, clientName8,
1645 /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1646 return ret;
1647 }
1648
1649 // Check the shim parameters after acquiring lock, if they have already been updated and
1650 // we were doing a shim update, return immediately
1651 if (shimUpdateOnly) {
1652 auto cameraState = getCameraState(cameraId);
1653 if (cameraState != nullptr) {
1654 if (!cameraState->getShimParams().isEmpty()) return ret;
1655 }
1656 }
1657
1658 status_t err;
1659
1660 sp<BasicClient> clientTmp = nullptr;
1661 std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1662 if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1663 IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1664 /*out*/&partial)) != NO_ERROR) {
1665 switch (err) {
1666 case -ENODEV:
1667 return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1668 "No camera device with ID \"%s\" currently available",
1669 cameraId.string());
1670 case -EBUSY:
1671 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1672 "Higher-priority client using camera, ID \"%s\" currently unavailable",
1673 cameraId.string());
1674 case -EUSERS:
1675 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1676 "Too many cameras already open, cannot open camera \"%s\"",
1677 cameraId.string());
1678 default:
1679 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1680 "Unexpected error %s (%d) opening camera \"%s\"",
1681 strerror(-err), err, cameraId.string());
1682 }
1683 }
1684
1685 if (clientTmp.get() != nullptr) {
1686 // Handle special case for API1 MediaRecorder where the existing client is returned
1687 device = static_cast<CLIENT*>(clientTmp.get());
1688 return ret;
1689 }
1690
1691 // give flashlight a chance to close devices if necessary.
1692 mFlashlight->prepareDeviceOpen(cameraId);
1693
1694 int facing = -1;
1695 int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
1696 if (facing == -1) {
1697 ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.string());
1698 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1699 "Unable to get camera device \"%s\" facing", cameraId.string());
1700 }
1701
1702 sp<BasicClient> tmp = nullptr;
1703 if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
1704 cameraId, api1CameraId, facing,
1705 clientPid, clientUid, getpid(),
1706 halVersion, deviceVersion, effectiveApiLevel,
1707 /*out*/&tmp)).isOk()) {
1708 return ret;
1709 }
1710 client = static_cast<CLIENT*>(tmp.get());
1711
1712 LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1713 __FUNCTION__);
//这里的client就是CameraDeviceClient
1715 err = client->initialize(mCameraProviderManager, mMonitorTags);
1716 if (err != OK) {
1717 ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
1718 // Errors could be from the HAL module open call or from AppOpsManager
1719 switch(err) {
1720 case BAD_VALUE:
1721 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1722 "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1723 case -EBUSY:
1724 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1725 "Camera \"%s\" is already open", cameraId.string());
1726 case -EUSERS:
1727 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1728 "Too many cameras already open, cannot open camera \"%s\"",
1729 cameraId.string());
1730 case PERMISSION_DENIED:
1731 return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1732 "No permission to open camera \"%s\"", cameraId.string());
1733 case -EACCES:
1734 return STATUS_ERROR_FMT(ERROR_DISABLED,
1735 "Camera \"%s\" disabled by policy", cameraId.string());
1736 case -ENODEV:
1737 default:
1738 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1739 "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1740 strerror(-err), err);
1741 }
1742 }
1743
1744 // Update shim paremeters for legacy clients
1745 if (effectiveApiLevel == API_1) {
1746 // Assume we have always received a Client subclass for API1
1747 sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1748 String8 rawParams = shimClient->getParameters();
1749 CameraParameters params(rawParams);
1750
1751 auto cameraState = getCameraState(cameraId);
1752 if (cameraState != nullptr) {
1753 cameraState->setShimParams(params);
1754 } else {
1755 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1756 __FUNCTION__, cameraId.string());
1757 }
1758 }
1759
1760 // Set rotate-and-crop override behavior
1761 if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
1762 client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
1763 }
1764
1765 if (shimUpdateOnly) {
1766 // If only updating legacy shim parameters, immediately disconnect client
1767 mServiceLock.unlock();
1768 client->disconnect();
1769 mServiceLock.lock();
1770 } else {
1771 // Otherwise, add client to active clients list
1772 finishConnectLocked(client, partial);
1773 }
1774 } // lock is destroyed, allow further connect calls
1775
1776 // Important: release the mutex here so the client can call back into the service from its
1777 // destructor (can be at the end of the call)
1778 device = client;
1779 return ret;
}
client->initialize(mCameraProviderManager) 初始化 CLIENT
实例。注意此处的模板类型 CLIENT
即是 CameraDeviceClient,传入的参数 mCameraProviderManager
则是与 HAL service 有关。
makeClient
主要是根据 API 版本以及 HAL 版本来选择生成具体的 Client
实例, 一般驱动版本halVersion和设备版本deviceVersion是相同的,所以进入第一个if分支,effectiveApiLevel参数是在调用connectHelper方法时传入的,值为API_2,所以进入else分支,直接使用我们上边传进来的参数构造一个CameraDeviceClient对象,而该对象也就是我们应用进程和CameraServer进程通信的使者了,所有的工作都是由它来进行中转的。
Status CameraService::makeClient(const sp<CameraService>& cameraService,
804 const sp<IInterface>& cameraCb, const String16& packageName,
805 const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
806 int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
807 int deviceVersion, apiLevel effectiveApiLevel,
808 /*out*/sp<BasicClient>* client) {
809
810 if (halVersion < 0 || halVersion == deviceVersion) {
811 // Default path: HAL version is unspecified by caller, create CameraClient
812 // based on device version reported by the HAL.
813 switch(deviceVersion) {
814 case CAMERA_DEVICE_API_VERSION_1_0:
815 if (effectiveApiLevel == API_1) { // Camera1 API route
816 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
817 *client = new CameraClient(cameraService, tmp, packageName, featureId,
818 api1CameraId, facing, clientPid, clientUid,
819 getpid());
820 } else { // Camera2 API route
821 ALOGW("Camera using old HAL version: %d", deviceVersion);
822 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
823 "Camera device \"%s\" HAL version %d does not support camera2 API",
824 cameraId.string(), deviceVersion);
825 }
826 break;
827 case CAMERA_DEVICE_API_VERSION_3_0:
828 case CAMERA_DEVICE_API_VERSION_3_1:
829 case CAMERA_DEVICE_API_VERSION_3_2:
830 case CAMERA_DEVICE_API_VERSION_3_3:
831 case CAMERA_DEVICE_API_VERSION_3_4:
832 case CAMERA_DEVICE_API_VERSION_3_5:
833 case CAMERA_DEVICE_API_VERSION_3_6:
834 if (effectiveApiLevel == API_1) { // Camera1 API route
835 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
836 *client = new Camera2Client(cameraService, tmp, packageName, featureId,
837 cameraId, api1CameraId,
838 facing, clientPid, clientUid,
839 servicePid);
840 } else { // Camera2 API route
841 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
842 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
843 *client = new CameraDeviceClient(cameraService, tmp, packageName, featureId,
844 cameraId, facing, clientPid, clientUid, servicePid);
845 }
846 break;
847 default:
848 // Should not be reachable
849 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
850 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
851 "Camera device \"%s\" has unknown HAL version %d",
852 cameraId.string(), deviceVersion);
853 }
854 } else {
。。。。。。
。。。。。。
873 }
874 return Status::ok();
}
最终这一 Client
就沿着前面分析下来的路径返回到 CameraDeviceImpl 实例中,被保存到 mRemoteDevice
。至此,打开相机流程中,从 App 到 CameraService 的调用逻辑基本上就算走完了。
根据上面的流程追踪,我们可以描绘一个比较简单直观的连路框架图,如下。
其中黑色虚线表示下行(控制)路线,红色虚线表明上行(状态、数据)路线。
接下来要分析的是从 CameraService 到 HAL Service 的连接过程。
从 CameraService 到 HAL Service
Android 中加入了 Treble 机制,它带来的一个巨大变化就是将原本的 CameraServer 进程分隔成 CameraServer 与 Provider service 两个进程,它们之间通过 HIDL(一个类似 Binder 的机制)进行通信。
在这种情况下,CameraServer 一端主体为 CameraService,它将会寻找现存的 Provider service,将其加入到内部的 CameraProviderManager 中进行管理,相关操作都是通过远端调用进行的。
而 Provider service 一端的主体为 CameraProvider,它在初始化时就已经连接到 libhardware 的 Camera HAL 实现层,并以 CameraModule 来进行管理, 而这两个进程的启动与初始化是在系统启动时就进行的
而在打开相机时,该层的完整连路会被创建出来。这一部分的主要调用逻辑如下图:
在 CameraService::makeClient 中,实例化了一个 CameraDeviceClient。现在我们就从它的构造函数开始,继续探索打开相机的流程。 这一部分主要活动在 Runtime 层,这里分成 CameraService 与 HAL Service 两侧来分析:
CameraService
CameraDeviceClient
/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
81 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
82 const String16& clientPackageName,
83 const std::unique_ptr<String16>& clientFeatureId,
84 const String8& cameraId,
85 int cameraFacing,
86 int clientPid,
87 uid_t clientUid,
88 int servicePid) :
89 Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
90 cameraId, /*API1 camera ID*/ -1,
91 cameraFacing, clientPid, clientUid, servicePid),
92 mInputStream(),
93 mStreamingRequestId(REQUEST_ID_NONE),
94 mRequestIdCounter(0) {
95
96 ATRACE_CALL();
97 ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
/frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
42template <typename TClientBase>
43Camera2ClientBase<TClientBase>::Camera2ClientBase(
44 const sp<CameraService>& cameraService,
45 const sp<TCamCallbacks>& remoteCallback,
46 const String16& clientPackageName,
47 const std::unique_ptr<String16>& clientFeatureId,
48 const String8& cameraId,
49 int api1CameraId,
50 int cameraFacing,
51 int clientPid,
52 uid_t clientUid,
53 int servicePid):
//模板 TClientBase,在 CameraDeviceClient 继承 Camera2ClientBase 时被指定为 CameraDeviceClientBase
54 TClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
55 cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
56 mSharedCameraCallbacks(remoteCallback),
57 mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
//创建了一个 Camera3Device
58 mDevice(new Camera3Device(cameraId)),
59 mDeviceActive(false), mApi1CameraId(api1CameraId)
60{
61 ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
62 String8(clientPackageName).string(), clientPid, clientUid);
63
64 mInitialClientPid = clientPid;
65 LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
66}
再回到CameraService类的connectHelper方法,client->initialize(mCameraProviderManager)逻辑的实现,这里的client就是CameraDeviceClient了。
CameraService 在创建 CameraDeviceClient 之后,会调用它的初始化函数:
//对外提供调用的初始化函数接口 initialize
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager) {
return initializeImpl(manager);
}
//初始化的具体实现函数,模板 TProviderPtr 在此处即是 CameraProviderManager 类
template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
ATRACE_CALL();
status_t res;
//首先将父类初始化,注意此处传入了 CameraProviderManager
res = Camera2ClientBase::initialize(providerPtr);
if (res != OK) {
return res;
}
String8 threadName;
//给成员变量 mFrameProcessor赋值
//它就是用来处理预览帧的,它继承了Thread类,相机的预览实际就是在一个无限循环当中不断的处理request来完成的。
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;
}
接下来再看Camera2ClientBase::initialize:
80template <typename TClientBase>
81status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
82 const String8& monitorTags) {
83 return initializeImpl(manager, monitorTags);
84}
85
//TClientBase 对应 CameraDeviceClientBase,而 TProviderPtr 对应的是 CameraProviderManager
86template <typename TClientBase>
87template <typename TProviderPtr>
88status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
89 const String8& monitorTags) {
90 ATRACE_CALL();
91 ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
92 TClientBase::mCameraIdStr.string());
93 status_t res;
94
//调用 CameraDeviceClientBase 的 startCameraOps 方法,检查 ops 的权限
95 // Verify ops permissions
96 res = TClientBase::startCameraOps();
97 if (res != OK) {
98 return res;
99 }
100
101 if (mDevice == NULL) {
102 ALOGE("%s: Camera %s: No device connected",
103 __FUNCTION__, TClientBase::mCameraIdStr.string());
104 return NO_INIT;
105 }
106
//初始化 Camera3Device 的实例,注意此处传入了 CameraProviderManager
107 res = mDevice->initialize(providerPtr, monitorTags);
108 if (res != OK) {
109 ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
110 __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
111 return res;
112 }
113
114 wp<NotificationListener> weakThis(this);
//在 Camera3Device 实例中设置 Notify 回调
115 res = mDevice->setNotifyCallback(weakThis);
116
117 return OK;
118}
Camera3Device
我们操作相机的所有工作在CameraServer进程都是由Camera3Device中转来和CameraDaemon进程进行通信的。
109status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
110 ATRACE_CALL();
111 Mutex::Autolock il(mInterfaceLock);
112 Mutex::Autolock l(mLock);
113
114 ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
115 if (mStatus != STATUS_UNINITIALIZED) {
116 CLOGE("Already initialized!");
117 return INVALID_OPERATION;
118 }
119 if (manager == nullptr) return INVALID_OPERATION;
//在CameraDaemon进程中执行真正的camera的open过程,同时会返回一个session对象
121 sp<ICameraDeviceSession> session;
122 ATRACE_BEGIN("CameraHal::openSession");
123 status_t res = manager->openSession(mId.string(), this,
124 /*out*/ &session);
125 ATRACE_END();
126 if (res != OK) {
127 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
128 return res;
129 }
130
131 res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
132 if (res != OK) {
133 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
134 session->close();
135 return res;
136 }
137 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
138
139 std::vector<std::string> physicalCameraIds;
140 bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
141 if (isLogical) {
142 for (auto& physicalId : physicalCameraIds) {
143 res = manager->getCameraCharacteristics(
144 physicalId, &mPhysicalDeviceInfoMap[physicalId]);
145 if (res != OK) {
146 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
147 physicalId.c_str(), strerror(-res), res);
148 session->close();
149 return res;
150 }
151
152 bool usePrecorrectArray =
153 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
154 if (usePrecorrectArray) {
155 res = mDistortionMappers[physicalId].setupStaticInfo(
156 mPhysicalDeviceInfoMap[physicalId]);
157 if (res != OK) {
158 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
159 "correction", physicalId.c_str());
160 session->close();
161 return res;
162 }
163 }
164
165 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
166 &mPhysicalDeviceInfoMap[physicalId],
167 mSupportNativeZoomRatio, usePrecorrectArray);
168 }
169 }
170
171 std::shared_ptr<RequestMetadataQueue> queue;
172 auto requestQueueRet = session->getCaptureRequestMetadataQueue(
173 [&queue](const auto& descriptor) {
174 queue = std::make_shared<RequestMetadataQueue>(descriptor);
175 if (!queue->isValid() || queue->availableToWrite() <= 0) {
176 ALOGE("HAL returns empty request metadata fmq, not use it");
177 queue = nullptr;
178 // don't use the queue onwards.
179 }
180 });
181 if (!requestQueueRet.isOk()) {
182 ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
183 requestQueueRet.description().c_str());
184 return DEAD_OBJECT;
185 }
186
187 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
188 auto resultQueueRet = session->getCaptureResultMetadataQueue(
189 [&resQueue](const auto& descriptor) {
190 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
191 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
192 ALOGE("HAL returns empty result metadata fmq, not use it");
193 resQueue = nullptr;
194 // Don't use the resQueue onwards.
195 }
196 });
197 if (!resultQueueRet.isOk()) {
198 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
199 resultQueueRet.description().c_str());
200 return DEAD_OBJECT;
201 }
202 IF_ALOGV() {
203 session->interfaceChain([](
204 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
205 ALOGV("Session interface chain:");
206 for (const auto& iface : interfaceChain) {
207 ALOGV(" %s", iface.c_str());
208 }
209 });
210 }
211
212 camera_metadata_entry bufMgrMode =
213 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
214 if (bufMgrMode.count > 0) {
215 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
216 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
217 }
218
219 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
220 for (size_t i = 0; i < capabilities.count; i++) {
221 uint8_t capability = capabilities.data.u8[i];
222 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
223 mSupportOfflineProcessing = true;
224 }
225 }
226
227 mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
228 std::string providerType;
229 mVendorTagId = manager->getProviderTagIdLocked(mId.string());
230 mTagMonitor.initialize(mVendorTagId);
231 if (!monitorTags.isEmpty()) {
232 mTagMonitor.parseTagsToMonitor(String8(monitorTags));
233 }
234
235 // Metadata tags needs fixup for monochrome camera device version less
236 // than 3.5.
237 hardware::hidl_version maxVersion{0,0};
238 res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
239 if (res != OK) {
240 ALOGE("%s: Error in getting camera device version id: %s (%d)",
241 __FUNCTION__, strerror(-res), res);
242 return res;
243 }
244 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
245 maxVersion.get_major(), maxVersion.get_minor());
246
247 bool isMonochrome = false;
248 for (size_t i = 0; i < capabilities.count; i++) {
249 uint8_t capability = capabilities.data.u8[i];
250 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
251 isMonochrome = true;
252 }
253 }
254 mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
255
256 return initializeCommonLocked();
257}
初始化函数调用了 CameraProviderManager 的 openSession
方法,开启了远端的 Session, 最后继续调用initializeCommonLocked完成初始化。
CameraProviderManager
/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::openSession(const std::string &id,
375 const sp<device::V3_2::ICameraDeviceCallback>& callback,
376 /*out*/
377 sp<device::V3_2::ICameraDeviceSession> *session) {
378
379 std::lock_guard<std::mutex> lock(mInterfaceMutex);
//首先调用 findDeviceInfoLocked,获取 HAL3 相关的 DeviceInfo3,
//这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。
//具体说就是它是在CameraService进行启动时,初始化CameraProviderManager对象的逻辑中,
//通过addProviderLocked方法生成具体的DeviceInfo对象,添加到mProviders成员变量中的
381 auto deviceInfo = findDeviceInfoLocked(id,
382 /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
383 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
384
385 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
386 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
387 if (parentProvider == nullptr) {
388 return DEAD_OBJECT;
389 }
390 const sp<provider::V2_4::ICameraProvider> provider = parentProvider->startProviderInterface();
391 if (provider == nullptr) {
392 return DEAD_OBJECT;
393 }
394 saveRef(DeviceMode::CAMERA, id, provider);
395
396 Status status;
397 hardware::Return<void> ret;
398 auto interface = deviceInfo3->startDeviceInterface<
399 CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
400 if (interface == nullptr) {
401 return DEAD_OBJECT;
402 }
//通过远端调用 CameraDevice 的 open 方法,创建 CameraDeviceSession 实例
//并将其本地调用接口通过入参session返回
//DeviceInfo3 这个类的 mInterface 成员类型是 ICameraDevice,通过它可以调用远端 CameraDevice
404 ret = interface->open(callback, [&status, &session]
405 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
406 status = s;
407 if (status == Status::OK) {
408 *session = cameraSession;
409 }
410 });
411 if (!ret.isOk()) {
412 removeRef(DeviceMode::CAMERA, id);
413 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
414 __FUNCTION__, id.c_str(), ret.description().c_str());
415 return DEAD_OBJECT;
416 }
417 return mapToStatusT(status);
}
HAL Service
CameraDevice
/hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp
CameraDevice 的实例实际上在初始化 HAL Service 之后就存在了。
前面说到,通过 CameraProviderManager 中的 deviceInfo 接口,调用远端 CameraDevice 实例的 open 方法:
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
177 ICameraDevice::open_cb _hidl_cb) {
178 Status status = initStatus();
179 sp<CameraDeviceSession> session = nullptr;
180
181 if (callback == nullptr) {
182 ALOGE("%s: cannot open camera %s. callback is null!",
183 __FUNCTION__, mCameraId.c_str());
184 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
185 return Void();
186 }
187
188 if (status != Status::OK) {
189 // Provider will never pass initFailed device to client, so
190 // this must be a disconnected camera
191 ALOGE("%s: cannot open camera %s. camera is disconnected!",
192 __FUNCTION__, mCameraId.c_str());
193 _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
194 return Void();
195 } else {
196 mLock.lock();
197
198 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
199 session = mSession.promote();
200 if (session != nullptr && !session->isClosed()) {
201 ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
202 mLock.unlock();
203 _hidl_cb(Status::CAMERA_IN_USE, nullptr);
204 return Void();
205 }
206
207 /** Open HAL device */
208 status_t res;
209 camera3_device_t *device;
210
211 ATRACE_BEGIN("camera3->open");
212 res = mModule->open(mCameraId.c_str(),
213 reinterpret_cast<hw_device_t**>(&device));
214 ATRACE_END();
215
216 if (res != OK) {
217 ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
218 mLock.unlock();
219 _hidl_cb(getHidlStatus(res), nullptr);
220 return Void();
221 }
222
223 /** Cross-check device version */
224 if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
225 ALOGE("%s: Could not open camera: "
226 "Camera device should be at least %x, reports %x instead",
227 __FUNCTION__,
228 CAMERA_DEVICE_API_VERSION_3_2,
229 device->common.version);
230 device->common.close(&device->common);
231 mLock.unlock();
232 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
233 return Void();
234 }
235
236 struct camera_info info;
237 res = mModule->getCameraInfo(mCameraIdInt, &info);
238 if (res != OK) {
239 ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
240 device->common.close(&device->common);
241 mLock.unlock();
242 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
243 return Void();
244 }
245
246 session = createSession(
247 device, info.static_camera_characteristics, callback);
248 if (session == nullptr) {
249 ALOGE("%s: camera device session allocation failed", __FUNCTION__);
250 mLock.unlock();
251 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
252 return Void();
253 }
254 if (session->isInitFailed()) {
255 ALOGE("%s: camera device session init failed", __FUNCTION__);
256 session = nullptr;
257 mLock.unlock();
258 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
259 return Void();
260 }
261 mSession = session;
262
263 IF_ALOGV() {
264 session->getInterface()->interfaceChain([](
265 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
266 ALOGV("Session interface chain:");
267 for (const auto& iface : interfaceChain) {
268 ALOGV(" %s", iface.c_str());
269 }
270 });
271 }
272 mLock.unlock();
273 }
274 _hidl_cb(status, session->getInterface());
275 return Void();
}
该方法的参数,第一个是callback对象,它的使用方法和我们之前讲的应用层调用openCamera时在CameraManager中传入的binder类型的callback是一样的,Server端拿到这个callback之后,就可以针对需要的节点事件回调应用层,而这里是在CameraDaemon回调CameraServer,道理是一样的。这个callback参数最终赋值给HAL层中的CameraDeviceSession类的mResultBatcher成员变量了;第二个参数是open_cb类型,从它的命名中可以看出来,它也是一个回调函数,非常方便,就像一个函数指针一样,它在CameraProviderManager一侧中像一个结构体一样传了过来,当CameraDevice类中的open执行完成后,就会将session对象作为参数回传到CameraProviderManager这一侧,我们就拿到了session,后续对camera的操作都是通过这个sesson对象来进行中转完成的。
mModule
是在 HAL Service 初始化时就已经配置好的,它对从 libhardware
库中加载的 Camera HAL 接口进行了一层封装。从这里往下就会一路走到 HWL 的构造流程去
211 ATRACE_BEGIN("camera3->open");
212 res = mModule->open(mCameraId.c_str(),
213 reinterpret_cast<hw_device_t**>(&device));
214 ATRACE_END();
创建 session 并让内部成员 mSession
持有,具体实现的函数为 creatSession
246 session = createSession(
247 device, info.static_camera_characteristics, callback);
248 if (session == nullptr) {
249 ALOGE("%s: camera device session allocation failed", __FUNCTION__);
250 mLock.unlock();
251 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
252 return Void();
253 }
254 if (session->isInitFailed()) {
255 ALOGE("%s: camera device session init failed", __FUNCTION__);
256 session = nullptr;
257 mLock.unlock();
258 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
259 return Void();
260 }
261 mSession = session;
creatSession
中的实现是直接创建了一个 CameraDeviceSession。当然在其构造函数中会调用内部的初始化函数,然后会进入 HAL 接口层 HWL 的初始化流程
HAL Service 连接到 Camera HAL
(thanks to: https://blog.youkuaiyun.com/qq_16775897/article/details/81537710)