在阅读本篇内容前、你需要首先了解 android 的 Binder IPC 通讯框架基本原理,才好更好理解 CameraServer 与CameraClient 之间通讯原理;此部分描述的是 android.hardware.Camera1 接口相机连接 CameraServer 的逻辑。
推荐两篇精品博客: Android Binder 进程间通讯机制
https://blog.csdn.net/freekiteyu/article/details/70082302
http://gityuan.com/2015/10/31/binder-prepare/
在上一篇中《详解 CameraService 都做了什么 之 CameraService 与 CameraProvider 通讯》中,我们已经梳理了 CameraService 是作为后台服务方式启动, CameraService 首次被强指针引用、调用 CameraService::onFirstRef() 函数;其函数内容如下:
源码路径:@frameworks/av/services/camera/libcameraservice/CameraService.cpp
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
//> 1. 继承 BnCameraService 类
BnCameraService::onFirstRef();
// Update battery life tracking if service is restarting
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
status_t res = INVALID_OPERATION;
//> 2. CameraProvider 服务
res = enumerateProviders();
if (res == OK) {
mInitialized = true;
}
//> 3. 激活 media.camera.proxy 服务
CameraService::pingCameraServiceProxy();
}
其中 BnCameraService::onFirstRef()是本篇梳理对象,以回答 Camera Server 与 Client 是如何通讯这个问题。明确回答 CameraServer 与 CameraClient间是采用 Binder 通讯框架机制、典型C/S通讯模型。
先梳理 Server 与 Client 端公共接口部分继承关系,然后在分别梳理 CameraClient 与 CameraServer 两端的实现逻辑,最后把两端串通起来。
源码路径 @frameworks/av/camera/include/camera/android/ICamera.h
class ICamera: public android::IInterface
{
/**
* Keep up-to-date with ICamera.aidl in frameworks/base
*/
public:
enum {
// Pass real YUV data in video buffers through ICameraClient.dataCallbackTimestamp().
VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV = 0,
// Pass metadata in video buffers through ICameraClient.dataCallbackTimestamp().
VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA = 1,
// Pass video buffers through IGraphicBufferProducer set with setVideoTarget().
VIDEO_BUFFER_MODE_BUFFER_QUEUE = 2,
};
DECLARE_META_INTERFACE(Camera);
// start preview mode, must call setPreviewTarget first
virtual status_t startPreview() = 0;
// start recording mode
virtual status_t startRecording() = 0;
/*
* take a picture.
* @param msgType the message type an application selectively turn on/off
* on a photo-by-photo basis. The supported message types are:
* CAMERA_MSG_SHUTTER, CAMERA_MSG_RAW_IMAGE, CAMERA_MSG_COMPRESSED_IMAGE,
* and CAMERA_MSG_POSTVIEW_FRAME. Any other message types will be ignored.
*/
virtual status_t takePicture(int msgType) = 0;
// send command to camera driver
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
// Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*.
// Returns OK if the specified video buffer mode is supported. If videoBufferMode is
// VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting video
// recording.
virtual status_t setVideoBufferMode(int32_t videoBufferMode) = 0;
// Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
virtual status_t setVideoTarget(
const sp<IGraphicBufferProducer>& bufferProducer) = 0;
};
class BnCamera: public android::BnInterface<ICamera>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
ICamera 继承 android::IInterface 接口类. ICamera 类声明内容中省略部分内容。BnCamera 继承 BnInterface 类,该类是
模板类、入口类型是 ICamera 。
@frameworks/av/camera/include/camera/android/ICameraClient.h
class ICameraClient: public android::IInterface
{
public:
DECLARE_META_INTERFACE(CameraClient);
virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
virtual void dataCallback(int32_t msgType, const sp<IMemory>& data,
camera_frame_metadata_t *metadata) = 0;
};
// ----------------------------------------------------------------------------
class BnCameraClient: public android::BnInterface<ICameraClient>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
ICameraClient 继承 android::IInterface 接口类; BnCameraClient继承BnInterface类,该类是模板类入口参数是ICameraClient类;
@frameworks/av/camera/include/camera/android/ICameraRecordingProxy.h
class ICameraRecordingProxy: public IInterface
{
public:
DECLARE_META_INTERFACE(CameraRecordingProxy);
virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener) = 0;
virtual void stopRecording() = 0;
virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
virtual void releaseRecordingFrameHandle(native_handle_t *handle) = 0;
virtual void releaseRecordingFrameHandleBatch(
const std::vector<native_handle_t*>& handles) = 0;
};
// ----------------------------------------------------------------------------
class BnCameraRecordingProxy: public BnInterface<ICameraRecordingProxy>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
@frameworks/av/camera/include/camera/android/ICameraRecordingProxyListener.h
class ICameraRecordingProxyListener: public IInterface
{
public:
DECLARE_META_INTERFACE(CameraRecordingProxyListener);
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
const sp<IMemory>& data) = 0;
virtual void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,
native_handle_t* handle) = 0;
virtual void recordingFrameHandleCallbackTimestampBatch(
const std::vector<nsecs_t>& timestamps,
const std::vector<native_handle_t*>& handles) = 0;
};
// ----------------------------------------------------------------------------
class BnCameraRecordingProxyListener: public BnInterface<ICameraRecordingProxyListener>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
BnCameraRecordingProxy 和 BnCameraRecordingProxyListener 继承 BnInterface 类,该类是Binder通讯的服务端实现。
源码路径 @frameworks/av/camera/Camera.cpp 是 Client 端具体实现;
我们先梳理下类的继承关系,看看 Camera.h 文件
@frameworks/av/camera/include/camera/Camera.h
class Camera :
public CameraBase<Camera>,
public ::android::hardware::BnCameraClient
{
public:
enum {
USE_CALLING_UID = ::android::hardware::ICameraService::USE_CALLING_UID
};
enum {
USE_CALLING_PID = ::android::hardware::ICameraService::USE_CALLING_PID
};
// construct a camera client from an existing remote
static sp<Camera> create(const sp<::android::hardware::ICamera>& camera);
static sp<Camera> connect(int cameraId,
const String16& clientPackageName,
int clientUid, int clientPid);
// ICameraClient interface
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata);
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
virtual void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle);
virtual void recordingFrameHandleCallbackTimestampBatch(
const std::vector<nsecs_t>& timestamps,
const std::vector<native_handle_t*>& handles);
class RecordingProxy : public BnCameraRecordingProxy
{
public:
explicit RecordingProxy(const sp<Camera>& camera);
// ICameraRecordingProxy interface
virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener);
virtual void stopRecording();
virtual void releaseRecordingFrame(const sp<IMemory>& mem);
virtual void releaseRecordingFrameHandle(native_handle_t* handle);
virtual void releaseRecordingFrameHandleBatch(
const std::vector<native_handle_t*>& handles);
private:
sp<Camera> mCamera;
};
protected:
explicit Camera(int cameraId);
Camera(const Camera&);
Camera& operator=(const Camera);
sp<ICameraRecordingProxyListener> mRecordingProxyListener;
friend class CameraBase;
};
Camera 继承 CameraBase 和 BnCameraClient 类,BnCameraClient类前面已经描述该类的继承关系,接下来看看CameraBase 类的定义,如下:
@frameworks/av/camera/include/camera/CameraBase.h
using hardware::CameraInfo;
template <typename TCam>
struct CameraTraits {
};
template <typename TCam, typename TCamTraits = CameraTraits<TCam> >
class CameraBase : public IBinder::DeathRecipient
{
public:
typedef typename TCamTraits::TCamListener TCamListener;
typedef typename TCamTraits::TCamUser TCamUser;
typedef typename TCamTraits::TCamCallbacks TCamCallbacks;
typedef typename TCamTraits::TCamConnectService TCamConnectService;
static sp<TCam> connect(int cameraId,
const String16& clientPackageName,
int clientUid, int clientPid);
virtual void disconnect();
void setListener(const sp<TCamListener>& listener);
static int getNumberOfCameras();
static status_t getCameraInfo(int cameraId,
/*out*/
struct hardware::CameraInfo* cameraInfo);
sp<TCamUser> remote();
// Status is set to 'UNKNOWN_ERROR' after successful (re)connection
status_t getStatus();
protected:
CameraBase(int cameraId);
virtual ~CameraBase();
// TCamCallbacks implementation
virtual void notifyCallback(int32_t msgType, int32_t ext,
int32_t ext2);
// Common instance variables
Mutex mLock;
virtual void binderDied(const wp<IBinder>& who);
// helper function to obtain camera service handle
static const sp<::android::hardware::ICameraService> getCameraService();
sp<TCamUser> mCamera;
status_t mStatus;
sp<TCamListener> mListener;
const int mCameraId;
typedef CameraBase<TCam> CameraBaseT;
};
CameraBase 是模板类,并继承 IBinder::DeathRecipient 类,该类中实现静态方法 getCameraInfo() 入口参数使用的变量 CameraInfo 定义如下:
namespace hardware {
class ICameraService;
class ICameraServiceListener;
enum {
/** The facing of the camera is opposite to that of the screen. */
CAMERA_FACING_BACK = 0,
/** The facing of the camera is the same as that of the screen. */
CAMERA_FACING_FRONT = 1,
};
struct CameraInfo : public android::Parcelable {
/**
* The direction that the camera faces to. It should be CAMERA_FACING_BACK
* or CAMERA_FACING_FRONT.
*/
int facing;
/**
* The orientation of the camera image. The value is the angle that the
* camera image needs to be rotated clockwise so it shows correctly on the
* display in its natural orientation. It should be 0, 90, 180, or 270.
*
* For example, suppose a device has a naturally tall screen. The
* back-facing camera sensor is mounted in landscape. You are looking at
* the screen. If the top side of the camera sensor is aligned with the
* right edge of the screen in natural orientation, the value should be
* 90. If the top side of a front-facing camera sensor is aligned with the
* right of the screen, the value should be 270.
*/
int orientation;
virtual status_t writeToParcel(android::Parcel* parcel) const;
virtual status_t readFromParcel(const android::Parcel* parcel);
};
} // namespace hardware
可以看到 facing 属性值可以是 CAMERA_FACING_BACK 或 CAMERA_FACING_FRONT 值,和 orientation 值的内容。
前面看来很多类定义,基本了解类间的继承关系,总结如下:
(1). Camera 类继承 BnCameraClient 类、具备 Binder 通讯服务端能力; ???并实现 ICameraClient 类中的虚方法;
(2). Camera 的子类 RecordingProxy 继承 BnCameraRecordingProxy 类,并实现类的虚方法;
(3). Camera 类定义 sp mRecordingProxyListener;具备 ICameraRecordingProxyListener 功能;
(4). Camera 类继承 CameraBase 类、该类中定义sp<::android::hardware::ICameraService> getCameraService() 方法;
该方法中获取 “media.camera” 服务对象,并保持在gCameraService中;
@frameworks/av/camera/CameraBase.cpp
sp<::android::hardware::ICameraService> gCameraService;
const char* kCameraServiceName = "media.camera";
///
// CameraBase definition
///
// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<::android::hardware::ICameraService> CameraBase<TCam, TCamTraits>::getCameraService()
{
Mutex::Autolock _l(gLock);
if (gCameraService.get() == 0) {
char value[PROPERTY_VALUE_MAX];
property_get("config.disable_cameraservice", value, "0");
if (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0) {
return gCameraService;
}
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16(kCameraServiceName));
if (binder != 0) {
break;
}
ALOGW("CameraService not published, waiting...");
usleep(kCameraServicePollDelay);
} while(true);
if (gDeathNotifier == NULL) {
gDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(gDeathNotifier);
gCameraService = interface_cast<::android::hardware::ICameraService>(binder);
}
ALOGE_IF(gCameraService == 0, "no CameraService!?");
return gCameraService;
}
通过 CameraBase<TCam, TCamTraits>::getCameraService() 方法可获取到 ICameraService 对象,通过这个对象实现与服务端通讯。
CameraClient 端我们暂时先梳理到这,下面还会从android APP实例上追踪代码,进一步说明CameraClient通讯过程,才能解疑答惑。
加强 CameraService 的认知,我们简单梳理类的内容,如下:
@frameworks/av/services/camera/libcameraservice/CameraService.h
class CameraService :
public BinderService<CameraService>,
public virtual ::android::hardware::BnCameraService,
public virtual IBinder::DeathRecipient,
public camera_module_callbacks_t,
public virtual CameraProviderManager::StatusListener
{
friend class BinderService<CameraService>; //> 友元类
friend class CameraClient; //> 友元类
public:
class Client;
class BasicClient;
class BasicClient : public virtual RefBase { //> 内部子类 1
public:
virtual status_t initialize(sp<CameraProviderManager> manager) = 0;
virtual binder::Status disconnect();
// because we can't virtually inherit IInterface, which breaks
// virtual inheritance
virtual sp<IBinder> asBinderWrapper() = 0;
// Return the remote callback binder object (e.g. ICameraDeviceCallbacks)
sp<IBinder> getRemote() {
return mRemoteBinder;
}
class OpsCallback : public BnAppOpsCallback {
public:
explicit OpsCallback(wp<BasicClient> client);
virtual void opChanged(int32_t op, const String16& packageName);
private:
wp<BasicClient> mClient;
}; // class OpsCallback
sp<OpsCallback> mOpsCallback;
// Track whether startCameraOps was called successfully, to avoid
// finishing what we didn't start.
bool mOpsActive;
// IAppOpsCallback interface, indirected through opListener
virtual void opChanged(int32_t op, const String16& packageName);
}; // class BasicClient
class Client : public hardware::BnCamera, public BasicClient //> 内部子类 2
{
public:
typedef hardware::ICameraClient TCamCallbacks;
// Interface used by CameraService
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
const String8& cameraIdStr,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid);
~Client();
// return our camera client
const sp<hardware::ICameraClient>& getRemoteCallback() {
return mRemoteCallback;
}
virtual sp<IBinder> asBinderWrapper() {
return asBinder(this);
}
// - The app-side Binder interface to receive callbacks from us
sp<hardware::ICameraClient> mRemoteCallback;
int mCameraId; // All API1 clients use integer camera IDs
}; // class Client
class ClientEventListener { //> 内部子类 3
public:
void onClientAdded(const resource_policy::ClientDescriptor<String8,
sp<CameraService::BasicClient>>& descriptor);
void onClientRemoved(const resource_policy::ClientDescriptor<String8,
sp<CameraService::BasicClient>>& descriptor);
}; // class ClientEventListener
class CameraClientManager : public resource_policy::ClientManager<String8,
sp<CameraService::BasicClient>, ClientEventListener> { //> 内部子类 4
public:
CameraClientManager();
virtual ~CameraClientManager();
/**
* Return a strong pointer to the active BasicClient for this camera ID, or an empty
* if none exists.
*/
sp<CameraService::BasicClient> getCameraClient(const String8& id) const;
}; // class CameraClientManager
class CameraState { //> 内部子类 5
public:
/**
* Make a new CameraState and set the ID, cost, and conflicting devices using the values
* returned in the HAL's camera_info struct for each device.
*/
CameraState(const String8& id, int cost, const std::set<String8>& conflicting);
virtual ~CameraState();
};// class CameraState
};
上面源码中省略很多内容,只是把类间关键内容摘录出来,我们看到 CameraService 类中 内部子类有 5 个,继承 5 个类,内容还是比较多的.
在 CameraService::onFirstRef() 中调用 BnCameraService::onFirstRef() 构造函数;
CameraService 继承 BnCameraService 类,该类是通过 ICameraService.aidl 自动生成的类,它继承了 BnInterface,BnInterface又继承了 BBinder,BBiner 继承了 IBinder。执行的 BnCameraService::onFirstRef() 构造方法是它父类BBinder的方法,
是建立Binder服务端通讯构造方法,此部分梳理省略。我们看看 BnCameraService 这个类申明:
源码路径:@out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_cortex-a53_shared_core/
gen/aidl/android/hardware/BnCameraService.h
class BnCameraService : public ::android::BnInterface<ICameraService> {
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 BnCameraService
这是服务端接收 IPC 通讯方法,实现都是 AIDL GEN 自动生成的。
源码内容如下:@out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_cortex-a53_shared_core/
gen/aidl/frameworks/av/camera/aidl/android/hardware/ICameraService.cpp
#include <android/hardware/BnCameraService.h>
#include <binder/Parcel.h>
namespace hardware {
::android::status_t BnCameraService::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags)
{
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
case Call::GETNUMBEROFCAMERAS:
{
int32_t in_type;
int32_t _aidl_return;
if (!(_aidl_data.checkInterface(this))) { _aidl_ret_status = ::android::BAD_TYPE; break; }
_aidl_ret_status = _aidl_data.readInt32(&in_type);
if (((_aidl_ret_status) != (::android::OK))) { break; }
//> 获取相机数量
::android::binder::Status _aidl_status(getNumberOfCameras(in_type, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { break; }
if (!_aidl_status.isOk()) { break; }
_aidl_ret_status = _aidl_reply->writeInt32(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) { break; }
}
break;
case Call::GETCAMERAINFO:
{
int32_t in_cameraId;
::android::hardware::CameraInfo _aidl_return;
if (!(_aidl_data.checkInterface(this))) { _aidl_ret_status = ::android::BAD_TYPE; break; }
_aidl_ret_status = _aidl_data.readInt32(&in_cameraId);
if (((_aidl_ret_status) != (::android::OK))) { break; }
//> 获取相机信息
::android::binder::Status _aidl_status(getCameraInfo(in_cameraId, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { break; }
if (!_aidl_status.isOk()) { break; }
_aidl_ret_status = _aidl_reply->writeParcelable(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) { break; }
}
break;
case Call::CONNECT:
{
::android::sp<::android::hardware::ICameraClient> in_client;
int32_t in_cameraId;
::android::String16 in_opPackageName;
int32_t in_clientUid;
int32_t in_clientPid;
::android::sp<::android::hardware::ICamera> _aidl_return;
if (!(_aidl_data.checkInterface(this))) { _aidl_ret_status = ::android::BAD_TYPE; break; }
_aidl_ret_status = _aidl_data.readStrongBinder(&in_client);
if (((_aidl_ret_status) != (::android::OK))) { break; }
_aidl_ret_status = _aidl_data.readInt32(&in_cameraId);
if (((_aidl_ret_status) != (::android::OK))) { break; }
_aidl_ret_status = _aidl_data.readString16(&in_opPackageName);
if (((_aidl_ret_status) != (::android::OK))) { break; }
_aidl_ret_status = _aidl_data.readInt32(&in_clientUid);
if (((_aidl_ret_status) != (::android::OK))) { break; }
_aidl_ret_status = _aidl_data.readInt32(&in_clientPid);
if (((_aidl_ret_status) != (::android::OK))) { break; }
//> 连接 camera
::android::binder::Status _aidl_status(connect(in_client, in_cameraId, in_opPackageName, in_clientUid, in_clientPid, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { break; }
if (!_aidl_status.isOk()) { break; }
_aidl_ret_status = _aidl_reply->writeStrongBinder(::android::hardware::ICamera::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) { break; }
}
break;
case Call::CONNECTDEVICE: {} break;
case Call::CONNECTLEGACY: {} break;
case Call::ADDLISTENER: {} break;
case Call::REMOVELISTENER: {} break;
case Call::GETCAMERACHARACTERISTICS: {} break;
case Call::GETCAMERAVENDORTAGDESCRIPTOR: {} break;
case Call::GETCAMERAVENDORTAGCACHE: {} break;
case Call::GETLEGACYPARAMETERS: {} break;
case Call::SUPPORTSCAMERAAPI: {} break;
case Call::SETTORCHMODE: {} break;
case Call::NOTIFYSYSTEMEVENT: {} break;
default:
{
_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
}
break;
}
if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
}
return _aidl_ret_status;
}
};//> namespace
CameraService 继承 BnCameraService::onTransact()的方法,在此方法中解析处理了AIDL定义的各命令码解析处理方法;至此看到了 Binder通讯的服务端命令解析处理源码,
为压缩代码量、省略部分命令码处理的代码。
我们看到在 onTransact()命令处理中、调用的是BpCamerService的方法,头文件内容如下:
@out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_cortex-a53_shared_core/gen/aidl/android/hardware/BnCameraService.h
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <android/hardware/ICameraService.h>
namespace android {
namespace hardware {
class BpCameraService : public ::android::BpInterface<ICameraService> {
public:
explicit BpCameraService(const ::android::sp<::android::IBinder>& _aidl_impl);
virtual ~BpCameraService() = default;
::android::binder::Status getNumberOfCameras(int32_t type, int32_t* _aidl_return) override;
::android::binder::Status getCameraInfo(int32_t cameraId, ::android::hardware::CameraInfo* _aidl_return) override;
::android::binder::Status connect(const ::android::sp<::android::hardware::ICameraClient>& client, int32_t cameraId,
const ::android::String16& opPackageName, int32_t clientUid, int32_t clientPid, ::android::sp<::android::hardware::ICamera>* _aidl_return) override;
::android::binder::Status connectDevice(const ::android::sp<::android::hardware::camera2::ICameraDeviceCallbacks>& callbacks,
const ::android::String16& cameraId, const ::android::String16& opPackageName, int32_t clientUid,
::android::sp<::android::hardware::camera2::ICameraDeviceUser>* _aidl_return) override;
::android::binder::Status connectLegacy(const ::android::sp<::android::hardware::ICameraClient>& client, int32_t cameraId, int32_t halVersion,
const ::android::String16& opPackageName, int32_t clientUid, ::android::sp<::android::hardware::ICamera>* _aidl_return) override;
::android::binder::Status addListener(const ::android::sp<::android::hardware::ICameraServiceListener>& listener,
::std::vector<::android::hardware::CameraStatus>* _aidl_return) override;
::android::binder::Status removeListener(const ::android::sp<::android::hardware::ICameraServiceListener>& listener) override;
::android::binder::Status getCameraCharacteristics(const ::android::String16& cameraId, ::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) override;
::android::binder::Status getCameraVendorTagDescriptor(::android::hardware::camera2::params::VendorTagDescriptor* _aidl_return) override;
::android::binder::Status getCameraVendorTagCache(::android::hardware::camera2::params::VendorTagDescriptorCache* _aidl_return) override;
::android::binder::Status getLegacyParameters(int32_t cameraId, ::android::String16* _aidl_return) override;
::android::binder::Status supportsCameraApi(const ::android::String16& cameraId, int32_t apiVersion, bool* _aidl_return) override;
::android::binder::Status setTorchMode(const ::android::String16& cameraId, bool enabled, const ::android::sp<::android::IBinder>& clientBinder) override;
::android::binder::Status notifySystemEvent(int32_t eventId, const ::std::vector<int32_t>& args) override;
}; // class BpCameraService
} // namespace hardware
} // namespace android
BpCameraService源码实现 ICameraService虚函数内容如下:
@out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_cortex-a53_shared_core/gen/aidl/frameworks/av/camera/aidl/android/hardware/ICameraService.cpp
#include <android/hardware/BpCameraService.h>
#include <binder/Parcel.h>
namespace hardware {
BpCameraService::BpCameraService(const ::android::sp<::android::IBinder>& _aidl_impl)
: BpInterface<ICameraService>(_aidl_impl){
}
//> 获取相机数量
::android::binder::Status BpCameraService::getNumberOfCameras(int32_t type, int32_t* _aidl_return)
{
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeInt32(type);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = remote()->transact(ICameraService::GETNUMBEROFCAMERAS, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
if (!_aidl_status.isOk()) { return _aidl_status; }
_aidl_ret_status = _aidl_reply.readInt32(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
//> 获取相机信息
::android::binder::Status BpCameraService::getCameraInfo(int32_t cameraId, ::android::hardware::CameraInfo* _aidl_return)
{
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error;}
_aidl_ret_status = _aidl_data.writeInt32(cameraId);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = remote()->transact(ICameraService::GETCAMERAINFO, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
if (!_aidl_status.isOk()) { return _aidl_status; }
_aidl_ret_status = _aidl_reply.readParcelable(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
//> 连接 camera
::android::binder::Status BpCameraService::connect(const ::android::sp<::android::hardware::ICameraClient>& client, int32_t cameraId,
const ::android::String16& opPackageName, int32_t clientUid, int32_t clientPid, ::android::sp<::android::hardware::ICamera>* _aidl_return)
{
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeStrongBinder(::android::hardware::ICameraClient::asBinder(client));
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeInt32(cameraId);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeString16(opPackageName);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeInt32(clientUid);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_data.writeInt32(clientPid);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = remote()->transact(ICameraService::CONNECT, _aidl_data, &_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
if (!_aidl_status.isOk()) { return _aidl_status; }
_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) { goto _aidl_error; }
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
....... //> 省略很多内容
} // namespace hardware
CameraService 在一次调用作为Binder客户端接口、获取Camera的 getNumberOfCameras、connect 和 getCameraInfo的结果,这是怎么回事呢?
我们从上一篇内容知道CameraService与CameraProvider也是通过Binder方式通讯的、很容易推测处、这是与 CameraProvider 服务端进行通讯。
ICameraService接口中命令编码和虚函数接口定义如下:
@out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_cortex-a53_shared_core/
gen/aidl/android/hardware/ICameraService.h
namespace hardware {
class ICameraService : public ::android::IInterface {
public:
DECLARE_META_INTERFACE(CameraService)
enum : int32_t {
ERROR_PERMISSION_DENIED = 1,
ERROR_ALREADY_EXISTS = 2,
ERROR_ILLEGAL_ARGUMENT = 3,
ERROR_DISCONNECTED = 4,
ERROR_TIMED_OUT = 5,
ERROR_DISABLED = 6,
ERROR_CAMERA_IN_USE = 7,
ERROR_MAX_CAMERAS_IN_USE = 8,
ERROR_DEPRECATED_HAL = 9,
ERROR_INVALID_OPERATION = 10,
CAMERA_TYPE_BACKWARD_COMPATIBLE = 0,
CAMERA_TYPE_ALL = 1,
USE_CALLING_UID = -1,
USE_CALLING_PID = -1,
CAMERA_HAL_API_VERSION_UNSPECIFIED = -1,
API_VERSION_1 = 1,
API_VERSION_2 = 2,
EVENT_NONE = 0,
EVENT_USER_SWITCHED = 1,
};
virtual ::android::binder::Status getNumberOfCameras(int32_t type, int32_t* _aidl_return) = 0;
virtual ::android::binder::Status getCameraInfo(int32_t cameraId, ::android::hardware::CameraInfo* _aidl_return) = 0;
virtual ::android::binder::Status connect(const ::android::sp<::android::hardware::ICameraClient>& client, int32_t cameraId,
const ::android::String16& opPackageName, int32_t clientUid, int32_t clientPid, ::android::sp<::android::hardware::ICamera>* _aidl_return) = 0;
virtual ::android::binder::Status connectDevice(const ::android::sp<::android::hardware::camera2::ICameraDeviceCallbacks>& callbacks,
const ::android::String16& cameraId, const ::android::String16& opPackageName, int32_t clientUid,
::android::sp<::android::hardware::camera2::ICameraDeviceUser>* _aidl_return) = 0;
virtual ::android::binder::Status connectLegacy(const ::android::sp<::android::hardware::ICameraClient>& client, int32_t cameraId,
int32_t halVersion, const ::android::String16& opPackageName, int32_t clientUid, ::android::sp<::android::hardware::ICamera>* _aidl_return) = 0;
virtual ::android::binder::Status addListener(const ::android::sp<::android::hardware::ICameraServiceListener>& listener,
::std::vector<::android::hardware::CameraStatus>* _aidl_return) = 0;
virtual ::android::binder::Status removeListener(const ::android::sp<::android::hardware::ICameraServiceListener>& listener) = 0;
virtual ::android::binder::Status getCameraCharacteristics(const ::android::String16& cameraId,
::android::hardware::camera2::impl::CameraMetadataNative* _aidl_return) = 0;
virtual ::android::binder::Status getCameraVendorTagDescriptor(::android::hardware::camera2::params::VendorTagDescriptor* _aidl_return) = 0;
virtual ::android::binder::Status getCameraVendorTagCache(::android::hardware::camera2::params::VendorTagDescriptorCache* _aidl_return) = 0;
virtual ::android::binder::Status getLegacyParameters(int32_t cameraId, ::android::String16* _aidl_return) = 0;
virtual ::android::binder::Status supportsCameraApi(const ::android::String16& cameraId, int32_t apiVersion, bool* _aidl_return) = 0;
virtual ::android::binder::Status setTorchMode(const ::android::String16& cameraId, bool enabled, const ::android::sp<::android::IBinder>& clientBinder) = 0;
virtual ::android::binder::Status notifySystemEvent(int32_t eventId, const ::std::vector<int32_t>& args) = 0;
enum Call {
GETNUMBEROFCAMERAS = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
GETCAMERAINFO = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
CONNECT = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
CONNECTDEVICE = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
CONNECTLEGACY = ::android::IBinder::FIRST_CALL_TRANSACTION + 4,
ADDLISTENER = ::android::IBinder::FIRST_CALL_TRANSACTION + 5,
REMOVELISTENER = ::android::IBinder::FIRST_CALL_TRANSACTION + 6,
GETCAMERACHARACTERISTICS = ::android::IBinder::FIRST_CALL_TRANSACTION + 7,
GETCAMERAVENDORTAGDESCRIPTOR = ::android::IBinder::FIRST_CALL_TRANSACTION + 8,
GETCAMERAVENDORTAGCACHE = ::android::IBinder::FIRST_CALL_TRANSACTION + 9,
GETLEGACYPARAMETERS = ::android::IBinder::FIRST_CALL_TRANSACTION + 10,
SUPPORTSCAMERAAPI = ::android::IBinder::FIRST_CALL_TRANSACTION + 11,
SETTORCHMODE = ::android::IBinder::FIRST_CALL_TRANSACTION + 12,
NOTIFYSYSTEMEVENT = ::android::IBinder::FIRST_CALL_TRANSACTION + 13,
};
}; // class ICameraService
} // namespace hardware
ICameraService 继承 android::IInterface 接口类; CameraService 继承 BnCameraService 类,而BnCameraService继承BnInterface类;
为进一步捋顺Binder通讯部分内容,我们在追踪一下关系,看看他们定义,内容如下:
@frameworks/native/include/binder/IInterface.h 内容如下:
#include <binder/Binder.h>
namespace android {
// ----------------------------------------------------------------------
class IInterface : public virtual RefBase
{
public:
IInterface();
static sp<IBinder> asBinder(const IInterface*);
static sp<IBinder> asBinder(const sp<IInterface>&);
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
// ----------------------------------------------------------------------
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
// ----------------------------------------------------------------------
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
// ----------------------------------------------------------------------
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
// ----------------------------------------------------------------------
#define DECLARE_META_INTERFACE(INTERFACE) \
static const ::android::String16 descriptor; \
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const ::android::String16 I##INTERFACE::descriptor(NAME); \
const ::android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
#define CHECK_INTERFACE(interface, data, reply) \
if (!(data).checkInterface(this)) { return PERMISSION_DENIED; } \
// ----------------------------------------------------------------------
// No user-serviceable parts after this...
template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
const String16& _descriptor)
{
if (_descriptor == INTERFACE::descriptor) return this;
return NULL;
}
template<typename INTERFACE>
inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const
{
return INTERFACE::getInterfaceDescriptor();
}
template<typename INTERFACE>
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
return this;
}
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
template<typename INTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
return remote();
}
至此、还需要看看 BBinder 和 BpRefBase 的定义,关系就梳理清晰了。内容如下:
源码路径 @frameworks/native/include/binder/Binder.h
class BBinder : public IBinder
{
public:
BBinder();
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0);
virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);
virtual void attachObject( const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func);
virtual void* findObject(const void* objectID) const;
virtual void detachObject(const void* objectID);
virtual BBinder* localBinder();
protected:
virtual ~BBinder();
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
private:
BBinder(const BBinder& o);
BBinder& operator=(const BBinder& o);
class Extras;
std::atomic<Extras*> mExtras;
void* mReserved0;
};
// ---------------------------------------------------------------------------
class BpRefBase : public virtual RefBase
{
protected:
explicit BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
inline IBinder* remote() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
std::atomic<int32_t> mState;
};
源码路径 @frameworks/native/include/binder/BpBinder.h
#include <binder/IBinder.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>
// ---------------------------------------------------------------------------
namespace android {
class BpBinder : public IBinder
{
public:
BpBinder(int32_t handle);
inline int32_t handle() const { return mHandle; }
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0);
virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);
virtual void attachObject( const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func);
virtual void* findObject(const void* objectID) const;
virtual void detachObject(const void* objectID);
virtual BpBinder* remoteBinder();
status_t setConstantData(const void* data, size_t size);
void sendObituary();
class ObjectManager
{
public:
ObjectManager();
~ObjectManager();
void attach( const void* objectID,
void* object,
void* cleanupCookie,
IBinder::object_cleanup_func func);
void* find(const void* objectID) const;
void detach(const void* objectID);
void kill();
private:
ObjectManager(const ObjectManager&);
ObjectManager& operator=(const ObjectManager&);
struct entry_t
{
void* object;
void* cleanupCookie;
IBinder::object_cleanup_func func;
};
KeyedVector<const void*, entry_t> mObjects;
};
protected:
virtual ~BpBinder();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
private:
const int32_t mHandle;
struct Obituary {
wp<DeathRecipient> recipient;
void* cookie;
uint32_t flags;
};
void reportOneDeath(const Obituary& obit);
bool isDescriptorCached() const;
mutable Mutex mLock;
volatile int32_t mAlive;
volatile int32_t mObitsSent;
Vector<Obituary>* mObituaries;
ObjectManager mObjects;
Parcel* mConstantData;
mutable String16 mDescriptorCache;
};
}; // namespace android
与 Binder 架构相关类的继承关系、至此就是关联起来了。
用户 APP 导入 frameworks中的android.hardware.Camera1 类、该类调用 android_hardware_Camera.cpp 中的注册的 JNI 本地方法;
android_hardware_Camera.cpp 封装的本地方法就是 libcamera_client.so 库的接口方法,所以用户App是 CameraClient 发起端。
用户 App 如使用系统的 android.hardware.Camera 功能,需要导入类 Camera.java包或者是基于Camera类做二次封装 ,
源码摘录如下:
@frameworks/base/core/java/android/hardware/Camera.java
private int cameraInitVersion(int cameraId, int halVersion) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mUsingPreviewAllocation = false;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
ActivityThread.currentOpPackageName());
}
private int cameraInitNormal(int cameraId) {
return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
//> native method
private native final int native_setup(Object camera_this, int cameraId, int halVersion,
String packageName);
可见 Camera.java 中调用了 JNI 封装的本地方法,native_setup() 源码内容如下:
@frameworks/base/core/jni/android_hardware_Camera.cpp
//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
{ "getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "_getCameraInfo",
"(ILandroid/hardware/Camera$CameraInfo;)V",
(void*)android_hardware_Camera_getCameraInfo },
{ "native_setup",
"(Ljava/lang/Object;IILjava/lang/String;)I",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
(void*)android_hardware_Camera_release },
{ "setPreviewSurface",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewSurface },
{ "startPreview",
"()V",
(void *)android_hardware_Camera_startPreview },
{ "_stopPreview",
"()V",
(void *)android_hardware_Camera_stopPreview },
{ "previewEnabled",
"()Z",
(void *)android_hardware_Camera_previewEnabled },
{ "setHasPreviewCallback",
"(ZZ)V",
(void *)android_hardware_Camera_setHasPreviewCallback },
{ "_addCallbackBuffer",
"([BI)V",
(void *)android_hardware_Camera_addCallbackBuffer },
{ "native_autoFocus",
"()V",
(void *)android_hardware_Camera_autoFocus },
{ "native_cancelAutoFocus",
"()V",
(void *)android_hardware_Camera_cancelAutoFocus },
{ "native_takePicture",
"(I)V",
(void *)android_hardware_Camera_takePicture },
{ "native_setParameters",
"(Ljava/lang/String;)V",
(void *)android_hardware_Camera_setParameters },
{ "native_getParameters",
"()Ljava/lang/String;",
(void *)android_hardware_Camera_getParameters },
{ "reconnect",
"()V",
(void*)android_hardware_Camera_reconnect },
{ "lock",
"()V",
(void*)android_hardware_Camera_lock },
{ "unlock",
"()V",
(void*)android_hardware_Camera_unlock },
{ "startSmoothZoom",
"(I)V",
(void *)android_hardware_Camera_startSmoothZoom },
{ "stopSmoothZoom",
"()V",
(void *)android_hardware_Camera_stopSmoothZoom },
{ "setDisplayOrientation",
"(I)V",
(void *)android_hardware_Camera_setDisplayOrientation },
{ "_enableShutterSound",
"(Z)Z",
(void *)android_hardware_Camera_enableShutterSound },
{ "_startFaceDetection",
"(I)V",
(void *)android_hardware_Camera_startFaceDetection },
{ "_stopFaceDetection",
"()V",
(void *)android_hardware_Camera_stopFaceDetection},
{ "enableFocusMoveCallback",
"(I)V",
(void *)android_hardware_Camera_enableFocusMoveCallback},
};
//> "native_setup", connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
// Convert jstring to String16
const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
env->GetStringChars(clientPackageName, NULL));
jsize rawClientNameLen = env->GetStringLength(clientPackageName);
String16 clientName(rawClientName, rawClientNameLen);
env->ReleaseStringChars(clientPackageName,
reinterpret_cast<const jchar*>(rawClientName));
sp<Camera> camera; //> CameraClient
if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
// Default path: hal version is don't care, do normal camera connect.
camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
} else {
jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
Camera::USE_CALLING_UID, camera);
if (status != NO_ERROR) {
return status;
}
}
if (camera == NULL) {
return -EACCES;
}
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
return NO_INIT;
}
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
// This should never happen
jniThrowRuntimeException(env, "Can't find android/hardware/Camera");
return INVALID_OPERATION;
}
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
// save context in opaque field
env->SetLongField(thiz, fields.context, (jlong)context.get());
// Update default display orientation in case the sensor is reverse-landscape
CameraInfo cameraInfo;
status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo);
if (rc != NO_ERROR) {
return rc;
}
int defaultOrientation = 0;
switch (cameraInfo.orientation) {
case 0:
break;
case 90:
if (cameraInfo.facing == CAMERA_FACING_FRONT) {
defaultOrientation = 180;
}
break;
case 180:
defaultOrientation = 180;
break;
case 270:
if (cameraInfo.facing != CAMERA_FACING_FRONT) {
defaultOrientation = 180;
}
break;
default:
ALOGE("Unexpected camera orientation %d!", cameraInfo.orientation);
break;
}
if (defaultOrientation != 0) {
ALOGV("Setting default display orientation to %d", defaultOrientation);
rc = camera->sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION,
defaultOrientation, 0);
if (rc != NO_ERROR) {
ALOGE("Unable to update default orientation: %s (%d)",
strerror(-rc), rc);
return rc;
}
}
return NO_ERROR;
}
JNI封装函数调用 libcamera_client.so 库中的方法 connect 和 connectLegacy 方法,内容如下:
Camera::Camera(int cameraId)
: CameraBase(cameraId)
{
}
CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
&::android::hardware::ICameraService::connect;
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid, int clientPid)
{
return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
status_t Camera::connectLegacy(int cameraId, int halVersion,
const String16& clientPackageName,
int clientUid,
sp<Camera>& camera)
{
ALOGV("%s: connect legacy camera device", __FUNCTION__);
sp<Camera> c = new Camera(cameraId);
sp<::android::hardware::ICameraClient> cl = c;
status_t status = NO_ERROR;
const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService();
binder::Status ret;
if (cs != nullptr) {
ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
clientUid, /*out*/&(c->mCamera));
}
if (ret.isOk() && c->mCamera != nullptr) {
IInterface::asBinder(c->mCamera)->linkToDeath(c);
c->mStatus = NO_ERROR;
camera = c;
} else {
switch(ret.serviceSpecificErrorCode()) {
case hardware::ICameraService::ERROR_DISCONNECTED:
status = -ENODEV;
break;
case hardware::ICameraService::ERROR_CAMERA_IN_USE:
status = -EBUSY;
break;
case hardware::ICameraService::ERROR_INVALID_OPERATION:
status = -EINVAL;
break;
case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
status = -EUSERS;
break;
case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
status = BAD_VALUE;
break;
case hardware::ICameraService::ERROR_DEPRECATED_HAL:
status = -EOPNOTSUPP;
break;
case hardware::ICameraService::ERROR_DISABLED:
status = -EACCES;
break;
case hardware::ICameraService::ERROR_PERMISSION_DENIED:
status = PERMISSION_DENIED;
break;
default:
status = -EINVAL;
ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
(cs != nullptr) ? "Service not available" : ret.toString8().string());
break;
}
c.clear();
}
return status;
}
由此我们知道 Camera.java 中调用 camera JNI接口、而 Camera JNI 封装了 libcamera_client.so 库中接口, libcamera_client 通过 Binder 调用 CameraServer 的接口内容,
CameraServer 在通过 Binder 通讯 调用 CameraProvider 服务接口,CameraProvider 通过 v4l2_camera_HAL 模块接口、调用内核的 v4l2 摄像头管理框架实现管理物理摄像头。
至此就把 CameraClient 与 CameraServer 之间通讯逻辑就描述清晰了.
从 App 编程的角度看, 如何使用 android camera API2 接口使用摄像头的呢?为了控制本篇内容量,
把这个内容放到下一篇《虚拟摄像头之八:从 Camera api2 角度看摄像头框架》文章中梳理,期待你的阅读。