getCameraIdList() 获取当前设备的相机设备列表 根据这个列表可以查询当前存在几个相机
本文将从当设备启动时主动初始化的列表和当设备存在拔插时的被动回调两条线路分析这个api
getCameraIdList
路径 frameworks/base/core/java/android/hardware/camera2/CameraManager.java
获取idlist,在下面代码可以看出调用的是CameraManagerGlobal的getCameraIdList
@NonNull
public String[] getCameraIdList() throws CameraAccessException {
return CameraManagerGlobal.get().getCameraIdList();
}
CameraManagerGlobal::getCameraIdList
路径 frameworks/base/core/java/android/hardware/camera2/CameraManager.java
这里面主要是获取到cameraService
根据CameraManager的mDeviceStatus里面的数据进行返回
private final ArrayMap<String, Integer> mDeviceStatus = new ArrayMap<String, Integer>();
public String[] getCameraIdList() {
String[] cameraIds = null;
synchronized(mLock) {
// Try to make sure we have an up-to-date list of camera devices.
//获取cameraService
connectCameraServiceLocked();
int idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT ||
status == ICameraServiceListener.STATUS_ENUMERATING) continue;
idCount++;
}
cameraIds = new String[idCount];
idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT ||
status == ICameraServiceListener.STATUS_ENUMERATING) continue;
cameraIds[idCount] = mDeviceStatus.keyAt(i);
idCount++;
}
}
//...接下来是排序
return cameraIds;
}
mDeviceStatus的添加 onStatusChangedLocked
路径 frameworks/base/core/java/android/hardware/camera2/CameraManager.java
可以明显看出这个数据结构中的值是受这个回调函数控制的当回调回来的是添加设备则添加移除则移除,这个回调是由函数connectCameraServiceLocked调用而来的
private final ArrayMap<String, Integer> mDeviceStatus = new ArrayMap<String, Integer>();
private void onStatusChangedLocked(int status, String id) {
//...
Integer oldStatus;
if (status == ICameraServiceListener.STATUS_NOT_PRESENT) {
oldStatus = mDeviceStatus.remove(id);
} else {
oldStatus = mDeviceStatus.put(id, status);
}
//...
final int callbackCount = mCallbackMap.size();
for (int i = 0; i < callbackCount; i++) {
Executor executor = mCallbackMap.valueAt(i);
final AvailabilityCallback callback = mCallbackMap.keyAt(i);
postSingleUpdate(callback, executor, id, status);
}
} // onStatusChangedLocked
connectCameraServiceLocked
路径 frameworks/base/core/java/android/hardware/camera2/CameraManager.java
这个函数是在getCameraIdList函数中调用过的 主要的用途就是获取链接到cameraService,并将自己作为监听注册给cameraService,
这样本文就从这开始介绍 主动:初始设备列表 和 被动:动态插拔设备列表 两种形式
主动:在调用注册函数后会获取到cameraStatuses的一个数组,这个里面存放了关于摄像头设备的挂载信息,遍历这个数组把他们放进mDeviceStatus中。
被动:当然这个类里面同样重写了onStatusChanged函数,并且这里面同样调用了onStatusChangedLocked,这样当cameraService想要通知当前的摄像设备的挂载状态时可以通过这个回调获取了
private void connectCameraServiceLocked() {
//...
IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
//...
ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
try {
CameraMetadataNative.setupGlobalVendorTagDescriptor();
} catch (ServiceSpecificException e) {
handleRecoverableSetupErrors(e);
}
try {
CameraStatus[] cameraStatuses = cameraService.addListener(this);
for (CameraStatus c : cameraStatuses) {
onStatusChangedLocked(c.status, c.cameraId);
}
mCameraService = cameraService;
} catch(ServiceSpecificException e) {
// Unexpected failure
throw new IllegalStateException("Failed to register a camera service listener", e);
} catch (RemoteException e) {
// Camera service is now down, leave mCameraService as null
}
}
//####################################################################
@Override
public void onStatusChanged(int status, String cameraId) throws RemoteException {
synchronized(mLock) {
onStatusChangedLocked(status, cameraId);
}
}
那当cameraManager被注册到cameraService后是如何首次返回摄像设备的挂载信息和在后续挂载信息改变时通知ca
Android相机框架解析:获取设备相机列表的流程

本文详细分析了Android系统如何通过CameraManager获取设备相机列表的过程,从CameraManager的getCameraIdList开始,深入到CameraService、CameraProviderManager、CameraProvider等组件,探讨了设备启动时的初始化列表和动态插拔设备时的回调机制,揭示了从硬件模块到上层应用的交互流程。
最低0.47元/天 解锁文章
481

被折叠的 条评论
为什么被折叠?



