This article uses Android 11 code to sort out.
The interface of Android Camera2 open Camera is the openCamera function of CameraManager, as follows:
frameworks/base/core/java/android/hardware/camera2/CameraManager.java
648 @RequiresPermission(android.Manifest.permission.CAMERA)
649 public void openCamera(@NonNull String cameraId,
650 @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
651 throws CameraAccessException {
652
653 openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
654 USE_CALLING_UID);
655 }
- Calling this function requires the android.Manifest.permission.CAMERA permission
- The first parameter is the camera ID
- The second parameter is the callback object for opening the camera operation. When the opening fails or succeeds, the corresponding function of the callback will be called back.
- The third parameter is Handler. The callback will be executed in the thread corresponding to the handler. If the parameter is empty, the callback will be executed in the current thread.
- Call the openCameraForUid function of CameraManager
Before calling openCameraForUid, some processing will be done on the parameter handler:
frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2190 public static Executor checkAndWrapHandler(Handler handler) {
2191 return new CameraHandlerExecutor(checkHandler(handler));
2192 }
Use the checkHandler return value as a parameter to construct a CameraHandlerExecutor object and return it.
frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2202 static Handler checkHandler(Handler handler) {
2203 if (handler == null) {
2204 Looper looper = Looper.myLooper();
2205 if (looper == null) {
2206 throw new IllegalArgumentException(
2207 "No handler given, and current thread has no looper!");
2208 }
2209 handler = new Handler(looper);
2210 }
2211 return handler;
2212 }
- If handler is empty, construct a Handler object with the looper object of the current thread as a parameter and return
- If handler is not empty, return handler directly.
frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2144 private static class CameraHandlerExecutor implements Executor {
2145 private final Handler mHandler;
2146
2147 public CameraHandlerExecutor(@NonNull Handler handler) {
2148 mHandler = Objects.requireNonNull(handler);
2149 }
2150
2151 @Override
2152 public void execute(Runnable command) {
2153 // Return value of 'post()' will be ignored in order to keep the
2154 // same camera behavior. For further details see b/74605221 .
2155 mHandler.post(command);
2156 }
2157 }
- Assign the parameter handler to the member variable mHandler. When the parameter of Objects.requireNonNull is null, a null pointer exception will be thrown.
- When executing the execute function, the post function of mHandler is actually called.
Back to the analysis of the openCameraForUid function:
frameworks/base/core/java/android/hardware/camera2/CameraManager.java
第四个参数为USE_CALLING_UID值为-1
711 public void openCameraForUid(@NonNull String cameraId,
712 @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
713 int clientUid)
714 throws CameraAccessException {
715
716 if (cameraId == null) {
717 throw new IllegalArgumentException("cameraId was null");
718 } else if (callback == null) {
719 throw new IllegalArgumentException("callback was null");
720 }
721 if (CameraManagerGlobal.sCameraServiceDisabled) {
722 throw new IllegalArgumentException("No cameras available on device");
723 }
724
725 openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
726 }
- The cameraId is empty and an IllegalArgumentException is thrown.
- callback is empty and an IllegalArgumentException is thrown.
- sCameraServiceDisabled is empty and an IllegalArgumentException is thrown.
- Call the openCameraDeviceUserAsync function. This function has a lot of content and will be analyzed in sections.
(1) Get the CameraCharacteristics object based on cameraId.
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
Implementation of getCameraCharacteristics:
//获取CameraService代理对象
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
//获取屏幕显示尺寸参数
Size displaySize = getDisplaySize();
//调用CameraService的getCameraCharacteristics函数返回CameraMetadataNative对象
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
//设置CameraMetadataNative对象的一些参数
try {
info.setCameraId(Integer.parseInt(cameraId));
} catch (NumberFormatException e) {
// For external camera, reaching here is expected.
Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
}
boolean hasConcurrentStreams =
CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
info.setDisplaySize(displaySize);
//以CameraMetadataNative为参数构造CameraCharacteristics对象返回
characteristics = new CameraCharacteristics(info);
Continue to look at the getCameraCharacteristics function in CameraService
frameworks/av/services/camera/libcameraservice/CameraService.cpp
This chapter is over, let’s continue the next chapter.
The WeChat public account will be released simultaneously, please scan the QR code to follow!