我们平时开发,知道怎么调度api,怎么调起camera,怎么调用camera的实例来操作camera就可以了,但是这些调度的背后都做了什么事情,我们可能不太清楚,本文打算从openCamera这个调用谈起,展开说下camera调起之后底层是怎么工作的?

Camera操作过程中最重要的四个步骤:

CameraManager-->openCamera ---> 打开相机

CameraDeviceImpl-->createCaptureSession ---> 创建捕获会话

CameraCaptureSession-->setRepeatingRequest ---> 设置预览界面

CameraDeviceImpl-->capture ---> 开始捕获图片

1.CameraManager

CameraManager是本地的SystemService集合中一个service,在SystemServiceRegistry中注册:

registerService(Context.CAMERA_SERVICE, CameraManager.class,

new CachedServiceFetcher() {

@Override

public CameraManager createService(ContextImpl ctx) {

return new CameraManager(ctx);

}});

SystemServiceRegistry中有两个HashMap集合来存储本地的SystemService数据,有一点要注意点一些,这和Binder的service不同,他们不是binder service,只是普通的调用模块,集成到一个本地service中,便于管理。

private static final HashMap, String> SYSTEM_SERVICE_NAMES =

new HashMap, String>();

private static final HashMap> SYSTEM_SERVICE_FETCHERS =

new HashMap>();

2.openCamera函数

CameraManager中两个openCamera(...),只是一个传入Handler,一个传入Executor,是想用线程池来执行Camera中耗时操作。

public void openCamera(@NonNull String cameraId,

@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)

public void openCamera(@NonNull String cameraId,

@NonNull @CallbackExecutor Executor executor,

@NonNull final CameraDevice.StateCallback callback)

cameraId 是一个标识,标识当前要打开的camera

callback 是一个状态回调,当前camera被打开的时候,这个状态回调会被触发的。

handler 是传入的一个执行耗时操作的handler

executor 操作线程池

了解一下openCamera的调用流程:

openCamera流程.jpg

2.1 openCameraDeviceUserAsync函数

private CameraDevice openCameraDeviceUserAsync(String cameraId,

CameraDevice.StateCallback callback, Executor executor, final int uid)

throws CameraAccessException

{

//......

}

返回值是CameraDevice,从《Android Camera模块解析之拍照》中讲解了Camera framework模块中主要类之间的关系,CameraDevice是抽象类,CameraDeviceImpl是其实现类,就是要获取CameraDeviceImpl的实例。

这个函数的主要作用就是到底层获取相机设备的信息,并获取当前指定cameraId的设备实例。

本函数的主要工作可以分为下面五点:

获取当前cameraId指定相机的设备信息

利用获取相机的设备信息创建CameraDeviceImpl实例

调用远程CameraService获取当前相机的远程服务

将获取的远程服务设置到CameraDeviceImpl实例中

返回CameraDeviceImpl实例

2.2 获取当前cameraId指定相机的设备信息

CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);

一句简单的调用,返回值是CameraCharacteristics,CameraCharacteristics提供了CameraDevice的各种属性,可以通过getCameraCharacteristics函数来查询。

public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)

throws CameraAccessException {

CameraCharacteristics characteristics = null;

if (CameraManagerGlobal.sCameraServiceDisabled) {

throw new IllegalArgumentException("No cameras available on device");

}

synchronized (mLock) {

ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

if (cameraService == null) {

throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,

"Camera service is currently unavailable");

}

try {

if (!supportsCamera2ApiLocked(cameraId)) {

int id = Integer.parseInt(cameraId);

String parameters = cameraService.getLegacyParameters(id);

CameraInfo info = cameraService.getCameraInfo(id);

characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info);

} else {

CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);

characteristics = new CameraCharacteristics(info);

}

} catch (ServiceSpecificException e) {

throwAsPublicException(e);

} catch (RemoteException e) {

throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,

"Camera service is currently unavailable", e);

}

}

return characteristics;

}

一个关键的函数----> supportsCamera2ApiLocked(cameraId),这个函数的意思是 当前camera服务是否支持camera2 api,如果支持,返回true,如果不支持,返回false。

private boolean supportsCameraApiLocked(String cameraId, int apiVersion) {

/*

* Possible return values:

* - NO_ERROR => CameraX API is supported

* - CAMERA_DEPRECATED_HAL => CameraX API is *not* supported (thrown as an exception)

* - Remote exception => If the camera service died

*

* Anything else is an unexpected error we don't want to recover from.

*/

try {

ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

// If no camera service, no support

if (cameraService == null) return false;

return cameraService.supportsCameraApi(cameraId, apiVersion);

} catch (RemoteException e) {

// Camera service is now down, no support for any API level

}

return false;

}

调用的CameraService对应的是ICameraService.aidl,对应的实现类在frameworks/av/services/camera/libcameraservice/CameraService.h

下面是CameraManager与CameraService之间的连接关系图示:

CameraService生成.jpg

CameraManagerGlobal是CameraManager中的内部类,服务端在native层,《Android Camera模块解析之拍照》中camera2介绍的时候已经说明了当前cameraservice是放在frameworks/av/services/camera/libcameraservice/中的,编译好了之后会生成一个libcameraservices.so的共享库。熟悉camera代码,首先应该熟悉camera架构的代码。

这儿监测的是当前camera架构是基于HAL什么版本的,看下面的switch判断:

当前device是基于HAL1.0 HAL3.0 HAL3.1,并且apiversion不是API_VERSION_2,此时支持,这里要搞清楚了,这里的API_VERSION_2不是api level 2,而是camera1还是camera2.

当前device是基于HAL3.2 HAL3.3 HAL3.4,此时支持

目前android版本,正常情况下都是支持camera2的

Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,

/*out*/ bool *isSupported) {

ATRACE_CALL();

const String8 id = String8(cameraId);

ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());

switch (apiVersion) {

case API_VERSION_1:

case API_VERSION_2:

break;

default:

String8 msg = String8::format("Unknown API version %d", apiVersion);

ALOGE("%s: %s", __FUNCTION__, msg.string());

return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());

}

int deviceVersion = getDeviceVersion(id);

switch(deviceVersion) {

case CAMERA_DEVICE_API_VERSION_1_0:

case CAMERA_DEVICE_API_VERSION_3_0:

case CAMERA_DEVICE_API_VERSION_3_1:

if (apiVersion == API_VERSION_2) {

ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",

__FUNCTION__, id.string(), deviceVersion);

*isSupported = false;

} else { // if (apiVersion == API_VERSION_1) {

ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",

__FUNCTION__, id.string());

*isSupported = true;

}

break;

case CAMERA_DEVICE_API_VERSION_3_2:

case CAMERA_DEVICE_API_VERSION_3_3:

case CAMERA_DEVICE_API_VERSION_3_4:

ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",

__FUNCTION__, id.string());

*isSupported = true;

break;

case -1: {

String8 msg = String8::format("Unknown camera ID %s", id.string());

ALOGE("%s: %s", __FUNCTION__, msg.string());

return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());

}

default: {

String8 msg = String8::format("Unknown device version %x for device %s",

deviceVersion, id.string());

ALOGE("%s: %s", __FUNCTION__, msg.string());

return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());

}

}

return Status::ok();

}

采用camera2 api来获取相机设备的信息。

CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);

characteristics = new CameraCharacteristics(info);

getCameraCharacteristics调用流程.jpg

其中DeviceInfo3是CameraProviderManager::ProviderInfo::DeviceInfo3,CameraProviderManager中的结构体,最终返回的是CameraMetadata类型,它是一个Parcelable类型,native中对应的代码是frameworks/av/camera/include/camera/CameraMetadata.h,java中对应的是frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java,Parcelable类型是可以跨进程传输的。下面是在native中定义CameraMetadata为CameraMetadataNative

namespace hardware {

namespace camera2 {

namespace impl {

using ::android::CameraMetadata;

typedef CameraMetadata CameraMetadataNative;

}

}

}

我们关注其中的一个调用函数:

status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,

CameraMetadata* characteristics) const {

auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});

if (deviceInfo == nullptr) return NAME_NOT_FOUND;

return deviceInfo->getCameraCharacteristics(characteristics);

}

发现了调用了一个findDeviceInfoLocked(...)函数,返回类型是一个DeviceInfo结构体,CameraProviderManager.h中定义了三个DeviceInfo结构体,除了DeviceInfo之外,还有DeviceInfo1与DeviceInfo3,他们都继承DeviceInfo,其中DeviceInfo1为HALv1服务,DeviceInfo3为HALv3-specific服务,都是提供camera device一些基本信息。这里主要看下findDeviceInfoLocked(...)函数:

CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(

const std::string& id,

hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {

for (auto& provider : mProviders) {

for (auto& deviceInfo : provider->mDevices) {

if (deviceInfo->mId == id &&

minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {

return deviceInfo.get();

}

}

}

return nullptr;

}

这儿的是mProviders是ProviderInfo类型的列表,这个ProviderInfo也是CameraProviderManager.h中定义的结构体,并且上面3种DeviceInfo都是定义在ProviderInfo里面的。下面给出了ProviderInfo的代码大纲,裁剪了很多代码,但是我们还是能看到核心的代码:ProviderInfo是管理当前手机的camera device设备的,通过addDevice保存在mDevices中,接下来我们看下这个addDevice是如何工作的。

struct ProviderInfo :

virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,

virtual public hardware::hidl_death_recipient

{

//......

ProviderInfo(const std::string &providerName,

sp<:camera::provider::v2_4::icameraprovider>& interface,

CameraProviderManager *manager);

~ProviderInfo();

status_t initialize();

const std::string& getType() const;

status_t addDevice(const std::string& name,

hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =

hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,

/*out*/ std::string *parsedId = nullptr);

// ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex

virtual hardware::Return cameraDeviceStatusChange(

const hardware::hidl_string& cameraDeviceName,

hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;

virtual hardware::Return torchModeStatusChange(

const hardware::hidl_string& cameraDeviceName,

hardware::camera::common::V1_0::TorchModeStatus newStatus) override;

// hidl_death_recipient interface - this locks the parent mInterfaceMutex

virtual void serviceDied(uint64_t cookie, const wp<:base::v1_0::ibase>& who) override;

// Basic device information, common to all camera devices

struct DeviceInfo {

//......

};

std::vector<:unique_ptr>> mDevices;

std::unordered_set<:string> mUniqueCameraIds;

int mUniqueDeviceCount;

// HALv1-specific camera fields, including the actual device interface

struct DeviceInfo1 : public DeviceInfo {

//......

};

// HALv3-specific camera fields, including the actual device interface

struct DeviceInfo3 : public DeviceInfo {

//......

};

private:

void removeDevice(std::string id);

};

mProviders是如何添加的?

addDevice是如何工作的?

mProviders添加的流程:

1.CameraService --> onFirstRef()

2.CameraService --> enumerateProviders()

3.CameraProviderManager --> initialize(this)

initialize(...)函数原型是:

status_t initialize(wp listener,

ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);

第2个参数默认是sHardwareServiceInteractionProxy类型,

struct ServiceInteractionProxy {

virtual bool registerForNotifications(

const std::string &serviceName,

const sp<:manager::v1_0::iservicenotification>

&notification) = 0;

virtual sp<:camera::provider::v2_4::icameraprovider> getService(

const std::string &serviceName) = 0;

virtual ~ServiceInteractionProxy() {}

};

// Standard use case - call into the normal generated static methods which invoke

// the real hardware service manager

struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {

virtual bool registerForNotifications(

const std::string &serviceName,

const sp<:manager::v1_0::iservicenotification>

&notification) override {

return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(

serviceName, notification);

}

virtual sp<:camera::provider::v2_4::icameraprovider> getService(

const std::string &serviceName) override {

return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);

}

};

hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName)出处在./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp,传入的参数可能是下面两种的一个:

const std::string kLegacyProviderName("legacy/0"); 代表 HALv1

const std::string kExternalProviderName("external/0"); 代码HALv3-specific

ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {

if (strcmp(name, kLegacyProviderName) == 0) {

CameraProvider* provider = new CameraProvider();

if (provider == nullptr) {

ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);

return nullptr;

}

if (provider->isInitFailed()) {

ALOGE("%s: camera provider init failed!", __FUNCTION__);

delete provider;

return nullptr;

}

return provider;

} else if (strcmp(name, kExternalProviderName) == 0) {

ExternalCameraProvider* provider = new ExternalCameraProvider();

return provider;

}

ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);

return nullptr;

}

addDevice是如何工作的?

1.CameraProviderManager::ProviderInfo::initialize()初始化的时候是检查当前的camera device,检查的执行函数是:

std::vector<:string> devices;

hardware::Return ret = mInterface->getCameraIdList([&status, &devices](

Status idStatus,

const hardware::hidl_vec<:hidl_string>& cameraDeviceNames) {

status = idStatus;

if (status == Status::OK) {

for (size_t i = 0; i < cameraDeviceNames.size(); i++) {

devices.push_back(cameraDeviceNames[i]);

}

} });

最终调用到./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp中的getCameraIdList函数:CAMERA_DEVICE_STATUS_PRESENT表明当前的camera是可用的,mCameraStatusMap存储了所有的camera 设备列表。

Return CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {

std::vector deviceNameList;

for (auto const& deviceNamePair : mCameraDeviceNames) {

if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {

deviceNameList.push_back(deviceNamePair.second);

}

}

hidl_vec hidlDeviceNameList(deviceNameList);

_hidl_cb(Status::OK, hidlDeviceNameList);

return Void();

}

我们理一下整体的调用结构:

Camera分层体系.jpg

1.上面谈的camera2 api就是在framework层的,在应用程序进程中。

2.CameraService,是camera2 api binder IPC通信方式调用到服务端的,camera相关的操作都在在服务端进行。所在的位置就是./frameworks/av/services/camera/下面

3.服务端也只是一个桥梁,service也会调用到HAL,硬件抽象层,具体位置在./hardware/interfaces/camera/provider/2.4

4.camera driver,底层的驱动层了,这是真正操作硬件的地方。

2.3 利用获取相机的设备信息创建CameraDeviceImpl实例

android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =

new android.hardware.camera2.impl.CameraDeviceImpl(

cameraId,

callback,

executor,

characteristics,

mContext.getApplicationInfo().targetSdkVersion);

创建CameraDevice实例,传入了刚刚获取的characteristics参数(camera设备信息赋值为CameraDevice实例)。这个实例接下来还是使用,使用的时候再谈一下。

2.4 调用远程CameraService获取当前相机的远程服务

// Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices

ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

if (cameraService == null) {

throw new ServiceSpecificException(

ICameraService.ERROR_DISCONNECTED,

"Camera service is currently unavailable");

}

cameraUser = cameraService.connectDevice(callbacks, cameraId,

mContext.getOpPackageName(), uid);

这个函数的主要目的就是连接当前的cameraDevice设备。调用到CameraService::connectDevice中。

connectDevice调用流程.jpg

Status CameraService::connectDevice(

const sp<:camera2::icameradevicecallbacks>& cameraCb,

const String16& cameraId,

const String16& clientPackageName,

int clientUid,

/*out*/

sp<:camera2::icameradeviceuser>* device) {

ATRACE_CALL();

Status ret = Status::ok();

String8 id = String8(cameraId);

sp client = nullptr;

ret = connectHelper<:camera2::icameradevicecallbacks>(cameraCb, id,

/*api1CameraId*/-1,

CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,

clientUid, USE_CALLING_PID, API_2,

/*legacyMode*/ false, /*shimUpdateOnly*/ false,

/*out*/client);

if(!ret.isOk()) {

logRejected(id, getCallingPid(), String8(clientPackageName),

ret.toString8());

return ret;

}

*device = client;

return ret;

}

connectDevice函数的第5个参数就是当前binder ipc的返回值,我们connectDevice之后,会得到一个cameraDeviceClient对象,这个对象会返回到应用程序进程中。我们接下来主要看看这个对象是如何生成的。

validateConnectLocked:检查当前的camera device是否可用,这儿的判断比较简单,只是简单判断当前设备是否存在。

handleEvictionsLocked:处理camera独占情况,主要的工作是当前的cameradevice如果已经被其他的设备使用了,或者是否有比当前调用优先级更高的调用等等,在执行完这个函数之后,才能完全判断当前的camera device是可用的,并且开始获取camera device的一些信息开始工作了。

CameraFlashlight-->prepareDeviceOpen:此时准备连接camera device 了,需要判断一下如果当前的camera device有可用的flashlight,那就要开始准备好了,但是flashlight被占用的那就没有办法了。只是一个通知作用。

getDeviceVersion:判断一下当前的camera device的version 版本,主要判断在CameraProviderManager::getHighestSupportedVersion函数中,这个函数中将camera device支持的最高和最低版本查清楚,然后我们判断当前的camera facing,只有两种情况CAMERA_FACING_BACK = 0与CAMERA_FACING_FRONT = 1,这些都是先置判断条件,只有这些检查都通过,说明当前camera device是确实可用的。

makeClient:是根据当前的CAMERA_DEVICE_API_VERSION来判断的,当前最新的HAL架构都是基于HALv3的,所以我们采用的client都是CameraDeviceClient

Status CameraService::makeClient(const sp& cameraService,

const sp& cameraCb, const String16& packageName, const String8& cameraId,

int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,

bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,

/*out*/sp* client) {

if (halVersion < 0 || halVersion == deviceVersion) {

// Default path: HAL version is unspecified by caller, create CameraClient

// based on device version reported by the HAL.

switch(deviceVersion) {

case CAMERA_DEVICE_API_VERSION_1_0:

if (effectiveApiLevel == API_1) { // Camera1 API route

sp tmp = static_cast(cameraCb.get());

*client = new CameraClient(cameraService, tmp, packageName,

api1CameraId, facing, clientPid, clientUid,

getpid(), legacyMode);

} else { // Camera2 API route

ALOGW("Camera using old HAL version: %d", deviceVersion);

return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,

"Camera device \"%s\" HAL version %d does not support camera2 API",

cameraId.string(), deviceVersion);

}

break;

case CAMERA_DEVICE_API_VERSION_3_0:

case CAMERA_DEVICE_API_VERSION_3_1:

case CAMERA_DEVICE_API_VERSION_3_2:

case CAMERA_DEVICE_API_VERSION_3_3:

case CAMERA_DEVICE_API_VERSION_3_4:

if (effectiveApiLevel == API_1) { // Camera1 API route

sp tmp = static_cast(cameraCb.get());

*client = new Camera2Client(cameraService, tmp, packageName,

cameraId, api1CameraId,

facing, clientPid, clientUid,

servicePid, legacyMode);

} else { // Camera2 API route

sp<:camera2::icameradevicecallbacks> tmp =

static_cast<:camera2::icameradevicecallbacks>(cameraCb.get());

*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,

facing, clientPid, clientUid, servicePid);

}

break;

default:

// Should not be reachable

ALOGE("Unknown camera device HAL version: %d", deviceVersion);

return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,

"Camera device \"%s\" has unknown HAL version %d",

cameraId.string(), deviceVersion);

}

} else {

// A particular HAL version is requested by caller. Create CameraClient

// based on the requested HAL version.

if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&

halVersion == CAMERA_DEVICE_API_VERSION_1_0) {

// Only support higher HAL version device opened as HAL1.0 device.

sp tmp = static_cast(cameraCb.get());

*client = new CameraClient(cameraService, tmp, packageName,

api1CameraId, facing, clientPid, clientUid,

servicePid, legacyMode);

} else {

// Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.

ALOGE("Invalid camera HAL version %x: HAL %x device can only be"

" opened as HAL %x device", halVersion, deviceVersion,

CAMERA_DEVICE_API_VERSION_1_0);

return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,

"Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",

cameraId.string(), deviceVersion, halVersion);

}

}

return Status::ok();

}

CameraClient.jpg

CameraClient与Camera2Client是之前系统版本使用的camera client对象,现在都使用CameraDeviceClient了

BnCamera --> ./frameworks/av/camera/include/camera/android/hardware/ICamera.h

ICamera --> ./frameworks/av/camera/include/camera/android/hardware/ICamera.h

BnCameraDeviceUser --> android/hardware/camera2/BnCameraDeviceUser.h 这是ICameraDeviceUser.aidl自动生成的binder 对象。所以最终得到的client对象就是ICameraDeviceUser.Stub对象。

2.5 将获取的远程服务设置到CameraDeviceImpl实例中

deviceImpl.setRemoteDevice(cameraUser);

device = deviceImpl;

这个cameraUser就是cameraservice端设置的ICameraDeviceUser.Stub对象,

public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {

synchronized(mInterfaceLock) {

// TODO: Move from decorator to direct binder-mediated exceptions

// If setRemoteFailure already called, do nothing

if (mInError) return;

mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);

IBinder remoteDeviceBinder = remoteDevice.asBinder();

// For legacy camera device, remoteDevice is in the same process, and

// asBinder returns NULL.

if (remoteDeviceBinder != null) {

try {

remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);

} catch (RemoteException e) {

CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);

throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,

"The camera device has encountered a serious error");

}

}

mDeviceExecutor.execute(mCallOnOpened);

mDeviceExecutor.execute(mCallOnUnconfigured);

}

}

这个mRemoteDevice是应用程序进程和android camera service端之间链接的桥梁,上层操作camera的方法会通过调用mRemoteDevice来调用到camera service端来实现操作底层camera驱动的目的。

小结

本文通过我们熟知的openCamera函数讲起,openCamera串起应用程序和cameraService之间的联系,通过研究cameraservice代码,我们知道了底层是如何通过HAL调用camera驱动设备的。下面会逐渐深入讲解camera底层知识,不足之处,敬请谅解。

android camera 工作原理,Android Camera原理之openCamera模块(一)相关推荐

  1. android lint工作机制,Android架构

    MVC mvc model view controller 模式视图控制器 M: 业务逻辑处理 V:处理数据显示的部分 C:Activity处理用户交互的问题,中间桥梁的作用,解耦的作用. 特点: 耦 ...

  2. boss直聘Android找工作界面,Android仿Boss直聘我的界面滑动效果

    最近在找工作,我在使用boss投简历的时候,看到boss的我的界面蛮有意思的,就想如何去实现它,可能是职业病吧,所以就打算仿一下.先看下仿的效果. image 其实我们拿到这个效果的时候,看到滑动,折 ...

  3. Android 高级UI解密 (三) :Canvas裁剪 与 二维、三维Camera几何变换(图层Layer原理)

    Android的绘图机制是核心内容之一,无论是什么样的功能最终都是以图像的形式呈现给用户.因此掌握Android的绘图技巧,有助于Android理解层次的提高,在面对产品经理提出的idea时也更有底气 ...

  4. Android ListView工作原理完全解析,带你从源码的角度彻底理解

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/44996879 在Android所有常用的原生控件当中,用法最复杂的应该就是List ...

  5. 高通Android平台硬件调试之Camera篇

    之前一段时间有幸在高通android平台上调试2款camera sensor,一款是OV的5M YUV sensor,支持jpeg out,同时也支持AF,调试比较比较简单,因为别的项目已经在使用了, ...

  6. Android 新老两代 Camera API 大起底

    https://blog.csdn.net/Byeweiyang/article/details/80515192 0.背景简介 最近有一部分相机相关的需求,专注于对拍摄的照片.视频的噪点.色温.明暗 ...

  7. Android大图片裁剪终极解决方案 原理分析

    约几个月前,我正为公司的APP在Android手机上实现拍照截图而烦恼不已. 上网搜索,确实有不少的例子,大多都是抄来抄去,而且水平多半处于demo的样子,可以用来讲解知识点,但是一碰到实际项目,就漏 ...

  8. 【高通SDM660平台 Android 10.0】(13) --- Camera ISP 之 数字成像系统介绍

    [高通SDM660平台 Android 10.0] --- Camera ISP 之 数字成像系统介绍 一.成像系统的组成 1.1 视角 1.2 曝光 1.3 感光度 ISO 1.4 光源 1.5 光 ...

  9. Android 7.0 GMS测试 Camera模块CTS fail项分析

    在上一篇博客中我们提到Camera模块fail项,本篇博客我们单独讲解Camera模块的. GMS中涉及Camera的有: 1.CTS部分的CtsCameraTestCases模块 2.CTS VER ...

最新文章

  1. MySQL数据库分组查询group by(having)
  2. 如何预约升级鸿蒙,超过66万人预约,华为亮出真正王牌旗舰,支持优先升级鸿蒙系统...
  3. python基础教程:对象之间的交互
  4. InstallShield安装打包编译自动化(3)- 更新Package GUID,Product GUID以及Upgrade GUID
  5. 【坚持】Selenium+Python学习记录 DAY10
  6. 运用计算机计算包含排斥原理,离散数学包含及排斥原理.ppt
  7. python写网页flash游戏辅助_会玩 | 使用 Python + Selenium制作Flash游戏辅助
  8. Centos7完全卸载MySQL 安装 启动
  9. nagios监控详解
  10. Android中action启动方法大全
  11. 计算机网络处理延时是什么原因,电脑网络延迟的解决方法是什么
  12. 史上最全电子元器件实物外形图+电路符号
  13. 如何用photoshop CS制作标准一寸照
  14. ​计算机视觉传感器系统
  15. 【我是初学者】关于获取配置文件.properties的常见三种方式--只是常见的方式,欢迎牛神来加瓦
  16. 实时行情难处理?睿凝资本选择DolphinDB解决流数据难题
  17. 一牛网:MTK软件,硬件芯片资料集锦(datasheet,规格书,原理图,参考设计,SDK等)二
  18. 手机订货系统优势是什么?订货软件优势有啥?
  19. 计算机速录方法,速录软件速录方法细说
  20. adb 不是内部命令

热门文章

  1. 微信登录小程序获取openId
  2. opencv python 调用网络摄像头 (局域网)
  3. 缺少dll文件怎么办?修复dll文件的多种方法
  4. publiccms部署步骤
  5. gm修改爆率需要重启服务器吗,传奇私服GM如何调试爆率、刷怪等
  6. java计算机毕业设计智能旅游电子票务系统演示录像2020源码+mysql数据库+系统+部署+lw文档
  7. The page cannot be refreshed without resending ... 昨天遇到一个这样得问题,在弹出的子页中用:
  8. 免费的思维导图软件哪个好?这篇文章告诉你
  9. 【ACWing】167. 木棒
  10. Python实现秒杀某宝商品抢购(附超详细代码)