1、Java 层
- frameworks/base/core/java/android/hardware/camera2/CameraManager.java
- frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException {
openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);
}
public void openCameraForUid(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler,
int clientUid)
throws CameraAccessException {
if (handler == null) {
if (Looper.myLooper() != null) {
handler = new Handler();
} else {
throw new IllegalArgumentException(
"Handler argument is null, but no looper exists in the calling thread");
}
}
openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
}
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 {
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,
oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion);
} catch (ServiceSpecificException e) {
......
} catch (RemoteException e) {
......
}
deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;
}
return device;
}
public class CameraDeviceImpl extends CameraDevice
implements IBinder.DeathRecipient {
...
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) {
mTotalPartialCount = 1;
} else {
mTotalPartialCount = partialCount;
}
mIsPrivilegedApp = checkPrivilegedAppList();
}
...
}
public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
synchronized(mInterfaceLock) {
mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
IBinder remoteDeviceBinder = remoteDevice.asBinder();
if (remoteDeviceBinder != null) {
try {
remoteDeviceBinder.linkToDeath(this, 0);
} catch (RemoteException e) {
......
}
}
mDeviceHandler.post(mCallOnOpened);
mDeviceHandler.post(mCallOnUnconfigured);
}
}
private final Runnable mCallOnOpened = new Runnable() {
public void run() {
StateCallbackKK sessionCallback = null;
synchronized(mInterfaceLock) {
sessionCallback = mSessionStateCallback;
}
if (sessionCallback != null) {
sessionCallback.onOpened(CameraDeviceImpl.this);
}
mDeviceCallback.onOpened(CameraDeviceImpl.this);
}
};
private final Runnable mCallOnUnconfigured = new Runnable() {
@Override
public void run() {
StateCallbackKK sessionCallback = null;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
sessionCallback = mSessionStateCallback;
}
if (sessionCallback != null) {
sessionCallback.onUnconfigured(CameraDeviceImpl.this);
}
}
};
2、C/C++ 层
- frameworks/av/services/camera/libcameraservice/CameraService.cpp
- frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
- frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
上面分析得知,Java 层中会通过 binder 跨进程调用 CameraService::connectDevice()
Status CameraService::connectDevice(
const sp& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
int clientUid,
sp* device) {
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,
false, false,
client);
*device = client;
return ret;
}
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,
sp& device) {
binder::Status ret = binder::Status::ok();
String8 clientName8(clientPackageName);
int originalClientPid = 0;
sp client = nullptr;
{
mFlashlight->prepareDeviceOpen(cameraId);
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
sp tmp = nullptr;
if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
&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);
device = client;
return ret;
}
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,
sp* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
switch(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, 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:
}
} else {
......
}
return Status::ok();
}
CameraDeviceClient::CameraDeviceClient(const sp& cameraService,
const sp& remoteCallback,
const String16& clientPackageName,
const std::optional& clientFeatureId,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
cameraId, -1, cameraFacing, sensorOrientation,
clientPid, clientUid, servicePid, overrideForPerfClass),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0),
mOverrideForPerfClass(overrideForPerfClass) {
ATRACE_CALL();
ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
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.");
}
status_t CameraDeviceClient::initialize(sp manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
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,
this,
true);
return OK;
}
template
template
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr,
const String8& monitorTags) {
// Verify ops permissions
res = TClientBase::startCameraOps();
res = mDevice->initialize(providerPtr, monitorTags);
return OK;
}
status_t CameraService::BasicClient::startCameraOps() {
sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
return OK;
}
status_t Camera3Device::initialize(sp manager) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
sp session;
ATRACE_BEGIN("CameraHal::openSession");
status_t res = manager->openSession(mId.string(), this,
&session);
ATRACE_END();
res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
std::shared_ptr queue;
auto requestQueueRet = session->getCaptureRequestMetadataQueue(
[&queue](const auto& descriptor) {
queue = std::make_shared(descriptor);
if (!queue->isValid() || queue->availableToWrite() <= 0) {
ALOGE("HAL returns empty request metadata fmq, not use it");
queue = nullptr;
// don't use the queue onwards.
}
});
std::unique_ptr& resQueue = mResultMetadataQueue;
auto resultQueueRet = session->getCaptureResultMetadataQueue(
[&resQueue](const auto& descriptor) {
resQueue = std::make_unique(descriptor);
if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
ALOGE("HAL returns empty result metadata fmq, not use it");
resQueue = nullptr;
// Don't use the resQueue onwards.
}
});
return initializeCommonLocked();
}
status_t Camera3Device::initializeCommonLocked() {
mStatusTracker = new StatusTracker(this);
status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
mInFlightStatusId = mStatusTracker->addComponent();
mRequestThread = new RequestThread(this, mStatusTracker, mInterface, sessionParamKeys);
res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
mPreparerThread = new PreparerThread();
...
}
status_t CameraProviderManager::openSession(const std::string &id,
const sp& callback,
sp *session) {
std::lock_guard lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
{3,0}, {4,0});
auto *deviceInfo3 = static_cast(deviceInfo);
const sp provider =
deviceInfo->mParentProvider->startProviderInterface();
if (provider == nullptr) {
return DEAD_OBJECT;
}
saveRef(DeviceMode::CAMERA, id, provider);
Status status;
hardware::Return ret;
auto interface = deviceInfo3->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
return mapToStatusT(status);
}
Return CameraDevice::open(const sp& callback, open_cb _hidl_cb) {
Status status = initStatus();
sp session = nullptr;
status_t res;
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast(&device));
ATRACE_END();
struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
session = createSession(
device, info.static_camera_characteristics, callback);
mSession = session;
mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();
}
sp CameraDevice::createSession(camera3_device_t* device,
const camera_metadata_t* deviceInfo,
const sp& callback) {
return new CameraDeviceSession(device, deviceInfo, callback);
}
ps:个人在网上找资料借鉴参考,仅供个人学习。