1. 程式人生 > >Android Camera程序間通訊類總結

Android Camera程序間通訊類總結

《Android Camera架構》
《Android Camera程序間通訊類總結》
《Android Camera模組解析之拍照》
《Android Camera模組解析之視訊錄製》
《Android Camera原理之CameraDeviceCallbacks回撥模組》
《Android Camera原理之openCamera模組(一)》
《Android Camera原理之openCamera模組(二)》
《Android Camera原理之createCaptureSession模組》
《Android Camera原理之setRepeatingRequest與capture模組》

《Android Camera原理之編譯》
《Android Camera原理之camera provider啟動》
《Android Camera原理之cameraserver與cameraprovider是怎樣聯絡的》
《Android Camera原理之camera service與camera provider session會話與capture request輪轉》
《Android Camera原理之camera HAL底層資料結構與類總結》
《Android Camera原理之camera service類與介面關係》

我們直達camera模組的程式碼根據層次可以分為下面幾層,開發者直接接觸的是Camera api的部分,Camera api會通過Binder IPC方式呼叫到Camera服務部分,但是這部分程式碼實在繁雜,需要將這部分IPC聯絡的方式總結一些,方便後來人方便的學習這一塊的內容。



  • Camera api部分:
    frameworks/base/core/java/android/hardware/camera2
  • Camera JNI部分:
    frameworks/base/core/jni/android_hardware_Camera.cpp
    編譯選項在目錄下的Android.bp
    make libandroid_runtime -j1
  • Camera UI庫部分:
    frameworks/av/camera/
    編譯選項在目錄下的Android.bp
    make libcamera_client -j1
  • Camera服務部分:
    frameworks/av/services/camera/libcameraservice/
    編譯選項在目錄下的Android.mk
    make libcameraservice -j1
  • Camera HAL部分:
    hardware/qcom/camera/


首先大家關注一下這個程式碼路徑:frameworks/av/camera/aidl/ 這裡是和cameraservice端互動的橋樑。


cameraservice端的程式碼在frameworks/av/services/camera/libcameraservice/下面。

1.ICameraDeviceUser.aidl

這個aidl檔案會自動生成:
./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繼承了ICameraDeviceUser.h

#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_

./frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.h中又發現了繼承BnCameraDeviceUser.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
{
//......
}

這個IPC呼叫時為了操作底層的Camera Device,獲取camera device重要資訊,並操作Camera Device,提供了int createStream(in OutputConfiguration outputConfiguration);來建立captute session機制,Surface getInputSurface();來返回相應的輸入流。

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;
    };

這是獲取當前Camera Device狀態的回撥,在操作camera device之前需要判斷當前的camera是否可用。

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
{
//......
}

這個Camera Service的主類,使用者程序中操作camera核心功能:connectDevice、設定閃光燈等等操作都是通過IPC呼叫camera service實現的。

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.其他aidl檔案

其他的aidl檔案都是IPC間傳輸的Parcelable型別的資料,例如CaptureRequest.aidl就是IPC中相機捕獲請求的資料,CameraInfo.aidl就是IPC中 camera資料的集