一、目的
主要了解canera2调用流程,方便以后学习查看
二、架构
三、应用层代码实现
private CameraManager mCameraManager;
mCameraManager = (CameraManager)BackCarActivity.this.getSystemService(Context.CAMERA_SERVICE);
try {
if (ActivityCompat.checkSelfPermission(BackCarActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.CAMERA},REQUEST_CAMERA_CODE);
}else {
//打开摄像头
Log.d("lili","open the camera");
mCameraManager.openCamera(mCameraID,stateCallback,mainHandler);
}
}catch (CameraAccessException e){
e.printStackTrace();
}
四、调用framework层
1、openCamera();
源码路径:
/home/lily/android_build_9/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
//方法一
@RequiresPermission(android.Manifest.permission.CAMERA)
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException {
openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
USE_CALLING_UID);
}
//方法二:
@RequiresPermission(android.Manifest.permission.CAMERA)
public void openCamera(@NonNull String cameraId,
@NonNull @CallbackExecutor Executor executor,
@NonNull final CameraDevice.StateCallback callback)
throws CameraAccessException {
if (executor == null) {
throw new IllegalArgumentException("executor was null");
}
openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);
}
//以上两种方法最终调用到openCameraForUid()方法
public void openCameraForUid(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
int clientUid)
throws CameraAccessException {
if (cameraId == null) {
throw new IllegalArgumentException("cameraId was null");
} else if (callback == null) {
throw new IllegalArgumentException("callback was null");
}
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No cameras available on device");
}
openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
}
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Executor executor, final int uid)
throws CameraAccessException {
......
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
ICameraDeviceUser cameraUser = null;
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
if (cameraService == null) {
throw new ServiceSpecificException(
ICameraService.ERROR_DISCONNECTED,
"Camera service is currently unavailable");
}
//连接到camera设备
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), uid);
.....
}
ICameraService上是aidl文件,也是就是说CameraManager通过通过 Binder 机制调用了 connectDevice 方法,这个connectDevice方法的实现在CameraService 中。
2、连接摄像头设备connectDevice (),构造cameraDeviceClient
ICameraService源码路径:
/home/lily/android_build_9/frameworks/av/camera/aidl/android/hardware/ICameraService.aidl
CameraService 源码路径:
/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/CameraService.cpp
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
ATRACE_CALL();
Status ret = Status::ok();
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(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;
}
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
....
if(!(ret = makeClient(this, cameraCb, clientPackageName,
cameraId, api1CameraId, facing,
clientPid, clientUid, getpid(), legacyMode,
halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
err = client->initialize(mCameraProviderManager, mMonitorTags);
....
}
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& 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<BasicClient>* client) {
...
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
...
}
-
在connectHelper中我们通过makeClient方法完成了client的生成并初始化;
-
在makeClient中根据API版本和Device版本来实例化Client的,在Android P 和Camera2的框架上这里CameraDeviceClient方法是由CameraDeviceClient.cpp实现的。
-
摄像头设备客户端实现。CameraDeviceClient
源码路径:/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, /*API1 camera ID*/ -1,
cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0) {
ATRACE_CALL();
ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
Camera2ClientBase.cpp源码路径:
/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
// Interface used by CameraService
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false), mApi1CameraId(api1CameraId)
{
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.cpp 源码路径
/home/lily/android_build_9/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),
mLastTemplateId(-1)
{
ATRACE_CALL();
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}
到此CameraService.cpp中的makeClient工作就已经完成了并构造了"CameraDeviceClient",接下来就是connectHelper中的client->initialize这块儿了,从上面分析我们知道这里的client 指的对象就是Camera3Device了,所以我们继续找到Camera3Device中的initialize方法,代码如下:
status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
...
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
...
}
CameraProviderManager.cpp 源码路径:
/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::openSession(const std::string &id,
const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Status status;
hardware::Return<void> ret;
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& 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);
}
ret = deviceInfo3->mInterface->open 实际上通过Hidl指向了CameraDevice::open(),该方法由CameraDevice.cpp实现,源码路径:
/home/lily/android_build_9/hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
...
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
...
res = mModule->open(mCameraId.c_str(), reinterpret_cast<hw_device_t**>(&device))为打开Camera的地方,但是这里还需要继续跟下去,指向了CameraModule.cpp中实现的open方法。
CameraModule.cpp源码路径:
home/lily/android_build_9/hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
不难发现,mModule->common.methods->open紧接着就是Hal层了,在这里我们需要先把Hal层启动流程弄清楚。在系统启动后,CameraService服务跑起来就是就会启动Hal层。
五、Famework启动HAL层,添加camera设备
CameraService.cpp 源码路径:
/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/CameraService.cpp
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
// Update battery life tracking if service is restarting
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
status_t res = INVALID_OPERATION;
//res = enumerateProviders()说明CameraService在初始化时,要先枚举Provider
res = enumerateProviders();
if (res == OK) {
mInitialized = true;
}
CameraService::pingCameraServiceProxy();
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
}
status_t CameraService::enumerateProviders() {
...
if (nullptr == mCameraProviderManager.get()) {
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);
if (res != OK) {
ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
__FUNCTION__, strerror(-res), res);
return res;
}
}
...
}
这里又先初始化CameraProviderManager,并获取第三方厂家TAG,获取闪光灯,获取相机设备数,CameraProviderManager.cpp源码路径:
/home/lily/android_build_9/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
ServiceInteractionProxy* proxy) {
// See if there's a passthrough HAL, but let's not complain if there's not
addProviderLocked(kLegacyProviderName, /*expected*/ false);
addProviderLocked(kExternalProviderName, /*expected*/ false);
return OK;
}
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
...
sp<ProviderInfo> providerInfo =
new ProviderInfo(newProvider, interface, this);
status_t res = providerInfo->initialize();
if (res != OK) {
return res;
}
...
}
status_t CameraProviderManager::ProviderInfo::initialize() {
...
for (auto& device : devices) {
std::string id;
status_t res = addDevice(device,
hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
if (res != OK) {
ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
__FUNCTION__, device.c_str(), strerror(-res), res);
continue;
}
}
...
}
//添加camera设备
status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
ALOGI("Enumerating new camera device: %s", name.c_str());
uint16_t major, minor;
std::string type, id;
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
return res;
}
if (type != mType) {
ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
type.c_str(), mType.c_str());
return BAD_VALUE;
}
if (mManager->isValidDeviceLocked(id, major)) {
ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
name.c_str(), id.c_str(), major);
return BAD_VALUE;
}
std::unique_ptr<DeviceInfo> deviceInfo;
switch (major) {
case 1:
deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
id, minor);
break;
case 3:
deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
id, minor);
break;
default:
ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
name.c_str(), major);
return BAD_VALUE;
}
if (deviceInfo == nullptr) return BAD_VALUE;
deviceInfo->mStatus = initialStatus;
bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
mDevices.push_back(std::move(deviceInfo));
mUniqueCameraIds.insert(id);
if (isAPI1Compatible) {
mUniqueAPI1CompatibleCameraIds.push_back(id);
}
if (parsedId != nullptr) {
*parsedId = id;
}
return OK;
}
//实例化divice
template<class DeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
CameraProviderManager::ProviderInfo::initializeDeviceInfo(
const std::string &name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion) const {
Status status;
auto cameraInterface =
getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
if (cameraInterface == nullptr) return nullptr;
CameraResourceCost resourceCost;
cameraInterface->getResourceCost([&status, &resourceCost](
Status s, CameraResourceCost cost) {
status = s;
resourceCost = cost;
});
if (status != Status::OK) {
ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
return nullptr;
}
for (auto& conflictName : resourceCost.conflictingDevices) {
uint16_t major, minor;
std::string type, id;
status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
if (res != OK) {
ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
return nullptr;
}
conflictName = id;
}
return std::unique_ptr<DeviceInfo>(
new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
cameraInterface));
}
//获取HAL远程接口代码
template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface
<device::V3_2::ICameraDevice>(const std::string &name) const {
Status status;
sp<device::V3_2::ICameraDevice> cameraInterface;
hardware::Return<void> ret;
ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
__FUNCTION__, name.c_str(), ret.description().c_str());
return nullptr;
}
if (status != Status::OK) {
ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
return nullptr;
}
return cameraInterface;
}
到了这里,可以看出ICameraDevice关联到了CameraDevice.cpp,那么providerInfo->initialize()就分析得差不多了,下面的就到了硬件层,回头来我们需要继续分析CameraProvider.cpp这里了,在这里就关注其初始化就可以了。
CameraProvider.cpp源码路径:
/home/lily/android_build_9/hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp
bool CameraProvider::initialize() {
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
mModule = new CameraModule(rawModule);
err = mModule->init();
if (err != OK) {
ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
// Setup vendor tags here so HAL can setup vendor keys in camera characteristics
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
if (!setUpVendorTags()) {
ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
}
// Setup callback now because we are going to try openLegacy next
err = mModule->setCallbacks(this);
if (err != OK) {
ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
mPreferredHal3MinorVersion =
property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
switch(mPreferredHal3MinorVersion) {
case 2:
case 3:
// OK
break;
default:
ALOGW("Unknown minor camera device HAL version %d in property "
"'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
mPreferredHal3MinorVersion);
mPreferredHal3MinorVersion = 3;
}
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
struct camera_info info;
auto rc = mModule->getCameraInfo(i, &info);
if (rc != NO_ERROR) {
ALOGE("%s: Camera info query failed!", __func__);
mModule.clear();
return true;
}
if (checkCameraVersion(i, info) != OK) {
ALOGE("%s: Camera version check failed!", __func__);
mModule.clear();
return true;
}
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", i);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
addDeviceNames(i);
}
return false; // mInitFailed
}