在Camera2 App中我们去打开相机时,最终是调用了mCameraManager.openCamera(cameraId)
。我们就从这里开始分析Camera2 的FrameWork层。openCamera()
最终是调用了CameraManager.openCameraDeviceUserAsync()
我们直接来看这个函数
/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Handler handler, final int uid)
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
synchronized (mLock) {
ICameraDeviceUser cameraUser = null;
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
new android.hardware.camera2.impl.CameraDeviceImpl(
cameraId,
callback,
handler,
characteristics,
mContext.getApplicationInfo().targetSdkVersion);
ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
try {
if (supportsCamera2ApiLocked(cameraId)) {
// 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);
} else {
// Use legacy camera implementation for HAL1 devices
int id;
try {
id = Integer.parseInt(cameraId);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
+ cameraId);
}
Log.i(TAG, "Using legacy camera HAL.");
cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
}
} catch (ServiceSpecificException e) {
if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
throw new AssertionError("Should've gone down the shim path");
} else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE ||
e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE ||
e.errorCode == ICameraService.ERROR_DISABLED ||
e.errorCode == ICameraService.ERROR_DISCONNECTED ||
e.errorCode == ICameraService.ERROR_INVALID_OPERATION) {
// Received one of the known connection errors
// The remote camera device cannot be connected to, so
// set the local camera to the startup error state
deviceImpl.setRemoteFailure(e);
if (e.errorCode == ICameraService.ERROR_DISABLED ||
e.errorCode == ICameraService.ERROR_DISCONNECTED ||
e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {
// Per API docs, these failures call onError and throw
throwAsPublicException(e);
}
} else {
// Unexpected failure - rethrow
throwAsPublicException(e);
}
} catch (RemoteException e) {
// Camera service died - act as if it's a CAMERA_DISCONNECTED case
ServiceSpecificException sse = new ServiceSpecificException(
ICameraService.ERROR_DISCONNECTED,
"Camera service is currently unavailable");
deviceImpl.setRemoteFailure(sse);
throwAsPublicException(sse);
}
// TODO: factor out callback to be non-nested, then move setter to constructor
// For now, calling setRemoteDevice will fire initial
// onOpened/onUnconfigured callbacks.
// This function call may post onDisconnected and throw CAMERA_DISCONNECTED if
// cameraUser dies during setup.
deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;
}
return device;
}
在这段代码中我们新建了一个android.hardware.camera2.impl.CameraDeviceImpl
对象,并且向其中保存了远端设备并把它返回了。我们先来分析下远端设备cameraUser
的获取。在HAL3.2+的时候
/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), uid);
这里第一句很容易知道这是通过了Android的Binder机制来获取了远端CameraService的一个代理。关于CameraService的启动时机以及初始化,下节会详细介绍。下面分析CameraService.connectDevice()
/**/frameworks/av/services/camera/libcameraservice/CameraService.cpp**/
Status CameraService::connectDevice(
const sp& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp* device) {
ATRACE_CALL();
Status ret = Status::ok();
String8 id = String8(cameraId);
sp client = nullptr;
ret = connectHelper(cameraCb, id,
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()
函数实际返回了一个CameraDeviceCilent
对象,而这个对象是由函数connectHelper()
返回的,函数如下:
/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
template
Status CameraService::connectHelper(const sp& cameraCb, const String8& cameraId,
int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp& device) {
binder::Status ret = binder::Status::ok();
String8 clientName8(clientPackageName);
/* Do something in */
......
/* Do something out */
sp tmp = nullptr;
if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
client = static_cast(tmp.get());
LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
__FUNCTION__);
err = client->initialize(mCameraProviderManager);
/* Do something in */
......
/* Do something out */
// Important: release the mutex here so the client can call back into the service from its
// destructor (can be at the end of the call)
device = client;
return ret;
}
这里先是调用了makeCilent()
函数返回一个BaseClient
对象,然后将这个BaseClient
对象转型为了一个CameraDeviceCilent
对象,然后执行它的初始化函数,最后将这个对象返回。
/**frameworks/base/core/java/android/hardware/camera2/CameraManager.java**/
Status CameraService::makeClient(const sp& cameraService,
const sp& cameraCb, const String16& packageName, const String8& cameraId,
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:
/* Do something in */
......
/* Do something out */
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, cameraIdToInt(cameraId),
facing, clientPid, clientUid, servicePid, legacyMode);
} else { // Camera2 API route
sp tmp =
static_cast(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 {
/* Do something in */
......
/* Do something out */
}
return Status::ok();
}
可以看到在Camera2 API时,最终创建了一个CameraDeviceCilent
对象并一路向上返回,最终被保存在CameraManager
中新建的CameraDeviceImpl
对象的mRemoteDevice
中。知道了deviceImpl.setRemoteDevice(cameraUser);
中的cameraUser
到底是什么,我们再来看看这个方法做了什么
/**/frameworks/base/core/java/android/hardware/camera2/Impl/CameraDeviceImpl.java**/
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.mDeviceHandler.post(mCallOnDisconnected);
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"The camera device has encountered a serious error");
}
}
mDeviceHandler.post(mCallOnOpened);
mDeviceHandler.post(mCallOnUnconfigured);
}
}
private final Runnable mCallOnOpened = new Runnable() {
@Override
public void run() {
StateCallbackKK sessionCallback = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
sessionCallback = mSessionStateCallback;
}
if (sessionCallback != null) {
sessionCallback.onOpened(CameraDeviceImpl.this);
}
mDeviceCallback.onOpened(CameraDeviceImpl.this);
}
};
这里mDeviceHandler
就是我们创建deviceImpl
传入的handler
,mDeviceCallback
就是我们自己callback
也就是我们自己打开相机时写的那个回调。这里就明白了当CameraDeviceCilent
创建成功并且通过CameraDeviceImpl.setRemoteDevice()
设置给CameraDeviceImpl
的时候就会回调相机打开成功的函数,而函数中的CameraDevice
实际就是CameraDeviceImpl
,可以看到CameraDeviceImpl
确实继承了CameraDevice
。
下图总结了这一段的流程。
接着我们看CameraDeviceCilent
的构造函数:
/**frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp**/
CameraDeviceClient::CameraDeviceClient(const sp& cameraService,
const sp& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0) {
ATRACE_CALL();
ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
可以看到这里就是调用了父类的构造函数,和一些初始化。CameraDeviceClient
新建完成后在CameraService.connectHelper
中执行了client->initialize(mCameraProviderManager);
/**frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp**/
status_t CameraDeviceClient::initialize(sp manager) {
return initializeImpl(manager);
}
template
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
ATRACE_CALL();
status_t res;
res = Camera2ClientBase::initialize(providerPtr);
if (res != OK) {
return res;
}
String8 threadName;
mFrameProcessor = new FrameProcessorBase(mDevice);
threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
mFrameProcessor->run(threadName.string());
mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
FRAME_PROCESSOR_LISTENER_MAX_ID,
/*listener*/this,
/*sendPartials*/true);
return OK;
}
这里执行了父类的初始化函数,然后进行了FrameProcessor 的创建与初始化配置等等,这个东西可能是用于处理上传的每帧数据的。上面执行了父类也就是Camera2ClientBase
的构造函数,这里又执行了它的初始化函数,接下来着重分析类Camera2ClientBase
。先看构造函数:
/**frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp**/
template
Camera2ClientBase::Camera2ClientBase(
const sp& cameraService,
const sp& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false)
{
ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
String8(clientPackageName).string(), clientPid, clientUid);
mInitialClientPid = clientPid;
mDevice = new Camera3Device(cameraId);
LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}
这里就是需要注意创建了一个Camera3Device
对象,接着分析Camera2ClientBase
的初始化函数:
/**frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp**/
template
status_t Camera2ClientBase::initialize(sp manager) {
return initializeImpl(manager);
}
template
template
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr) {
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
TClientBase::mCameraIdStr.string());
status_t res;
// Verify ops permissions
res = TClientBase::startCameraOps();
if (res != OK) {
return res;
}
if (mDevice == NULL) {
ALOGE("%s: Camera %s: No device connected",
__FUNCTION__, TClientBase::mCameraIdStr.string());
return NO_INIT;
}
res = mDevice->initialize(providerPtr);
if (res != OK) {
ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
__FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
return res;
}
wp weakThis(this);
res = mDevice->setNotifyCallback(weakThis);
return OK;
}
注意此处,TClientBase
对应 CameraDeviceClientBase
,而 TProviderPtr
对应的是 CameraProviderManager
。这里调用了Camera3Device
的初始化函数,此前我们已经新建了Camera3Device
对象,调用了构造函数。
/**frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp*/
Camera3Device::Camera3Device(const String8 &id):
mId(id),
mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextShutterFrameNumber(0),
mNextReprocessShutterFrameNumber(0),
mListener(NULL),
mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID)
{
ATRACE_CALL();
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}
这里主要进行了参数的初始化以及两个回调接口的设置。
/**frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp*/
status_t Camera3Device::initialize(sp manager) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
if (mStatus != STATUS_UNINITIALIZED) {
CLOGE("Already initialized!");
return INVALID_OPERATION;
}
if (manager == nullptr) return INVALID_OPERATION;
sp session;
ATRACE_BEGIN("CameraHal::openSession");
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
ATRACE_END();
if (res != OK) {
SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
return res;
}
/* Do something in */
......
/* Do something out */
return initializeCommonLocked();
}
这里可以看到通过CameraProviderManager
开启了远端session
/**frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp**/
status_t CameraProviderManager::openSession(const std::string &id,
const sp& callback,
/*out*/
sp *session) {
std::lock_guard lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast(deviceInfo);
Status status;
hardware::Return ret;
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
return mapToStatusT(status);
}
首先调用findDeviceInfoLocked()
,获取 HAL3 相关的 DeviceInfo3
,这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。通过远端调用 CameraDevice
的 open()
方法,创建 CameraDeviceSession
实例并将其本地调用接口通过入参session
返回。 (DeviceInfo3
这个类的 mInterface
成员类型是 ICameraDevice
,通过它可以调用远端 CameraDevice 中的方法。)这里就进入了HAL层了,CameraDevice.open()
中最终调用了CameraDevice.createDeviceSession()
创建了一个CameraDeviceSession
。
这一段的流程图如下: