Summary of Android Camera Interprocess Communication Classes

Keywords: Mobile Android Java Session

Android Camera Architecture
Summary of Android Camera Interprocess Communication Classes
Photographs of Android Camera Module Resolution
"Video Recording of Android Camera Module Parsing"
"Camera Device Callbacks Callback Module of Android Camera Principle"
openCamera Module of Android Camera Principle (1)
openCamera Module of Android Camera Principle (2)
"Create Capture Session Module of Android Camera Principle"
setRepeatingRequest and capture Module of Android Camera Principle
Compilation of Android Camera Principles
camera provider Launch of Android Camera Principle
How does Camera Server of Android Camera Principle relate to Camera Provider?
"camera service and camera provider session and capture request Rotation of Android Camera Principle"
"camera HAL underlying data structure and class summary of Android Camera principle"
"camera service Classes and Interface Relations of Android Camera Principles"

The code of our direct camera module can be divided into the following layers according to the layers. The developer contacts the part of Camera api directly. Camera api will call the part of Camera service through Binder IPC, but this part of code is really complicated. It needs to summarize the way of IPC connection in this part, which is convenient for later generations. Learn the content of this section.

  • Camera api section:
    frameworks/base/core/java/android/hardware/camera2
  • Camera JNI Part:
    frameworks/base/core/jni/android_hardware_Camera.cpp
    Compile options in the directory of Android.bp
    make libandroid_runtime -j1
  • Camera UI Library Section:
    frameworks/av/camera/
    Compile options in the directory of Android.bp
    make libcamera_client -j1
  • Camera Service Section:
    frameworks/av/services/camera/libcameraservice/
    Compile options in the directory of Android.mk
    make libcameraservice -j1
  • Camera HAL:
    hardware/qcom/camera/

Let's start by looking at this code path: frameworks/av/camera/aidl / here is the bridge to interact with the cameraservice side.


The code on the cameraservice side is under frameworks/av/services/camera/libcameraservice/

1.ICameraDeviceUser.aidl

This aidl file will be automatically generated:
./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/camera2/ICameraDeviceUser.h

#ifndef AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_I_CAMERA_DEVICE_USER_H_
#define AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_I_CAMERA_DEVICE_USER_H_

#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Status.h>
#include <camera/CameraMetadata.h>
#include <camera/camera2/CaptureRequest.h>
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
#include <cstdint>
#include <gui/view/Surface.h>
#include <utils/StrongPointer.h>
#include <vector>

namespace android {

namespace hardware {

namespace camera2 {

class ICameraDeviceUser : public ::android::IInterface {
public:
  DECLARE_META_INTERFACE(CameraDeviceUser)
  enum  : int32_t {
    NO_IN_FLIGHT_REPEATING_FRAMES = -1,
    NORMAL_MODE = 0,
    CONSTRAINED_HIGH_SPEED_MODE = 1,
    VENDOR_MODE_START = 32768,
    TEMPLATE_PREVIEW = 1,
    TEMPLATE_STILL_CAPTURE = 2,
    TEMPLATE_RECORD = 3,
    TEMPLATE_VIDEO_SNAPSHOT = 4,
    TEMPLATE_ZERO_SHUTTER_LAG = 5,
    TEMPLATE_MANUAL = 6,
  };
  virtual ::android::binder::Status disconnect() = 0;
  virtual ::android::binder::Status submitRequest(const ::android::hardware::camera2::CaptureRequest& request, bool streaming, ::android::hardware::camera2::utils::SubmitInfo* _aidl_return) = 0;
  virtual ::android::binder::Status submitRequestList(const ::std::vector<::android::hardware::camera2::CaptureRequest>& requestList, bool streaming, ::android::hardware::camera2::utils::SubmitInfo* _aidl_return) = 0;
  virtual ::android::binder::Status cancelRequest(int32_t requestId, int64_t* _aidl_return) = 0;
  virtual ::android::binder::Status beginConfigure() = 0;
  virtual ::android::binder::Status endConfigure(int32_t operatingMode, const ::android::hardware::camera2::impl::CameraMetadataNative& sessionParams) = 0;
  virtual ::android::binder::Status deleteStream(int32_t streamId) = 0;
  virtual ::android::binder::Status createStream(const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration, int32_t* _aidl_return) = 0;
  virtual ::android::binder::Status createInputStream(int32_t width, int32_t height, int32_t format, int32_t* _aidl_return) = 0;
  virtual ::android::binder::Status getInputSurface(::android::view::Surface* _aidl_return) = 0;
  virtual ::android::binder::Status createDefaultRequest(int32_t templateId, ::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) = 0;
  virtual ::android::binder::Status getCameraInfo(::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) = 0;
  virtual ::android::binder::Status waitUntilIdle() = 0;
  virtual ::android::binder::Status flush(int64_t* _aidl_return) = 0;
  virtual ::android::binder::Status prepare(int32_t streamId) = 0;
  virtual ::android::binder::Status tearDown(int32_t streamId) = 0;
  virtual ::android::binder::Status prepare2(int32_t maxCount, int32_t streamId) = 0;
  virtual ::android::binder::Status updateOutputConfiguration(int32_t streamId, const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration) = 0;
  virtual ::android::binder::Status finalizeOutputConfigurations(int32_t streamId, const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration) = 0;
  enum Call {
    DISCONNECT = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
    SUBMITREQUEST = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
    SUBMITREQUESTLIST = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
    CANCELREQUEST = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
    BEGINCONFIGURE = ::android::IBinder::FIRST_CALL_TRANSACTION + 4,
    ENDCONFIGURE = ::android::IBinder::FIRST_CALL_TRANSACTION + 5,
    DELETESTREAM = ::android::IBinder::FIRST_CALL_TRANSACTION + 6,
    CREATESTREAM = ::android::IBinder::FIRST_CALL_TRANSACTION + 7,
    CREATEINPUTSTREAM = ::android::IBinder::FIRST_CALL_TRANSACTION + 8,
    GETINPUTSURFACE = ::android::IBinder::FIRST_CALL_TRANSACTION + 9,
    CREATEDEFAULTREQUEST = ::android::IBinder::FIRST_CALL_TRANSACTION + 10,
    GETCAMERAINFO = ::android::IBinder::FIRST_CALL_TRANSACTION + 11,
    WAITUNTILIDLE = ::android::IBinder::FIRST_CALL_TRANSACTION + 12,
    FLUSH = ::android::IBinder::FIRST_CALL_TRANSACTION + 13,
    PREPARE = ::android::IBinder::FIRST_CALL_TRANSACTION + 14,
    TEARDOWN = ::android::IBinder::FIRST_CALL_TRANSACTION + 15,
    PREPARE2 = ::android::IBinder::FIRST_CALL_TRANSACTION + 16,
    UPDATEOUTPUTCONFIGURATION = ::android::IBinder::FIRST_CALL_TRANSACTION + 17,
    FINALIZEOUTPUTCONFIGURATIONS = ::android::IBinder::FIRST_CALL_TRANSACTION + 18,
  };
};  // class ICameraDeviceUser

class ICameraDeviceUserDefault : public ICameraDeviceUser {
public:
  ::android::IBinder* onAsBinder() override;
  ::android::binder::Status disconnect() override;
  ::android::binder::Status submitRequest(const ::android::hardware::camera2::CaptureRequest& request, bool streaming, ::android::hardware::camera2::utils::SubmitInfo* _aidl_return) override;
  ::android::binder::Status submitRequestList(const ::std::vector<::android::hardware::camera2::CaptureRequest>& requestList, bool streaming, ::android::hardware::camera2::utils::SubmitInfo* _aidl_return) override;
  ::android::binder::Status cancelRequest(int32_t requestId, int64_t* _aidl_return) override;
  ::android::binder::Status beginConfigure() override;
  ::android::binder::Status endConfigure(int32_t operatingMode, const ::android::hardware::camera2::impl::CameraMetadataNative& sessionParams) override;
  ::android::binder::Status deleteStream(int32_t streamId) override;
  ::android::binder::Status createStream(const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration, int32_t* _aidl_return) override;
  ::android::binder::Status createInputStream(int32_t width, int32_t height, int32_t format, int32_t* _aidl_return) override;
  ::android::binder::Status getInputSurface(::android::view::Surface* _aidl_return) override;
  ::android::binder::Status createDefaultRequest(int32_t templateId, ::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) override;
  ::android::binder::Status getCameraInfo(::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) override;
  ::android::binder::Status waitUntilIdle() override;
  ::android::binder::Status flush(int64_t* _aidl_return) override;
  ::android::binder::Status prepare(int32_t streamId) override;
  ::android::binder::Status tearDown(int32_t streamId) override;
  ::android::binder::Status prepare2(int32_t maxCount, int32_t streamId) override;
  ::android::binder::Status updateOutputConfiguration(int32_t streamId, const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration) override;
  ::android::binder::Status finalizeOutputConfigurations(int32_t streamId, const ::android::hardware::camera2::params::OutputConfiguration& outputConfiguration) override;

};

}  // namespace camera2

}  // namespace hardware

}  // namespace android

#endif  // AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_I_CAMERA_DEVICE_USER_H_

/ out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/camera2/BnCameraDeviceUser.h inherited ICameraDeviceUser.

#ifndef AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_BN_CAMERA_DEVICE_USER_H_
#define AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_BN_CAMERA_DEVICE_USER_H_

#include <binder/IInterface.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>

namespace android {

namespace hardware {

namespace camera2 {

class BnCameraDeviceUser : public ::android::BnInterface<ICameraDeviceUser> {
public:
  ::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override;
};  // class BnCameraDeviceUser

}  // namespace camera2

}  // namespace hardware

}  // namespace android

#endif  // AIDL_GENERATED_ANDROID_HARDWARE_CAMERA2_BN_CAMERA_DEVICE_USER_H_

The code inheriting BnCameraDeviceUser.h was found in. / frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.h.

struct CameraDeviceClientBase :
         public CameraService::BasicClient,
         public hardware::camera2::BnCameraDeviceUser
{
    typedef hardware::camera2::ICameraDeviceCallbacks TCamCallbacks;

    const sp<hardware::camera2::ICameraDeviceCallbacks>& getRemoteCallback() {
        return mRemoteCallback;
    }

protected:
    CameraDeviceClientBase(const sp<CameraService>& cameraService,
            const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
            const String16& clientPackageName,
            const String8& cameraId,
            int api1CameraId,
            int cameraFacing,
            int clientPid,
            uid_t clientUid,
            int servicePid);

    sp<hardware::camera2::ICameraDeviceCallbacks> mRemoteCallback;
};

class CameraDeviceClient :
        public Camera2ClientBase<CameraDeviceClientBase>,
        public camera2::FrameProcessorBase::FilteredListener
{
//......
}

This IPC call provides int create Stream (in Output Configuration output Configuration) to manipulate the underlying Camera Device, get important information about camera device, and operate Camera Device; to create captute session mechanism, Surface get Input Surface (); to return the corresponding input stream.

2.ICameraDeviceCallbacks.aidl

./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/camera2/ICameraDeviceCallbacks.h
| |
| |
./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/camera2/BnCameraDeviceCallbacks.h
| |
| |
frameworks/av/camera/ndk/impl/ACameraDevice.h

    // Callbacks from camera service
    class ServiceCallback : public hardware::camera2::BnCameraDeviceCallbacks {
      public:
        explicit ServiceCallback(CameraDevice* device) : mDevice(device) {}
        binder::Status onDeviceError(int32_t errorCode,
                           const CaptureResultExtras& resultExtras) override;
        binder::Status onDeviceIdle() override;
        binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
                              int64_t timestamp) override;
        binder::Status onResultReceived(const CameraMetadata& metadata,
                              const CaptureResultExtras& resultExtras,
                              const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) override;
        binder::Status onPrepared(int streamId) override;
        binder::Status onRequestQueueEmpty() override;
        binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
                int32_t stoppedSequenceId) override;
      private:
        const wp<CameraDevice> mDevice;
    };

This is a callback to get the current Camera Device status, and you need to determine whether the current Camera is available before operating the camera device.

3.ICameraService.aidl

./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/ICameraService.h
| |
| |
./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/BnCameraService.h
| |
| |
frameworks/av/services/camera/libcameraservice/CameraService.h

class CameraService :
    public BinderService<CameraService>,
    public virtual ::android::hardware::BnCameraService,
    public virtual IBinder::DeathRecipient,
    public virtual CameraProviderManager::StatusListener
{
//......
}

This main class of Camera Service, which operates the core functions of Camera in user process: Connection Device, setting flash and so on, is implemented by calling camera service by IPC.

4.ICameraServiceProxy.aidl

./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/ICameraServiceProxy.h
| |
| |
./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/BnCameraServiceProxy.h
| |
| |
frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java

    private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
        @Override
        public void pingForUserUpdate() {
            if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
                Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
                        " camera service UID!");
                return;
            }
            notifySwitchWithRetries(30);
        }

        @Override
        public void notifyCameraState(String cameraId, int newCameraState, int facing,
                String clientName, int apiLevel) {
            if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
                Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
                        " camera service UID!");
                return;
            }
            String state = cameraStateToString(newCameraState);
            String facingStr = cameraFacingToString(facing);
            if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
                    state + " for client " + clientName + " API Level " + apiLevel);

            updateActivityCount(cameraId, newCameraState, facing, clientName, apiLevel);
        }
    };

5.ICameraServiceListener.aidl

./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/ICameraServiceListener.h
| |
| |
./out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm_armv7-a-neon_core_shared_platform/gen/aidl/android/hardware/BnCameraServiceListener.h
| |
| |
frameworks/base/core/java/android/hardware/camera2/CameraManager.java

    private static final class CameraManagerGlobal extends ICameraServiceListener.Stub
            implements IBinder.DeathRecipient {
    }

6. Other aidl files

Other aidl files are Parcelable data transmitted between IPCs. For example, CaptureRequest.aidl is the data requested by the camera in IPC, and CameraInfo.aidl is the collection of camera data in IPC.

Posted by lynxus on Sun, 21 Jul 2019 04:18:55 -0700