目录
1.1、openCameraDeviceUserAsync:
1.1.1、openCameraDeviceUserAsync
目录
1.1.1、openCameraDeviceUserAsync:
1.1.2、getCameraCharacteristics:
一、framework
base/core/java/android/hardware/camera2/CameraManager.java
调用opencamera,根据传入的参数执行不同的接口,检查是否开启camera功能。
openCamera->openCameraForUid()->openCameraDeviceUserAsync()->connectHelper()->makeClient()->CameraDeviceClient()->Camera2ClientBase()->
->initialize()->initializeImpl()->
那么这就是打开camera个过程,其实是获取CameraDeviceImpl到应用。
重要的包含结构
CameraDeviceImpl
ICameraDeviceUserWrapper
ICameraDeviceUser(通过cameraService.connectDevice获取,framework和service交互)
对应CameraDeviceClient(framework和service交互,就是创建client)
Camera2ClientBase
Camera3Device
CameraDeviceClient属于camerasever,所以可以调用CameraProviderManager 里面的deviceInfo3-> mInterface(privder里面的CameraDevice)CameraDevice通过CameraModule(包含加载的hal模块句柄)可以访问hal
1、开启camera:
1.1、openCameraDeviceUserAsync
根据传入的cameraid获取对应的配置属性,并将其保存,注册camera状态的回调函数,最后打开camera,并返回device。
->getCameraCharacteristics()//
->android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
new android.hardware.camera2.impl.CameraDeviceImpl();//保存此次传入的camera的相 机id以及相关属性。
->ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();//获取一个 CameraDeviceCallbacks
->ICameraService cameraService = CameraManagerGlobal.get().getCameraService();//获取 CameraService
->cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), mContext.getAttributionTag(), uid);//根据cameraid来打 开camera
->deviceImpl.setRemoteDevice(cameraUser);//设置远程设备,触发Onopened/OnConfigured
->return device;//返回一个CameraDevice
获取cameraService
1.1.1、openCameraDeviceUserAsync:
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Executor executor, 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,
executor,
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(), mContext.getAttributionTag(), 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,
getDisplaySize());
}
} 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;
}
1.1.2、getCameraCharacteristics:
获取CameraServer,获取屏幕显示比例,判断是否是逻辑相机,将相机信息保存到CameraMetadataNative(java层的CameraMetadata),然后返回一个characteristics。
public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
throws CameraAccessException {
CameraCharacteristics characteristics = null;
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No cameras available on device");
}
synchronized (mLock) {
/*
* Get the camera characteristics from the camera service directly if it supports it,
* otherwise get them from the legacy shim instead.
*/
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
if (cameraService == null) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable");
}
try {
Size displaySize = getDisplaySize();
// First check isHiddenPhysicalCamera to avoid supportsCamera2ApiLocked throwing
// exception in case cameraId is a hidden physical camera.
if (!isHiddenPhysicalCamera(cameraId) && !supportsCamera2ApiLocked(cameraId)) {
// Legacy backwards compatibility path; build static info from the camera
// parameters
int id = Integer.parseInt(cameraId);
String parameters = cameraService.getLegacyParameters(id);
CameraInfo info = cameraService.getCameraInfo(id);
characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info,
id, displaySize);
} else {
// Normal path: Get the camera characteristics directly from the camera service
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
try {
info.setCameraId(Integer.parseInt(cameraId));
} catch (NumberFormatException e) {
// For external camera, reaching here is expected.
Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
}
boolean hasConcurrentStreams =
CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
info.setDisplaySize(displaySize);
characteristics = new CameraCharacteristics(info);
}
} catch (ServiceSpecificException e) {
throwAsPublicException(e);
} catch (RemoteException e) {
// Camera service died - act as if the camera was disconnected
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable", e);
}
}
return characteristics;
}
1.1.3、CameraDeviceImpl
1)构造函数中传入的StateCallback赋给了CameraDeviceImpl中的mDeviceCallback,以及其他相应的参数赋值到CameraDeviceImpl中。
public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
CameraCharacteristics characteristics, int appTargetSdkVersion) {
if (cameraId == null || callback == null || executor == null || characteristics == null) {
throw new IllegalArgumentException("Null argument given");
}
mCameraId = cameraId;
mDeviceCallback = callback;
mDeviceExecutor = executor;
mCharacteristics = characteristics;
mAppTargetSdkVersion = appTargetSdkVersion;
final int MAX_TAG_LEN = 23;
String tag = String.format("CameraDevice-JV-%s", mCameraId);
if (tag.length() > MAX_TAG_LEN) {
tag = tag.substring(0, MAX_TAG_LEN);
}
TAG = tag;
Integer partialCount =
mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
if (partialCount == null) {
// 1 means partial result is not supported.
mTotalPartialCount = 1;
} else {
mTotalPartialCount = partialCount;
}
}
2)返回CameraDeviceCallbacks
CameraDeviceCallbacks继承ICameraDeviceCallbacks.Stub,而ICameraDeviceCallbacks.Stub是可以在Binder IPC中传输的对象,很显然这个才是应用程序与CameraService通信的回调,在这个回调中的执行方法标识当前的camera的执行状态。
ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
/************************************************************************/
public CameraDeviceCallbacks getCallbacks() {
return mCallbacks;
}
/************************************************************************/
private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
/************************************************************************/
public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
......
}
1.1.4、获取CameraService
1)获取CameraManagerGlobal对象,然后调用connectCameraServiceLocked。
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
/***********************************************************************************/
// Singleton instance
public static CameraManagerGlobal get() {
return gCameraManager;
}
/***********************************************************************************/
private static final CameraManagerGlobal gCameraManager = new CameraManagerGlobal();
public ICameraService getCameraService() {
synchronized(mLock) {
connectCameraServiceLocked();
if (mCameraService == null && !sCameraServiceDisabled) {
Log.e(TAG, "Camera service is unavailable");
}
return mCameraService;
}
}
/***********************************************************************************/
2)connectCameraServiceLocked
private void connectCameraServiceLocked() {
// Only reconnect if necessary
if (mCameraService != null || sCameraServiceDisabled) return;
Log.i(TAG, "Connecting to camera service");
IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
if (cameraServiceBinder == null) {
// Camera service is now down, leave mCameraService as null
return;
}
try {
cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
} catch (RemoteException e) {
// Camera service is now down, leave mCameraService as null
return;
}
ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
try {
CameraMetadataNative.setupGlobalVendorTagDescriptor();
} catch (ServiceSpecificException e) {
handleRecoverableSetupErrors(e);
}
try {
CameraStatus[] cameraStatuses = cameraService.addListener(this);
for (CameraStatus c : cameraStatuses) {
onStatusChangedLocked(c.status, c.cameraId);
if (c.unavailablePhysicalCameras != null) {
for (String unavailPhysicalCamera : c.unavailablePhysicalCameras) {
onPhysicalCameraStatusChangedLocked(
ICameraServiceListener.STATUS_NOT_PRESENT,
c.cameraId, unavailPhysicalCamera);
}
}
}
mCameraService = cameraService;
} catch(ServiceSpecificException e) {
// Unexpected failure
throw new IllegalStateException("Failed to register a camera service listener", e);
} catch (RemoteException e) {
// Camera service is now down, leave mCameraService as null
}
try {
ConcurrentCameraIdCombination[] cameraIdCombinations =
cameraService.getConcurrentCameraIds();
for (ConcurrentCameraIdCombination comb : cameraIdCombinations) {
mConcurrentCameraIdCombinations.add(comb.getConcurrentCameraIdCombination());
}
} catch (ServiceSpecificException e) {
// Unexpected failure
throw new IllegalStateException("Failed to get concurrent camera id combinations",
e);
} catch (RemoteException e) {
// Camera service died in all probability
}
}
3)connectDevice
connectDevice->connectHelper->makeClient->
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
const std::unique_ptr<String16>& clientFeatureId,
int clientUid,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
ATRACE_CALL();
Status ret = Status::ok();
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
String16 clientPackageNameAdj = clientPackageName;
if (getCurrentServingCall() == BinderCallType::HWBINDER) {
std::string vendorClient =
StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
clientPackageNameAdj = String16(vendorClient.c_str());
}
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
ret.toString8());
return ret;
}
*device = client;
return ret;
}
1.1.5、setRemoteDevice
mDeviceExecutor.execute(mCallOnOpened);
mDeviceExecutor.execute(mCallOnUnconfigured);
其中可从CameraDeviceImpl构造函数得知mDeviceCallback,mDeviceExecutor即是传入的参数。
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);
}
通过我们追代码的流程分析,很清楚的可以理解下图: