Merge changes from topic "aidlCameraHal"
* changes:
cameraserver: Modified rules for different kinds of system cameras.
Implement AidlCamera3Device implementation.
Add AidlProviderInfo to handle aidl hal providers.
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 6d884cb..22bb234 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -43,6 +43,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V1-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 8428881..3626378 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -49,6 +49,7 @@
"common/CameraProviderManager.cpp",
"common/FrameProcessorBase.cpp",
"common/hidl/HidlProviderInfo.cpp",
+ "common/aidl/AidlProviderInfo.cpp",
"api1/Camera2Client.cpp",
"api1/client2/Parameters.cpp",
"api1/client2/FrameProcessor.cpp",
@@ -84,6 +85,9 @@
"device3/hidl/HidlCamera3Device.cpp",
"device3/hidl/HidlCamera3OfflineSession.cpp",
"device3/hidl/HidlCamera3OutputUtils.cpp",
+ "device3/aidl/AidlCamera3Device.cpp",
+ "device3/aidl/AidlCamera3OutputUtils.cpp",
+ "device3/aidl/AidlCamera3OfflineSession.cpp",
"gui/RingBufferConsumer.cpp",
"hidl/AidlCameraDeviceCallbacks.cpp",
"hidl/AidlCameraServiceListener.cpp",
@@ -115,6 +119,7 @@
"libutilscallstack",
"libutils",
"libbinder",
+ "libbinder_ndk",
"libactivitymanager_aidl",
"libpermission",
"libcutils",
@@ -148,6 +153,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V1-ndk",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
@@ -155,10 +161,12 @@
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
"android.hardware.camera.device@3.8",
+ "android.hardware.camera.device-V1-ndk",
"media_permission-aidl-cpp",
],
static_libs: [
+ "libaidlcommonsupport",
"libprocessinfoservice_aidl",
"libbinderthreadstateutils",
"media_permission-aidl-cpp",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 5740038..271cfec 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -132,8 +132,9 @@
static const String16
sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
const char *sFileName = "lastOpenSessionDumpFile";
-static constexpr int32_t kVendorClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
-static constexpr int32_t kVendorClientState = ActivityManager::PROCESS_STATE_PERSISTENT_UI;
+static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
+static constexpr int32_t kSystemNativeClientState =
+ ActivityManager::PROCESS_STATE_PERSISTENT_UI;
const String8 CameraService::kOfflineDevice("offline-");
const String16 CameraService::kWatchAllClientsFlag("all");
@@ -155,6 +156,12 @@
}
}
+// The word 'System' here does not refer to clients only on the system
+// partition. They just need to have a android system uid.
+static bool doesClientHaveSystemUid() {
+ return (CameraThreadState::getCallingUid() < AID_APP_START);
+}
+
void CameraService::onFirstRef()
{
@@ -923,7 +930,7 @@
}
Status CameraService::makeClient(const sp<CameraService>& cameraService,
- const sp<IInterface>& cameraCb, const String16& packageName,
+ const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
const std::optional<String16>& featureId, const String8& cameraId,
int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid, int deviceVersion, apiLevel effectiveApiLevel, bool overrideForPerfClass,
@@ -949,15 +956,14 @@
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName, featureId,
- cameraId, api1CameraId,
- facing, sensorOrientation, clientPid, clientUid,
+ cameraId, api1CameraId, facing, sensorOrientation, clientPid, clientUid,
servicePid, overrideForPerfClass);
} else { // Camera2 API route
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
- *client = new CameraDeviceClient(cameraService, tmp, packageName, featureId,
- cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
- overrideForPerfClass);
+ *client = new CameraDeviceClient(cameraService, tmp, packageName,
+ systemNativeClient, featureId, cameraId, facing, sensorOrientation,
+ clientPid, clientUid, servicePid, overrideForPerfClass);
}
break;
default:
@@ -1053,7 +1059,7 @@
sp<Client> tmp = nullptr;
if (!(ret = connectHelper<ICameraClient,Client>(
sp<ICameraClient>{nullptr}, id, cameraId,
- internalPackageName, {}, uid, USE_CALLING_PID,
+ internalPackageName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__, /*out*/ tmp)
).isOk()) {
@@ -1288,9 +1294,9 @@
userid_t clientUserId = multiuser_get_user_id(clientUid);
- // Only allow clients who are being used by the current foreground device user, unless calling
- // from our own process OR the caller is using the cameraserver's HIDL interface.
- if (getCurrentServingCall() != BinderCallType::HWBINDER && callingPid != getpid() &&
+ // For non-system clients : Only allow clients who are being used by the current foreground
+ // device user, unless calling from our own process.
+ if (!doesClientHaveSystemUid() && callingPid != getpid() &&
(mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
"device user %d, currently allowed device users: %s)", callingPid, clientUserId,
@@ -1327,12 +1333,12 @@
}
void CameraService::finishConnectLocked(const sp<BasicClient>& client,
- const CameraService::DescriptorPtr& desc, int oomScoreOffset) {
+ const CameraService::DescriptorPtr& desc, int oomScoreOffset, bool systemNativeClient) {
// Make a descriptor for the incoming client
auto clientDescriptor =
CameraService::CameraClientManager::makeClientDescriptor(client, desc,
- oomScoreOffset);
+ oomScoreOffset, systemNativeClient);
auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
@@ -1362,7 +1368,7 @@
status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
- int oomScoreOffset,
+ int oomScoreOffset, bool systemNativeClient,
/*out*/
sp<BasicClient>* client,
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
@@ -1437,7 +1443,7 @@
clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
state->getConflicting(), actualScore, clientPid, actualState,
- oomScoreOffset);
+ oomScoreOffset, systemNativeClient);
resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
@@ -1580,7 +1586,7 @@
String8 id = cameraIdIntToStr(api1CameraId);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
- clientPackageName, {}, clientUid, clientPid, API_1,
+ clientPackageName,/*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
/*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, /*out*/client);
if(!ret.isOk()) {
@@ -1612,14 +1618,14 @@
// 1) If cameraserver tries to access this camera device, accept the
// connection.
// 2) The camera device is a publicly hidden secure camera device AND some
- // component is trying to access it on a non-hwbinder thread (generally a non HAL client),
- // reject it.
+ // non system component is trying to access it.
// 3) if the camera device is advertised by the camera HAL as SYSTEM_ONLY
// and the serving thread is a non hwbinder thread, the client must have
// android.permission.SYSTEM_CAMERA permissions to connect.
int cPid = CameraThreadState::getCallingPid();
int cUid = CameraThreadState::getCallingUid();
+ bool systemClient = doesClientHaveSystemUid();
SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(cameraId, &systemCameraKind) != OK) {
// This isn't a known camera ID, so it's not a system camera
@@ -1632,8 +1638,7 @@
return false;
}
// (2)
- if (getCurrentServingCall() != BinderCallType::HWBINDER &&
- systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) {
+ if (!systemClient && systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) {
ALOGW("Rejecting access to secure hidden camera %s", cameraId.c_str());
return true;
}
@@ -1641,8 +1646,7 @@
// getCameraCharacteristics() allows for calls to succeed (albeit after hiding some
// characteristics) even if clients don't have android.permission.CAMERA. We do not want the
// same behavior for system camera devices.
- if (getCurrentServingCall() != BinderCallType::HWBINDER &&
- systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
+ if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
!hasPermissionsForSystemCamera(cPid, cUid, /*logPermissionFailure*/true)) {
ALOGW("Rejecting access to system only camera %s, inadequete permissions",
cameraId.c_str());
@@ -1667,11 +1671,12 @@
sp<CameraDeviceClient> client = nullptr;
String16 clientPackageNameAdj = clientPackageName;
int callingPid = CameraThreadState::getCallingPid();
-
- if (getCurrentServingCall() == BinderCallType::HWBINDER) {
- std::string vendorClient =
- StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
- clientPackageNameAdj = String16(vendorClient.c_str());
+ bool systemNativeClient = false;
+ if (doesClientHaveSystemUid() && (clientPackageNameAdj.size() == 0)) {
+ std::string systemClient =
+ StringPrintf("client.pid<%d>", CameraThreadState::getCallingPid());
+ clientPackageNameAdj = String16(systemClient.c_str());
+ systemNativeClient = true;
}
if (oomScoreOffset < 0) {
@@ -1695,7 +1700,7 @@
}
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
- /*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
+ /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient,clientFeatureId,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
targetSdkVersion, /*out*/client);
@@ -1726,7 +1731,7 @@
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, const String16& clientPackageName,
+ int api1CameraId, const String16& clientPackageName, bool systemNativeClient,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
/*out*/sp<CLIENT>& device) {
@@ -1745,7 +1750,7 @@
sp<CLIENT> client = nullptr;
int facing = -1;
int orientation = 0;
- bool isNdk = (clientPackageName.size() == 0);
+ bool isNonSystemNdk = (clientPackageName.size() == 0);
{
// Acquire mServiceLock and prevent other clients from connecting
std::unique_ptr<AutoConditionLock> lock =
@@ -1779,8 +1784,8 @@
sp<BasicClient> clientTmp = nullptr;
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
- IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, /*out*/&clientTmp,
- /*out*/&partial)) != NO_ERROR) {
+ IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, systemNativeClient,
+ /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
switch (err) {
case -ENODEV:
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
@@ -1820,8 +1825,8 @@
sp<BasicClient> tmp = nullptr;
bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
mPerfClassPrimaryCameraIds, cameraId.string(), targetSdkVersion);
- if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
- cameraId, api1CameraId, facing, orientation,
+ if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
+ clientFeatureId, cameraId, api1CameraId, facing, orientation,
clientPid, clientUid, getpid(),
deviceVersion, effectiveApiLevel, overrideForPerfClass,
/*out*/&tmp)).isOk()) {
@@ -1923,7 +1928,7 @@
mServiceLock.lock();
} else {
// Otherwise, add client to active clients list
- finishConnectLocked(client, partial, oomScoreOffset);
+ finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient);
}
client->setImageDumpMask(mImageDumpMask);
@@ -1935,7 +1940,7 @@
int32_t openLatencyMs = ns2ms(systemTime() - openTimeNs);
CameraServiceProxyWrapper::logOpen(cameraId, facing, clientPackageName,
- effectiveApiLevel, isNdk, openLatencyMs);
+ effectiveApiLevel, isNonSystemNdk, openLatencyMs);
{
Mutex::Autolock lock(mInjectionParametersLock);
@@ -1998,7 +2003,8 @@
kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
/*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
onlineClientDesc->getOwnerId(), onlinePriority.getState(),
- /*ommScoreOffset*/ 0);
+ // native clients don't have offline processing support.
+ /*ommScoreOffset*/ 0, /*systemNativeClient*/false);
// Allow only one offline device per camera
auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
@@ -3169,7 +3175,7 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
- const String16& clientPackageName,
+ const String16& clientPackageName, bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraIdStr,
int api1CameraId, int cameraFacing, int sensorOrientation,
@@ -3177,7 +3183,7 @@
int servicePid) :
CameraService::BasicClient(cameraService,
IInterface::asBinder(cameraClient),
- clientPackageName, clientFeatureId,
+ clientPackageName, systemNativeClient, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation,
clientPid, clientUid,
servicePid),
@@ -3207,13 +3213,14 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
- const String8& cameraIdStr, int cameraFacing, int sensorOrientation,
- int clientPid, uid_t clientUid,
+ const String16& clientPackageName, bool nativeClient,
+ const std::optional<String16>& clientFeatureId, const String8& cameraIdStr,
+ int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid):
mDestructionStarted(false),
mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation),
- mClientPackageName(clientPackageName), mClientFeatureId(clientFeatureId),
+ mClientPackageName(clientPackageName), mSystemNativeClient(nativeClient),
+ mClientFeatureId(clientFeatureId),
mClientPid(clientPid), mClientUid(clientUid),
mServicePid(servicePid),
mDisconnected(false), mUidIsTrusted(false),
@@ -3256,7 +3263,19 @@
}
mClientPackageName = packages[0];
}
- if (getCurrentServingCall() != BinderCallType::HWBINDER) {
+
+ // There are 2 scenarios in which a client won't have AppOps operations
+ // (both scenarios : native clients)
+ // 1) It's an system native client*, the package name will be empty
+ // and it will return from this function in the previous if condition
+ // (This is the same as the previously existing behavior).
+ // 2) It is a system native client, but its package name has been
+ // modified for debugging, however it still must not use AppOps since
+ // the package name is not a real one.
+ //
+ // * system native client - native client with UID < AID_APP_START. It
+ // doesn't exclude clients not on the system partition.
+ if (!mSystemNativeClient) {
mAppOpsManager = std::make_unique<AppOpsManager>();
}
@@ -4078,23 +4097,23 @@
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
const String8& key, const sp<BasicClient>& value, int32_t cost,
const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
- int32_t state, int32_t oomScoreOffset) {
+ int32_t state, int32_t oomScoreOffset, bool systemNativeClient) {
- bool isVendorClient = getCurrentServingCall() == BinderCallType::HWBINDER;
- int32_t score_adj = isVendorClient ? kVendorClientScore : score;
- int32_t state_adj = isVendorClient ? kVendorClientState: state;
+ int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score;
+ int32_t state_adj = systemNativeClient ? kSystemNativeClientState: state;
return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
- key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient,
- oomScoreOffset);
+ key, value, cost, conflictingKeys, score_adj, ownerId, state_adj,
+ systemNativeClient, oomScoreOffset);
}
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial,
- int32_t oomScoreOffset) {
+ int32_t oomScoreOffset, bool systemNativeClient) {
return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
partial->getConflicting(), partial->getPriority().getScore(),
- partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset);
+ partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset,
+ systemNativeClient);
}
// ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index c73d28a..95d5101 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -350,6 +350,7 @@
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
const String16& clientPackageName,
+ bool nativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraIdStr,
int cameraFacing,
@@ -372,6 +373,7 @@
const int mCameraFacing;
const int mOrientation;
String16 mClientPackageName;
+ bool mSystemNativeClient;
std::optional<String16> mClientFeatureId;
pid_t mClientPid;
const uid_t mClientUid;
@@ -459,6 +461,7 @@
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraIdStr,
int api1CameraId,
@@ -542,14 +545,15 @@
*/
static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
- int32_t ownerId, int32_t state, int oomScoreOffset);
+ int32_t ownerId, int32_t state, int oomScoreOffset, bool systemNativeClient);
/**
* Make a ClientDescriptor object wrapping the given BasicClient strong pointer with
* values intialized from a prior ClientDescriptor.
*/
static DescriptorPtr makeClientDescriptor(const sp<BasicClient>& value,
- const CameraService::DescriptorPtr& partial, int oomScoreOffset);
+ const CameraService::DescriptorPtr& partial, int oomScoreOffset,
+ bool systemNativeClient);
}; // class CameraClientManager
@@ -783,7 +787,7 @@
// Only call with with mServiceLock held.
status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
- int scoreOffset,
+ int scoreOffset, bool systemNativeClient,
/*out*/
sp<BasicClient>* client,
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
@@ -815,7 +819,7 @@
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, const String16& clientPackageName,
+ int api1CameraId, const String16& clientPackageName, bool systemNativeClient,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
/*out*/sp<CLIENT>& device);
@@ -892,7 +896,7 @@
* This method must be called with mServiceLock held.
*/
void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc,
- int oomScoreOffset);
+ int oomScoreOffset, bool systemNativeClient);
/**
* Returns the underlying camera Id string mapped to a camera id int
@@ -1226,10 +1230,10 @@
static binder::Status makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName,
- const std::optional<String16>& featureId, const String8& cameraId, int api1CameraId,
- int facing, int sensorOrientation, int clientPid, uid_t clientUid, int servicePid,
- int deviceVersion, apiLevel effectiveApiLevel, bool overrideForPerfClass,
- /*out*/sp<BasicClient>* client);
+ bool systemNativeClient, const std::optional<String16>& featureId,
+ const String8& cameraId, int api1CameraId, int facing, int sensorOrientation,
+ int clientPid, uid_t clientUid, int servicePid, int deviceVersion,
+ apiLevel effectiveApiLevel, bool overrideForPerfClass, /*out*/sp<BasicClient>* client);
status_t checkCameraAccess(const String16& opPackageName);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 8c72bd7..5fcd43e 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -60,9 +60,10 @@
uid_t clientUid,
int servicePid,
bool overrideForPerfClass):
- Camera2ClientBase(cameraService, cameraClient, clientPackageName, clientFeatureId,
- cameraDeviceId, api1CameraId, cameraFacing, sensorOrientation,
- clientPid, clientUid, servicePid, overrideForPerfClass, /*legacyClient*/ true),
+ Camera2ClientBase(cameraService, cameraClient, clientPackageName,
+ false/*systemNativeClient - since no ndk for api1*/, clientFeatureId,
+ cameraDeviceId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
+ clientUid, servicePid, overrideForPerfClass, /*legacyClient*/ true),
mParameters(api1CameraId, cameraFacing)
{
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index d26b730..3e44230 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -58,6 +58,7 @@
const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
@@ -69,6 +70,7 @@
BasicClient(cameraService,
IInterface::asBinder(remoteCallback),
clientPackageName,
+ systemNativeClient,
clientFeatureId,
cameraId,
cameraFacing,
@@ -86,6 +88,7 @@
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int cameraFacing,
@@ -94,8 +97,8 @@
uid_t clientUid,
int servicePid,
bool overrideForPerfClass) :
- Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
- cameraId, /*API1 camera ID*/ -1, cameraFacing, sensorOrientation,
+ Camera2ClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
+ clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing, sensorOrientation,
clientPid, clientUid, servicePid, overrideForPerfClass),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 1b0c61a..4989724 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,6 +50,7 @@
CameraDeviceClientBase(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
@@ -178,6 +179,7 @@
CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool clientPackageOverride,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int cameraFacing,
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 920a176..ef1d2de 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -54,7 +54,8 @@
CameraService::BasicClient(
cameraService,
IInterface::asBinder(remoteCallback),
- clientPackageName, clientFeatureId,
+ // (v)ndk doesn't have offline session support
+ clientPackageName, /*overridePackageName*/false, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation, clientPid, clientUid, servicePid),
mRemoteCallback(remoteCallback), mOfflineSession(session),
mCompositeStreamMap(offlineCompositeStreamMap) {}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 55c7579..a29f3a6 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -34,6 +34,7 @@
#include "api2/CameraDeviceClient.h"
#include "device3/Camera3Device.h"
+#include "device3/aidl/AidlCamera3Device.h"
#include "device3/hidl/HidlCamera3Device.h"
#include "utils/CameraThreadState.h"
#include "utils/CameraServiceProxyWrapper.h"
@@ -48,6 +49,7 @@
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
@@ -58,9 +60,9 @@
int servicePid,
bool overrideForPerfClass,
bool legacyClient):
- TClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
- cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid, clientUid,
- servicePid),
+ TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
+ clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
+ clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false), mApi1CameraId(api1CameraId)
@@ -118,8 +120,10 @@
mLegacyClient);
break;
case IPCTransport::AIDL:
- ALOGE("%s: AIDL camera3Devices not available yet", __FUNCTION__);
- return NO_INIT;
+ mDevice =
+ new AidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
+ mLegacyClient);
+ break;
default:
ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
TClientBase::mCameraIdStr.string());
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 296ef43..182e6ef 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -48,6 +48,7 @@
Camera2ClientBase(const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
+ bool systemNativeClient,
const std::optional<String16>& clientFeatureId,
const String8& cameraId,
int api1CameraId,
diff --git a/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
new file mode 100644
index 0000000..db7692a
--- /dev/null
+++ b/services/camera/libcameraservice/common/CameraProviderInfoTemplated.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDERINFO_TEMPLATEDH
+
+#include "common/CameraProviderManager.h"
+
+namespace android {
+
+template <class VendorTagSectionVectorType, class VendorTagSectionType>
+status_t IdlVendorTagDescriptor::createDescriptorFromIdl(
+ const VendorTagSectionVectorType& vts,
+ sp<VendorTagDescriptor>& descriptor) {
+
+ int tagCount = 0;
+
+ for (size_t s = 0; s < vts.size(); s++) {
+ tagCount += vts[s].tags.size();
+ }
+
+ if (tagCount < 0 || tagCount > INT32_MAX) {
+ ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+ return BAD_VALUE;
+ }
+
+ Vector<uint32_t> tagArray;
+ LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+ "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+ sp<IdlVendorTagDescriptor> desc = new IdlVendorTagDescriptor();
+ desc->mTagCount = tagCount;
+
+ SortedVector<String8> sections;
+ KeyedVector<uint32_t, String8> tagToSectionMap;
+
+ int idx = 0;
+ for (size_t s = 0; s < vts.size(); s++) {
+ const VendorTagSectionType& section = vts[s];
+ const char *sectionName = section.sectionName.c_str();
+ if (sectionName == NULL) {
+ ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+ return BAD_VALUE;
+ }
+ String8 sectionString(sectionName);
+ sections.add(sectionString);
+
+ for (size_t j = 0; j < section.tags.size(); j++) {
+ uint32_t tag = section.tags[j].tagId;
+ if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+ ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+
+ tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+ const char *tagName = section.tags[j].tagName.c_str();
+ if (tagName == NULL) {
+ ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ desc->mTagToNameMap.add(tag, String8(tagName));
+ tagToSectionMap.add(tag, sectionString);
+
+ int tagType = (int) section.tags[j].tagType;
+ if (tagType < 0 || tagType >= NUM_TYPES) {
+ ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+ return BAD_VALUE;
+ }
+ desc->mTagToTypeMap.add(tag, tagType);
+ }
+ }
+
+ desc->mSections = sections;
+
+ for (size_t i = 0; i < tagArray.size(); ++i) {
+ uint32_t tag = tagArray[i];
+ String8 sectionString = tagToSectionMap.valueFor(tag);
+
+ // Set up tag to section index map
+ ssize_t index = sections.indexOf(sectionString);
+ LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+ desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+ // Set up reverse mapping
+ ssize_t reverseIndex = -1;
+ if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+ }
+ desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+ }
+
+ descriptor = std::move(desc);
+ return OK;
+}
+
+
+} // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4227d28..1b8863a 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,15 +20,18 @@
#include "CameraProviderManager.h"
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <android/hardware/camera/device/3.8/ICameraDevice.h>
#include <algorithm>
#include <chrono>
#include "common/DepthPhotoProcessor.h"
#include "hidl/HidlProviderInfo.h"
+#include "aidl/AidlProviderInfo.h"
#include <dlfcn.h>
#include <future>
#include <inttypes.h>
+#include <android/binder_manager.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/ServiceManagement.h>
#include <functional>
@@ -59,12 +62,43 @@
const float CameraProviderManager::kDepthARTolerance = .1f;
+// AIDL Devices start with major version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMajorOffset = 2;
+// AIDL Devices start with minor version 1, offset added to bring them up to HIDL.
+const uint16_t kAidlDeviceMinorOffset = 7;
+
CameraProviderManager::HidlServiceInteractionProxyImpl
CameraProviderManager::sHidlServiceInteractionProxy{};
CameraProviderManager::~CameraProviderManager() {
}
+const char* FrameworkTorchStatusToString(const TorchModeStatus& s) {
+ switch (s) {
+ case TorchModeStatus::NOT_AVAILABLE:
+ return "NOT_AVAILABLE";
+ case TorchModeStatus::AVAILABLE_OFF:
+ return "AVAILABLE_OFF";
+ case TorchModeStatus::AVAILABLE_ON:
+ return "AVAILABLE_ON";
+ }
+ ALOGW("Unexpected HAL torch mode status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
+const char* FrameworkDeviceStatusToString(const CameraDeviceStatus& s) {
+ switch (s) {
+ case CameraDeviceStatus::NOT_PRESENT:
+ return "NOT_PRESENT";
+ case CameraDeviceStatus::PRESENT:
+ return "PRESENT";
+ case CameraDeviceStatus::ENUMERATING:
+ return "ENUMERATING";
+ }
+ ALOGW("Unexpected HAL device status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
hardware::hidl_vec<hardware::hidl_string>
CameraProviderManager::HidlServiceInteractionProxyImpl::listServices() {
hardware::hidl_vec<hardware::hidl_string> ret;
@@ -78,17 +112,9 @@
return ret;
}
-status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
- HidlServiceInteractionProxy* hidlProxy) {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- if (hidlProxy == nullptr) {
- ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
- return BAD_VALUE;
- }
- mListener = listener;
+status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
+ HidlServiceInteractionProxy *hidlProxy) {
mHidlServiceProxy = hidlProxy;
- mDeviceState = 0;
-
// Registering will trigger notifications for all already-known providers
bool success = mHidlServiceProxy->registerForNotifications(
/* instance name, empty means no filter */ "",
@@ -102,10 +128,54 @@
for (const auto& instance : mHidlServiceProxy->listServices()) {
this->addHidlProviderLocked(instance);
}
+ return OK;
+}
+
+static std::string getFullAidlProviderName(const std::string instance) {
+ std::string aidlHalServiceDescriptor =
+ std::string(aidl::android::hardware::camera::provider::ICameraProvider::descriptor);
+ return aidlHalServiceDescriptor + "/" + instance;
+}
+
+status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
+ const char * aidlHalServiceDescriptor =
+ aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
+ auto sm = defaultServiceManager();
+ auto aidlProviders = sm->getDeclaredInstances(
+ String16(aidlHalServiceDescriptor));
+ for (const auto &aidlInstance : aidlProviders) {
+ std::string aidlServiceName =
+ getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
+ auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
+ if (res != OK) {
+ ALOGE("%s Unable to register for notifications with AIDL service manager",
+ __FUNCTION__);
+ return res;
+ }
+ addAidlProviderLocked(aidlServiceName.c_str());
+ }
+ return OK;
+}
+
+status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
+ HidlServiceInteractionProxy* hidlProxy) {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ if (hidlProxy == nullptr) {
+ ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ mListener = listener;
+ mDeviceState = 0;
+ auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
+ if (res != OK) {
+ // Logging done in called function;
+ return res;
+ }
+ res = tryToAddAidlProvidersLocked();
IPCThreadState::self()->flushCommands();
- return OK;
+ return res;
}
std::pair<int, int> CameraProviderManager::getCameraCount() const {
@@ -380,6 +450,22 @@
return false;
}
+template <class ProviderInfoType, class HalCameraProviderType>
+status_t CameraProviderManager::setTorchModeT(sp<ProviderInfo> &parentProvider,
+ std::shared_ptr<HalCameraProvider> *halCameraProvider) {
+ if (halCameraProvider == nullptr) {
+ return BAD_VALUE;
+ }
+ ProviderInfoType *idlProviderInfo = static_cast<ProviderInfoType *>(parentProvider.get());
+ auto idlInterface = idlProviderInfo->startProviderInterface();
+ if (idlInterface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ *halCameraProvider =
+ std::make_shared<HalCameraProviderType>(idlInterface, idlInterface->descriptor);
+ return OK;
+}
+
status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
@@ -394,18 +480,19 @@
}
std::shared_ptr<HalCameraProvider> halCameraProvider = nullptr;
IPCTransport providerTransport = parentProvider->getIPCTransport();
+ status_t res = OK;
if (providerTransport == IPCTransport::HIDL) {
- HidlProviderInfo * hidlProviderInfo = static_cast<HidlProviderInfo *>(parentProvider.get());
- const sp<provider::V2_4::ICameraProvider> hidlInterface =
- hidlProviderInfo->startProviderInterface();
- if (hidlInterface == nullptr) {
- return DEAD_OBJECT;
+ res = setTorchModeT<HidlProviderInfo, HidlHalCameraProvider>(parentProvider,
+ &halCameraProvider);
+ if (res != OK) {
+ return res;
}
- halCameraProvider =
- std::make_shared<HidlHalCameraProvider>(hidlInterface, hidlInterface->descriptor);
} else if (providerTransport == IPCTransport::AIDL) {
- ALOGE("%s AIDL hal providers not supported yet", __FUNCTION__);
- return INVALID_OPERATION;
+ res = setTorchModeT<AidlProviderInfo, AidlHalCameraProvider>(parentProvider,
+ &halCameraProvider);
+ if (res != OK) {
+ return res;
+ }
} else {
ALOGE("%s Invalid provider transport", __FUNCTION__);
return INVALID_OPERATION;
@@ -518,6 +605,89 @@
return res;
}
+status_t CameraProviderManager::openAidlSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<aidl::android::hardware::camera::device::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 *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
+ sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ auto provider =
+ static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
+ if (provider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ std::shared_ptr<HalCameraProvider> halCameraProvider =
+ std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
+ saveRef(DeviceMode::CAMERA, id, halCameraProvider);
+
+ auto interface = aidlDeviceInfo3->startDeviceInterface();
+ if (interface == nullptr) {
+ removeRef(DeviceMode::CAMERA, id);
+ return DEAD_OBJECT;
+ }
+
+ auto ret = interface->open(callback, session);
+ if (!ret.isOk()) {
+ removeRef(DeviceMode::CAMERA, id);
+ ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+ __FUNCTION__, id.c_str(), ret.getMessage());
+ return DEAD_OBJECT;
+ }
+ return OK;
+}
+
+status_t CameraProviderManager::openAidlInjectionSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraInjectionSession> *session) {
+
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
+ sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ auto provider =
+ static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
+ if (provider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ std::shared_ptr<HalCameraProvider> halCameraProvider =
+ std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
+ saveRef(DeviceMode::CAMERA, id, halCameraProvider);
+
+ auto interface = aidlDeviceInfo3->startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ auto ret = interface->openInjectionSession(callback, session);
+ if (!ret.isOk()) {
+ removeRef(DeviceMode::CAMERA, id);
+ ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+ __FUNCTION__, id.c_str(), ret.getMessage());
+ return DEAD_OBJECT;
+ }
+ return OK;
+}
+
status_t CameraProviderManager::openHidlSession(const std::string &id,
const sp<device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
@@ -622,6 +792,26 @@
}
}
+// We ignore sp<IBinder> param here since we need std::shared_ptr<...> which
+// will be retrieved through the ndk api through addAidlProviderLocked ->
+// tryToInitializeAidlProvider.
+void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
+ status_t res = OK;
+ std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
+ {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ res = addAidlProviderLocked(String8(name).c_str());
+ }
+
+ sp<StatusListener> listener = getStatusListener();
+ if (nullptr != listener.get() && res == OK) {
+ listener->onNewProviderRegistered();
+ }
+
+ IPCThreadState::self()->flushCommands();
+}
+
hardware::Return<void> CameraProviderManager::onRegistration(
const hardware::hidl_string& /*fqName*/,
const hardware::hidl_string& name,
@@ -653,6 +843,59 @@
return OK;
}
+void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
+ const std::vector<std::string> &devices) {
+
+ sp<StatusListener> listener = mManager->getStatusListener();
+
+ for (auto& device : devices) {
+ std::string id;
+ status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
+ if (res != OK) {
+ ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
+ __FUNCTION__, device.c_str(), strerror(-res), res);
+ continue;
+ }
+ }
+
+ ALOGI("Camera provider %s ready with %zu camera devices",
+ mProviderName.c_str(), mDevices.size());
+
+ // Process cached status callbacks
+ std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
+ std::make_unique<std::vector<CameraStatusInfoT>>();
+ {
+ std::lock_guard<std::mutex> lock(mInitLock);
+
+ for (auto& statusInfo : mCachedStatus) {
+ std::string id, physicalId;
+ status_t res = OK;
+ if (statusInfo.isPhysicalCameraStatus) {
+ res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
+ statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
+ } else {
+ res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
+ }
+ if (res == OK) {
+ cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
+ id.c_str(), physicalId.c_str(), statusInfo.status);
+ }
+ }
+ mCachedStatus.clear();
+
+ mInitialized = true;
+ }
+
+ // The cached status change callbacks cannot be fired directly from this
+ // function, due to same-thread deadlock trying to acquire mInterfaceMutex
+ // twice.
+ if (listener != nullptr) {
+ mInitialStatusCallbackFuture = std::async(std::launch::async,
+ &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
+ listener, std::move(cachedStatus));
+ }
+}
+
CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
const std::string& id,
hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
@@ -1387,6 +1630,23 @@
return falseRet;
}
+status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
+ const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
+ using aidl::android::hardware::camera::provider::ICameraProvider;
+ std::shared_ptr<ICameraProvider> interface =
+ ICameraProvider::fromBinder(ndk::SpAIBinder(
+ AServiceManager_getService(providerName.c_str())));
+
+ if (interface == nullptr) {
+ ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ providerName.c_str());
+ return BAD_VALUE;
+ }
+
+ AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
+ return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
+}
+
status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
sp<provider::V2_4::ICameraProvider> interface;
@@ -1395,7 +1655,7 @@
if (interface == nullptr) {
// The interface may not be started yet. In that case, this is not a
// fatal error.
- ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ ALOGW("%s: HIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
providerName.c_str());
return BAD_VALUE;
}
@@ -1404,6 +1664,54 @@
return hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);
}
+status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
+ // Several camera provider instances can be temporarily present.
+ // Defer initialization of a new instance until the older instance is properly removed.
+ auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
+ bool providerPresent = false;
+ bool preexisting =
+ (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
+
+ // We need to use the extracted provider name here since 'newProvider' has
+ // the fully qualified name of the provider service in case of AIDL. We want
+ // just instance name.
+ using aidl::android::hardware::camera::provider::ICameraProvider;
+ std::string extractedProviderName =
+ newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
+ for (const auto& providerInfo : mProviders) {
+ if (providerInfo->mProviderName == extractedProviderName) {
+ ALOGW("%s: Camera provider HAL with name '%s' already registered",
+ __FUNCTION__, newProvider.c_str());
+ // Do not add new instances for lazy HAL external provider or aidl
+ // binders previously seen.
+ if (preexisting || providerInfo->isExternalLazyHAL()) {
+ return ALREADY_EXISTS;
+ } else {
+ ALOGW("%s: The new provider instance will get initialized immediately after the"
+ " currently present instance is removed!", __FUNCTION__);
+ providerPresent = true;
+ break;
+ }
+ }
+ }
+
+ sp<AidlProviderInfo> providerInfo =
+ new AidlProviderInfo(extractedProviderName, providerInstance, this);
+
+ if (!providerPresent) {
+ status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
+ if (res != OK) {
+ return res;
+ }
+ mAidlProviderWithBinders.emplace(newProvider);
+ }
+
+ mProviders.push_back(providerInfo);
+ mProviderInstanceId++;
+
+ return OK;
+}
+
status_t CameraProviderManager::addHidlProviderLocked(const std::string& newProvider,
bool preexisting) {
// Several camera provider instances can be temporarily present.
@@ -1467,9 +1775,13 @@
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == removedProviderName) {
IPCTransport providerTransport = providerInfo->getIPCTransport();
+ std::string removedAidlProviderName = getFullAidlProviderName(removedProviderName);
switch(providerTransport) {
case IPCTransport::HIDL:
return tryToInitializeHidlProviderLocked(removedProviderName, providerInfo);
+ case IPCTransport::AIDL:
+ return tryToInitializeAidlProviderLocked(removedAidlProviderName,
+ providerInfo);
default:
ALOGE("%s Unsupported Transport %d", __FUNCTION__, providerTransport);
}
@@ -1513,6 +1825,70 @@
return mType;
}
+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 (getIPCTransport() == IPCTransport::AIDL) {
+ // Till HIDL support exists, map AIDL versions to HIDL.
+ // TODO:b/196432585 Explore if we can get rid of this.
+ major += kAidlDeviceMajorOffset;
+ minor += kAidlDeviceMinorOffset;
+ }
+
+ 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 3:
+ deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
+ break;
+ default:
+ ALOGE("%s: Device %s: Unsupported IDL device HAL major version %d:", __FUNCTION__,
+ name.c_str(), major);
+ return BAD_VALUE;
+ }
+ if (deviceInfo == nullptr) return BAD_VALUE;
+ deviceInfo->notifyDeviceStateChange(getDeviceState());
+ deviceInfo->mStatus = initialStatus;
+ bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
+
+ mDevices.push_back(std::move(deviceInfo));
+
+ mUniqueCameraIds.insert(id);
+ if (isAPI1Compatible) {
+ // addDevice can be called more than once for the same camera id if HAL
+ // supports openLegacy.
+ if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
+ id) == mUniqueAPI1CompatibleCameraIds.end()) {
+ mUniqueAPI1CompatibleCameraIds.push_back(id);
+ }
+ }
+
+ if (parsedId != nullptr) {
+ *parsedId = id;
+ }
+ return OK;
+}
+
void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
if ((*it)->mId == id) {
@@ -1643,6 +2019,197 @@
return mConcurrentCameraIdCombinations;
}
+void CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeInternal(
+ const std::string& cameraDeviceName, CameraDeviceStatus newStatus) {
+ sp<StatusListener> listener;
+ std::string id;
+ std::lock_guard<std::mutex> lock(mInitLock);
+ CameraDeviceStatus internalNewStatus = newStatus;
+ if (!mInitialized) {
+ mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
+ cameraDeviceName.c_str(), std::string().c_str(),
+ internalNewStatus);
+ return;
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
+ return;
+ }
+ listener = mManager->getStatusListener();
+ }
+
+ // Call without lock held to allow reentrancy into provider manager
+ if (listener != nullptr) {
+ listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
+ }
+}
+
+status_t CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeLocked(
+ std::string* id, const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ bool known = false;
+ std::string cameraId;
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
+ ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
+ FrameworkDeviceStatusToString(newStatus),
+ FrameworkDeviceStatusToString(deviceInfo->mStatus));
+ deviceInfo->mStatus = newStatus;
+ // TODO: Handle device removal (NOT_PRESENT)
+ cameraId = deviceInfo->mId;
+ known = true;
+ deviceInfo->mIsDeviceAvailable =
+ (newStatus == CameraDeviceStatus::PRESENT);
+ deviceInfo->mDeviceAvailableSignal.signal();
+ break;
+ }
+ }
+ // Previously unseen device; status must not be NOT_PRESENT
+ if (!known) {
+ if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+ ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ addDevice(cameraDeviceName, newStatus, &cameraId);
+ } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+ removeDevice(cameraId);
+ } else if (isExternalLazyHAL()) {
+ // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
+ // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
+ // notif. would overwrite it
+ return BAD_VALUE;
+ }
+
+ if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
+ ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
+ __FUNCTION__, mProviderName.c_str());
+ }
+ *id = cameraId;
+ return OK;
+}
+
+void CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeInternal(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ sp<StatusListener> listener;
+ std::string id;
+ std::string physicalId;
+ std::lock_guard<std::mutex> lock(mInitLock);
+ if (!mInitialized) {
+ mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
+ physicalCameraDeviceName, newStatus);
+ return;
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
+ physicalCameraDeviceName, newStatus)) {
+ return;
+ }
+
+ listener = mManager->getStatusListener();
+ }
+ // Call without lock held to allow reentrancy into provider manager
+ if (listener != nullptr) {
+ listener->onDeviceStatusChanged(String8(id.c_str()),
+ String8(physicalId.c_str()), newStatus);
+ }
+ return;
+}
+
+status_t CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeLocked(
+ std::string* id, std::string* physicalId,
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus) {
+ bool known = false;
+ std::string cameraId;
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ cameraId = deviceInfo->mId;
+ if (!deviceInfo->mIsLogicalCamera) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
+ physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
+ ALOGE("%s: Invalid combination of camera id %s, physical id %s",
+ __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+ ALOGI("Camera device %s physical device %s status is now %s",
+ cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
+ FrameworkDeviceStatusToString(newStatus));
+ known = true;
+ break;
+ }
+ }
+ // Previously unseen device; status must not be NOT_PRESENT
+ if (!known) {
+ ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str(),
+ physicalCameraDeviceName.c_str());
+ return BAD_VALUE;
+ }
+
+ *id = cameraId;
+ *physicalId = physicalCameraDeviceName.c_str();
+ return OK;
+}
+
+void CameraProviderManager::ProviderInfo::torchModeStatusChangeInternal(
+ const std::string& cameraDeviceName,
+ TorchModeStatus newStatus) {
+ sp<StatusListener> listener;
+ SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
+ std::string id;
+ bool known = false;
+ {
+ // Hold mLock for accessing mDevices
+ std::lock_guard<std::mutex> lock(mLock);
+ for (auto& deviceInfo : mDevices) {
+ if (deviceInfo->mName == cameraDeviceName) {
+ ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
+ FrameworkTorchStatusToString(newStatus));
+ id = deviceInfo->mId;
+ known = true;
+ systemCameraKind = deviceInfo->mSystemCameraKind;
+ if (TorchModeStatus::AVAILABLE_ON != newStatus) {
+ mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
+ }
+ break;
+ }
+ }
+ if (!known) {
+ ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
+ mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
+ return;
+ }
+ // no lock needed since listener is set up only once during
+ // CameraProviderManager initialization and then never changed till it is
+ // destructed.
+ listener = mManager->getStatusListener();
+ }
+ // Call without lock held to allow reentrancy into provider manager
+ // The problem with holding mLock here is that we
+ // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
+ // back into CameraProviderManager which might try to hold mLock again (eg:
+ // findDeviceInfo, which should be holding mLock while iterating through
+ // each provider's devices).
+ if (listener != nullptr) {
+ listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
+ }
+ return;
+}
+
void CameraProviderManager::ProviderInfo::notifyDeviceInfoStateChangeLocked(
int64_t newDeviceState) {
std::lock_guard<std::mutex> lock(mLock);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 4568209..3d108bd 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -33,6 +33,7 @@
#include <utils/Errors.h>
#include <android/hardware/ICameraService.h>
#include <utils/IPCTransport.h>
+#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
#include <android/hardware/camera/common/1.0/types.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
@@ -97,6 +98,26 @@
#define CAMERA_DEVICE_API_VERSION_3_8 HARDWARE_DEVICE_API_VERSION(3, 8)
/**
+ * The vendor tag descriptor class that takes HIDL/AIDL vendor tag information as
+ * input. Not part of VendorTagDescriptor class because that class is used
+ * in AIDL generated sources which don't have access to AIDL / HIDL headers.
+ */
+class IdlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+ /**
+ * Create a VendorTagDescriptor object from the HIDL/AIDL VendorTagSection
+ * vector.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ template <class VendorTagSectionVectorType, class VendorTagSectionType>
+ static status_t createDescriptorFromIdl(
+ const VendorTagSectionVectorType& vts,
+ /*out*/
+ sp<VendorTagDescriptor>& descriptor);
+};
+
+/**
* A manager for all camera providers available on an Android device.
*
* Responsible for enumerating providers and the individual camera devices
@@ -106,11 +127,13 @@
* opening them for active use.
*
*/
-class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
+class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification,
+ public virtual IServiceManager::LocalRegistrationCallback {
public:
// needs to be made friend strict since HidlProviderInfo needs to inherit
// from CameraProviderManager::ProviderInfo which isn't a public member.
friend struct HidlProviderInfo;
+ friend struct AidlProviderInfo;
~CameraProviderManager();
// Tiny proxy for the static methods in a HIDL interface that communicate with the hardware
@@ -315,6 +338,18 @@
*/
status_t notifyDeviceStateChange(int64_t newState);
+ status_t openAidlSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session);
+
+ status_t openAidlInjectionSession(const std::string &id,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
+ /*out*/
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraInjectionSession> *session);
+
/**
* Open an active session to a camera device.
*
@@ -339,6 +374,9 @@
const hardware::hidl_string& name,
bool preexisting) override;
+ // LocalRegistrationCallback::onServiceRegistration
+ virtual void onServiceRegistration(const String16& name, const sp<IBinder> &binder) override;
+
/**
* Dump out information about available providers and devices
*/
@@ -402,6 +440,17 @@
sp<hardware::camera::provider::V2_4::ICameraProvider> mCameraProvider;
};
+ struct AidlHalCameraProvider : public HalCameraProvider {
+ AidlHalCameraProvider(
+ const std::shared_ptr<
+ aidl::android::hardware::camera::provider::ICameraProvider> &provider,
+ const char *descriptor) :
+ HalCameraProvider(descriptor), mCameraProvider(provider) { };
+ private:
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mCameraProvider;
+ };
+
+
// Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
// ICameraProvider alive while it is in use by the camera with the given ID for camera
// capabilities
@@ -418,10 +467,11 @@
std::mutex mProviderInterfaceMapLock;
struct ProviderInfo : public virtual RefBase {
friend struct HidlProviderInfo;
+ friend struct AidlProviderInfo;
const std::string mProviderName;
const std::string mProviderInstance;
const metadata_vendor_id_t mProviderTagid;
- int mMinorVersion;
+ int32_t mMinorVersion;
sp<VendorTagDescriptor> mVendorTagDescriptor;
bool mSetTorchModeSupported;
bool mIsRemote;
@@ -436,6 +486,7 @@
status_t dump(int fd, const Vector<String16>& args) const;
+ void initializeProviderInfoCommon(const std::vector<std::string> &devices);
/**
* Setup vendor tags for this provider
*/
@@ -452,6 +503,8 @@
virtual bool successfullyStartedProviderInterface() = 0;
+ virtual int64_t getDeviceState() = 0;
+
std::vector<std::unordered_set<std::string>> getConcurrentCameraIdCombinations();
/**
@@ -469,7 +522,6 @@
const std::set<std::string>& perfClassPrimaryCameraIds,
int targetSdkVersion, bool *isSupported) = 0;
-
/**
* Remove all devices associated with this provider and notify listeners
* with NOT_PRESENT state.
@@ -666,6 +718,14 @@
// End of scope for mInitLock
std::future<void> mInitialStatusCallbackFuture;
+
+ std::unique_ptr<ProviderInfo::DeviceInfo>
+ virtual initializeDeviceInfo(
+ const std::string &name, const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion) = 0;
+
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() = 0;
+
void notifyInitialStatusChange(sp<StatusListener> listener,
std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus);
@@ -682,10 +742,46 @@
// Generate vendor tag id
static metadata_vendor_id_t generateVendorTagId(const std::string &name);
+ status_t addDevice(
+ const std::string& name, CameraDeviceStatus initialStatus,
+ /*out*/ std::string* parsedId);
+
+ void cameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ status_t cameraDeviceStatusChangeLocked(
+ std::string* id, const std::string& cameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ void physicalCameraDeviceStatusChangeInternal(const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ status_t physicalCameraDeviceStatusChangeLocked(
+ std::string* id, std::string* physicalId,
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ CameraDeviceStatus newStatus);
+
+ void torchModeStatusChangeInternal(const std::string& cameraDeviceName,
+ TorchModeStatus newStatus);
+
void removeDevice(std::string id);
};
+ template <class ProviderInfoType, class HalCameraProviderType>
+ status_t setTorchModeT(sp<ProviderInfo> &parentProvider,
+ std::shared_ptr<HalCameraProvider> *halCameraProvider);
+
+ // Try to get hidl provider services declared. Expects mInterfaceMutex to be
+ // locked. Also registers for hidl provider service notifications.
+ status_t tryToInitAndAddHidlProvidersLocked(HidlServiceInteractionProxy *hidlProxy);
+
+ // Try to get aidl provider services declared. Expects mInterfaceMutex to be
+ // locked. Also registers for aidl provider service notifications.
+ status_t tryToAddAidlProvidersLocked();
+
/**
* Save the ICameraProvider while it is being used by a camera or torch client
*/
@@ -709,9 +805,14 @@
status_t addHidlProviderLocked(const std::string& newProvider, bool preexisting = false);
+ status_t addAidlProviderLocked(const std::string& newProvider);
+
status_t tryToInitializeHidlProviderLocked(const std::string& providerName,
const sp<ProviderInfo>& providerInfo);
+ status_t tryToInitializeAidlProviderLocked(const std::string& providerName,
+ const sp<ProviderInfo>& providerInfo);
+
bool isLogicalCameraLocked(const std::string& id, std::vector<std::string>* physicalCameraIds);
// No method corresponding to the same provider / member belonging to the
@@ -725,6 +826,8 @@
size_t mProviderInstanceId = 0;
std::vector<sp<ProviderInfo>> mProviders;
+ // Provider names of AIDL providers with retrieved binders.
+ std::set<std::string> mAidlProviderWithBinders;
static const char* deviceStatusToString(
const hardware::camera::common::V1_0::CameraDeviceStatus&);
@@ -744,6 +847,8 @@
std::vector<std::string>& systemCameraDeviceIds) const;
status_t usbDeviceDetached(const std::string &usbDeviceId);
+ ndk::ScopedAStatus onAidlRegistration(const std::string& in_name,
+ const ::ndk::SpAIBinder& in_binder);
};
} // namespace android
diff --git a/services/camera/libcameraservice/common/HalConversionsTemplated.h b/services/camera/libcameraservice/common/HalConversionsTemplated.h
new file mode 100644
index 0000000..96a715c
--- /dev/null
+++ b/services/camera/libcameraservice/common/HalConversionsTemplated.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+#define ANDROID_SERVERS_CAMERA_HAL_CONVERSION_TEMPLATED_H
+
+#include "common/CameraProviderManager.h"
+
+#include <device3/Camera3StreamInterface.h>
+
+namespace android {
+
+template <class HalCameraDeviceStatus>
+HalCameraDeviceStatus mapFrameworkToHalCameraDeviceStatus(
+ const CameraDeviceStatus& s) {
+ switch(s) {
+ case CameraDeviceStatus::PRESENT:
+ return HalCameraDeviceStatus::PRESENT;
+ case CameraDeviceStatus::NOT_PRESENT:
+ return HalCameraDeviceStatus::NOT_PRESENT;
+ case CameraDeviceStatus::ENUMERATING:
+ return HalCameraDeviceStatus::ENUMERATING;
+ }
+ ALOGW("Unexpectedcamera device status code %d", s);
+ return HalCameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraDeviceStatus>
+CameraDeviceStatus HalToFrameworkCameraDeviceStatus(
+ const HalCameraDeviceStatus& s) {
+ switch(s) {
+ case HalCameraDeviceStatus::PRESENT:
+ return CameraDeviceStatus::PRESENT;
+ case HalCameraDeviceStatus::NOT_PRESENT:
+ return CameraDeviceStatus::NOT_PRESENT;
+ case HalCameraDeviceStatus::ENUMERATING:
+ return CameraDeviceStatus::ENUMERATING;
+ }
+ ALOGW("Unexpectedcamera device status code %d", s);
+ return CameraDeviceStatus::NOT_PRESENT;
+}
+
+template <class HalCameraResourceCost>
+CameraResourceCost HalToFrameworkResourceCost(
+ const HalCameraResourceCost& s) {
+ CameraResourceCost internalResourceCost;
+ internalResourceCost.resourceCost = (uint32_t)s.resourceCost;
+ for (const auto device : s.conflictingDevices) {
+ internalResourceCost.conflictingDevices.emplace_back(device.c_str());
+ }
+ return internalResourceCost;
+}
+
+template <class HalTorchModeStatus>
+TorchModeStatus HalToFrameworkTorchModeStatus(
+ const HalTorchModeStatus& s) {
+ switch(s) {
+ case HalTorchModeStatus::NOT_AVAILABLE:
+ return TorchModeStatus::NOT_AVAILABLE;
+ case HalTorchModeStatus::AVAILABLE_OFF:
+ return TorchModeStatus::AVAILABLE_OFF;
+ case HalTorchModeStatus::AVAILABLE_ON:
+ return TorchModeStatus::AVAILABLE_ON;
+ }
+ ALOGW("Unexpectedcamera torch mode status code %d", s);
+ return TorchModeStatus::NOT_AVAILABLE;
+}
+
+template <class HalCameraDeviceStatus>
+ const char* HalDeviceStatusToString(const HalCameraDeviceStatus& s) {
+ switch(s) {
+ case HalCameraDeviceStatus::NOT_PRESENT:
+ return "NOT_PRESENT";
+ case HalCameraDeviceStatus::PRESENT:
+ return "PRESENT";
+ case HalCameraDeviceStatus::ENUMERATING:
+ return "ENUMERATING";
+ }
+ ALOGW("Unexpected HAL device status code %d", s);
+ return "UNKNOWN_STATUS";
+}
+
+}
+
+#endif
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
new file mode 100644
index 0000000..0922b74
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "AidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
+
+#include <cutils/properties.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_manager.h>
+#include <android/hardware/ICameraService.h>
+#include <camera_metadata_hidden.h>
+
+#include "device3/ZoomRatioMapper.h"
+#include <utils/SessionConfigurationUtils.h>
+#include <utils/Trace.h>
+
+namespace {
+const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
+} // anonymous namespace
+
+namespace android {
+
+namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
+
+using namespace aidl::android::hardware;
+using namespace hardware::camera;
+using hardware::camera2::utils::CameraIdAndSessionConfiguration;
+using hardware::ICameraService;
+
+using HalDeviceStatusType = aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ICameraProvider = aidl::android::hardware::camera::provider::ICameraProvider;
+using StatusListener = CameraProviderManager::StatusListener;
+
+status_t AidlProviderInfo::mapToStatusT(const ndk::ScopedAStatus& s) {
+ using Status = aidl::android::hardware::camera::common::Status;
+ Status st = static_cast<Status>(s.getServiceSpecificError());
+ switch(st) {
+ case Status::OK:
+ return OK;
+ case Status::ILLEGAL_ARGUMENT:
+ return BAD_VALUE;
+ case Status::CAMERA_IN_USE:
+ return -EBUSY;
+ case Status::MAX_CAMERAS_IN_USE:
+ return -EUSERS;
+ case Status::METHOD_NOT_SUPPORTED:
+ return UNKNOWN_TRANSACTION;
+ case Status::OPERATION_NOT_SUPPORTED:
+ return INVALID_OPERATION;
+ case Status::CAMERA_DISCONNECTED:
+ return DEAD_OBJECT;
+ case Status::INTERNAL_ERROR:
+ return INVALID_OPERATION;
+ }
+ ALOGW("Unexpected HAL status code %d", static_cast<int>(st));
+ return INVALID_OPERATION;
+}
+
+AidlProviderInfo::AidlProviderInfo(
+ const std::string &providerName,
+ const std::string &providerInstance,
+ CameraProviderManager *manager) :
+ CameraProviderManager::ProviderInfo(providerName, providerInstance, manager) {}
+
+status_t AidlProviderInfo::initializeAidlProvider(
+ std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
+
+ status_t res = parseProviderName(mProviderName, &mType, &mId);
+ if (res != OK) {
+ ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ ALOGI("Connecting to new camera provider: %s, isRemote? %d",
+ mProviderName.c_str(), interface->isRemote());
+
+ // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
+ // before setCallback returns
+ mCallbacks =
+ ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
+ ndk::ScopedAStatus status =
+ interface->setCallback(mCallbacks);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
+ auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
+ if (link != STATUS_OK) {
+ ALOGW("%s: Unable to link to provider '%s' death notifications",
+ __FUNCTION__, mProviderName.c_str());
+ return DEAD_OBJECT;
+ }
+
+ if (!kEnableLazyHal) {
+ // Save HAL reference indefinitely
+ mSavedInterface = interface;
+ } else {
+ mActiveInterface = interface;
+ }
+
+ ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
+ __FUNCTION__, mProviderName.c_str(), mDeviceState);
+ notifyDeviceStateChange(currentDeviceState);
+
+ res = setUpVendorTags();
+ if (res != OK) {
+ ALOGE("%s: Unable to set up vendor tags from provider '%s'",
+ __FUNCTION__, mProviderName.c_str());
+ return res;
+ }
+
+ // Get initial list of camera devices, if any
+ std::vector<std::string> devices;
+ std::vector<std::string> retDevices;
+ status = interface->getCameraIdList(&retDevices);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ for (auto& name : retDevices) {
+ uint16_t major, minor;
+ std::string type, id;
+ status_t res = parseDeviceName(name, &major, &minor, &type, &id);
+ if (res != OK) {
+ ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
+ return res;
+ } else {
+ devices.push_back(name);
+ mProviderPublicCameraIds.push_back(id);
+ }
+ }
+
+ // Get list of concurrent streaming camera device combinations
+ res = getConcurrentCameraIdsInternalLocked(interface);
+ if (res != OK) {
+ return res;
+ }
+
+ mSetTorchModeSupported = true;
+
+ mIsRemote = interface->isRemote();
+
+ initializeProviderInfoCommon(devices);
+ return OK;
+}
+
+void AidlProviderInfo::binderDied(void *cookie) {
+ AidlProviderInfo *provider = reinterpret_cast<AidlProviderInfo *>(cookie);
+ ALOGI("Camera provider '%s' has died; removing it", provider->mProviderInstance.c_str());
+ provider->mManager->removeProvider(provider->mProviderInstance);
+}
+
+status_t AidlProviderInfo::setUpVendorTags() {
+ if (mVendorTagDescriptor != nullptr)
+ return OK;
+
+ std::vector<camera::common::VendorTagSection> vts;
+ ::ndk::ScopedAStatus status;
+ const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ status = interface->getVendorTags(&vts);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.getMessage());
+ return mapToStatusT(status);
+ }
+
+ // Read all vendor tag definitions into a descriptor
+ status_t res;
+ if ((res =
+ IdlVendorTagDescriptor::
+ createDescriptorFromIdl<std::vector<camera::common::VendorTagSection>,
+ camera::common::VendorTagSection>(vts, /*out*/mVendorTagDescriptor))
+ != OK) {
+ ALOGE("%s: Could not generate descriptor from vendor tag operations,"
+ "received error %s (%d). Camera clients will not be able to use"
+ "vendor tags", __FUNCTION__, strerror(res), res);
+ return res;
+ }
+
+ return OK;
+}
+
+status_t AidlProviderInfo::notifyDeviceStateChange(int64_t newDeviceState) {
+
+ mDeviceState = newDeviceState;
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface != nullptr) {
+ // Send current device state
+ interface->notifyDeviceStateChange(mDeviceState);
+ }
+ return OK;
+}
+
+bool AidlProviderInfo::successfullyStartedProviderInterface() {
+ return startProviderInterface() != nullptr;
+}
+
+std::shared_ptr<camera::device::ICameraDevice>
+AidlProviderInfo::startDeviceInterface(const std::string &name) {
+ ::ndk::ScopedAStatus status;
+ std::shared_ptr<camera::device::ICameraDevice> cameraInterface;
+ const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
+ if (interface == nullptr) {
+ return nullptr;
+ }
+ status = interface->getCameraDeviceInterface(name, &cameraInterface);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
+ __FUNCTION__, name.c_str(), status.getMessage());
+ return nullptr;
+ }
+ return cameraInterface;
+}
+
+const std::shared_ptr<ICameraProvider> AidlProviderInfo::startProviderInterface() {
+ ATRACE_CALL();
+ ALOGV("Request to start camera provider: %s", mProviderName.c_str());
+ if (mSavedInterface != nullptr) {
+ return mSavedInterface;
+ }
+ if (!kEnableLazyHal) {
+ ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
+ return nullptr;
+ }
+
+ auto interface = mActiveInterface.lock();
+ if (interface == nullptr) {
+ // Try to get service without starting
+ interface =
+ ICameraProvider::fromBinder(
+ ndk::SpAIBinder(AServiceManager_checkService(mProviderName.c_str())));
+ if (interface == nullptr) {
+ ALOGV("Camera provider actually needs restart, calling getService(%s)",
+ mProviderName.c_str());
+ interface =
+ ICameraProvider::fromBinder(
+ ndk::SpAIBinder(
+ AServiceManager_getService(mProviderName.c_str())));
+
+ // Set all devices as ENUMERATING, provider should update status
+ // to PRESENT after initializing.
+ // This avoids failing getCameraDeviceInterface_V3_x before devices
+ // are ready.
+ for (auto& device : mDevices) {
+ device->mIsDeviceAvailable = false;
+ }
+
+ interface->setCallback(mCallbacks);
+ auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(),
+ this);
+ if (link != STATUS_OK) {
+ ALOGW("%s: Unable to link to provider '%s' death notifications",
+ __FUNCTION__, mProviderName.c_str());
+ mManager->removeProvider(mProviderName);
+ return nullptr;
+ }
+
+ // Send current device state
+ interface->notifyDeviceStateChange(mDeviceState);
+ }
+ mActiveInterface = interface;
+ } else {
+ ALOGV("Camera provider (%s) already in use. Re-using instance.",
+ mProviderName.c_str());
+ }
+
+ return interface;
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::cameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->cameraDeviceStatusChange(cameraDeviceName, newStatus);
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::torchModeStatusChange(
+ const std::string& cameraDeviceName,
+ aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->torchModeStatusChange(cameraDeviceName, newStatus);
+
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ sp<AidlProviderInfo> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: Parent provider not alive", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return parent->physicalCameraDeviceStatusChange(cameraDeviceName, physicalCameraDeviceName,
+ newStatus);
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlProviderInfo::torchModeStatusChange(const std::string& cameraDeviceName,
+ aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
+ torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+};
+
+::ndk::ScopedAStatus AidlProviderInfo::physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ HalDeviceStatusType newStatus) {
+ physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+ HalToFrameworkCameraDeviceStatus(newStatus));
+ return ::ndk::ScopedAStatus::ok();
+};
+
+std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
+ AidlProviderInfo::initializeDeviceInfo(
+ const std::string &name, const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion) {
+ ::ndk::ScopedAStatus status;
+
+ auto cameraInterface = startDeviceInterface(name);
+ if (cameraInterface == nullptr) return nullptr;
+
+ camera::common::CameraResourceCost resourceCost;
+ status = cameraInterface->getResourceCost(&resourceCost);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
+ name.c_str(), status.getMessage());
+ 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<DeviceInfo3>(
+ new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
+ this, mProviderPublicCameraIds, cameraInterface));
+}
+
+status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
+
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface == nullptr) {
+ ALOGE("%s: camera provider interface for %s is not valid", __FUNCTION__,
+ mProviderName.c_str());
+ return INVALID_OPERATION;
+ }
+
+ return getConcurrentCameraIdsInternalLocked(interface);
+}
+
+status_t AidlProviderInfo::getConcurrentCameraIdsInternalLocked(
+ std::shared_ptr<ICameraProvider> &interface) {
+ if (interface == nullptr) {
+ ALOGE("%s: null interface provided", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ std::vector<aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination> combs;
+ ::ndk::ScopedAStatus status = interface->getConcurrentCameraIds(&combs);
+
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error in getting concurrent camera ID list from provider '%s'",
+ __FUNCTION__, mProviderName.c_str());
+ return mapToStatusT(status);
+ }
+ mConcurrentCameraIdCombinations.clear();
+ for (const auto& combination : combs) {
+ std::unordered_set<std::string> deviceIds;
+ for (const auto &cameraDeviceId : combination.combination) {
+ deviceIds.insert(cameraDeviceId.c_str());
+ }
+ mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
+ }
+
+ return OK;
+}
+
+AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
+ const std::string& name,
+ const metadata_vendor_id_t tagId,
+ const std::string &id, uint16_t minorVersion,
+ const CameraResourceCost& resourceCost,
+ sp<CameraProviderManager::ProviderInfo> parentProvider,
+ const std::vector<std::string>& publicCameraIds,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface) :
+ DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
+
+ // Get camera characteristics and initialize flash unit availability
+ aidl::android::hardware::camera::device::CameraMetadata chars;
+ ::ndk::ScopedAStatus status = interface->getCameraCharacteristics(&chars);
+ std::vector<uint8_t> &metadata = chars.metadata;
+ camera_metadata_t *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
+ size_t expectedSize = metadata.size();
+ int resV = validate_camera_metadata_structure(buffer, &expectedSize);
+ if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ set_camera_metadata_vendor_id(buffer, mProviderTagid);
+ mCameraCharacteristics = buffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ return;
+ }
+
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting camera characteristics for device %s"
+ " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
+ status.getMessage());
+ return;
+ }
+
+ if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+ const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
+ if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
+ for (size_t i = 0; i < stateMap.count; i += 2) {
+ mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
+ }
+ } else {
+ ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
+ stateMap.count);
+ }
+ }
+
+ mSystemCameraKind = getSystemCameraKind();
+
+ status_t res = fixupMonochromeTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return;
+ }
+ auto stat = addDynamicDepthTags();
+ if (OK != stat) {
+ ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+ stat);
+ }
+ res = deriveHeicTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+
+ if (camera3::SessionConfigurationUtils::isUltraHighResolutionSensor(mCameraCharacteristics)) {
+ status_t status = addDynamicDepthTags(/*maxResolution*/true);
+ if (OK != status) {
+ ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
+ __FUNCTION__, strerror(-status), status);
+ }
+
+ status = deriveHeicTags(/*maxResolution*/true);
+ if (OK != status) {
+ ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
+ "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
+ }
+ }
+
+ res = addRotateCropTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ }
+ res = addPreCorrectionActiveArraySize();
+ if (OK != res) {
+ ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ }
+ res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+ &mCameraCharacteristics, &mSupportNativeZoomRatio);
+ if (OK != res) {
+ ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+
+ camera_metadata_entry flashAvailable =
+ mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
+ if (flashAvailable.count == 1 &&
+ flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+ mHasFlashUnit = true;
+ } else {
+ mHasFlashUnit = false;
+ }
+
+ camera_metadata_entry entry =
+ mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
+ if (entry.count == 1) {
+ mTorchDefaultStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchDefaultStrengthLevel = 0;
+ }
+ entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
+ if (entry.count == 1) {
+ mTorchMaximumStrengthLevel = entry.data.i32[0];
+ } else {
+ mTorchMaximumStrengthLevel = 0;
+ }
+
+ mTorchStrengthLevel = 0;
+
+ queryPhysicalCameraIds();
+
+ // Get physical camera characteristics if applicable
+ if (mIsLogicalCamera) {
+ for (auto& id : mPhysicalIds) {
+ if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
+ mPublicCameraIds.end()) {
+ continue;
+ }
+
+ aidl::android::hardware::camera::device::CameraMetadata pChars;
+ status = interface->getPhysicalCameraCharacteristics(id, &pChars);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
+ __FUNCTION__, id.c_str(), id.c_str(), status.getMessage());
+ return;
+ }
+ std::vector<uint8_t> &pMetadata = pChars.metadata;
+ camera_metadata_t *pBuffer =
+ reinterpret_cast<camera_metadata_t*>(pMetadata.data());
+ size_t expectedSize = pMetadata.size();
+ int res = validate_camera_metadata_structure(pBuffer, &expectedSize);
+ if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ set_camera_metadata_vendor_id(pBuffer, mProviderTagid);
+ mPhysicalCameraCharacteristics[id] = pBuffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ return;
+ }
+
+ res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
+ &mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
+ if (OK != res) {
+ ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+ }
+
+ if (!kEnableLazyHal) {
+ // Save HAL reference indefinitely
+ mSavedInterface = interface;
+ }
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::setTorchMode(bool enabled) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ ::ndk::ScopedAStatus s = interface->setTorchMode(enabled);
+ if (!s.isOk()) {
+ ALOGE("%s Unable to set torch mode: %s", __FUNCTION__, s.getMessage());
+ return mapToStatusT(s);
+ }
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::turnOnTorchWithStrengthLevel(
+ int32_t torchStrength) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus s = interface->turnOnTorchWithStrengthLevel(torchStrength);
+ if (!s.isOk()) {
+ ALOGE("%s Unable to set torch mode strength %d : %s", __FUNCTION__, torchStrength,
+ s.getMessage());
+ return mapToStatusT(s);
+ }
+ mTorchStrengthLevel = torchStrength;
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
+ if (torchStrength == nullptr) {
+ return BAD_VALUE;
+ }
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus status = interface->getTorchStrengthLevel(torchStrength);
+ if (!status.isOk()) {
+ ALOGE("%s: Couldn't get torch strength level: %s", __FUNCTION__, status.getMessage());
+ return mapToStatusT(status);
+ }
+ return OK;
+}
+
+std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+AidlProviderInfo::AidlDeviceInfo3::startDeviceInterface() {
+ Mutex::Autolock l(mDeviceAvailableLock);
+ std::shared_ptr<camera::device::ICameraDevice> device;
+ ATRACE_CALL();
+ if (mSavedInterface == nullptr) {
+ sp<AidlProviderInfo> parentProvider =
+ static_cast<AidlProviderInfo *>(mParentProvider.promote().get());
+ if (parentProvider != nullptr) {
+ // Wait for lazy HALs to confirm device availability
+ if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
+ ALOGV("%s: Wait for external device to become available %s",
+ __FUNCTION__,
+ mId.c_str());
+
+ auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
+ kDeviceAvailableTimeout);
+ if (res != OK) {
+ ALOGE("%s: Failed waiting for device to become available",
+ __FUNCTION__);
+ return nullptr;
+ }
+ }
+
+ device = parentProvider->startDeviceInterface(mName);
+ }
+ } else {
+ device = mSavedInterface;
+ }
+ return device;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::dumpState(int fd) {
+ native_handle_t* handle = native_handle_create(1,0);
+ handle->data[0] = fd;
+ const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+ ::ndk::ScopedFileDescriptor sFd;
+ sFd.set(fcntl(fd, F_DUPFD_CLOEXEC, 0));
+ auto ret = interface->dumpState(sFd);
+ native_handle_delete(handle);
+ if (!ret.isOk()) {
+ return mapToStatusT(ret);
+ }
+ return OK;
+}
+
+status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
+ const SessionConfiguration &configuration, bool overrideForPerfClass, bool *status) {
+
+ camera::device::StreamConfiguration streamConfiguration;
+ bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+ CameraMetadata physicalChars;
+ getPhysicalCameraCharacteristics(id.c_str(), &physicalChars);
+ return physicalChars;
+ };
+ auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
+ String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
+ streamConfiguration, overrideForPerfClass, &earlyExit);
+
+ if (!bRes.isOk()) {
+ return UNKNOWN_ERROR;
+ }
+
+ if (earlyExit) {
+ *status = false;
+ return OK;
+ }
+
+ const std::shared_ptr<camera::device::ICameraDevice> interface =
+ startDeviceInterface();
+
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ ::ndk::ScopedAStatus ret =
+ interface->isStreamCombinationSupported(streamConfiguration, status);
+ if (!ret.isOk()) {
+ *status = false;
+ ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
+ return mapToStatusT(ret);
+ }
+ return OK;
+
+}
+
+status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion,
+ std::vector<camera::provider::CameraIdAndStreamCombination>
+ *halCameraIdsAndStreamCombinations,
+ bool *earlyExit) {
+ binder::Status bStatus = binder::Status::ok();
+ std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamsV;
+ bool shouldExit = false;
+ status_t res = OK;
+ for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
+ const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
+ camera::device::StreamConfiguration streamConfiguration;
+ CameraMetadata deviceInfo;
+ bool overrideForPerfClass =
+ SessionConfigurationUtils::targetPerfClassPrimaryCamera(
+ perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
+ res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo);
+ if (res != OK) {
+ return res;
+ }
+ camera3::metadataGetter getMetadata =
+ [this](const String8 &id, bool overrideForPerfClass) {
+ CameraMetadata physicalDeviceInfo;
+ mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
+ &physicalDeviceInfo);
+ return physicalDeviceInfo;
+ };
+ std::vector<std::string> physicalCameraIds;
+ mManager->isLogicalCameraLocked(cameraId, &physicalCameraIds);
+ bStatus =
+ SessionConfigurationUtils::convertToHALStreamCombination(
+ cameraIdAndSessionConfig.mSessionConfiguration,
+ String8(cameraId.c_str()), deviceInfo, getMetadata,
+ physicalCameraIds, streamConfiguration,
+ overrideForPerfClass, &shouldExit);
+ if (!bStatus.isOk()) {
+ ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if (shouldExit) {
+ *earlyExit = true;
+ return OK;
+ }
+ camera::provider::CameraIdAndStreamCombination halCameraIdAndStream;
+ halCameraIdAndStream.cameraId = cameraId;
+ halCameraIdAndStream.streamConfiguration = streamConfiguration;
+ halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
+ }
+ *halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
+ return OK;
+}
+
+status_t AidlProviderInfo::isConcurrentSessionConfigurationSupported(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion, bool *isSupported) {
+
+ std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamCombinations;
+ bool knowUnsupported = false;
+ status_t res = convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds,
+ targetSdkVersion, &halCameraIdsAndStreamCombinations, &knowUnsupported);
+ if (res != OK) {
+ ALOGE("%s unable to convert session configurations provided to HAL stream"
+ "combinations", __FUNCTION__);
+ return res;
+ }
+ if (knowUnsupported) {
+ // We got to know the streams aren't valid before doing the HAL
+ // call itself.
+ *isSupported = false;
+ return OK;
+ }
+
+ // Check if the provider is currently active - not going to start it up for this notification
+ auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
+ if (interface == nullptr) {
+ // TODO: This might be some other problem
+ return INVALID_OPERATION;
+ }
+ ::ndk::ScopedAStatus status = interface->isConcurrentStreamCombinationSupported(
+ halCameraIdsAndStreamCombinations, isSupported);
+ if (!status.isOk()) {
+ *isSupported = false;
+ ALOGE("%s: hal interface session configuration query failed", __FUNCTION__);
+ return mapToStatusT(status);
+ }
+
+ return OK;
+}
+
+} //namespace android
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
new file mode 100644
index 0000000..aa71e85
--- /dev/null
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_AIDLPROVIDERINFOH
+
+#include "common/CameraProviderManager.h"
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/provider/BnCameraProviderCallback.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+
+namespace android {
+
+struct AidlProviderInfo : public CameraProviderManager::ProviderInfo {
+ // Current overall Android device physical status
+ int64_t mDeviceState;
+
+ // This pointer is used to keep a reference to the ICameraProvider that was last accessed.
+ std::weak_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mActiveInterface;
+
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> mSavedInterface;
+
+ AidlProviderInfo(
+ const std::string &providerName,
+ const std::string &providerInstance,
+ CameraProviderManager *manager);
+
+ static status_t mapToStatusT(const ndk::ScopedAStatus& s);
+
+ // Start camera device interface, start the camera provider process for lazy
+ // hals, if needed
+ status_t initializeAidlProvider(
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>& interface,
+ int64_t currentDeviceState);
+
+ static void binderDied(void *cookie);
+
+ virtual IPCTransport getIPCTransport() override {return IPCTransport::AIDL;}
+
+ const std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
+ startProviderInterface();
+
+ virtual status_t setUpVendorTags() override;
+ virtual status_t notifyDeviceStateChange(int64_t newDeviceState) override;
+
+ virtual bool successfullyStartedProviderInterface() override;
+
+ virtual int64_t getDeviceState() override { return mDeviceState; };
+
+ /**
+ * Query the camera provider for concurrent stream configuration support
+ */
+ virtual status_t isConcurrentSessionConfigurationSupported(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion, bool *isSupported) override;
+
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ startDeviceInterface(const std::string &deviceName);
+
+ // AIDL ICameraProviderCallback interface - these lock the parent
+ // mInterfaceMutex
+
+ ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+ ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::TorchModeStatus newStatus);
+
+ ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus);
+
+ struct AidlProviderCallbacks :
+ public aidl::android::hardware::camera::provider::BnCameraProviderCallback {
+ AidlProviderCallbacks(wp<AidlProviderInfo> parent) : mParent(parent) { }
+ virtual ::ndk::ScopedAStatus cameraDeviceStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+ virtual ::ndk::ScopedAStatus torchModeStatusChange(const std::string& cameraDeviceName,
+ ::aidl::android::hardware::camera::common::TorchModeStatus newStatus) override;
+
+ virtual ::ndk::ScopedAStatus physicalCameraDeviceStatusChange(
+ const std::string& cameraDeviceName,
+ const std::string& physicalCameraDeviceName,
+ ::aidl::android::hardware::camera::common::CameraDeviceStatus newStatus) override;
+
+ private:
+ wp<AidlProviderInfo> mParent = nullptr;
+
+ };
+
+ struct AidlDeviceInfo3 : public CameraProviderManager::ProviderInfo::DeviceInfo3 {
+
+ //TODO: fix init
+ const hardware::hidl_version mVersion = hardware::hidl_version{3, 2};
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ mSavedInterface = nullptr;
+
+ AidlDeviceInfo3(const std::string& , const metadata_vendor_id_t ,
+ const std::string &, uint16_t ,
+ const CameraResourceCost& ,
+ sp<ProviderInfo> ,
+ const std::vector<std::string>& ,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>);
+
+ ~AidlDeviceInfo3() {}
+
+ virtual status_t setTorchMode(bool enabled) override;
+ virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) override;
+ virtual status_t getTorchStrengthLevel(int32_t *torchStrength) override;
+
+ virtual status_t dumpState(int fd) override;
+
+ virtual status_t isSessionConfigurationSupported(
+ const SessionConfiguration &/*configuration*/,
+ bool overrideForPerfClass,
+ bool *status/*status*/);
+
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
+ startDeviceInterface();
+ };
+
+ private:
+
+ // Helper for initializeDeviceInfo to use the right CameraProvider get method.
+ virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+ const metadata_vendor_id_t , const std::string &,
+ uint16_t ) override;
+
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
+
+ //Expects to have mLock locked
+
+ status_t getConcurrentCameraIdsInternalLocked(
+ std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider> &interface);
+
+ //expects to have mManager->mInterfaceMutex locked
+
+ status_t convertToAidlHALStreamCombinationAndCameraIdsLocked(
+ const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
+ const std::set<std::string>& perfClassPrimaryCameraIds,
+ int targetSdkVersion,
+ std::vector<aidl::android::hardware::camera::provider::CameraIdAndStreamCombination>
+ *halCameraIdsAndStreamCombinations,
+ bool *earlyExit);
+ std::shared_ptr<AidlProviderCallbacks> mCallbacks = nullptr;
+ ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+};
+
+} // namespace android
+#endif
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index e8432a6..3c5ea75 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "HidlProviderInfo.h"
+#include "common/HalConversionsTemplated.h"
+#include "common/CameraProviderInfoTemplated.h"
#include <cutils/properties.h>
@@ -42,6 +44,7 @@
using StatusListener = CameraProviderManager::StatusListener;
+using HalDeviceStatusType = android::hardware::camera::common::V1_0::CameraDeviceStatus;
using hardware::camera::provider::V2_5::DeviceState;
using hardware::ICameraService;
@@ -111,83 +114,6 @@
return "UNKNOWN_ERROR";
}
-static common::V1_0::CameraDeviceStatus mapToHidlCameraDeviceStatus(const CameraDeviceStatus& s) {
- switch(s) {
- case CameraDeviceStatus::PRESENT:
- return common::V1_0::CameraDeviceStatus::PRESENT;
- case CameraDeviceStatus::NOT_PRESENT:
- return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
- case CameraDeviceStatus::ENUMERATING:
- return common::V1_0::CameraDeviceStatus::ENUMERATING;
- }
- ALOGW("Unexpectedcamera device status code %d", s);
- return common::V1_0::CameraDeviceStatus::NOT_PRESENT;
-}
-
-static CameraDeviceStatus hidlToInternalCameraDeviceStatus(
- const common::V1_0::CameraDeviceStatus& s) {
- switch(s) {
- case common::V1_0::CameraDeviceStatus::PRESENT:
- return CameraDeviceStatus::PRESENT;
- case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
- return CameraDeviceStatus::NOT_PRESENT;
- case common::V1_0::CameraDeviceStatus::ENUMERATING:
- return CameraDeviceStatus::ENUMERATING;
- }
- ALOGW("Unexpectedcamera device status code %d", s);
- return CameraDeviceStatus::NOT_PRESENT;
-}
-
-static TorchModeStatus hidlToInternalTorchModeStatus(
- const common::V1_0::TorchModeStatus& s) {
- switch(s) {
- case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
- return TorchModeStatus::NOT_AVAILABLE;
- case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
- return TorchModeStatus::AVAILABLE_OFF;
- case common::V1_0::TorchModeStatus::AVAILABLE_ON:
- return TorchModeStatus::AVAILABLE_ON;
- }
- ALOGW("Unexpectedcamera torch mode status code %d", s);
- return TorchModeStatus::NOT_AVAILABLE;
-}
-
-static CameraResourceCost hidlToInternalResourceCost(
- const common::V1_0::CameraResourceCost& s) {
- CameraResourceCost internalResourceCost;
- internalResourceCost.resourceCost = s.resourceCost;
- for (const auto device : s.conflictingDevices) {
- internalResourceCost.conflictingDevices.emplace_back(device.c_str());
- }
- return internalResourceCost;
-}
-
-static const char* deviceStatusToString(const common::V1_0::CameraDeviceStatus& s) {
- switch(s) {
- case common::V1_0::CameraDeviceStatus::NOT_PRESENT:
- return "NOT_PRESENT";
- case common::V1_0::CameraDeviceStatus::PRESENT:
- return "PRESENT";
- case common::V1_0::CameraDeviceStatus::ENUMERATING:
- return "ENUMERATING";
- }
- ALOGW("Unexpected HAL device status code %d", s);
- return "UNKNOWN_STATUS";
-}
-
-static const char* torchStatusToString(const common::V1_0::TorchModeStatus& s) {
- switch(s) {
- case common::V1_0::TorchModeStatus::NOT_AVAILABLE:
- return "NOT_AVAILABLE";
- case common::V1_0::TorchModeStatus::AVAILABLE_OFF:
- return "AVAILABLE_OFF";
- case common::V1_0::TorchModeStatus::AVAILABLE_ON:
- return "AVAILABLE_ON";
- }
- ALOGW("Unexpected HAL torch mode status code %d", s);
- return "UNKNOWN_STATUS";
-}
-
status_t HidlProviderInfo::initializeHidlProvider(
sp<provider::V2_4::ICameraProvider>& interface,
int64_t currentDeviceState) {
@@ -326,55 +252,7 @@
mIsRemote = interface->isRemote();
- sp<StatusListener> listener = mManager->getStatusListener();
- for (auto& device : devices) {
- std::string id;
- status_t res = addDevice(device, 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;
- }
- }
-
- ALOGI("Camera provider %s ready with %zu camera devices",
- mProviderName.c_str(), mDevices.size());
-
- // Process cached status callbacks
- std::unique_ptr<std::vector<CameraStatusInfoT>> cachedStatus =
- std::make_unique<std::vector<CameraStatusInfoT>>();
- {
- std::lock_guard<std::mutex> lock(mInitLock);
-
- for (auto& statusInfo : mCachedStatus) {
- std::string id, physicalId;
- status_t res = OK;
- if (statusInfo.isPhysicalCameraStatus) {
- res = physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
- statusInfo.cameraId, statusInfo.physicalCameraId,
- mapToHidlCameraDeviceStatus(statusInfo.status));
- } else {
- res = cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId,
- mapToHidlCameraDeviceStatus(statusInfo.status));
- }
- if (res == OK) {
- cachedStatus->emplace_back(statusInfo.isPhysicalCameraStatus,
- id.c_str(), physicalId.c_str(), statusInfo.status);
- }
- }
- mCachedStatus.clear();
-
- mInitialized = true;
- }
-
- // The cached status change callbacks cannot be fired directly from this
- // function, due to same-thread deadlock trying to acquire mInterfaceMutex
- // twice.
- if (listener != nullptr) {
- mInitialStatusCallbackFuture = std::async(std::launch::async,
- &CameraProviderManager::ProviderInfo::notifyInitialStatusChange, this,
- listener, std::move(cachedStatus));
- }
+ initializeProviderInfoCommon(devices);
return OK;
}
@@ -409,7 +287,10 @@
// Read all vendor tag definitions into a descriptor
status_t res;
- if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/mVendorTagDescriptor))
+ if ((res = IdlVendorTagDescriptor::createDescriptorFromIdl<
+ hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>,
+ hardware::camera::common::V1_0::VendorTagSection>(vts,
+ /*out*/mVendorTagDescriptor))
!= OK) {
ALOGE("%s: Could not generate descriptor from vendor tag operations,"
"received error %s (%d). Camera clients will not be able to use"
@@ -539,256 +420,25 @@
hardware::Return<void> HidlProviderInfo::cameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- sp<StatusListener> listener;
- std::string id;
- std::lock_guard<std::mutex> lock(mInitLock);
- CameraDeviceStatus internalNewStatus = hidlToInternalCameraDeviceStatus(newStatus);
- if (!mInitialized) {
- mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
- cameraDeviceName.c_str(), std::string().c_str(),
- internalNewStatus);
- return hardware::Void();
- }
-
- {
- std::lock_guard<std::mutex> lock(mLock);
- if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
- return hardware::Void();
- }
- listener = mManager->getStatusListener();
- }
-
- // Call without lock held to allow reentrancy into provider manager
- if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()), internalNewStatus);
- }
-
+ HalDeviceStatusType newStatus) {
+ cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
return hardware::Void();
}
-status_t HidlProviderInfo::addDevice(const std::string& name,
- common::V1_0::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:
- ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:", __FUNCTION__,
- name.c_str(), major);
- return BAD_VALUE;
- case 3:
- deviceInfo = initializeDeviceInfo(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->notifyDeviceStateChange(mDeviceState);
- deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(initialStatus);
- bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
-
- mDevices.push_back(std::move(deviceInfo));
-
- mUniqueCameraIds.insert(id);
- if (isAPI1Compatible) {
- // addDevice can be called more than once for the same camera id if HAL
- // supports openLegacy.
- if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
- id) == mUniqueAPI1CompatibleCameraIds.end()) {
- mUniqueAPI1CompatibleCameraIds.push_back(id);
- }
- }
-
- if (parsedId != nullptr) {
- *parsedId = id;
- }
- return OK;
-}
-
-status_t HidlProviderInfo::cameraDeviceStatusChangeLocked(
- std::string* id, const hardware::hidl_string& cameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- bool known = false;
- std::string cameraId;
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
- ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
- deviceStatusToString(newStatus),
- deviceStatusToString(mapToHidlCameraDeviceStatus(deviceInfo->mStatus)));
- deviceInfo->mStatus = hidlToInternalCameraDeviceStatus(newStatus);
- // TODO: Handle device removal (NOT_PRESENT)
- cameraId = deviceInfo->mId;
- known = true;
- deviceInfo->mIsDeviceAvailable =
- (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT);
- deviceInfo->mDeviceAvailableSignal.signal();
- break;
- }
- }
- // Previously unseen device; status must not be NOT_PRESENT
- if (!known) {
- if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
- ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str());
- return BAD_VALUE;
- }
- addDevice(cameraDeviceName, newStatus, &cameraId);
- } else if (newStatus == hardware::camera::common::V1_0::CameraDeviceStatus::NOT_PRESENT) {
- removeDevice(cameraId);
- } else if (isExternalLazyHAL()) {
- // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
- // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
- // notif. would overwrite it
- return BAD_VALUE;
- }
- if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
- ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
- __FUNCTION__, mProviderName.c_str());
- }
- *id = cameraId;
- return OK;
-}
-
hardware::Return<void> HidlProviderInfo::physicalCameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
const hardware::hidl_string& physicalCameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- sp<StatusListener> listener;
- std::string id;
- std::string physicalId;
- std::lock_guard<std::mutex> lock(mInitLock);
- CameraDeviceStatus newInternalStatus = hidlToInternalCameraDeviceStatus(newStatus);
- if (!mInitialized) {
- mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
- physicalCameraDeviceName, newInternalStatus);
- return hardware::Void();
- }
-
- {
- std::lock_guard<std::mutex> lock(mLock);
-
- if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
- physicalCameraDeviceName, newStatus)) {
- return hardware::Void();
- }
-
- listener = mManager->getStatusListener();
- }
- // Call without lock held to allow reentrancy into provider manager
- if (listener != nullptr) {
- listener->onDeviceStatusChanged(String8(id.c_str()),
- String8(physicalId.c_str()), newInternalStatus);
- }
+ HalDeviceStatusType newStatus) {
+ physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
+ HalToFrameworkCameraDeviceStatus(newStatus));
return hardware::Void();
}
-status_t HidlProviderInfo::physicalCameraDeviceStatusChangeLocked(
- std::string* id, std::string* physicalId,
- const hardware::hidl_string& cameraDeviceName,
- const hardware::hidl_string& physicalCameraDeviceName,
- hardware::camera::common::V1_0::CameraDeviceStatus newStatus) {
- bool known = false;
- std::string cameraId;
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- cameraId = deviceInfo->mId;
- if (!deviceInfo->mIsLogicalCamera) {
- ALOGE("%s: Invalid combination of camera id %s, physical id %s",
- __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
- if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
- physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
- ALOGE("%s: Invalid combination of camera id %s, physical id %s",
- __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
- ALOGI("Camera device %s physical device %s status is now %s",
- cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
- deviceStatusToString(newStatus));
- known = true;
- break;
- }
- }
- // Previously unseen device; status must not be NOT_PRESENT
- if (!known) {
- ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(),
- physicalCameraDeviceName.c_str());
- return BAD_VALUE;
- }
-
- *id = cameraId;
- *physicalId = physicalCameraDeviceName.c_str();
- return OK;
-}
-
hardware::Return<void> HidlProviderInfo::torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) {
- sp<StatusListener> listener;
- SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
- std::string id;
- bool known = false;
- {
- // Hold mLock for accessing mDevices
- std::lock_guard<std::mutex> lock(mLock);
- for (auto& deviceInfo : mDevices) {
- if (deviceInfo->mName == cameraDeviceName) {
- ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
- torchStatusToString(newStatus));
- id = deviceInfo->mId;
- known = true;
- systemCameraKind = deviceInfo->mSystemCameraKind;
- if (hardware::camera::common::V1_0::TorchModeStatus::AVAILABLE_ON != newStatus) {
- mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
- }
- break;
- }
- }
- if (!known) {
- ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
- return hardware::Void();
- }
- // no lock needed since listener is set up only once during
- // CameraProviderManager initialization and then never changed till it is
- // destructed.
- listener = mManager->getStatusListener();
- }
- // Call without lock held to allow reentrancy into provider manager
- // The problem with holding mLock here is that we
- // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
- // back into CameraProviderManager which might try to hold mLock again (eg:
- // findDeviceInfo, which should be holding mLock while iterating through
- // each provider's devices).
- if (listener != nullptr) {
- listener->onTorchStatusChanged(String8(id.c_str()),
- hidlToInternalTorchModeStatus(newStatus), systemCameraKind);
- }
+
+ torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
return hardware::Void();
}
@@ -836,7 +486,7 @@
}
return std::unique_ptr<DeviceInfo3>(
- new HidlDeviceInfo3(name, tagId, id, minorVersion, hidlToInternalResourceCost(resourceCost),
+ new HidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
this, mProviderPublicCameraIds, cameraInterface));
}
@@ -1474,91 +1124,4 @@
return INVALID_OPERATION;
}
-status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
- const hardware::hidl_vec<common::V1_0::VendorTagSection>& vts,
- sp<VendorTagDescriptor>& descriptor) {
-
- int tagCount = 0;
-
- for (size_t s = 0; s < vts.size(); s++) {
- tagCount += vts[s].tags.size();
- }
-
- if (tagCount < 0 || tagCount > INT32_MAX) {
- ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
- return BAD_VALUE;
- }
-
- Vector<uint32_t> tagArray;
- LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
- "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
-
-
- sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
- desc->mTagCount = tagCount;
-
- SortedVector<String8> sections;
- KeyedVector<uint32_t, String8> tagToSectionMap;
-
- int idx = 0;
- for (size_t s = 0; s < vts.size(); s++) {
- const common::V1_0::VendorTagSection& section = vts[s];
- const char *sectionName = section.sectionName.c_str();
- if (sectionName == NULL) {
- ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
- return BAD_VALUE;
- }
- String8 sectionString(sectionName);
- sections.add(sectionString);
-
- for (size_t j = 0; j < section.tags.size(); j++) {
- uint32_t tag = section.tags[j].tagId;
- if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
- ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
-
- tagArray.editItemAt(idx++) = section.tags[j].tagId;
-
- const char *tagName = section.tags[j].tagName.c_str();
- if (tagName == NULL) {
- ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
- desc->mTagToNameMap.add(tag, String8(tagName));
- tagToSectionMap.add(tag, sectionString);
-
- int tagType = (int) section.tags[j].tagType;
- if (tagType < 0 || tagType >= NUM_TYPES) {
- ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
- return BAD_VALUE;
- }
- desc->mTagToTypeMap.add(tag, tagType);
- }
- }
-
- desc->mSections = sections;
-
- for (size_t i = 0; i < tagArray.size(); ++i) {
- uint32_t tag = tagArray[i];
- String8 sectionString = tagToSectionMap.valueFor(tag);
-
- // Set up tag to section index map
- ssize_t index = sections.indexOf(sectionString);
- LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
- desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
-
- // Set up reverse mapping
- ssize_t reverseIndex = -1;
- if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
- KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
- reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
- }
- desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
- }
-
- descriptor = std::move(desc);
- return OK;
-}
-
} //namespace android
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index 0ba2aff..4181fea 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -21,25 +21,6 @@
namespace android {
-/**
- * The vendor tag descriptor class that takes HIDL vendor tag information as
- * input. Not part of VendorTagDescriptor class because that class is used
- * in AIDL generated sources which don't have access to HIDL headers.
- */
-class HidlVendorTagDescriptor : public VendorTagDescriptor {
-public:
- /**
- * Create a VendorTagDescriptor object from the HIDL VendorTagSection
- * vector.
- *
- * Returns OK on success, or a negative error code.
- */
- static status_t createDescriptorFromHidl(
- const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
- /*out*/
- sp<VendorTagDescriptor>& descriptor);
-};
-
struct HidlProviderInfo : public CameraProviderManager::ProviderInfo,
virtual public hardware::camera::provider::V2_6::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient {
@@ -70,6 +51,8 @@
virtual bool successfullyStartedProviderInterface() override;
+ virtual int64_t getDeviceState() override {return mDeviceState;};
+
virtual status_t setUpVendorTags() override;
virtual status_t notifyDeviceStateChange(int64_t) override;
@@ -129,24 +112,10 @@
private:
- status_t cameraDeviceStatusChangeLocked(
- std::string* , const hardware::hidl_string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus );
-
- status_t physicalCameraDeviceStatusChangeLocked(
- std::string* , std::string* ,
- const hardware::hidl_string& ,
- const hardware::hidl_string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus );
-
- status_t addDevice(const std::string& ,
- hardware::camera::common::V1_0::CameraDeviceStatus ,
- /*out*/ std::string *);
-
- std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
+ virtual std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &,
const metadata_vendor_id_t , const std::string &,
- uint16_t );
- status_t reCacheConcurrentStreamingCameraIdsLocked();
+ uint16_t ) override;
+ virtual status_t reCacheConcurrentStreamingCameraIdsLocked() override;
//Expects to have mLock locked
status_t getConcurrentCameraIdsInternalLocked(
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index f31241c..eb3cdf2 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -65,8 +65,6 @@
#include "utils/TraceHFR.h"
#include "utils/CameraServiceProxyWrapper.h"
-#include "../common/hidl/HidlProviderInfo.h"
-
#include <algorithm>
#include <tuple>
@@ -2737,11 +2735,7 @@
physicalMetadata, outputBuffers, numOutputBuffers, inputStreamId);
}
-/**
- * HalInterface inner class methods
- */
-
-void Camera3Device::HalInterface::cleanupNativeHandles(
+void Camera3Device::cleanupNativeHandles(
std::vector<native_handle_t*> *handles, bool closeFd) {
if (handles == nullptr) {
return;
@@ -2758,6 +2752,10 @@
return;
}
+/**
+ * HalInterface inner class methods
+ */
+
void Camera3Device::HalInterface::getInflightBufferKeys(
std::vector<std::pair<int32_t, int32_t>>* out) {
mBufferRecords.getInflightBufferKeys(out);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 0f5e65b..e60e617 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -78,11 +78,17 @@
public camera3::RequestBufferInterface,
public camera3::FlushBufferInterface {
friend class HidlCamera3Device;
+ friend class AidlCamera3Device;
public:
explicit Camera3Device(const String8& id, bool overrideForPerfClass, bool legacyClient = false);
virtual ~Camera3Device();
+ // Delete and optionally close native handles and clear the input vector afterward
+ static void cleanupNativeHandles(
+ std::vector<native_handle_t*> *handles, bool closeFd = false);
+
+ IPCTransport getTransportType() { return mInterface->getTransportType(); }
/**
* CameraDeviceBase interface
@@ -450,10 +456,6 @@
return OK;
}
- // Delete and optionally close native handles and clear the input vector afterward
- static void cleanupNativeHandles(
- std::vector<native_handle_t*> *handles, bool closeFd = false);
-
virtual void onBufferFreed(int streamId, const native_handle_t* handle) override;
std::mutex mFreedBuffersLock;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
index 7dc8e10..2e05dda 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtilsTemplated.h
@@ -60,12 +60,12 @@
}
inline void readBufferFromVec(std::vector<uint8_t> &dst, const std::vector<uint8_t> &src) {
- // TODO: Check if we're really supposed to copy
dst = src;
}
+
// Reading one camera metadata from result argument via fmq or from the result
// Assuming the fmq is protected by a lock already
-template <class FmqType, class MetadataType>
+template <class FmqType, class FmqPayloadType, class MetadataType>
status_t readOneCameraMetadataLockedT(
std::unique_ptr<FmqType>& fmq,
uint64_t fmqResultSize,
@@ -76,7 +76,7 @@
if (fmq == nullptr) {
return NO_MEMORY; // logged in initialize()
}
- if (!fmq->read(resultMetadata.data(), fmqResultSize)) {
+ if (!fmq->read(reinterpret_cast<FmqPayloadType *>(resultMetadata.data()), fmqResultSize)) {
ALOGE("%s: Cannot read camera metadata from fmq, size = %" PRIu64,
__FUNCTION__, fmqResultSize);
return INVALID_OPERATION;
@@ -130,8 +130,21 @@
return handle.fds[0].get();
}
+inline const hardware::hidl_vec<uint8_t>&
+getResultMetadata(const android::hardware::camera::device::V3_2::CameraMetadata &result) {
+ return result;
+}
+
+inline const std::vector<uint8_t>&
+getResultMetadata(const aidl::android::hardware::camera::device::CameraMetadata &result) {
+ return result.metadata;
+}
+
+// Fmqpayload type is needed since AIDL generates an fmq of payload type int8_t
+// for a byte fmq vs MetadataType which is uint8_t. For HIDL, the same type is
+// generated for metadata and fmq payload : uint8_t.
template <class StatesType, class CaptureResultType, class PhysMetadataType, class MetadataType,
- class FmqType, class BufferStatusType>
+ class FmqType, class BufferStatusType, class FmqPayloadType = uint8_t>
void processOneCaptureResultLockedT(
StatesType& states,
const CaptureResultType& result,
@@ -144,9 +157,9 @@
// Read and validate the result metadata.
MetadataType resultMetadata;
- res = readOneCameraMetadataLockedT(
+ res = readOneCameraMetadataLockedT<FmqType, FmqPayloadType, MetadataType>(
fmq, result.fmqResultSize,
- resultMetadata, result.result);
+ resultMetadata, getResultMetadata(result.result));
if (res != OK) {
ALOGE("%s: Frame %d: Failed to read capture result metadata",
__FUNCTION__, result.frameNumber);
@@ -161,8 +174,9 @@
std::vector<MetadataType> physResultMetadata;
physResultMetadata.resize(physResultCount);
for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
- res = readOneCameraMetadataLockedT(fmq, physicalCameraMetadata[i].fmqMetadataSize,
- physResultMetadata[i], physicalCameraMetadata[i].metadata);
+ res = readOneCameraMetadataLockedT<FmqType, FmqPayloadType, MetadataType>(fmq,
+ physicalCameraMetadata[i].fmqMetadataSize,
+ physResultMetadata[i], getResultMetadata(physicalCameraMetadata[i].metadata));
if (res != OK) {
ALOGE("%s: Frame %d: Failed to read capture result metadata for camera %s",
__FUNCTION__, result.frameNumber,
@@ -170,8 +184,8 @@
return;
}
physCamIds[i] = physicalCameraMetadata[i].physicalCameraId.c_str();
- phyCamMetadatas[i] = reinterpret_cast<const camera_metadata_t*>(
- physResultMetadata[i].data());
+ phyCamMetadatas[i] =
+ reinterpret_cast<const camera_metadata_t*>(physResultMetadata[i].data());
}
r.num_physcam_metadata = physResultCount;
r.physcam_ids = physCamIds.data();
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
new file mode 100644
index 0000000..9ace0f9
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -0,0 +1,1580 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlCamera3-Device"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+//#define LOG_NNDEBUG 0 // Per-frame verbose logging
+
+#ifdef LOG_NNDEBUG
+#define ALOGVV(...) ALOGV(__VA_ARGS__)
+#else
+#define ALOGVV(...) ((void)0)
+#endif
+
+// Convenience macro for transient errors
+#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+ ##__VA_ARGS__)
+
+#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
+ ##__VA_ARGS__)
+
+// Convenience macros for transitioning to the error state
+#define SET_ERR(fmt, ...) setErrorState( \
+ "%s: " fmt, __FUNCTION__, \
+ ##__VA_ARGS__)
+#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
+ "%s: " fmt, __FUNCTION__, \
+ ##__VA_ARGS__)
+
+#include <inttypes.h>
+
+#include <utility>
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+#include <utils/Timers.h>
+#include <cutils/properties.h>
+
+#include <aidl/android/hardware/camera/device/ICameraInjectionSession.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/hardware/camera2/ICameraDeviceUser.h>
+
+#include "utils/CameraTraces.h"
+#include "mediautils/SchedulingPolicyService.h"
+#include "device3/Camera3OutputStream.h"
+#include "device3/Camera3InputStream.h"
+#include "device3/Camera3FakeStream.h"
+#include "device3/Camera3SharedOutputStream.h"
+#include "device3/aidl/AidlCamera3OutputUtils.h"
+#include "device3/aidl/AidlCamera3OfflineSession.h"
+#include "CameraService.h"
+#include "utils/CameraThreadState.h"
+#include "utils/SessionConfigurationUtils.h"
+#include "utils/TraceHFR.h"
+#include "utils/CameraServiceProxyWrapper.h"
+
+#include "../../common/aidl/AidlProviderInfo.h"
+
+#include <algorithm>
+
+#include "AidlCamera3Device.h"
+
+using namespace android::camera3;
+using namespace aidl::android::hardware;
+using aidl::android::hardware::camera::metadata::SensorPixelMode;
+using aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
+using aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
+
+namespace android {
+
+RequestAvailableDynamicRangeProfilesMap
+mapToAidlDynamicProfile(int dynamicRangeProfile) {
+ return static_cast<RequestAvailableDynamicRangeProfilesMap>(dynamicRangeProfile);
+}
+
+aidl::android::hardware::graphics::common::PixelFormat AidlCamera3Device::mapToAidlPixelFormat(
+ int frameworkFormat) {
+ return (aidl::android::hardware::graphics::common::PixelFormat) frameworkFormat;
+}
+
+aidl::android::hardware::graphics::common::Dataspace AidlCamera3Device::mapToAidlDataspace(
+ android_dataspace dataSpace) {
+ return (aidl::android::hardware::graphics::common::Dataspace)dataSpace;
+}
+
+aidl::android::hardware::graphics::common::BufferUsage AidlCamera3Device::mapToAidlConsumerUsage(
+ uint64_t usage) {
+ return (aidl::android::hardware::graphics::common::BufferUsage)usage;
+}
+
+aidl::android::hardware::camera::device::StreamRotation
+AidlCamera3Device::mapToAidlStreamRotation(camera_stream_rotation_t rotation) {
+ switch (rotation) {
+ case CAMERA_STREAM_ROTATION_0:
+ return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+ case CAMERA_STREAM_ROTATION_90:
+ return aidl::android::hardware::camera::device::StreamRotation::ROTATION_90;
+ case CAMERA_STREAM_ROTATION_180:
+ return aidl::android::hardware::camera::device::StreamRotation::ROTATION_180;
+ case CAMERA_STREAM_ROTATION_270:
+ return aidl::android::hardware::camera::device::StreamRotation::ROTATION_270;
+ }
+ ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
+ return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+}
+
+status_t AidlCamera3Device::mapToAidlStreamConfigurationMode(
+ camera_stream_configuration_mode_t operationMode,
+ aidl::android::hardware::camera::device::StreamConfigurationMode *mode) {
+ using StreamConfigurationMode =
+ aidl::android::hardware::camera::device::StreamConfigurationMode;
+ if (mode == nullptr) return BAD_VALUE;
+ if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+ switch(operationMode) {
+ case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
+ *mode = StreamConfigurationMode::NORMAL_MODE;
+ break;
+ case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+ *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
+ break;
+ default:
+ ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
+ return BAD_VALUE;
+ }
+ } else {
+ *mode = static_cast<StreamConfigurationMode>(operationMode);
+ }
+ return OK;
+}
+
+int AidlCamera3Device::mapToFrameworkFormat(
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
+ return static_cast<uint32_t>(pixelFormat);
+}
+
+android_dataspace AidlCamera3Device::mapToFrameworkDataspace(
+ aidl::android::hardware::graphics::common::Dataspace dataSpace) {
+ return static_cast<android_dataspace>(dataSpace);
+}
+
+uint64_t AidlCamera3Device::mapConsumerToFrameworkUsage(
+ aidl::android::hardware::graphics::common::BufferUsage usage) {
+ return (uint64_t)usage;
+}
+
+uint64_t AidlCamera3Device::mapProducerToFrameworkUsage(
+ aidl::android::hardware::graphics::common::BufferUsage usage) {
+ return (uint64_t)usage;
+}
+
+AidlCamera3Device::AidlCamera3Device(const String8& id, bool overrideForPerfClass,
+ bool legacyClient) : Camera3Device(id, overrideForPerfClass, legacyClient) {
+ mCallbacks = ndk::SharedRefBase::make<AidlCameraDeviceCallbacks>(this);
+}
+
+status_t AidlCamera3Device::initialize(sp<CameraProviderManager> manager,
+ const String8& monitorTags) {
+ ATRACE_CALL();
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.string());
+ if (mStatus != STATUS_UNINITIALIZED) {
+ CLOGE("Already initialized!");
+ return INVALID_OPERATION;
+ }
+ if (manager == nullptr) return INVALID_OPERATION;
+
+ std::shared_ptr<camera::device::ICameraDeviceSession> session;
+ ATRACE_BEGIN("CameraHal::openSession");
+ status_t res = manager->openAidlSession(mId.string(), mCallbacks,
+ /*out*/ &session);
+ ATRACE_END();
+ if (res != OK) {
+ SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
+ return res;
+ }
+ if (session == nullptr) {
+ ALOGE("JCLog: null session returned");
+ SET_ERR("Session iface returned is null");
+ return INVALID_OPERATION;
+ }
+ res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo);
+ if (res != OK) {
+ SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
+ session->close();
+ return res;
+ }
+ mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
+
+ std::vector<std::string> physicalCameraIds;
+ bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
+ if (isLogical) {
+ for (auto& physicalId : physicalCameraIds) {
+ // Do not override characteristics for physical cameras
+ res = manager->getCameraCharacteristics(
+ physicalId, /*overrideForPerfClass*/false, &mPhysicalDeviceInfoMap[physicalId]);
+ if (res != OK) {
+ SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
+ physicalId.c_str(), strerror(-res), res);
+ session->close();
+ return res;
+ }
+
+ bool usePrecorrectArray =
+ DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
+ if (usePrecorrectArray) {
+ res = mDistortionMappers[physicalId].setupStaticInfo(
+ mPhysicalDeviceInfoMap[physicalId]);
+ if (res != OK) {
+ SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
+ "correction", physicalId.c_str());
+ session->close();
+ return res;
+ }
+ }
+
+ mZoomRatioMappers[physicalId] = ZoomRatioMapper(
+ &mPhysicalDeviceInfoMap[physicalId],
+ mSupportNativeZoomRatio, usePrecorrectArray);
+
+ if (SessionConfigurationUtils::isUltraHighResolutionSensor(
+ mPhysicalDeviceInfoMap[physicalId])) {
+ mUHRCropAndMeteringRegionMappers[physicalId] =
+ UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId],
+ usePrecorrectArray);
+ }
+ }
+ }
+
+ std::shared_ptr<AidlRequestMetadataQueue> queue;
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
+
+ ::ndk::ScopedAStatus requestQueueRet = session->getCaptureRequestMetadataQueue(&desc);
+ if (!requestQueueRet.isOk()) {
+ ALOGE("Transaction error when getting result metadata queue from camera session: %s",
+ requestQueueRet.getMessage());
+ return AidlProviderInfo::mapToStatusT(requestQueueRet);
+ }
+ queue = std::make_unique<AidlRequestMetadataQueue>(desc);
+ if (!queue->isValid() || queue->availableToWrite() <= 0) {
+ ALOGE("HAL returns empty result metadata fmq, not use it");
+ queue = nullptr;
+ // Don't use resQueue onwards.
+ }
+
+ std::unique_ptr<AidlResultMetadataQueue>& resQueue = mResultMetadataQueue;
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> resDesc;
+ ::ndk::ScopedAStatus resultQueueRet = session->getCaptureResultMetadataQueue(&resDesc);
+ if (!resultQueueRet.isOk()) {
+ ALOGE("Transaction error when getting result metadata queue from camera session: %s",
+ resultQueueRet.getMessage());
+ return AidlProviderInfo::mapToStatusT(resultQueueRet);
+ }
+ resQueue = std::make_unique<AidlResultMetadataQueue>(resDesc);
+ if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
+ ALOGE("HAL returns empty result metadata fmq, not use it");
+ resQueue = nullptr;
+ // Don't use resQueue onwards.
+ }
+
+ camera_metadata_entry bufMgrMode =
+ mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
+ if (bufMgrMode.count > 0) {
+ mUseHalBufManager = (bufMgrMode.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ }
+
+ camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ for (size_t i = 0; i < capabilities.count; i++) {
+ uint8_t capability = capabilities.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
+ mSupportOfflineProcessing = true;
+ }
+ }
+
+ mInterface = new AidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
+
+ std::string providerType;
+ mVendorTagId = manager->getProviderTagIdLocked(mId.string());
+ mTagMonitor.initialize(mVendorTagId);
+ if (!monitorTags.isEmpty()) {
+ mTagMonitor.parseTagsToMonitor(String8(monitorTags));
+ }
+
+ for (size_t i = 0; i < capabilities.count; i++) {
+ uint8_t capability = capabilities.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
+ mNeedFixupMonochromeTags = true;
+ }
+ }
+
+ return initializeCommonLocked();
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::processCaptureResult(
+ const std::vector<camera::device::CaptureResult>& results) {
+ sp<AidlCamera3Device> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->processCaptureResult(results);
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::notify(
+ const std::vector<camera::device::NotifyMsg>& msgs) {
+ sp<AidlCamera3Device> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->notify(msgs);
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::processCaptureResult(
+ const std::vector<camera::device::CaptureResult>& results) {
+ // Ideally we should grab mLock, but that can lead to deadlock, and
+ // it's not super important to get up to date value of mStatus for this
+ // warning print, hence skipping the lock here
+ if (mStatus == STATUS_ERROR) {
+ // Per API contract, HAL should act as closed after device error
+ // But mStatus can be set to error by framework as well, so just log
+ // a warning here.
+ ALOGW("%s: received capture result in error state.", __FUNCTION__);
+ }
+
+ sp<NotificationListener> listener;
+ {
+ std::lock_guard<std::mutex> l(mOutputLock);
+ listener = mListener.promote();
+ }
+
+ if (mProcessCaptureResultLock.tryLock() != OK) {
+ // This should never happen; it indicates a wrong client implementation
+ // that doesn't follow the contract. But, we can be tolerant here.
+ ALOGE("%s: callback overlapped! waiting 1s...",
+ __FUNCTION__);
+ if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
+ ALOGE("%s: cannot acquire lock in 1s, dropping results",
+ __FUNCTION__);
+ // really don't know what to do, so bail out.
+ return ::ndk::ScopedAStatus::ok();
+ }
+ }
+ AidlCaptureOutputStates states {
+ {
+ mId,
+ mInFlightLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
+ mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mNextResultFrameNumber,
+ mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
+ mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
+ mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
+ mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
+ *this, *(mInterface), mLegacyClient}, mResultMetadataQueue
+ };
+
+ for (const auto& result : results) {
+ processOneCaptureResultLocked(states, result, result.physicalCameraMetadata);
+ }
+ mProcessCaptureResultLock.unlock();
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::notify(
+ const std::vector<camera::device::NotifyMsg>& msgs) {
+ // Ideally we should grab mLock, but that can lead to deadlock, and
+ // it's not super important to get up to date value of mStatus for this
+ // warning print, hence skipping the lock here
+ if (mStatus == STATUS_ERROR) {
+ // Per API contract, HAL should act as closed after device error
+ // But mStatus can be set to error by framework as well, so just log
+ // a warning here.
+ ALOGW("%s: received notify message in error state.", __FUNCTION__);
+ }
+
+ sp<NotificationListener> listener;
+ {
+ std::lock_guard<std::mutex> l(mOutputLock);
+ listener = mListener.promote();
+ }
+
+ AidlCaptureOutputStates states {
+ { mId,
+ mInFlightLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
+ mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mNextResultFrameNumber,
+ mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
+ mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
+ mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
+ mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
+ *this, *(mInterface), mLegacyClient}, mResultMetadataQueue
+ };
+ for (const auto& msg : msgs) {
+ camera3::notify(states, msg);
+ }
+ return ::ndk::ScopedAStatus::ok();
+
+}
+
+status_t AidlCamera3Device::switchToOffline(
+ const std::vector<int32_t>& streamsToKeep,
+ /*out*/ sp<CameraOfflineSessionBase>* session) {
+ ATRACE_CALL();
+ if (session == nullptr) {
+ ALOGE("%s: session must not be null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock il(mInterfaceLock);
+
+ bool hasInputStream = mInputStream != nullptr;
+ int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
+ bool inputStreamSupportsOffline = hasInputStream ?
+ mInputStream->getOfflineProcessingSupport() : false;
+ auto outputStreamIds = mOutputStreams.getStreamIds();
+ auto streamIds = outputStreamIds;
+ if (hasInputStream) {
+ streamIds.push_back(mInputStream->getId());
+ }
+
+ // Check all streams in streamsToKeep supports offline mode
+ for (auto id : streamsToKeep) {
+ if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
+ ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
+ return BAD_VALUE;
+ } else if (id == inputStreamId) {
+ if (!inputStreamSupportsOffline) {
+ ALOGE("%s: input stream %d cannot be switched to offline",
+ __FUNCTION__, id);
+ return BAD_VALUE;
+ }
+ } else {
+ sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
+ if (!stream->getOfflineProcessingSupport()) {
+ ALOGE("%s: output stream %d cannot be switched to offline",
+ __FUNCTION__, id);
+ return BAD_VALUE;
+ }
+ }
+ }
+ // TODO: block surface sharing and surface group streams until we can support them
+
+ // Stop repeating request, wait until all remaining requests are submitted, then call into
+ // HAL switchToOffline
+ camera::device::CameraOfflineSessionInfo offlineSessionInfo;
+ std::shared_ptr<camera::device::ICameraOfflineSession> offlineSession;
+ camera3::BufferRecords bufferRecords;
+ status_t ret = static_cast<AidlRequestThread *>(mRequestThread.get())->switchToOffline(
+ streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
+
+ if (ret != OK) {
+ SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
+ return ret;
+ }
+
+ bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
+ if (!succ) {
+ SET_ERR("HAL must not be calling requestStreamBuffers call");
+ // TODO: block ALL callbacks from HAL till app configured new streams?
+ return UNKNOWN_ERROR;
+ }
+
+ // Verify offlineSessionInfo
+ std::vector<int32_t> offlineStreamIds;
+ offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
+ for (auto offlineStream : offlineSessionInfo.offlineStreams) {
+ // verify stream IDs
+ int32_t id = offlineStream.id;
+ if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
+ SET_ERR("stream ID %d not found!", id);
+ return UNKNOWN_ERROR;
+ }
+
+ // When not using HAL buf manager, only allow streams requested by app to be preserved
+ if (!mUseHalBufManager) {
+ if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
+ SET_ERR("stream ID %d must not be switched to offline!", id);
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ offlineStreamIds.push_back(id);
+ sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
+ static_cast<sp<Camera3StreamInterface>>(mInputStream) :
+ static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
+ // Verify number of outstanding buffers
+ if (stream->getOutstandingBuffersCount() != (uint32_t)offlineStream.numOutstandingBuffers) {
+ SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
+ id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ // Verify all streams to be deleted don't have any outstanding buffers
+ if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
+ inputStreamId) == offlineStreamIds.end()) {
+ if (mInputStream->hasOutstandingBuffers()) {
+ SET_ERR("Input stream %d still has %zu outstanding buffer!",
+ inputStreamId, mInputStream->getOutstandingBuffersCount());
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ for (const auto& outStreamId : outputStreamIds) {
+ if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
+ outStreamId) == offlineStreamIds.end()) {
+ auto outStream = mOutputStreams.get(outStreamId);
+ if (outStream->hasOutstandingBuffers()) {
+ SET_ERR("Output stream %d still has %zu outstanding buffer!",
+ outStreamId, outStream->getOutstandingBuffersCount());
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+
+ InFlightRequestMap offlineReqs;
+ // Verify inflight requests and their pending buffers
+ {
+ std::lock_guard<std::mutex> l(mInFlightLock);
+ for (auto offlineReq : offlineSessionInfo.offlineRequests) {
+ int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
+ if (idx == NAME_NOT_FOUND) {
+ SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
+ return UNKNOWN_ERROR;
+ }
+
+ const auto& inflightReq = mInFlightMap.valueAt(idx);
+ // TODO: check specific stream IDs
+ size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
+ if (numBuffersLeft != offlineReq.pendingStreams.size()) {
+ SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
+ inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
+ return UNKNOWN_ERROR;
+ }
+ offlineReqs.add(offlineReq.frameNumber, inflightReq);
+ }
+ }
+
+ // Create Camera3OfflineSession and transfer object ownership
+ // (streams, inflight requests, buffer caches)
+ camera3::StreamSet offlineStreamSet;
+ sp<camera3::Camera3Stream> inputStream;
+ for (auto offlineStream : offlineSessionInfo.offlineStreams) {
+ int32_t id = offlineStream.id;
+ if (mInputStream != nullptr && id == mInputStream->getId()) {
+ inputStream = mInputStream;
+ } else {
+ offlineStreamSet.add(id, mOutputStreams.get(id));
+ }
+ }
+
+ // TODO: check if we need to lock before copying states
+ // though technically no other thread should be talking to Camera3Device at this point
+ Camera3OfflineStates offlineStates(
+ mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
+ mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mNextResultFrameNumber, mNextReprocessResultFrameNumber,
+ mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
+ mZoomRatioMappers, mRotateAndCropMappers);
+
+ *session = new AidlCamera3OfflineSession(mId, inputStream, offlineStreamSet,
+ std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
+
+ // Delete all streams that has been transferred to offline session
+ Mutex::Autolock l(mLock);
+ for (auto offlineStream : offlineSessionInfo.offlineStreams) {
+ int32_t id = offlineStream.id;
+ if (mInputStream != nullptr && id == mInputStream->getId()) {
+ mInputStream.clear();
+ } else {
+ mOutputStreams.remove(id);
+ }
+ }
+
+ // disconnect all other streams and switch to UNCONFIGURED state
+ if (mInputStream != nullptr) {
+ ret = mInputStream->disconnect();
+ if (ret != OK) {
+ SET_ERR_L("disconnect input stream failed!");
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ for (auto streamId : mOutputStreams.getStreamIds()) {
+ sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
+ ret = stream->disconnect();
+ if (ret != OK) {
+ SET_ERR_L("disconnect output stream %d failed!", streamId);
+ return UNKNOWN_ERROR;
+ }
+ }
+
+ mInputStream.clear();
+ mOutputStreams.clear();
+ mNeedConfig = true;
+ internalUpdateStatusLocked(STATUS_UNCONFIGURED);
+ mOperatingMode = NO_MODE;
+ mIsConstrainedHighSpeedConfiguration = false;
+ mRequestThread->clearPreviousRequest();
+
+ return OK;
+ // TO be done by CameraDeviceClient/Camera3OfflineSession
+ // register the offline client to camera service
+ // Setup result passthing threads etc
+ // Initialize offline session so HAL can start sending callback to it (result Fmq)
+ // TODO: check how many onIdle callback will be sent
+ // Java side to make sure the CameraCaptureSession is properly closed
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::requestStreamBuffers(
+ const std::vector<camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* status) {
+
+ sp<AidlCamera3Device> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->requestStreamBuffers(bufReqs, outBuffers, status);
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::requestStreamBuffers(
+ const std::vector<camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* status) {
+
+ RequestBufferStates states {
+ mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
+ mSessionStatsBuilder, *this, *(mInterface), *this};
+ camera3::requestStreamBuffers(states, bufReqs, outBuffers, status);
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::returnStreamBuffers(
+ const std::vector<camera::device::StreamBuffer>& buffers) {
+ sp<AidlCamera3Device> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->returnStreamBuffers(buffers);
+}
+
+::ndk::ScopedAStatus AidlCamera3Device::returnStreamBuffers(
+ const std::vector<camera::device::StreamBuffer>& buffers) {
+ ReturnBufferStates states {
+ mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
+ *(mInterface)};
+ camera3::returnStreamBuffers(states, buffers);
+ return ::ndk::ScopedAStatus::ok();
+}
+
+AidlCamera3Device::AidlHalInterface::AidlHalInterface(
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> &session,
+ std::shared_ptr<AidlRequestMetadataQueue> queue,
+ bool useHalBufManager, bool supportOfflineProcessing) :
+ HalInterface(useHalBufManager, supportOfflineProcessing),
+ mAidlSession(session),
+ mRequestMetadataQueue(queue) { }
+
+AidlCamera3Device::AidlHalInterface::AidlHalInterface(
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession>
+ &deviceSession,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraInjectionSession>
+ &injectionSession, std::shared_ptr<AidlRequestMetadataQueue> queue,
+ bool useHalBufManager, bool supportOfflineProcessing) :
+ HalInterface(useHalBufManager, supportOfflineProcessing),
+ mAidlSession(deviceSession),
+ mAidlInjectionSession(injectionSession),
+ mRequestMetadataQueue(queue) { }
+
+bool AidlCamera3Device::AidlHalInterface::valid() {
+ return (mAidlSession != nullptr);
+}
+
+void AidlCamera3Device::AidlHalInterface::clear() {
+ mAidlSession.reset();
+}
+
+status_t AidlCamera3Device::AidlHalInterface::flush() {
+ ATRACE_NAME("CameraHal::flush");
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ auto err = mAidlSession->flush();
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ res = AidlProviderInfo::mapToStatusT(err);
+ }
+
+ return res;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::dump(int /*fd*/) {
+ ATRACE_NAME("CameraHal::dump");
+ if (!valid()) return INVALID_OPERATION;
+
+ // Handled by CameraProviderManager::dump
+
+ return OK;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::repeatingRequestEnd(uint32_t frameNumber,
+ const std::vector<int32_t> &streamIds) {
+ ATRACE_NAME("AidlCameraHal::repeatingRequestEnd");
+ if (!valid()) return INVALID_OPERATION;
+
+ mAidlSession->repeatingRequestEnd(frameNumber, streamIds);
+
+ return OK;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::close() {
+ ATRACE_NAME("CameraHal::close()");
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ auto err = mAidlSession->close();
+ // Interface will be dead shortly anyway, so don't log errors
+ if (!err.isOk()) {
+ res = DEAD_OBJECT;
+ }
+
+ return res;
+}
+
+void AidlCamera3Device::AidlHalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
+ ATRACE_NAME("CameraHal::signalPipelineDrain");
+ if (!valid()) {
+ ALOGE("%s called on invalid camera!", __FUNCTION__);
+ return;
+ }
+
+ auto err = mAidlSession->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return;
+ }
+}
+
+bool AidlCamera3Device::AidlHalInterface::isReconfigurationRequired(
+ CameraMetadata& oldSessionParams, CameraMetadata& newSessionParams) {
+ // We do reconfiguration by default;
+ bool required = true;
+ if (mIsReconfigurationQuerySupported) {
+ aidl::android::hardware::camera::device::CameraMetadata oldParams, newParams;
+ camera_metadata_t* oldSessionMeta = const_cast<camera_metadata_t*>(
+ oldSessionParams.getAndLock());
+ uint8_t *oldSessionByteP = reinterpret_cast<uint8_t*>(oldSessionMeta);
+
+ camera_metadata_t* newSessionMeta = const_cast<camera_metadata_t*>(
+ newSessionParams.getAndLock());
+ uint8_t *newSessionByteP = reinterpret_cast<uint8_t*>(newSessionMeta);
+ // std::vector has no setToExternal, so we hacve to copy
+ oldParams.metadata.assign(oldSessionByteP,
+ oldSessionByteP + get_camera_metadata_size(oldSessionMeta));
+ newParams.metadata.assign(newSessionByteP,
+ newSessionByteP + get_camera_metadata_size(newSessionMeta));
+ auto err = mAidlSession->isReconfigurationRequired(oldParams, newParams, &required);
+ oldSessionParams.unlock(oldSessionMeta);
+ newSessionParams.unlock(newSessionMeta);
+ if (!err.isOk()) {
+ ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.getMessage());
+ return true;
+ }
+ }
+
+ return required;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::constructDefaultRequestSettings(
+ camera_request_template_t templateId,
+ /*out*/ camera_metadata_t **requestTemplate) {
+ ATRACE_NAME("CameraAidlHal::constructDefaultRequestSettings");
+ using aidl::android::hardware::camera::device::RequestTemplate;
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ RequestTemplate id;
+ aidl::android::hardware::camera::device::CameraMetadata request;
+ switch (templateId) {
+ case CAMERA_TEMPLATE_PREVIEW:
+ id = RequestTemplate::PREVIEW;
+ break;
+ case CAMERA_TEMPLATE_STILL_CAPTURE:
+ id = RequestTemplate::STILL_CAPTURE;
+ break;
+ case CAMERA_TEMPLATE_VIDEO_RECORD:
+ id = RequestTemplate::VIDEO_RECORD;
+ break;
+ case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
+ id = RequestTemplate::VIDEO_SNAPSHOT;
+ break;
+ case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
+ id = RequestTemplate::ZERO_SHUTTER_LAG;
+ break;
+ case CAMERA_TEMPLATE_MANUAL:
+ id = RequestTemplate::MANUAL;
+ break;
+ default:
+ // Unknown template ID, or this HAL is too old to support it
+ return BAD_VALUE;
+ }
+ auto err = mAidlSession->constructDefaultRequestSettings(id, &request);
+
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+ const camera_metadata *r =
+ reinterpret_cast<const camera_metadata_t*>(request.metadata.data());
+ size_t expectedSize = request.metadata.size();
+ int ret = validate_camera_metadata_structure(r, &expectedSize);
+ if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ *requestTemplate = clone_camera_metadata(r);
+ if (*requestTemplate == nullptr) {
+ ALOGE("%s: Unable to clone camera metadata received from HAL",
+ __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+
+ return res;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::configureStreams(
+ const camera_metadata_t *sessionParams,
+ camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
+ using camera::device::StreamType;
+ using camera::device::StreamConfigurationMode;
+
+ ATRACE_NAME("CameraHal::configureStreams");
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ // Convert stream config to AIDL
+ std::set<int> activeStreams;
+ camera::device::StreamConfiguration requestedConfiguration;
+ requestedConfiguration.streams.resize(config->num_streams);
+ for (size_t i = 0; i < config->num_streams; i++) {
+ camera::device::Stream &dst = requestedConfiguration.streams[i];
+ camera3::camera_stream_t *src = config->streams[i];
+
+ Camera3Stream* cam3stream = Camera3Stream::cast(src);
+ cam3stream->setBufferFreedListener(this);
+ int streamId = cam3stream->getId();
+ StreamType streamType;
+ switch (src->stream_type) {
+ case CAMERA_STREAM_OUTPUT:
+ streamType = StreamType::OUTPUT;
+ break;
+ case CAMERA_STREAM_INPUT:
+ streamType = StreamType::INPUT;
+ break;
+ default:
+ ALOGE("%s: Stream %d: Unsupported stream type %d",
+ __FUNCTION__, streamId, config->streams[i]->stream_type);
+ return BAD_VALUE;
+ }
+ dst.id = streamId;
+ dst.streamType = streamType;
+ dst.width = src->width;
+ dst.height = src->height;
+ dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
+ dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t) src->rotation);
+ dst.format = mapToAidlPixelFormat(cam3stream->isFormatOverridden() ?
+ cam3stream->getOriginalFormat() : src->format);
+ dst.dataSpace = mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
+ cam3stream->getOriginalDataSpace() : src->data_space);
+
+ dst.bufferSize = bufferSizes[i];
+ if (src->physical_camera_id != nullptr) {
+ dst.physicalCameraId = src->physical_camera_id;
+ }
+ dst.groupId = cam3stream->getHalStreamGroupId();
+ dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
+ size_t j = 0;
+ for (int mode : src->sensor_pixel_modes_used) {
+ dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
+ }
+ dst.dynamicRangeProfile = mapToAidlDynamicProfile(src->dynamic_range_profile);
+ dst.useCase = static_cast<ScalerAvailableStreamUseCases>(src->use_case);
+ activeStreams.insert(streamId);
+ // Create Buffer ID map if necessary
+ mBufferRecords.tryCreateBufferCache(streamId);
+ }
+ // remove BufferIdMap for deleted streams
+ mBufferRecords.removeInactiveBufferCaches(activeStreams);
+
+ StreamConfigurationMode operationMode;
+ res = mapToAidlStreamConfigurationMode(
+ (camera_stream_configuration_mode_t) config->operation_mode,
+ /*out*/ &operationMode);
+ if (res != OK) {
+ return res;
+ }
+ requestedConfiguration.operationMode = operationMode;
+ size_t sessionParamSize = get_camera_metadata_size(sessionParams);
+ uint8_t *sessionParamP =
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
+
+ // std::vector has no setToExternal, so we have to copy
+ requestedConfiguration.sessionParams.metadata.assign(
+ sessionParamP, sessionParamP + sessionParamSize);
+ requestedConfiguration.operationMode = operationMode;
+
+ // Invoke configureStreams
+ std::vector<camera::device::HalStream> finalConfiguration;
+
+ requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
+ requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
+ auto err = mAidlSession->configureStreams(requestedConfiguration, &finalConfiguration);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+
+ // And convert output stream configuration from AIDL
+
+ for (size_t i = 0; i < config->num_streams; i++) {
+ camera3::camera_stream_t *dst = config->streams[i];
+ int streamId = Camera3Stream::cast(dst)->getId();
+
+ // Start scan at i, with the assumption that the stream order matches
+ size_t realIdx = i;
+ bool found = false;
+ size_t halStreamCount = finalConfiguration.size();
+ for (size_t idx = 0; idx < halStreamCount; idx++) {
+ if (finalConfiguration[realIdx].id == streamId) {
+ found = true;
+ break;
+ }
+ realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
+ }
+ if (!found) {
+ ALOGE("%s: Stream %d not found in stream configuration response from HAL",
+ __FUNCTION__, streamId);
+ return INVALID_OPERATION;
+ }
+ camera::device::HalStream &src = finalConfiguration[realIdx];
+
+ Camera3Stream* dstStream = Camera3Stream::cast(dst);
+ int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
+ android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
+
+ dstStream->setOfflineProcessingSupport(src.supportOffline);
+
+ if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+ dstStream->setFormatOverride(false);
+ dstStream->setDataSpaceOverride(false);
+ if (dst->format != overrideFormat) {
+ ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
+ streamId, dst->format);
+ }
+ if (dst->data_space != overrideDataSpace) {
+ ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
+ streamId, dst->format);
+ }
+ } else {
+ bool needFormatOverride =
+ requestedConfiguration.streams[i].format != src.overrideFormat;
+ bool needDataspaceOverride =
+ requestedConfiguration.streams[i].dataSpace != src.overrideDataSpace;
+ // Override allowed with IMPLEMENTATION_DEFINED
+ dstStream->setFormatOverride(needFormatOverride);
+ dstStream->setDataSpaceOverride(needDataspaceOverride);
+ dst->format = overrideFormat;
+ dst->data_space = overrideDataSpace;
+ }
+
+ if (dst->stream_type == CAMERA_STREAM_INPUT) {
+ if (static_cast<int64_t>(src.producerUsage) != 0) {
+ ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
+ __FUNCTION__, streamId);
+ return INVALID_OPERATION;
+ }
+ dstStream->setUsage(
+ mapConsumerToFrameworkUsage(src.consumerUsage));
+ } else {
+ // OUTPUT
+ if (static_cast<int64_t>(src.consumerUsage) != 0) {
+ ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
+ __FUNCTION__, streamId);
+ return INVALID_OPERATION;
+ }
+ dstStream->setUsage(
+ mapProducerToFrameworkUsage(src.producerUsage));
+ }
+ dst->max_buffers = src.maxBuffers;
+ }
+
+ return res;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::configureInjectedStreams(
+ const camera_metadata_t* sessionParams, camera_stream_configuration* config,
+ const std::vector<uint32_t>& bufferSizes,
+ const CameraMetadata& cameraCharacteristics) {
+ using camera::device::StreamType;
+ using camera::device::StreamConfigurationMode;
+
+ ATRACE_NAME("InjectionCameraHal::configureStreams");
+ if (!valid()) return INVALID_OPERATION;
+ status_t res = OK;
+
+ if (config->input_is_multi_resolution) {
+ ALOGE("%s: Injection camera device doesn't support multi-resolution input "
+ "stream", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ // Convert stream config to AIDL
+ std::set<int> activeStreams;
+ camera::device::StreamConfiguration requestedConfiguration;
+ requestedConfiguration.streams.resize(config->num_streams);
+ for (size_t i = 0; i < config->num_streams; i++) {
+ camera::device::Stream& dst = requestedConfiguration.streams[i];
+ camera3::camera_stream_t* src = config->streams[i];
+
+ Camera3Stream* cam3stream = Camera3Stream::cast(src);
+ cam3stream->setBufferFreedListener(this);
+ int streamId = cam3stream->getId();
+ StreamType streamType;
+ switch (src->stream_type) {
+ case CAMERA_STREAM_OUTPUT:
+ streamType = StreamType::OUTPUT;
+ break;
+ case CAMERA_STREAM_INPUT:
+ streamType = StreamType::INPUT;
+ break;
+ default:
+ ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
+ streamId, config->streams[i]->stream_type);
+ return BAD_VALUE;
+ }
+ dst.id = streamId;
+ dst.streamType = streamType;
+ dst.width = src->width;
+ dst.height = src->height;
+ dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
+ dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t)src->rotation);
+ dst.format =
+ mapToAidlPixelFormat(cam3stream->isFormatOverridden() ? cam3stream->getOriginalFormat()
+ : src->format);
+ dst.dataSpace =
+ mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
+ cam3stream->getOriginalDataSpace() : src->data_space);
+ dst.bufferSize = bufferSizes[i];
+ if (src->physical_camera_id != nullptr) {
+ dst.physicalCameraId = src->physical_camera_id;
+ }
+ dst.groupId = cam3stream->getHalStreamGroupId();
+ dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
+ size_t j = 0;
+ for (int mode : src->sensor_pixel_modes_used) {
+ dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
+ }
+ activeStreams.insert(streamId);
+ // Create Buffer ID map if necessary
+ mBufferRecords.tryCreateBufferCache(streamId);
+ }
+ // remove BufferIdMap for deleted streams
+ mBufferRecords.removeInactiveBufferCaches(activeStreams);
+
+ StreamConfigurationMode operationMode;
+ res = mapToAidlStreamConfigurationMode(
+ (camera_stream_configuration_mode_t)config->operation_mode,
+ /*out*/ &operationMode);
+ if (res != OK) {
+ return res;
+ }
+ requestedConfiguration.operationMode = operationMode;
+ size_t sessionParamSize = get_camera_metadata_size(sessionParams);
+ uint8_t *sessionParamP =
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
+ requestedConfiguration.operationMode = operationMode;
+ requestedConfiguration.sessionParams.metadata.assign(
+ sessionParamP, sessionParamP + sessionParamSize);
+
+ // See which version of HAL we have
+ if (mAidlInjectionSession != nullptr) {
+ requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
+ requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
+
+ const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
+ uint8_t *aidlCharsP =
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata));
+ aidl::android::hardware::camera::device::CameraMetadata aidlChars;
+ aidlChars.metadata.assign(aidlCharsP, aidlCharsP + get_camera_metadata_size(rawMetadata));
+ cameraCharacteristics.unlock(rawMetadata);
+
+ auto err = mAidlInjectionSession->configureInjectionStreams(requestedConfiguration,
+ aidlChars);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+ } else {
+ ALOGE("%s: mAidlInjectionSession == nullptr, the injection not supported ", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ return res;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::processBatchCaptureRequests(
+ std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
+ ATRACE_NAME("CameraHal::processBatchCaptureRequests");
+ if (!valid()) return INVALID_OPERATION;
+
+ std::vector<camera::device::CaptureRequest> captureRequests;
+ size_t batchSize = requests.size();
+ if (batchSize > INT_MAX) {
+ ALOGE("%s batchSize %zu > INT_MAX, aidl interface cannot handle batch size", __FUNCTION__,
+ batchSize);
+ return BAD_VALUE;
+ }
+ captureRequests.resize(batchSize);
+ std::vector<native_handle_t*> handlesCreated;
+ std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
+
+ status_t res = OK;
+ for (size_t i = 0; i < batchSize; i++) {
+ res = wrapAsAidlRequest(requests[i], /*out*/&captureRequests[i],
+ /*out*/&handlesCreated, /*out*/&inflightBuffers);
+
+ if (res != OK) {
+ mBufferRecords.popInflightBuffers(inflightBuffers);
+ cleanupNativeHandles(&handlesCreated);
+ return res;
+ }
+ }
+
+ std::vector<camera::device::BufferCache> cachesToRemove;
+ {
+ std::lock_guard<std::mutex> lock(mFreedBuffersLock);
+ for (auto& pair : mFreedBuffers) {
+ // The stream might have been removed since onBufferFreed
+ if (mBufferRecords.isStreamCached(pair.first)) {
+ cachesToRemove.push_back({pair.first, static_cast<int64_t>(pair.second)});
+ }
+ }
+ mFreedBuffers.clear();
+ }
+
+ *numRequestProcessed = 0;
+
+ // Write metadata to FMQ.
+ for (size_t i = 0; i < batchSize; i++) {
+ camera_capture_request_t* request = requests[i];
+ camera::device::CaptureRequest* captureRequest;
+ captureRequest = &captureRequests[i];
+
+ if (request->settings != nullptr) {
+ size_t settingsSize = get_camera_metadata_size(request->settings);
+ if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
+ reinterpret_cast<const int8_t*>(request->settings), settingsSize)) {
+ captureRequest->settings.metadata.resize(0);
+ captureRequest->fmqSettingsSize = settingsSize;
+ } else {
+ if (mRequestMetadataQueue != nullptr) {
+ ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
+ }
+ uint8_t *settingsP =
+ reinterpret_cast<uint8_t*>(
+ const_cast<camera_metadata_t*>(request->settings));
+ size_t settingsSize = get_camera_metadata_size(request->settings);
+ captureRequest->settings.metadata.assign(settingsP, settingsP + settingsSize);
+ captureRequest->fmqSettingsSize = 0u;
+ }
+ } else {
+ // A null request settings maps to a size-0 CameraMetadata
+ captureRequest->settings.metadata.resize(0);
+ captureRequest->fmqSettingsSize = 0u;
+ }
+
+ captureRequest ->inputWidth = request->input_width;
+ captureRequest->inputHeight = request->input_height;
+
+ std::vector<camera::device::PhysicalCameraSetting>& physicalCameraSettings =
+ captureRequest->physicalCameraSettings;
+ physicalCameraSettings.resize(request->num_physcam_settings);
+ for (size_t j = 0; j < request->num_physcam_settings; j++) {
+ if (request->physcam_settings != nullptr) {
+ size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
+ if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
+ reinterpret_cast<const int8_t*>(request->physcam_settings[j]),
+ settingsSize)) {
+ physicalCameraSettings[j].settings.metadata.resize(0);
+ physicalCameraSettings[j].fmqSettingsSize = settingsSize;
+ } else {
+ if (mRequestMetadataQueue != nullptr) {
+ ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
+ }
+ uint8_t *physicalSettingsP =
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
+ request->physcam_settings[j]));
+ physicalCameraSettings[j].settings.metadata.assign(physicalSettingsP,
+ physicalSettingsP + settingsSize);
+ physicalCameraSettings[j].fmqSettingsSize = 0u;
+ }
+ } else {
+ physicalCameraSettings[j].fmqSettingsSize = 0u;
+ physicalCameraSettings[j].settings.metadata.resize(0);
+ }
+ physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
+ }
+ }
+
+ int32_t numRequests = 0;
+ auto retS = mAidlSession->processCaptureRequest(captureRequests, cachesToRemove,
+ &numRequests);
+ if (!retS.isOk()) {
+ res = AidlProviderInfo::mapToStatusT(retS);
+ }
+ if (res == OK) {
+ if (numRequests < 0) {
+ res = INVALID_OPERATION;
+ } else {
+ *numRequestProcessed = static_cast<uint32_t>(numRequests);
+ }
+
+ }
+ if (res == OK && *numRequestProcessed == batchSize) {
+ if (mAidlSession->isRemote()) {
+ // Only close acquire fence FDs when the AIDL transaction succeeds (so the FDs have been
+ // sent to camera HAL processes)
+ cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
+ } else {
+ // In passthrough mode the FDs are now owned by HAL
+ cleanupNativeHandles(&handlesCreated);
+ }
+ } else {
+ ALOGE("%s Error with processCaptureRequest %s ", __FUNCTION__, retS.getMessage());
+ mBufferRecords.popInflightBuffers(inflightBuffers);
+ cleanupNativeHandles(&handlesCreated);
+ }
+ return res;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::wrapAsAidlRequest(camera_capture_request_t* request,
+ /*out*/camera::device::CaptureRequest* captureRequest,
+ /*out*/std::vector<native_handle_t*>* handlesCreated,
+ /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
+ using camera::device::BufferStatus;
+ using camera::device::StreamBuffer;
+ ATRACE_CALL();
+ if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
+ ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
+ "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
+ return BAD_VALUE;
+ }
+
+ captureRequest->frameNumber = request->frame_number;
+
+ captureRequest->fmqSettingsSize = 0;
+
+ {
+ if (request->input_buffer != nullptr) {
+ int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
+ buffer_handle_t buf = *(request->input_buffer->buffer);
+ auto pair = getBufferId(buf, streamId);
+ bool isNewBuffer = pair.first;
+ uint64_t bufferId = pair.second;
+ captureRequest->inputBuffer.streamId = streamId;
+ captureRequest->inputBuffer.bufferId = bufferId;
+ captureRequest->inputBuffer.buffer =
+ (isNewBuffer) ? camera3::dupToAidlIfNotNull(buf) :
+ aidl::android::hardware::common::NativeHandle();
+ captureRequest->inputBuffer.status = BufferStatus::OK;
+ native_handle_t *acquireFence = nullptr;
+ if (request->input_buffer->acquire_fence != -1) {
+ acquireFence = native_handle_create(1,0);
+ acquireFence->data[0] = request->input_buffer->acquire_fence;
+ handlesCreated->push_back(acquireFence);
+ }
+ // duping here is okay, in aidl ownership is not given to aidl_handle
+ captureRequest->inputBuffer.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
+ captureRequest->inputBuffer.releaseFence =
+ aidl::android::hardware::common::NativeHandle();
+
+ mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
+ request->input_buffer->buffer);
+ inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
+ } else {
+ captureRequest->inputBuffer.streamId = -1;
+ captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
+ }
+
+ captureRequest->outputBuffers.resize(request->num_output_buffers);
+ for (size_t i = 0; i < request->num_output_buffers; i++) {
+ const camera_stream_buffer_t *src = request->output_buffers + i;
+ StreamBuffer &dst = captureRequest->outputBuffers[i];
+ int32_t streamId = Camera3Stream::cast(src->stream)->getId();
+ if (src->buffer != nullptr) {
+ buffer_handle_t buf = *(src->buffer);
+ auto pair = getBufferId(buf, streamId);
+ bool isNewBuffer = pair.first;
+ dst.bufferId = pair.second;
+ dst.buffer = isNewBuffer ?
+ camera3::dupToAidlIfNotNull(buf) :
+ aidl::android::hardware::common::NativeHandle();
+ native_handle_t *acquireFence = nullptr;
+ if (src->acquire_fence != -1) {
+ acquireFence = native_handle_create(1,0);
+ acquireFence->data[0] = src->acquire_fence;
+ handlesCreated->push_back(acquireFence);
+ }
+ dst.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
+ } else if (mUseHalBufManager) {
+ // HAL buffer management path
+ dst.bufferId = BUFFER_ID_NO_BUFFER;
+ dst.buffer = aidl::android::hardware::common::NativeHandle();
+ dst.acquireFence = aidl::android::hardware::common::NativeHandle();
+ } else {
+ ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ dst.streamId = streamId;
+ dst.status = BufferStatus::OK;
+ dst.releaseFence = aidl::android::hardware::common::NativeHandle();
+
+ // Output buffers are empty when using HAL buffer manager
+ if (!mUseHalBufManager) {
+ mBufferRecords.pushInflightBuffer(
+ captureRequest->frameNumber, streamId, src->buffer);
+ inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
+ }
+ }
+ }
+ return OK;
+}
+
+status_t AidlCamera3Device::AidlHalInterface::switchToOffline(
+ const std::vector<int32_t>& streamsToKeep,
+ /*out*/aidl::android::hardware::camera::device::CameraOfflineSessionInfo*
+ offlineSessionInfo,
+ /*out*/std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession>*
+ offlineSession,
+ /*out*/camera3::BufferRecords* bufferRecords) {
+ ATRACE_NAME("CameraHal::switchToOffline");
+ if (!valid()) {
+ ALOGE("%s called on invalid camera!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
+ ALOGE("%s: output arguments must not be null!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ auto err = mAidlSession->switchToOffline(streamsToKeep, offlineSessionInfo, offlineSession);
+
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+
+ return verifyBufferCaches(offlineSessionInfo, bufferRecords);
+}
+
+AidlCamera3Device::AidlRequestThread::AidlRequestThread(wp<Camera3Device> parent,
+ sp<camera3::StatusTracker> statusTracker,
+ sp<HalInterface> interface,
+ const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager,
+ bool supportCameraMute) :
+ RequestThread(parent, statusTracker, interface, sessionParamKeys, useHalBufManager,
+ supportCameraMute) {}
+
+status_t AidlCamera3Device::AidlRequestThread::switchToOffline(
+ const std::vector<int32_t>& streamsToKeep,
+ /*out*/camera::device::CameraOfflineSessionInfo* offlineSessionInfo,
+ /*out*/std::shared_ptr<camera::device::ICameraOfflineSession>* offlineSession,
+ /*out*/camera3::BufferRecords* bufferRecords) {
+ Mutex::Autolock l(mRequestLock);
+ clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
+
+ // Wait until request thread is fully stopped
+ // TBD: check if request thread is being paused by other APIs (shouldn't be)
+
+ // We could also check for mRepeatingRequests.empty(), but the API interface
+ // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
+ // new requests during the call; hence skip that check.
+ bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
+ while (!queueEmpty) {
+ status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
+ if (res == TIMED_OUT) {
+ ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
+ return res;
+ } else if (res != OK) {
+ ALOGE("%s: request thread failed to submit a request: %s (%d)!",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
+ }
+ return (static_cast<AidlHalInterface *>(mInterface.get()))->switchToOffline(
+ streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
+}
+
+status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::injectionInitialize(
+ const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::shared_ptr<camera::device::ICameraDeviceCallback>&callback) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mInjectionLock);
+
+ if (manager == nullptr) {
+ ALOGE("%s: manager does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ if (parent->getTransportType() != IPCTransport::AIDL) {
+ ALOGE("%s Parent transport not AIDL for injected camera id %s, aborting", __FUNCTION__,
+ injectedCamId.c_str());
+ return INVALID_OPERATION;
+ }
+ mInjectedCamId = injectedCamId;
+ std::shared_ptr<camera::device::ICameraInjectionSession> injectionSession;
+ ATRACE_BEGIN("Injection CameraHal::openSession");
+ status_t res = manager->openAidlInjectionSession(injectedCamId.string(), callback,
+ /*out*/ &injectionSession);
+ ATRACE_END();
+ if (res != OK) {
+ ALOGE("Injection camera could not open camera session: %s (%d)",
+ strerror(-res), res);
+ return res;
+ }
+ std::shared_ptr<camera::device::ICameraDeviceSession> deviceSession = nullptr;
+ auto ret = injectionSession->getCameraDeviceSession(&deviceSession);
+ if (!ret.isOk() || deviceSession == nullptr) {
+ ALOGE("%s Camera injection session couldn't return ICameraDeviceSession", __FUNCTION__);
+ return AidlProviderInfo::mapToStatusT(ret);
+ }
+
+ std::shared_ptr<AidlRequestMetadataQueue> queue;
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
+
+ ::ndk::ScopedAStatus requestQueueRet = deviceSession->getCaptureRequestMetadataQueue(&desc);
+ if (!requestQueueRet.isOk()) {
+ ALOGE("Injection camera transaction error when getting result metadata queue from camera"
+ " session: %s", requestQueueRet.getMessage());
+ return AidlProviderInfo::mapToStatusT(requestQueueRet);
+ }
+ queue = std::make_unique<AidlRequestMetadataQueue>(desc);
+ if (!queue->isValid() || queue->availableToWrite() <= 0) {
+ ALOGE("HAL returns empty result metadata fmq, not use it");
+ queue = nullptr;
+ // Don't use resQueue onwards.
+ }
+
+ std::unique_ptr<AidlResultMetadataQueue>& resQueue = mInjectionResultMetadataQueue;
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> resDesc;
+ ::ndk::ScopedAStatus resultQueueRet = deviceSession->getCaptureResultMetadataQueue(&resDesc);
+ if (!resultQueueRet.isOk()) {
+ ALOGE("Transaction error when getting result metadata queue from camera session: %s",
+ resultQueueRet.getMessage());
+ return AidlProviderInfo::mapToStatusT(resultQueueRet);
+ }
+ resQueue = std::make_unique<AidlResultMetadataQueue>(resDesc);
+ if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
+ ALOGE("HAL returns empty result metadata fmq, not use it");
+ resQueue = nullptr;
+ // Don't use resQueue onwards.
+ }
+
+ ALOGV("%s: Injection camera interface = new HalInterface()", __FUNCTION__);
+
+ mInjectedCamHalInterface =
+ new AidlHalInterface(deviceSession, injectionSession, queue, parent->mUseHalBufManager,
+ parent->mSupportOfflineProcessing);
+ if (mInjectedCamHalInterface == nullptr) {
+ ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ return OK;
+}
+
+status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::replaceHalInterface(
+ sp<HalInterface> newHalInterface, bool keepBackup) {
+ Mutex::Autolock lock(mInjectionLock);
+ if (newHalInterface.get() == nullptr) {
+ ALOGE("%s: The newHalInterface does not exist, to stop replacing.",
+ __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ sp<Camera3Device> parent = mParent.promote();
+ if (parent == nullptr) {
+ ALOGE("%s: parent does not exist!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if (parent->getTransportType() != IPCTransport::AIDL ||
+ newHalInterface->getTransportType() != IPCTransport::AIDL) {
+ ALOGE("%s Parent transport not AIDL for replacing hal interface", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ AidlCamera3Device *aidlParent = static_cast<AidlCamera3Device *>(parent.get());
+ if (keepBackup) {
+ if (mBackupHalInterface == nullptr) {
+ mBackupHalInterface = parent->mInterface;
+ }
+ if (mBackupResultMetadataQueue == nullptr) {
+ mBackupResultMetadataQueue = std::move(aidlParent->mResultMetadataQueue);
+ aidlParent->mResultMetadataQueue = std::move(mInjectionResultMetadataQueue);
+ }
+ } else {
+ mBackupHalInterface = nullptr;
+ aidlParent->mResultMetadataQueue = std::move(mBackupResultMetadataQueue);
+ mBackupResultMetadataQueue = nullptr;
+ }
+ parent->mInterface = newHalInterface;
+ return OK;
+}
+
+status_t AidlCamera3Device::injectionCameraInitialize(const String8 &injectedCamId,
+ sp<CameraProviderManager> manager) {
+ return (static_cast<AidlCamera3DeviceInjectionMethods *>
+ (mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager,
+ std::shared_ptr<camera::device::ICameraDeviceCallback>(mCallbacks));
+};
+
+sp<Camera3Device::RequestThread> AidlCamera3Device::createNewRequestThread(
+ wp<Camera3Device> parent, sp<camera3::StatusTracker> statusTracker,
+ sp<Camera3Device::HalInterface> interface,
+ const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager,
+ bool supportCameraMute) {
+ return new AidlRequestThread(parent, statusTracker, interface, sessionParamKeys,
+ useHalBufManager, supportCameraMute);
+};
+
+sp<Camera3Device::Camera3DeviceInjectionMethods>
+AidlCamera3Device::createCamera3DeviceInjectionMethods(wp<Camera3Device> parent) {
+ return new AidlCamera3DeviceInjectionMethods(parent);
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
new file mode 100644
index 0000000..e7998b9
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_AIDLCAMERA3DEVICE_H
+#define ANDROID_SERVERS_AIDLCAMERA3DEVICE_H
+
+#include "../Camera3Device.h"
+#include "AidlCamera3OutputUtils.h"
+#include <fmq/AidlMessageQueue.h>
+
+#include <aidl/android/hardware/camera/device/BnCameraDeviceCallback.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/device/ICameraInjectionSession.h>
+namespace android {
+
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+/**
+ * CameraDevice for AIDL HAL devices.
+ */
+class AidlCamera3Device :
+ public Camera3Device {
+ public:
+
+ using AidlRequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+ class AidlCameraDeviceCallbacks;
+ friend class AidlCameraDeviceCallbacks;
+ explicit AidlCamera3Device(const String8& id, bool overrideForPerfClass,
+ bool legacyClient = false);
+
+ virtual ~AidlCamera3Device() { }
+
+ static aidl::android::hardware::graphics::common::PixelFormat mapToAidlPixelFormat(
+ int frameworkFormat);
+ static aidl::android::hardware::graphics::common::Dataspace mapToAidlDataspace(
+ android_dataspace dataSpace);
+ static aidl::android::hardware::graphics::common::BufferUsage mapToAidlConsumerUsage(
+ uint64_t usage);
+ static aidl::android::hardware::camera::device::StreamRotation
+ mapToAidlStreamRotation(camera_stream_rotation_t rotation);
+
+ static status_t mapToAidlStreamConfigurationMode(
+ camera_stream_configuration_mode_t operationMode,
+ aidl::android::hardware::camera::device::StreamConfigurationMode *mode);
+
+ static int mapToFrameworkFormat(
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
+ static android_dataspace mapToFrameworkDataspace(
+ aidl::android::hardware::graphics::common::Dataspace);
+ static uint64_t mapConsumerToFrameworkUsage(
+ aidl::android::hardware::graphics::common::BufferUsage usage);
+ static uint64_t mapProducerToFrameworkUsage(
+ aidl::android::hardware::graphics::common::BufferUsage usage);
+
+ virtual status_t switchToOffline(const std::vector<int32_t>& /*streamsToKeep*/,
+ /*out*/ sp<CameraOfflineSessionBase>* /*session*/) override;
+
+ status_t initialize(sp<CameraProviderManager> manager, const String8& monitorTags) override;
+ class AidlHalInterface : public Camera3Device::HalInterface {
+ public:
+ AidlHalInterface(std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceSession> &session,
+ std::shared_ptr<AidlRequestMetadataQueue> queue,
+ bool useHalBufManager, bool supportOfflineProcessing);
+ AidlHalInterface(
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession>
+ &injectionSession,
+ std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraInjectionSession> &session,
+ std::shared_ptr<AidlRequestMetadataQueue> queue,
+ bool useHalBufManager, bool supportOfflineProcessing);
+
+ virtual IPCTransport getTransportType() {return IPCTransport::AIDL; }
+
+
+ // Returns true if constructed with a valid device or session, and not yet cleared
+ virtual bool valid() override;
+
+ // Reset this HalInterface object (does not call close())
+ virtual void clear() override;
+
+ // Caller takes ownership of requestTemplate
+ virtual status_t constructDefaultRequestSettings(camera_request_template templateId,
+ /*out*/ camera_metadata_t **requestTemplate) override;
+
+ virtual status_t configureStreams(const camera_metadata_t *sessionParams,
+ /*inout*/ camera_stream_configuration_t *config,
+ const std::vector<uint32_t>& bufferSizes) override;
+ // The injection camera configures the streams to hal.
+ virtual status_t configureInjectedStreams(
+ const camera_metadata_t* sessionParams,
+ /*inout*/ camera_stream_configuration_t* config,
+ const std::vector<uint32_t>& bufferSizes,
+ const CameraMetadata& cameraCharacteristics) override;
+
+ // When the call succeeds, the ownership of acquire fences in requests is transferred to
+ // HalInterface. More specifically, the current implementation will send the fence to
+ // HAL process and close the FD in cameraserver process. When the call fails, the ownership
+ // of the acquire fence still belongs to the caller.
+ virtual status_t processBatchCaptureRequests(
+ std::vector<camera_capture_request_t*>& requests,
+ /*out*/uint32_t* numRequestProcessed) override;
+
+ // Calls into the HAL interface
+ virtual status_t flush() override;
+ virtual status_t dump(int fd) override;
+ virtual status_t close() override;
+ virtual void signalPipelineDrain(const std::vector<int>& streamIds) override;
+ virtual bool isReconfigurationRequired(CameraMetadata& oldSessionParams,
+ CameraMetadata& newSessionParams) override;
+
+ virtual status_t repeatingRequestEnd(uint32_t ,
+ const std::vector<int32_t> &) override;
+
+ status_t switchToOffline(
+ const std::vector<int32_t>& streamsToKeep,
+ /*out*/aidl::android::hardware::camera::device::CameraOfflineSessionInfo*
+ offlineSessionInfo,
+ /*out*/std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession>*
+ offlineSession,
+ /*out*/camera3::BufferRecords* bufferRecords);
+
+ private:
+
+ // Always valid
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession>
+ mAidlSession = nullptr;
+ //Valid for injection sessions
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraInjectionSession>
+ mAidlInjectionSession = nullptr;
+
+ status_t wrapAsAidlRequest(camera_capture_request_t* request,
+ /*out*/aidl::android::hardware::camera::device::CaptureRequest* captureRequest,
+ /*out*/std::vector<native_handle_t*>* handlesCreated,
+ /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers);
+
+ std::shared_ptr<AidlRequestMetadataQueue> mRequestMetadataQueue;
+ }; // class AidlHalInterface
+
+ /**
+ * Implementation of aidl::android::hardware::camera::device::ICameraDeviceCallback
+ */
+ ::ndk::ScopedAStatus processCaptureResult(
+ const std::vector<aidl::android::hardware::camera::device::CaptureResult>& results);
+ ::ndk::ScopedAStatus notify(
+ const std::vector<aidl::android::hardware::camera::device::NotifyMsg>& msgs);
+
+ ::ndk::ScopedAStatus requestStreamBuffers(
+ const std::vector<aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* status);
+
+ ::ndk::ScopedAStatus returnStreamBuffers(
+ const std::vector<aidl::android::hardware::camera::device::StreamBuffer>& buffers);
+
+ class AidlRequestThread : public Camera3Device::RequestThread {
+ public:
+ AidlRequestThread(wp<Camera3Device> parent,
+ sp<camera3::StatusTracker> statusTracker,
+ sp<HalInterface> interface,
+ const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager,
+ bool supportCameraMute);
+
+ status_t switchToOffline(
+ const std::vector<int32_t>& streamsToKeep,
+ /*out*/aidl::android::hardware::camera::device::CameraOfflineSessionInfo*
+ offlineSessionInfo,
+ /*out*/std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraOfflineSession>*
+ offlineSession,
+ /*out*/camera3::BufferRecords* bufferRecords);
+ }; // class AidlRequestThread
+
+ class AidlCamera3DeviceInjectionMethods : public Camera3DeviceInjectionMethods {
+ public:
+ // Initialize the injection camera and generate an hal interface.
+ status_t injectionInitialize(
+ const String8& injectedCamId, sp<CameraProviderManager> manager,
+ const std::shared_ptr<
+ aidl::android::hardware::camera::device::ICameraDeviceCallback>&
+ callback);
+ AidlCamera3DeviceInjectionMethods(wp<Camera3Device> parent) :
+ Camera3DeviceInjectionMethods(parent) { };
+ ~AidlCamera3DeviceInjectionMethods() {}
+ private:
+ // Backup of the original camera hal result FMQ.
+ std::unique_ptr<AidlResultMetadataQueue> mBackupResultMetadataQueue;
+
+ // FMQ writes the result for the injection camera. Must be guarded by
+ // mProcessCaptureResultLock.
+ std::unique_ptr<AidlResultMetadataQueue> mInjectionResultMetadataQueue;
+
+ // Use injection camera hal interface to replace and backup original
+ // camera hal interface.
+ virtual status_t replaceHalInterface(sp<HalInterface> newHalInterface,
+ bool keepBackup) override;
+ };
+
+ // We need a separate class which inherits from AIDL ICameraDeviceCallbacks
+ // since we use the ndk backend for AIDL HAL interfaces. The ndk backend of
+ // ICameraDeviceCallbacks doesn't support sp<> (since it doesn't inherit
+ // from RefBase).
+ // As a result we can't write sp<Camera3Device> = new AidlCamera3Device(...).
+ // It supports std::shared_ptr instead. Other references to
+ // Camera3Device in cameraserver use sp<> widely, so to keep supporting
+ // that, we create a new class which will be managed through std::shared_ptr
+ // internally by AidlCamera3Device.
+ class AidlCameraDeviceCallbacks :
+ public aidl::android::hardware::camera::device::BnCameraDeviceCallback {
+ public:
+
+ AidlCameraDeviceCallbacks(wp<AidlCamera3Device> parent) : mParent(parent) { }
+ ~AidlCameraDeviceCallbacks() { }
+ ::ndk::ScopedAStatus processCaptureResult(
+ const std::vector<
+ aidl::android::hardware::camera::device::CaptureResult>& results) override;
+ ::ndk::ScopedAStatus notify(
+ const std::vector<
+ aidl::android::hardware::camera::device::NotifyMsg>& msgs) override;
+
+ ::ndk::ScopedAStatus requestStreamBuffers(
+ const std::vector<
+ aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* status) override;
+
+ ::ndk::ScopedAStatus returnStreamBuffers(
+ const std::vector<
+ aidl::android::hardware::camera::device::StreamBuffer>& buffers) override;
+ private:
+ wp<AidlCamera3Device> mParent = nullptr;
+ };
+
+ private:
+ virtual status_t injectionCameraInitialize(const String8 &injectCamId,
+ sp<CameraProviderManager> manager) override;
+
+ virtual sp<RequestThread> createNewRequestThread(wp<Camera3Device> parent,
+ sp<camera3::StatusTracker> statusTracker,
+ sp<HalInterface> interface,
+ const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager,
+ bool supportCameraMute) override;
+
+ virtual sp<Camera3DeviceInjectionMethods>
+ createCamera3DeviceInjectionMethods(wp<Camera3Device>) override;
+
+ // FMQ to write result on. Must be guarded by mProcessCaptureResultLock.
+ std::unique_ptr<AidlResultMetadataQueue> mResultMetadataQueue = nullptr;
+
+ std::shared_ptr<AidlCameraDeviceCallbacks> mCallbacks = nullptr;
+
+
+}; // class AidlCamera3Device
+
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
new file mode 100644
index 0000000..895ce56
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlCamera3-OffLnSsn"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+//#define LOG_NNDEBUG 0 // Per-frame verbose logging
+
+#ifdef LOG_NNDEBUG
+#define ALOGVV(...) ALOGV(__VA_ARGS__)
+#else
+#define ALOGVV(...) ((void)0)
+#endif
+
+#include <inttypes.h>
+
+#include <utils/Trace.h>
+
+#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+
+#include "device3/aidl/AidlCamera3OfflineSession.h"
+#include "device3/Camera3OutputStream.h"
+#include "device3/aidl/AidlCamera3OutputUtils.h"
+#include "device3/Camera3InputStream.h"
+#include "device3/Camera3SharedOutputStream.h"
+#include "utils/CameraTraces.h"
+
+using namespace android::camera3;
+using namespace aidl::android::hardware;
+
+namespace android {
+
+
+AidlCamera3OfflineSession::~AidlCamera3OfflineSession() {
+ ATRACE_CALL();
+ ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.string());
+ AidlCamera3OfflineSession::disconnectSession();
+}
+
+status_t AidlCamera3OfflineSession::initialize(wp<NotificationListener> listener) {
+ ATRACE_CALL();
+
+ if (mSession == nullptr) {
+ ALOGE("%s: AIDL session is null!", __FUNCTION__);
+ return DEAD_OBJECT;
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ mListener = listener;
+
+ // setup result FMQ
+ std::unique_ptr<AidlResultMetadataQueue>& resQueue = mResultMetadataQueue;
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
+ ::ndk::ScopedAStatus resultQueueRet = mSession->getCaptureResultMetadataQueue(&desc);
+ if (!resultQueueRet.isOk()) {
+ ALOGE("Transaction error when getting result metadata queue from camera session: %s",
+ resultQueueRet.getMessage());
+ return DEAD_OBJECT;
+ }
+ resQueue = std::make_unique<AidlResultMetadataQueue>(desc);
+ if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
+ ALOGE("HAL returns empty result metadata fmq, not use it");
+ resQueue = nullptr;
+ // Don't use resQueue onwards.
+ }
+
+ mStatus = STATUS_ACTIVE;
+ }
+
+ mSession->setCallback(mCallbacks);
+
+ return OK;
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::AidlCameraDeviceCallbacks::processCaptureResult(
+ const std::vector<camera::device::CaptureResult>& results) {
+ sp<AidlCamera3OfflineSession> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->processCaptureResult(results);
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::processCaptureResult(
+ const std::vector<camera::device::CaptureResult>& results) {
+ sp<NotificationListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mStatus != STATUS_ACTIVE) {
+ ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ listener = mListener.promote();
+ }
+
+ AidlCaptureOutputStates states {
+ {mId,
+ mOfflineReqsLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
+ mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mNextResultFrameNumber,
+ mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
+ mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
+ mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
+ mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
+ *this, mBufferRecords, /*legacyClient*/ false}, mResultMetadataQueue
+ };
+
+ std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
+ for (const auto& result : results) {
+ processOneCaptureResultLocked(states, result, result.physicalCameraMetadata);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::AidlCameraDeviceCallbacks::notify(
+ const std::vector<camera::device::NotifyMsg>& msgs) {
+ sp<AidlCamera3OfflineSession> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->notify(msgs);
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::notify(
+ const std::vector<camera::device::NotifyMsg>& msgs) {
+ sp<NotificationListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mStatus != STATUS_ACTIVE) {
+ ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ listener = mListener.promote();
+ }
+
+ AidlCaptureOutputStates states {
+ {mId,
+ mOfflineReqsLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
+ mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mNextResultFrameNumber,
+ mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
+ mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
+ mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
+ mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
+ *this, mBufferRecords, /*legacyClient*/ false}, mResultMetadataQueue
+ };
+ for (const auto& msg : msgs) {
+ camera3::notify(states, msg);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::AidlCameraDeviceCallbacks::requestStreamBuffers(
+ const std::vector<::aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<::aidl::android::hardware::camera::device::StreamBufferRet>* buffers,
+ ::aidl::android::hardware::camera::device::BufferRequestStatus* status) {
+ sp<AidlCamera3OfflineSession> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->requestStreamBuffers(bufReqs, buffers, status);
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::requestStreamBuffers(
+ const std::vector<::aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<::aidl::android::hardware::camera::device::StreamBufferRet>* buffers,
+ ::aidl::android::hardware::camera::device::BufferRequestStatus* status) {
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mStatus != STATUS_ACTIVE) {
+ ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ }
+
+ RequestBufferStates states {
+ mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
+ *this, mBufferRecords, *this};
+ camera3::requestStreamBuffers(states, bufReqs, buffers, status);
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::AidlCameraDeviceCallbacks::returnStreamBuffers(
+ const std::vector<camera::device::StreamBuffer>& buffers) {
+ sp<AidlCamera3OfflineSession> p = mParent.promote();
+ if (p == nullptr) {
+ ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return p->returnStreamBuffers(buffers);
+}
+
+::ndk::ScopedAStatus AidlCamera3OfflineSession::returnStreamBuffers(
+ const std::vector<camera::device::StreamBuffer>& buffers) {
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mStatus != STATUS_ACTIVE) {
+ ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ }
+
+ ReturnBufferStates states {
+ mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
+ mBufferRecords};
+
+ camera3::returnStreamBuffers(states, buffers);
+ return ::ndk::ScopedAStatus::ok();
+}
+
+void AidlCamera3OfflineSession::disconnectSession() {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mSession != nullptr) {
+ mSession->close();
+ }
+ mSession.reset();
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
new file mode 100644
index 0000000..ad4a480
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_AIDL_CAMERA3OFFLINESESSION_H
+#define ANDROID_SERVERS_AIDL_CAMERA3OFFLINESESSION_H
+
+#include <memory>
+#include <mutex>
+
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+#include "AidlCamera3OutputUtils.h"
+#include <aidl/android/hardware/camera/device/BnCameraDeviceCallback.h>
+#include <aidl/android/hardware/camera/device/ICameraOfflineSession.h>
+
+#include <fmq/AidlMessageQueue.h>
+
+#include "common/CameraOfflineSessionBase.h"
+
+#include "device3/Camera3BufferManager.h"
+#include "device3/Camera3OfflineSession.h"
+#include "utils/TagMonitor.h"
+#include <camera_metadata_hidden.h>
+
+namespace android {
+
+namespace camera3 {
+
+class Camera3Stream;
+class Camera3OutputStreamInterface;
+class Camera3StreamInterface;
+
+} // namespace camera3
+
+/**
+ * AidlCamera3OfflineSession for offline session defined in AIDL ICameraOfflineSession
+ */
+class AidlCamera3OfflineSession :
+ public Camera3OfflineSession {
+ public:
+
+ virtual ~AidlCamera3OfflineSession();
+
+ virtual status_t initialize(wp<NotificationListener> listener) override;
+
+ /**
+ * Implementation of aidl::android::hardware::camera::device::ICameraDeviceCallback
+ */
+ ::ndk::ScopedAStatus processCaptureResult(
+ const std::vector<aidl::android::hardware::camera::device::CaptureResult>& results);
+ ::ndk::ScopedAStatus notify(
+ const std::vector<aidl::android::hardware::camera::device::NotifyMsg>& msgs);
+ ::ndk::ScopedAStatus requestStreamBuffers(
+ const std::vector<aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* status);
+
+ ::ndk::ScopedAStatus returnStreamBuffers(
+ const std::vector<aidl::android::hardware::camera::device::StreamBuffer>& buffers);
+
+ // See explanation for why we need a separate class for this in
+ // AidlCamera3Device::AidlCameraDeviceCallbacks in AidlCamera3Device.h
+ class AidlCameraDeviceCallbacks :
+ virtual public aidl::android::hardware::camera::device::BnCameraDeviceCallback {
+ public:
+
+ AidlCameraDeviceCallbacks(wp<AidlCamera3OfflineSession> parent) : mParent(parent) { }
+ ~AidlCameraDeviceCallbacks() {}
+ ::ndk::ScopedAStatus processCaptureResult(
+ const std::vector<
+ aidl::android::hardware::camera::device::CaptureResult>& results) override;
+ ::ndk::ScopedAStatus notify(
+ const std::vector<
+ aidl::android::hardware::camera::device::NotifyMsg>& msgs) override;
+
+ ::ndk::ScopedAStatus requestStreamBuffers(
+ const std::vector<
+ aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* out_buffers,
+ aidl::android::hardware::camera::device::BufferRequestStatus* _aidl_return
+ ) override;
+
+ ::ndk::ScopedAStatus returnStreamBuffers(
+ const std::vector<
+ aidl::android::hardware::camera::device::StreamBuffer>& buffers) override;
+ private:
+ wp<AidlCamera3OfflineSession> mParent = nullptr;
+ };
+
+ // initialize by Camera3Device.
+ explicit AidlCamera3OfflineSession(const String8& id,
+ const sp<camera3::Camera3Stream>& inputStream,
+ const camera3::StreamSet& offlineStreamSet,
+ camera3::BufferRecords&& bufferRecords,
+ const camera3::InFlightRequestMap& offlineReqs,
+ const Camera3OfflineStates& offlineStates,
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession>
+ offlineSession) :
+ Camera3OfflineSession(id, inputStream, offlineStreamSet, std::move(bufferRecords),
+ offlineReqs, offlineStates),
+ mSession(offlineSession) { mCallbacks = std::make_shared<AidlCameraDeviceCallbacks>(this);};
+
+ /**
+ * End of CameraOfflineSessionBase interface
+ */
+
+ private:
+ std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession> mSession;
+ // FMQ to write result on. Must be guarded by mProcessCaptureResultLock.
+ std::unique_ptr<AidlResultMetadataQueue> mResultMetadataQueue;
+
+ std::shared_ptr<AidlCameraDeviceCallbacks> mCallbacks;
+
+ virtual void disconnectSession() override;
+
+}; // class AidlCamera3OfflineSession
+
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
new file mode 100644
index 0000000..3809f37
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlCamera3-OutputUtils"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+//#define LOG_NDEBUG 0
+//#define LOG_NNDEBUG 0 // Per-frame verbose logging
+
+#ifdef LOG_NNDEBUG
+#define ALOGVV(...) ALOGV(__VA_ARGS__)
+#else
+#define ALOGVV(...) ((void)0)
+#endif
+
+// Convenience macros for transitioning to the error state
+#define SET_ERR(fmt, ...) states.setErrIntf.setErrorState( \
+ "%s: " fmt, __FUNCTION__, \
+ ##__VA_ARGS__)
+
+#include <inttypes.h>
+
+#include <utils/Log.h>
+#include <utils/SortedVector.h>
+#include <utils/Trace.h>
+
+#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include <aidlcommonsupport/NativeHandle.h>
+
+#include <camera/CameraUtils.h>
+#include <camera_metadata_hidden.h>
+
+#include "device3/aidl/AidlCamera3OutputUtils.h"
+#include "device3/Camera3OutputUtilsTemplated.h"
+
+#include "system/camera_metadata.h"
+
+using namespace android::camera3;
+using namespace android::hardware::camera;
+
+namespace android {
+namespace camera3 {
+
+void processOneCaptureResultLocked(
+ AidlCaptureOutputStates& states,
+ const aidl::android::hardware::camera::device::CaptureResult& result,
+ const std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata>
+ &physicalCameraMetadata) {
+ processOneCaptureResultLockedT<AidlCaptureOutputStates,
+ aidl::android::hardware::camera::device::CaptureResult,
+ std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata>,
+ std::vector<uint8_t>, AidlResultMetadataQueue,
+ aidl::android::hardware::camera::device::BufferStatus, int8_t>(states, result,
+ physicalCameraMetadata);
+}
+
+void notify(CaptureOutputStates& states,
+ const aidl::android::hardware::camera::device::NotifyMsg& msg) {
+
+ using ErrorCode = aidl::android::hardware::camera::device::ErrorCode;
+ using Tag = aidl::android::hardware::camera::device::NotifyMsg::Tag;
+
+ ATRACE_CALL();
+ camera_notify_msg m;
+
+ switch (msg.getTag()) {
+ case Tag::error:
+ m.type = CAMERA_MSG_ERROR;
+ m.message.error.frame_number = msg.get<Tag::error>().frameNumber;
+ if (msg.get<Tag::error>().errorStreamId >= 0) {
+ sp<Camera3StreamInterface> stream =
+ states.outputStreams.get(msg.get<Tag::error>().errorStreamId);
+ if (stream == nullptr) {
+ ALOGE("%s: Frame %d: Invalid error stream id %d", __FUNCTION__,
+ m.message.error.frame_number, msg.get<Tag::error>().errorStreamId);
+ return;
+ }
+ m.message.error.error_stream = stream->asHalStream();
+ } else {
+ m.message.error.error_stream = nullptr;
+ }
+ switch (msg.get<Tag::error>().errorCode) {
+ case ErrorCode::ERROR_DEVICE:
+ m.message.error.error_code = CAMERA_MSG_ERROR_DEVICE;
+ break;
+ case ErrorCode::ERROR_REQUEST:
+ m.message.error.error_code = CAMERA_MSG_ERROR_REQUEST;
+ break;
+ case ErrorCode::ERROR_RESULT:
+ m.message.error.error_code = CAMERA_MSG_ERROR_RESULT;
+ break;
+ case ErrorCode::ERROR_BUFFER:
+ m.message.error.error_code = CAMERA_MSG_ERROR_BUFFER;
+ break;
+ }
+ break;
+ case Tag::shutter:
+ m.type = CAMERA_MSG_SHUTTER;
+ m.message.shutter.frame_number = msg.get<Tag::shutter>().frameNumber;
+ m.message.shutter.timestamp = msg.get<Tag::shutter>().timestamp;
+ m.message.shutter.readout_timestamp = msg.get<Tag::shutter>().readoutTimestamp;
+ break;
+ }
+ notify(states, &m);
+}
+
+
+// The buffers requested through this call are not tied to any CaptureRequest in
+// particular. They may used by the hal for a particular frame's output buffer
+// or for its internal use as well. In the case that the hal does use any buffer
+// from the requested list here, for a particular frame's output buffer, the
+// buffer will be returned with the processCaptureResult call corresponding to
+// the frame. The other buffers will be returned through returnStreamBuffers.
+// The buffers returned via returnStreamBuffers will not have a valid
+// timestamp(0) and will be dropped by the bufferqueue.
+void requestStreamBuffers(RequestBufferStates& states,
+ const std::vector<aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<::aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
+ ::aidl::android::hardware::camera::device::BufferRequestStatus* status) {
+ using aidl::android::hardware::camera::device::BufferStatus;
+ using aidl::android::hardware::camera::device::StreamBuffer;
+ using aidl::android::hardware::camera::device::BufferRequestStatus;
+ using aidl::android::hardware::camera::device::StreamBufferRet;
+ using aidl::android::hardware::camera::device::StreamBufferRequestError;
+ using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
+ if (outBuffers == nullptr || status == nullptr) {
+ ALOGE("%s outBuffers / buffer status nullptr", __FUNCTION__);
+ return;
+ }
+ std::lock_guard<std::mutex> lock(states.reqBufferLock);
+ std::vector<StreamBufferRet> bufRets;
+ outBuffers->clear();
+ if (!states.useHalBufManager) {
+ ALOGE("%s: Camera %s does not support HAL buffer management",
+ __FUNCTION__, states.cameraId.string());
+ *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
+ return;
+ }
+
+ SortedVector<int32_t> streamIds;
+ ssize_t sz = streamIds.setCapacity(bufReqs.size());
+ if (sz < 0 || static_cast<size_t>(sz) != bufReqs.size()) {
+ ALOGE("%s: failed to allocate memory for %zu buffer requests",
+ __FUNCTION__, bufReqs.size());
+ *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
+ return;
+ }
+
+ if (bufReqs.size() > states.outputStreams.size()) {
+ ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
+ __FUNCTION__, bufReqs.size(), states.outputStreams.size());
+ *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
+ return;
+ }
+
+ // Check for repeated streamId
+ for (const auto& bufReq : bufReqs) {
+ if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
+ ALOGE("%s: Stream %d appear multiple times in buffer requests",
+ __FUNCTION__, bufReq.streamId);
+ *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
+ return;
+ }
+ streamIds.add(bufReq.streamId);
+ }
+
+ if (!states.reqBufferIntf.startRequestBuffer()) {
+ ALOGE("%s: request buffer disallowed while camera service is configuring",
+ __FUNCTION__);
+ *status = BufferRequestStatus::FAILED_CONFIGURING;
+ return;
+ }
+
+ bufRets.resize(bufReqs.size());
+
+ bool allReqsSucceeds = true;
+ bool oneReqSucceeds = false;
+ for (size_t i = 0; i < bufReqs.size(); i++) {
+ const auto& bufReq = bufReqs[i];
+ auto& bufRet = bufRets[i];
+ int32_t streamId = bufReq.streamId;
+ sp<Camera3OutputStreamInterface> outputStream = states.outputStreams.get(streamId);
+ if (outputStream == nullptr) {
+ ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
+ std::vector<StreamBufferRet> emptyBufRets;
+ *status = BufferRequestStatus::FAILED_CONFIGURING;
+ states.reqBufferIntf.endRequestBuffer();
+ return;
+ }
+
+ bufRet.streamId = streamId;
+ if (outputStream->isAbandoned()) {
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::STREAM_DISCONNECTED);
+ allReqsSucceeds = false;
+ continue;
+ }
+
+ size_t handOutBufferCount = outputStream->getOutstandingBuffersCount();
+ uint32_t numBuffersRequested = bufReq.numBuffersRequested;
+ size_t totalHandout = handOutBufferCount + numBuffersRequested;
+ uint32_t maxBuffers = outputStream->asHalStream()->max_buffers;
+ if (totalHandout > maxBuffers) {
+ // Not able to allocate enough buffer. Exit early for this stream
+ ALOGE("%s: request too much buffers for stream %d: at HAL: %zu + requesting: %d"
+ " > max: %d", __FUNCTION__, streamId, handOutBufferCount,
+ numBuffersRequested, maxBuffers);
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
+ allReqsSucceeds = false;
+ continue;
+ }
+
+ std::vector<StreamBuffer> tmpRetBuffers(numBuffersRequested);
+ bool currentReqSucceeds = true;
+ std::vector<camera_stream_buffer_t> streamBuffers(numBuffersRequested);
+ std::vector<buffer_handle_t> newBuffers;
+ size_t numAllocatedBuffers = 0;
+ size_t numPushedInflightBuffers = 0;
+ for (size_t b = 0; b < numBuffersRequested; b++) {
+ camera_stream_buffer_t& sb = streamBuffers[b];
+ // Since this method can run concurrently with request thread
+ // We need to update the wait duration everytime we call getbuffer
+ nsecs_t waitDuration = states.reqBufferIntf.getWaitDuration();
+ status_t res = outputStream->getBuffer(&sb, waitDuration);
+ if (res != OK) {
+ if (res == NO_INIT || res == DEAD_OBJECT) {
+ ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::STREAM_DISCONNECTED);
+ states.sessionStatsBuilder.stopCounter(streamId);
+ } else {
+ ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ if (res == TIMED_OUT || res == NO_MEMORY) {
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
+ } else {
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::UNKNOWN_ERROR);
+ }
+ }
+ currentReqSucceeds = false;
+ break;
+ }
+ numAllocatedBuffers++;
+
+ buffer_handle_t *buffer = sb.buffer;
+ auto pair = states.bufferRecordsIntf.getBufferId(*buffer, streamId);
+ bool isNewBuffer = pair.first;
+ uint64_t bufferId = pair.second;
+ StreamBuffer& hBuf = tmpRetBuffers[b];
+
+ hBuf.streamId = streamId;
+ hBuf.bufferId = bufferId;
+
+ hBuf.buffer = (isNewBuffer) ? camera3::dupToAidlIfNotNull(*buffer) :
+ aidl::android::hardware::common::NativeHandle();
+ hBuf.status = BufferStatus::OK;
+ hBuf.releaseFence = aidl::android::hardware::common::NativeHandle();
+ if (isNewBuffer) {
+ newBuffers.push_back(*buffer);
+ }
+
+ native_handle_t *acquireFence = nullptr;
+ if (sb.acquire_fence != -1) {
+ acquireFence = native_handle_create(1,0);
+ acquireFence->data[0] = sb.acquire_fence;
+ }
+ //makeToAidl passes ownership to aidl NativeHandle made. Ownership
+ //is passed : see system/window.h : dequeueBuffer
+ hBuf.acquireFence = makeToAidlIfNotNull(acquireFence);
+ if (acquireFence != nullptr) {
+ native_handle_delete(acquireFence);
+ }
+ hBuf.releaseFence = aidl::android::hardware::common::NativeHandle();
+
+ res = states.bufferRecordsIntf.pushInflightRequestBuffer(bufferId, buffer, streamId);
+ if (res != OK) {
+ ALOGE("%s: Can't get register request buffers for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::UNKNOWN_ERROR);
+ currentReqSucceeds = false;
+ break;
+ }
+ numPushedInflightBuffers++;
+ }
+ if (currentReqSucceeds) {
+ bufRet.val.set<Tag::buffers>(std::move(tmpRetBuffers));
+ oneReqSucceeds = true;
+ } else {
+ allReqsSucceeds = false;
+ for (size_t b = 0; b < numPushedInflightBuffers; b++) {
+ StreamBuffer& hBuf = tmpRetBuffers[b];
+ buffer_handle_t* buffer;
+ status_t res = states.bufferRecordsIntf.popInflightRequestBuffer(
+ hBuf.bufferId, &buffer);
+ if (res != OK) {
+ SET_ERR("%s: popInflightRequestBuffer failed for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ }
+ }
+ for (size_t b = 0; b < numAllocatedBuffers; b++) {
+ camera_stream_buffer_t& sb = streamBuffers[b];
+ sb.acquire_fence = -1;
+ sb.status = CAMERA_BUFFER_STATUS_ERROR;
+ }
+ returnOutputBuffers(states.useHalBufManager, nullptr,
+ streamBuffers.data(), numAllocatedBuffers, 0,
+ 0, false,
+ 0, states.sessionStatsBuilder);
+ for (auto buf : newBuffers) {
+ states.bufferRecordsIntf.removeOneBufferCache(streamId, buf);
+ }
+ }
+ }
+
+ *status = allReqsSucceeds ? BufferRequestStatus::OK :
+ oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
+ BufferRequestStatus::FAILED_UNKNOWN,
+ // Transfer ownership of buffer fds to outBuffers
+ *outBuffers = std::move(bufRets);
+
+ states.reqBufferIntf.endRequestBuffer();
+}
+
+void returnStreamBuffers(ReturnBufferStates& states,
+ const std::vector<aidl::android::hardware::camera::device::StreamBuffer>& buffers) {
+ returnStreamBuffersT(states, buffers);
+}
+
+} // camera3
+} // namespace android
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.h
new file mode 100644
index 0000000..e795624
--- /dev/null
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SERVERS_AIDL_CAMERA3_OUTPUT_UTILS_H
+#define ANDROID_SERVERS_AIDL_CAMERA3_OUTPUT_UTILS_H
+
+#include <memory>
+#include <mutex>
+
+#include <cutils/native_handle.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <common/CameraDeviceBase.h>
+
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/device/ICameraDeviceCallback.h>
+#include "device3/BufferUtils.h"
+#include "device3/InFlightRequest.h"
+#include "device3/Camera3Stream.h"
+#include "device3/Camera3OutputStreamInterface.h"
+#include "device3/Camera3OutputUtils.h"
+#include "utils/SessionStatsBuilder.h"
+#include "utils/TagMonitor.h"
+
+namespace android {
+
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+using AidlResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+namespace camera3 {
+ inline aidl::android::hardware::common::NativeHandle dupToAidlIfNotNull(
+ const native_handle_t *nh) {
+ if (nh == nullptr) {
+ return aidl::android::hardware::common::NativeHandle();
+ }
+ return dupToAidl(nh);
+ }
+
+ inline aidl::android::hardware::common::NativeHandle makeToAidlIfNotNull(
+ const native_handle_t *nh) {
+ if (nh == nullptr) {
+ return aidl::android::hardware::common::NativeHandle();
+ }
+ return makeToAidl(nh);
+ }
+
+ /**
+ * Helper methods shared between AidlCamera3Device/AidlCamera3OfflineSession for HAL callbacks
+ */
+
+ // Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
+ // callbacks
+ struct AidlCaptureOutputStates : public CaptureOutputStates {
+ std::unique_ptr<AidlResultMetadataQueue>& fmq;
+ };
+
+ // Handle one capture result. Assume callers hold the lock to serialize all
+ // processCaptureResult calls
+ void processOneCaptureResultLocked(
+ AidlCaptureOutputStates& states,
+ const aidl::android::hardware::camera::device::CaptureResult& result,
+ const std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata>
+ &physicalCameraMetadata);
+
+ void notify(CaptureOutputStates& states,
+ const aidl::android::hardware::camera::device::NotifyMsg& msg,
+ bool hasReadoutTime, uint64_t readoutTime);
+
+ void notify(CaptureOutputStates& states,
+ const aidl::android::hardware::camera::device::NotifyMsg& msg);
+
+ void requestStreamBuffers(RequestBufferStates& states,
+ const std::vector<aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
+ std::vector<::aidl::android::hardware::camera::device::StreamBufferRet>* out_buffers,
+ ::aidl::android::hardware::camera::device::BufferRequestStatus* _aidl_return);
+
+ void returnStreamBuffers(ReturnBufferStates& states,
+ const std::vector<aidl::android::hardware::camera::device::StreamBuffer>& buffers);
+
+} // namespace camera3
+
+} // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
index afe9d56..1563dcf 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
@@ -38,6 +38,8 @@
#include <camera_metadata_hidden.h>
#include "device3/hidl/HidlCamera3OutputUtils.h"
+#include "device3/aidl/AidlCamera3OutputUtils.h"
+#include "device3/Camera3Device.h"
#include "device3/Camera3OutputUtilsTemplated.h"
#include "system/camera_metadata.h"
@@ -132,7 +134,116 @@
notify(states, &m);
}
+static void convertToAidl(
+ const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& hidlBufReqs,
+ std::vector<aidl::android::hardware::camera::device::BufferRequest> &aidlBufReqs) {
+ size_t i = 0;
+ aidlBufReqs.resize(hidlBufReqs.size());
+ for (const auto &hidlBufReq : hidlBufReqs) {
+ aidlBufReqs[i].streamId = hidlBufReq.streamId;
+ aidlBufReqs[i].numBuffersRequested = hidlBufReq.numBuffersRequested;
+ i++;
+ }
+}
+static hardware::camera::device::V3_5::StreamBufferRequestError
+convertToHidl(aidl::android::hardware::camera::device::StreamBufferRequestError aError) {
+ using AError = aidl::android::hardware::camera::device::StreamBufferRequestError;
+ using HError = hardware::camera::device::V3_5::StreamBufferRequestError;
+
+ switch(aError) {
+ case AError::NO_BUFFER_AVAILABLE:
+ return HError::NO_BUFFER_AVAILABLE;
+ case AError::MAX_BUFFER_EXCEEDED:
+ return HError::MAX_BUFFER_EXCEEDED;
+ case AError::STREAM_DISCONNECTED:
+ return HError::STREAM_DISCONNECTED;
+ default:
+ return HError::UNKNOWN_ERROR;
+ }
+}
+
+static hardware::camera::device::V3_5::BufferRequestStatus
+convertToHidl(const aidl::android::hardware::camera::device::BufferRequestStatus &aBufStatus) {
+ using AStatus = aidl::android::hardware::camera::device::BufferRequestStatus;
+ using HStatus = hardware::camera::device::V3_5::BufferRequestStatus;
+ switch (aBufStatus) {
+ case AStatus::OK:
+ return HStatus::OK;
+ case AStatus::FAILED_PARTIAL:
+ return HStatus::FAILED_PARTIAL;
+ case AStatus::FAILED_CONFIGURING:
+ return HStatus::FAILED_CONFIGURING;
+ case AStatus::FAILED_ILLEGAL_ARGUMENTS:
+ return HStatus::FAILED_ILLEGAL_ARGUMENTS;
+ case AStatus::FAILED_UNKNOWN:
+ return HStatus::FAILED_UNKNOWN;
+ }
+ return HStatus::FAILED_UNKNOWN;
+}
+
+static hardware::camera::device::V3_2::BufferStatus
+convertToHidl(const aidl::android::hardware::camera::device::BufferStatus &aBufStatus) {
+ using AStatus = aidl::android::hardware::camera::device::BufferStatus;
+ using HStatus = hardware::camera::device::V3_2::BufferStatus;
+ switch (aBufStatus) {
+ case AStatus::OK:
+ return HStatus::OK;
+ case AStatus::ERROR:
+ return HStatus::ERROR;
+ }
+ return HStatus::ERROR;
+}
+
+static native_handle_t *convertToHidl(const aidl::android::hardware::common::NativeHandle &ah,
+ std::vector<native_handle_t *> &handlesCreated) {
+ if (isHandleNull(ah)) {
+ return nullptr;
+ }
+ native_handle_t *nh = makeFromAidl(ah);
+ handlesCreated.emplace_back(nh);
+ return nh;
+}
+
+static void convertToHidl(
+ const std::vector<aidl::android::hardware::camera::device::StreamBuffer> &aBuffers,
+ hardware::camera::device::V3_5::StreamBuffersVal &hBuffersVal,
+ std::vector<native_handle_t *> &handlesCreated) {
+ using HStreamBuffer = hardware::camera::device::V3_2::StreamBuffer;
+ hardware::hidl_vec<HStreamBuffer> tmpBuffers(aBuffers.size());
+ size_t i = 0;
+ for (const auto &aBuf : aBuffers) {
+ tmpBuffers[i].status = convertToHidl(aBuf.status);
+ tmpBuffers[i].streamId = aBuf.streamId;
+ tmpBuffers[i].bufferId = aBuf.bufferId;
+ tmpBuffers[i].buffer = convertToHidl(aBuf.buffer, handlesCreated);
+ tmpBuffers[i].acquireFence = convertToHidl(aBuf.acquireFence, handlesCreated);
+ tmpBuffers[i].releaseFence = convertToHidl(aBuf.releaseFence, handlesCreated);
+ }
+ hBuffersVal.buffers(std::move(tmpBuffers));
+}
+
+static void convertToHidl(
+ const std::vector<aidl::android::hardware::camera::device::StreamBufferRet> &aidlBufRets,
+ hardware::hidl_vec<hardware::camera::device::V3_5::StreamBufferRet> &hidlBufRets,
+ std::vector<native_handle_t *> &handlesCreated) {
+ size_t i = 0;
+ using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
+ hidlBufRets.resize(aidlBufRets.size());
+ for (const auto &aidlBufRet : aidlBufRets) {
+ auto &hidlBufRet = hidlBufRets[i];
+ hidlBufRet.streamId = aidlBufRet.streamId;
+ switch(aidlBufRet.val.getTag()) {
+ case Tag::error:
+ hidlBufRet.val.error(convertToHidl(aidlBufRet.val.get<Tag::error>()));
+ break;
+ case Tag::buffers:
+ convertToHidl(aidlBufRet.val.get<Tag::buffers>(), hidlBufRet.val, handlesCreated);
+ break;
+ }
+ i++;
+ }
+}
// The buffers requested through this call are not tied to any CaptureRequest in
// particular. They may used by the hal for a particular frame's output buffer
@@ -145,194 +256,22 @@
void requestStreamBuffers(RequestBufferStates& states,
const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
hardware::camera::device::V3_5::ICameraDeviceCallback::requestStreamBuffers_cb _hidl_cb) {
- using android::hardware::camera::device::V3_2::BufferStatus;
+ using android::hardware::camera::device::V3_2::BufferStatus;
using android::hardware::camera::device::V3_2::StreamBuffer;
using android::hardware::camera::device::V3_5::BufferRequestStatus;
using android::hardware::camera::device::V3_5::StreamBufferRet;
using android::hardware::camera::device::V3_5::StreamBufferRequestError;
+ std::vector<aidl::android::hardware::camera::device::BufferRequest> aidlBufReqs;
+ hardware::hidl_vec<hardware::camera::device::V3_5::StreamBufferRet> hidlBufRets;
+ convertToAidl(bufReqs, aidlBufReqs);
+ std::vector<::aidl::android::hardware::camera::device::StreamBufferRet> aidlBufRets;
+ ::aidl::android::hardware::camera::device::BufferRequestStatus aidlBufRetStatus;
- std::lock_guard<std::mutex> lock(states.reqBufferLock);
-
- hardware::hidl_vec<StreamBufferRet> bufRets;
- if (!states.useHalBufManager) {
- ALOGE("%s: Camera %s does not support HAL buffer management",
- __FUNCTION__, states.cameraId.string());
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
- return;
- }
-
- SortedVector<int32_t> streamIds;
- ssize_t sz = streamIds.setCapacity(bufReqs.size());
- if (sz < 0 || static_cast<size_t>(sz) != bufReqs.size()) {
- ALOGE("%s: failed to allocate memory for %zu buffer requests",
- __FUNCTION__, bufReqs.size());
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
- return;
- }
-
- if (bufReqs.size() > states.outputStreams.size()) {
- ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
- __FUNCTION__, bufReqs.size(), states.outputStreams.size());
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
- return;
- }
-
- // Check for repeated streamId
- for (const auto& bufReq : bufReqs) {
- if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
- ALOGE("%s: Stream %d appear multiple times in buffer requests",
- __FUNCTION__, bufReq.streamId);
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
- return;
- }
- streamIds.add(bufReq.streamId);
- }
-
- if (!states.reqBufferIntf.startRequestBuffer()) {
- ALOGE("%s: request buffer disallowed while camera service is configuring",
- __FUNCTION__);
- _hidl_cb(BufferRequestStatus::FAILED_CONFIGURING, bufRets);
- return;
- }
-
- bufRets.resize(bufReqs.size());
-
- bool allReqsSucceeds = true;
- bool oneReqSucceeds = false;
- for (size_t i = 0; i < bufReqs.size(); i++) {
- const auto& bufReq = bufReqs[i];
- auto& bufRet = bufRets[i];
- int32_t streamId = bufReq.streamId;
- sp<Camera3OutputStreamInterface> outputStream = states.outputStreams.get(streamId);
- if (outputStream == nullptr) {
- ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
- hardware::hidl_vec<StreamBufferRet> emptyBufRets;
- _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, emptyBufRets);
- states.reqBufferIntf.endRequestBuffer();
- return;
- }
-
- bufRet.streamId = streamId;
- if (outputStream->isAbandoned()) {
- bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
- allReqsSucceeds = false;
- continue;
- }
-
- size_t handOutBufferCount = outputStream->getOutstandingBuffersCount();
- uint32_t numBuffersRequested = bufReq.numBuffersRequested;
- size_t totalHandout = handOutBufferCount + numBuffersRequested;
- uint32_t maxBuffers = outputStream->asHalStream()->max_buffers;
- if (totalHandout > maxBuffers) {
- // Not able to allocate enough buffer. Exit early for this stream
- ALOGE("%s: request too much buffers for stream %d: at HAL: %zu + requesting: %d"
- " > max: %d", __FUNCTION__, streamId, handOutBufferCount,
- numBuffersRequested, maxBuffers);
- bufRet.val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
- allReqsSucceeds = false;
- continue;
- }
-
- hardware::hidl_vec<StreamBuffer> tmpRetBuffers(numBuffersRequested);
- bool currentReqSucceeds = true;
- std::vector<camera_stream_buffer_t> streamBuffers(numBuffersRequested);
- std::vector<buffer_handle_t> newBuffers;
- size_t numAllocatedBuffers = 0;
- size_t numPushedInflightBuffers = 0;
- for (size_t b = 0; b < numBuffersRequested; b++) {
- camera_stream_buffer_t& sb = streamBuffers[b];
- // Since this method can run concurrently with request thread
- // We need to update the wait duration everytime we call getbuffer
- nsecs_t waitDuration = states.reqBufferIntf.getWaitDuration();
- status_t res = outputStream->getBuffer(&sb, waitDuration);
- if (res != OK) {
- if (res == NO_INIT || res == DEAD_OBJECT) {
- ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
- __FUNCTION__, streamId, strerror(-res), res);
- bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
- states.sessionStatsBuilder.stopCounter(streamId);
- } else {
- ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
- __FUNCTION__, streamId, strerror(-res), res);
- if (res == TIMED_OUT || res == NO_MEMORY) {
- bufRet.val.error(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
- } else {
- bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
- }
- }
- currentReqSucceeds = false;
- break;
- }
- numAllocatedBuffers++;
-
- buffer_handle_t *buffer = sb.buffer;
- auto pair = states.bufferRecordsIntf.getBufferId(*buffer, streamId);
- bool isNewBuffer = pair.first;
- uint64_t bufferId = pair.second;
- StreamBuffer& hBuf = tmpRetBuffers[b];
-
- hBuf.streamId = streamId;
- hBuf.bufferId = bufferId;
- hBuf.buffer = (isNewBuffer) ? *buffer : nullptr;
- hBuf.status = BufferStatus::OK;
- hBuf.releaseFence = nullptr;
- if (isNewBuffer) {
- newBuffers.push_back(*buffer);
- }
-
- native_handle_t *acquireFence = nullptr;
- if (sb.acquire_fence != -1) {
- acquireFence = native_handle_create(1,0);
- acquireFence->data[0] = sb.acquire_fence;
- }
- hBuf.acquireFence.setTo(acquireFence, /*shouldOwn*/true);
- hBuf.releaseFence = nullptr;
-
- res = states.bufferRecordsIntf.pushInflightRequestBuffer(bufferId, buffer, streamId);
- if (res != OK) {
- ALOGE("%s: Can't get register request buffers for stream %d: %s (%d)",
- __FUNCTION__, streamId, strerror(-res), res);
- bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
- currentReqSucceeds = false;
- break;
- }
- numPushedInflightBuffers++;
- }
- if (currentReqSucceeds) {
- bufRet.val.buffers(std::move(tmpRetBuffers));
- oneReqSucceeds = true;
- } else {
- allReqsSucceeds = false;
- for (size_t b = 0; b < numPushedInflightBuffers; b++) {
- StreamBuffer& hBuf = tmpRetBuffers[b];
- buffer_handle_t* buffer;
- status_t res = states.bufferRecordsIntf.popInflightRequestBuffer(
- hBuf.bufferId, &buffer);
- if (res != OK) {
- SET_ERR("%s: popInflightRequestBuffer failed for stream %d: %s (%d)",
- __FUNCTION__, streamId, strerror(-res), res);
- }
- }
- for (size_t b = 0; b < numAllocatedBuffers; b++) {
- camera_stream_buffer_t& sb = streamBuffers[b];
- sb.acquire_fence = -1;
- sb.status = CAMERA_BUFFER_STATUS_ERROR;
- }
- returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
- streamBuffers.data(), numAllocatedBuffers, /*timestamp*/0,
- /*readoutTimestamp*/0, /*requested*/false,
- /*requestTimeNs*/0, states.sessionStatsBuilder);
- for (auto buf : newBuffers) {
- states.bufferRecordsIntf.removeOneBufferCache(streamId, buf);
- }
- }
- }
-
- _hidl_cb(allReqsSucceeds ? BufferRequestStatus::OK :
- oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
- BufferRequestStatus::FAILED_UNKNOWN,
- bufRets);
- states.reqBufferIntf.endRequestBuffer();
+ requestStreamBuffers(states, aidlBufReqs, &aidlBufRets, &aidlBufRetStatus);
+ std::vector<native_handle_t *> handlesCreated;
+ convertToHidl(aidlBufRets, hidlBufRets, handlesCreated);
+ _hidl_cb(convertToHidl(aidlBufRetStatus), hidlBufRets);
+ Camera3Device::cleanupNativeHandles(&handlesCreated);
}
void returnStreamBuffers(ReturnBufferStates& states,
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index ca73e4c..3c98a5e 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -52,6 +52,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V1-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index c3f0620..4928faf 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -44,6 +44,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
+ "android.hardware.camera.provider-V1-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 751f24f..43591c2 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -21,7 +21,9 @@
#include "../api2/HeicCompositeStream.h"
#include "android/hardware/camera/metadata/3.8/types.h"
#include "common/CameraDeviceBase.h"
+#include "common/HalConversionsTemplated.h"
#include "../CameraService.h"
+#include "device3/aidl/AidlCamera3Device.h"
#include "device3/hidl/HidlCamera3Device.h"
#include "device3/Camera3OutputStream.h"
#include "system/graphics-base-v1.1.h"
@@ -514,108 +516,103 @@
void mapStreamInfo(const OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId,
- int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
+ int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
if (stream == nullptr) {
return;
}
- stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
- stream->v3_7.v3_4.v3_2.width = streamInfo.width;
- stream->v3_7.v3_4.v3_2.height = streamInfo.height;
- stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
+ stream->streamType = aidl::android::hardware::camera::device::StreamType::OUTPUT;
+ stream->width = streamInfo.width;
+ stream->height = streamInfo.height;
+ stream->format = AidlCamera3Device::mapToAidlPixelFormat(streamInfo.format);
auto u = streamInfo.consumerUsage;
camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
- stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
- stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
- stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
- stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
- stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
- stream->v3_7.v3_4.bufferSize = 0;
- stream->v3_7.groupId = groupId;
- stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
-
+ stream->usage = AidlCamera3Device::mapToAidlConsumerUsage(u);
+ stream->dataSpace = AidlCamera3Device::mapToAidlDataspace(streamInfo.dataSpace);
+ stream->rotation = AidlCamera3Device::mapToAidlStreamRotation(rotation);
+ stream->id = -1; // Invalid stream id
+ stream->physicalCameraId = std::string(physicalId.string());
+ stream->bufferSize = 0;
+ stream->groupId = groupId;
+ stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
size_t idx = 0;
+ using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
for (auto mode : streamInfo.sensorPixelModesUsed) {
- stream->v3_7.sensorPixelModesUsed[idx++] =
- static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+ stream->sensorPixelModesUsed[idx++] =
+ static_cast<SensorPixelMode>(mode);
}
- stream->dynamicRangeProfile =
- static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
- streamInfo.dynamicRangeProfile);
- stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
- streamInfo.streamUseCase);
+ using DynamicRangeProfile =
+ aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
+ stream->dynamicRangeProfile = static_cast<DynamicRangeProfile>(streamInfo.dynamicRangeProfile);
+ using StreamUseCases =
+ aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
+ stream->useCase = static_cast<StreamUseCases>(streamInfo.streamUseCase);
}
-binder::Status checkPhysicalCameraId(
- const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
- const String8 &logicalCameraId) {
- if (physicalCameraId.size() == 0) {
- return binder::Status::ok();
+status_t
+convertAidlToHidl38StreamCombination(
+ const aidl::android::hardware::camera::device::StreamConfiguration &aidl,
+ hardware::camera::device::V3_8::StreamConfiguration &hidl) {
+ hidl.operationMode =
+ static_cast<hardware::camera::device::V3_2::StreamConfigurationMode>(aidl.operationMode);
+ if (aidl.streamConfigCounter < 0) {
+ return BAD_VALUE;
}
- if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
- physicalCameraId.string()) == physicalCameraIds.end()) {
- String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
- logicalCameraId.string(), physicalCameraId.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- return binder::Status::ok();
-}
+ hidl.streamConfigCounter = static_cast<uint32_t>(aidl.streamConfigCounter);
+ hidl.multiResolutionInputImage = aidl.multiResolutionInputImage;
+ hidl.sessionParams = aidl.sessionParams.metadata;
+ hidl.streams.resize(aidl.streams.size());
+ size_t i = 0;
+ for (const auto &stream : aidl.streams) {
+ //hidlv3_8
+ hidl.streams[i].dynamicRangeProfile =
+ static_cast<
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
+ (stream.dynamicRangeProfile);
+ hidl.streams[i].useCase =
+ static_cast<
+ CameraMetadataEnumAndroidScalerAvailableStreamUseCases>
+ (stream.useCase);
-binder::Status checkSurfaceType(size_t numBufferProducers,
- bool deferredConsumer, int surfaceType) {
- if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
- ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
- __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
- } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
- ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
- }
-
- bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
- (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
-
- if (deferredConsumer && !validSurfaceType) {
- ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
- }
-
- return binder::Status::ok();
-}
-
-binder::Status checkOperatingMode(int operatingMode,
- const CameraMetadata &staticInfo, const String8 &cameraId) {
- if (operatingMode < 0) {
- String8 msg = String8::format(
- "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
- }
-
- bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
- if (isConstrainedHighSpeed) {
- camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
- bool isConstrainedHighSpeedSupported = false;
- for(size_t i = 0; i < entry.count; ++i) {
- uint8_t capability = entry.data.u8[i];
- if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
- isConstrainedHighSpeedSupported = true;
- break;
- }
+ // hidl v3_7
+ hidl.streams[i].v3_7.groupId = stream.groupId;
+ hidl.streams[i].v3_7.sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
+ size_t j = 0;
+ for (const auto &mode : stream.sensorPixelModesUsed) {
+ hidl.streams[i].v3_7.sensorPixelModesUsed[j] =
+ static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+ j++;
}
- if (!isConstrainedHighSpeedSupported) {
- String8 msg = String8::format(
- "Camera %s: Try to create a constrained high speed configuration on a device"
- " that doesn't support it.", cameraId.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- msg.string());
- }
- }
- return binder::Status::ok();
+ //hidl v3_4
+ hidl.streams[i].v3_7.v3_4.physicalCameraId = stream.physicalCameraId;
+
+ if (stream.bufferSize < 0) {
+ return BAD_VALUE;
+ }
+ hidl.streams[i].v3_7.v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
+
+ // hild v3_2
+ hidl.streams[i].v3_7.v3_4.v3_2.id = stream.id;
+ hidl.streams[i].v3_7.v3_4.v3_2.format =
+ static_cast<hardware::graphics::common::V1_0::PixelFormat>(stream.format);
+
+ if (stream.width < 0 || stream.height < 0) {
+ return BAD_VALUE;
+ }
+ hidl.streams[i].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
+ hidl.streams[i].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
+ hidl.streams[i].v3_7.v3_4.v3_2.usage =
+ static_cast<hardware::camera::device::V3_2::BufferUsageFlags>(stream.usage);
+ hidl.streams[i].v3_7.v3_4.v3_2.streamType =
+ static_cast<hardware::camera::device::V3_2::StreamType>(stream.streamType);
+ hidl.streams[i].v3_7.v3_4.v3_2.dataSpace =
+ static_cast<hardware::camera::device::V3_2::DataspaceFlags>(stream.dataSpace);
+ hidl.streams[i].v3_7.v3_4.v3_2.rotation =
+ static_cast<hardware::camera::device::V3_2::StreamRotation>(stream.rotation);
+ i++;
+ }
+ return OK;
}
binder::Status
@@ -623,9 +620,9 @@
const SessionConfiguration& sessionConfiguration,
const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
- hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+ aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
-
+ using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
auto operatingMode = sessionConfiguration.getOperatingMode();
binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
if (!res.isOk()) {
@@ -638,7 +635,7 @@
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
*earlyExit = false;
- auto ret = HidlCamera3Device::mapToStreamConfigurationMode(
+ auto ret = AidlCamera3Device::mapToAidlStreamConfigurationMode(
static_cast<camera_stream_configuration_mode_t> (operatingMode),
/*out*/ &streamConfiguration.operationMode);
if (ret != OK) {
@@ -659,19 +656,27 @@
streamConfiguration.streams.resize(streamCount);
size_t streamIdx = 0;
if (isInputValid) {
- hardware::hidl_vec<CameraMetadataEnumAndroidSensorPixelMode> defaultSensorPixelModes;
+ std::vector<SensorPixelMode> defaultSensorPixelModes;
defaultSensorPixelModes.resize(1);
defaultSensorPixelModes[0] =
- static_cast<CameraMetadataEnumAndroidSensorPixelMode>(
- ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
- streamConfiguration.streams[streamIdx++].v3_7 = {{{/*streamId*/0,
- hardware::camera::device::V3_2::StreamType::INPUT,
- static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
- static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
- HidlCamera3Device::mapToPixelFormat(sessionConfiguration.getInputFormat()),
- /*usage*/ 0, HAL_DATASPACE_UNKNOWN,
- hardware::camera::device::V3_2::StreamRotation::ROTATION_0},
- /*physicalId*/ nullptr, /*bufferSize*/0}, /*groupId*/-1, defaultSensorPixelModes};
+ static_cast<SensorPixelMode>(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
+ aidl::android::hardware::camera::device::Stream stream;
+ stream.id = 0;
+ stream.streamType = aidl::android::hardware::camera::device::StreamType::INPUT;
+ stream.width = static_cast<uint32_t> (sessionConfiguration.getInputWidth());
+ stream.height = static_cast<uint32_t> (sessionConfiguration.getInputHeight());
+ stream.format =
+ AidlCamera3Device::AidlCamera3Device::mapToAidlPixelFormat(
+ sessionConfiguration.getInputFormat());
+ stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0);
+ stream.dataSpace =
+ static_cast<aidl::android::hardware::graphics::common::Dataspace>(
+ HAL_DATASPACE_UNKNOWN);
+ stream.rotation = aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
+ stream.bufferSize = 0;
+ stream.groupId = -1;
+ stream.sensorPixelModesUsed = defaultSensorPixelModes;
+ streamConfiguration.streams[streamIdx++] = stream;
streamConfiguration.multiResolutionInputImage =
sessionConfiguration.inputIsMultiResolution();
}
@@ -798,6 +803,138 @@
return binder::Status::ok();
}
+void mapStreamInfo(const OutputStreamInfo &streamInfo,
+ camera3::camera_stream_rotation_t rotation, String8 physicalId,
+ int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
+ if (stream == nullptr) {
+ return;
+ }
+
+ stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
+ stream->v3_7.v3_4.v3_2.width = streamInfo.width;
+ stream->v3_7.v3_4.v3_2.height = streamInfo.height;
+ stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
+ auto u = streamInfo.consumerUsage;
+ camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
+ stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
+ stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
+ stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
+ stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
+ stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
+ stream->v3_7.v3_4.bufferSize = 0;
+ stream->v3_7.groupId = groupId;
+ stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
+
+ size_t idx = 0;
+ for (auto mode : streamInfo.sensorPixelModesUsed) {
+ stream->v3_7.sensorPixelModesUsed[idx++] =
+ static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
+ }
+ stream->dynamicRangeProfile =
+ static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
+ streamInfo.dynamicRangeProfile);
+ stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
+ streamInfo.streamUseCase);
+}
+
+binder::Status checkPhysicalCameraId(
+ const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
+ const String8 &logicalCameraId) {
+ if (physicalCameraId.size() == 0) {
+ return binder::Status::ok();
+ }
+ if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
+ physicalCameraId.string()) == physicalCameraIds.end()) {
+ String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
+ logicalCameraId.string(), physicalCameraId.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ return binder::Status::ok();
+}
+
+binder::Status checkSurfaceType(size_t numBufferProducers,
+ bool deferredConsumer, int surfaceType) {
+ if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
+ ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
+ __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
+ } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
+ ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
+ }
+
+ bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
+ (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
+
+ if (deferredConsumer && !validSurfaceType) {
+ ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
+ }
+
+ return binder::Status::ok();
+}
+
+binder::Status checkOperatingMode(int operatingMode,
+ const CameraMetadata &staticInfo, const String8 &cameraId) {
+ if (operatingMode < 0) {
+ String8 msg = String8::format(
+ "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ msg.string());
+ }
+
+ bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
+ if (isConstrainedHighSpeed) {
+ camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ bool isConstrainedHighSpeedSupported = false;
+ for(size_t i = 0; i < entry.count; ++i) {
+ uint8_t capability = entry.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
+ isConstrainedHighSpeedSupported = true;
+ break;
+ }
+ }
+ if (!isConstrainedHighSpeedSupported) {
+ String8 msg = String8::format(
+ "Camera %s: Try to create a constrained high speed configuration on a device"
+ " that doesn't support it.", cameraId.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ msg.string());
+ }
+ }
+
+ return binder::Status::ok();
+}
+
+binder::Status
+convertToHALStreamCombination(
+ const SessionConfiguration& sessionConfiguration,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+ hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+ bool overrideForPerfClass, bool *earlyExit) {
+ aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
+ auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
+ getMetadata, physicalCameraIds, aidlStreamConfiguration, overrideForPerfClass,
+ earlyExit);
+ if (!ret.isOk()) {
+ return ret;
+ }
+ if (earlyExit != nullptr && *earlyExit) {
+ return binder::Status::ok();
+ }
+
+ if (convertAidlToHidl38StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Invalid AIDL->HIDL3.8 conversion");
+ }
+
+ return binder::Status::ok();
+}
+
static bool inStreamConfigurationMap(int format, int width, int height,
const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
auto scs = sm.find(format);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 3dcbdbc..e326ce7 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -22,6 +22,7 @@
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
#include <android/hardware/camera/device/3.8/types.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
@@ -115,6 +116,10 @@
bool isStreamUseCaseSupported(int streamUseCase, const CameraMetadata &deviceInfo);
+void mapStreamInfo(const OutputStreamInfo &streamInfo,
+ camera3::camera_stream_rotation_t rotation, String8 physicalId,
+ int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/);
+
// Check that the physicalCameraId passed in is spported by the camera
// device.
binder::Status checkPhysicalCameraId(
@@ -145,6 +150,14 @@
hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38);
+binder::Status
+convertToHALStreamCombination(
+ const SessionConfiguration& sessionConfiguration,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
+ aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
+ bool overrideForPerfClass, bool *earlyExit);
+
// Utility function to convert a V3_7::StreamConfiguration to
// V3_4::StreamConfiguration. Return false if the original V3_7 configuration cannot
// be used by older version HAL.