blob: 0cde82c6ecbe3058686239fa6ccd6c5a57b26342 [file] [log] [blame]
From f584caaf5f6cd31cc6b8e30a4b62893d6d85818e Mon Sep 17 00:00:00 2001
From: Jackeagle <jackeagle102@gmail.com>
Date: Thu, 18 Oct 2018 04:21:22 -0400
Subject: [PATCH 1/5] [SQUASH] Revert Camera Specific AOSP Reverts
Revert "Revert "CameraService: fix camera removal paths""
This reverts commit e1922854c4bf71d9170011b904b701d1b38e303e.
Revert "Revert "CameraService: Update camera and torch state lists also at runtime""
This reverts commit cb343b767cd41829bb994c9c0e671a9c3e5d7cfb.
Revert "Revert "Camera: Add API level to service proxy notification""
This reverts commit 48888c68523e50038e92b8d73fa4d471fe266972.
Revert "Revert "Camera: expose external camera to API1""
This reverts commit 92607517666eca78bb94817f780977c7024cdda4.
Revert "Revert "Camera: fix camera ID in flashlight control""
This reverts commit 2c7225b2fe3017d1fd146e55420c6b616f44d16b.
Revert "Revert "Camera: Support all API1 compatible camera devices""
This reverts commit 842255a5aff37bb06d43a06bb44be0a67c4570ac.
Revert "Revert "Camera: Filter logical camera ids to API1 app""
This reverts commit 4e10dacc6a5edc0b4382e570173e9f7ff89af9bd.
---
.../aidl/android/hardware/ICameraServiceProxy.aidl | 8 +-
camera/ndk/impl/ACameraManager.cpp | 3 +
.../camera/libcameraservice/CameraFlashlight.cpp | 52 ++--
.../camera/libcameraservice/CameraFlashlight.h | 11 +-
services/camera/libcameraservice/CameraService.cpp | 317 ++++++++++-----------
services/camera/libcameraservice/CameraService.h | 35 ++-
.../camera/libcameraservice/api1/Camera2Client.cpp | 7 +-
.../camera/libcameraservice/api1/Camera2Client.h | 3 +-
.../camera/libcameraservice/api1/CameraClient.cpp | 14 +-
.../libcameraservice/api1/client2/Parameters.cpp | 56 +++-
.../libcameraservice/api1/client2/Parameters.h | 7 +
.../libcameraservice/api2/CameraDeviceClient.cpp | 59 ++--
.../libcameraservice/api2/CameraDeviceClient.h | 1 +
.../libcameraservice/common/Camera2ClientBase.cpp | 15 +-
.../libcameraservice/common/Camera2ClientBase.h | 3 +
.../common/CameraProviderManager.cpp | 173 ++++++++---
.../common/CameraProviderManager.h | 30 +-
17 files changed, 476 insertions(+), 318 deletions(-)
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 5dc23eb..7575948 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -46,8 +46,14 @@ interface ICameraServiceProxy
const int CAMERA_FACING_EXTERNAL = 2;
/**
+ * Values for notifyCameraState api level
+ */
+ const int CAMERA_API_LEVEL_1 = 1;
+ const int CAMERA_API_LEVEL_2 = 2;
+
+ /**
* Update the status of a camera device.
*/
oneway void notifyCameraState(String cameraId, int facing, int newCameraState,
- String clientName);
+ String clientName, int apiLevel);
}
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index e409ddd..c59d0e7 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -340,6 +340,9 @@ void CameraManagerGlobal::onStatusChangedLocked(
msg->setString(kCameraIdKey, AString(cameraId));
msg->post();
}
+ if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
+ mDeviceStatusMap.erase(cameraId);
+ }
}
} // namespace android
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 9c45331..61b9acb 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -32,13 +32,15 @@
namespace android {
+using hardware::camera::common::V1_0::TorchModeStatus;
+
/////////////////////////////////////////////////////////////////////
// CameraFlashlight implementation begins
// used by camera service to control flashflight.
/////////////////////////////////////////////////////////////////////
CameraFlashlight::CameraFlashlight(sp<CameraProviderManager> providerManager,
- camera_module_callbacks_t* callbacks) :
+ CameraProviderManager::StatusListener* callbacks) :
mProviderManager(providerManager),
mCallbacks(callbacks),
mFlashlightMapInitialized(false) {
@@ -59,7 +61,7 @@ status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
} else {
// Only HAL1 devices do not support setTorchMode
mFlashControl =
- new CameraHardwareInterfaceFlashControl(mProviderManager, *mCallbacks);
+ new CameraHardwareInterfaceFlashControl(mProviderManager, mCallbacks);
}
return OK;
@@ -118,19 +120,15 @@ status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
return res;
}
-int CameraFlashlight::getNumberOfCameras() {
- return mProviderManager->getAPI1CompatibleCameraCount();
-}
-
status_t CameraFlashlight::findFlashUnits() {
Mutex::Autolock l(mLock);
status_t res;
std::vector<String8> cameraIds;
- int numberOfCameras = getNumberOfCameras();
+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+ int numberOfCameras = static_cast<int>(ids.size());
cameraIds.resize(numberOfCameras);
// No module, must be provider
- std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
for (size_t i = 0; i < cameraIds.size(); i++) {
cameraIds[i] = String8(ids[i].c_str());
}
@@ -184,7 +182,8 @@ bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
- ALOGE("%s: camera %s not present when findFlashUnits() was called",
+ // Might be external camera
+ ALOGW("%s: camera %s not present when findFlashUnits() was called",
__FUNCTION__, cameraId.string());
return false;
}
@@ -218,12 +217,13 @@ status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
if (mOpenedCameraIds.size() == 0) {
// notify torch unavailable for all cameras with a flash
- int numCameras = getNumberOfCameras();
+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+ int numCameras = static_cast<int>(ids.size());
for (int i = 0; i < numCameras; i++) {
- if (hasFlashUnitLocked(String8::format("%d", i))) {
- mCallbacks->torch_mode_status_change(mCallbacks,
- String8::format("%d", i).string(),
- TORCH_MODE_STATUS_NOT_AVAILABLE);
+ String8 id8(ids[i].c_str());
+ if (hasFlashUnitLocked(id8)) {
+ mCallbacks->onTorchStatusChanged(
+ id8, TorchModeStatus::NOT_AVAILABLE);
}
}
}
@@ -263,12 +263,13 @@ status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
if (isBackwardCompatibleMode(cameraId)) {
// notify torch available for all cameras with a flash
- int numCameras = getNumberOfCameras();
+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
+ int numCameras = static_cast<int>(ids.size());
for (int i = 0; i < numCameras; i++) {
- if (hasFlashUnitLocked(String8::format("%d", i))) {
- mCallbacks->torch_mode_status_change(mCallbacks,
- String8::format("%d", i).string(),
- TORCH_MODE_STATUS_AVAILABLE_OFF);
+ String8 id8(ids[i].c_str());
+ if (hasFlashUnitLocked(id8)) {
+ mCallbacks->onTorchStatusChanged(
+ id8, TorchModeStatus::AVAILABLE_OFF);
}
}
}
@@ -315,9 +316,9 @@ status_t ProviderFlashControl::setTorchMode(const String8& cameraId, bool enable
CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
sp<CameraProviderManager> manager,
- const camera_module_callbacks_t& callbacks) :
+ CameraProviderManager::StatusListener* callbacks) :
mProviderManager(manager),
- mCallbacks(&callbacks),
+ mCallbacks(callbacks),
mTorchEnabled(false) {
}
@@ -333,8 +334,7 @@ CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
if (mCallbacks) {
ALOGV("%s: notify the framework that torch was turned off",
__FUNCTION__);
- mCallbacks->torch_mode_status_change(mCallbacks,
- mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+ mCallbacks->onTorchStatusChanged(mCameraId, TorchModeStatus::AVAILABLE_OFF);
}
}
}
@@ -368,8 +368,7 @@ status_t CameraHardwareInterfaceFlashControl::setTorchMode(
// disabling the torch mode of currently opened device
disconnectCameraDevice();
mTorchEnabled = false;
- mCallbacks->torch_mode_status_change(mCallbacks,
- cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
+ mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_OFF);
return OK;
}
@@ -379,8 +378,7 @@ status_t CameraHardwareInterfaceFlashControl::setTorchMode(
}
mTorchEnabled = true;
- mCallbacks->torch_mode_status_change(mCallbacks,
- cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
+ mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_ON);
return OK;
}
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index c86ee85..1baaba2 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -19,7 +19,6 @@
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
-#include <hardware/camera_common.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include "common/CameraProviderManager.h"
@@ -55,7 +54,7 @@ class FlashControlBase : public virtual VirtualLightRefBase {
class CameraFlashlight : public virtual VirtualLightRefBase {
public:
CameraFlashlight(sp<CameraProviderManager> providerManager,
- camera_module_callbacks_t* callbacks);
+ CameraProviderManager::StatusListener* callbacks);
virtual ~CameraFlashlight();
// Find all flash units. This must be called before other methods. All
@@ -93,13 +92,11 @@ class CameraFlashlight : public virtual VirtualLightRefBase {
// opening cameras)
bool isBackwardCompatibleMode(const String8& cameraId);
- int getNumberOfCameras();
-
sp<FlashControlBase> mFlashControl;
sp<CameraProviderManager> mProviderManager;
- const camera_module_callbacks_t *mCallbacks;
+ CameraProviderManager::StatusListener* mCallbacks;
SortedVector<String8> mOpenedCameraIds;
// camera id -> if it has a flash unit
@@ -134,7 +131,7 @@ class CameraHardwareInterfaceFlashControl : public FlashControlBase {
public:
CameraHardwareInterfaceFlashControl(
sp<CameraProviderManager> manager,
- const camera_module_callbacks_t& callbacks);
+ CameraProviderManager::StatusListener* callbacks);
virtual ~CameraHardwareInterfaceFlashControl();
// FlashControlBase
@@ -166,7 +163,7 @@ class CameraHardwareInterfaceFlashControl : public FlashControlBase {
status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
sp<CameraProviderManager> mProviderManager;
- const camera_module_callbacks_t *mCallbacks;
+ CameraProviderManager::StatusListener* mCallbacks;
sp<CameraHardwareInterface> mDevice;
String8 mCameraId;
CameraParameters mParameters;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 01220e3..de0fac5 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -109,79 +109,13 @@ static void setLogLevel(int level) {
// ----------------------------------------------------------------------------
-extern "C" {
-static void camera_device_status_change(
- const struct camera_module_callbacks* callbacks,
- int camera_id,
- int new_status) {
- sp<CameraService> cs = const_cast<CameraService*>(
- static_cast<const CameraService*>(callbacks));
- String8 id = String8::format("%d", camera_id);
-
- CameraDeviceStatus newStatus{CameraDeviceStatus::NOT_PRESENT};
- switch (new_status) {
- case CAMERA_DEVICE_STATUS_NOT_PRESENT:
- newStatus = CameraDeviceStatus::NOT_PRESENT;
- break;
- case CAMERA_DEVICE_STATUS_PRESENT:
- newStatus = CameraDeviceStatus::PRESENT;
- break;
- case CAMERA_DEVICE_STATUS_ENUMERATING:
- newStatus = CameraDeviceStatus::ENUMERATING;
- break;
- default:
- ALOGW("Unknown device status change to %d", new_status);
- break;
- }
- cs->onDeviceStatusChanged(id, newStatus);
-}
-
-static void torch_mode_status_change(
- const struct camera_module_callbacks* callbacks,
- const char* camera_id,
- int new_status) {
- if (!callbacks || !camera_id) {
- ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
- callbacks, camera_id);
- }
- sp<CameraService> cs = const_cast<CameraService*>(
- static_cast<const CameraService*>(callbacks));
-
- TorchModeStatus status;
- switch (new_status) {
- case TORCH_MODE_STATUS_NOT_AVAILABLE:
- status = TorchModeStatus::NOT_AVAILABLE;
- break;
- case TORCH_MODE_STATUS_AVAILABLE_OFF:
- status = TorchModeStatus::AVAILABLE_OFF;
- break;
- case TORCH_MODE_STATUS_AVAILABLE_ON:
- status = TorchModeStatus::AVAILABLE_ON;
- break;
- default:
- ALOGE("Unknown torch status %d", new_status);
- return;
- }
-
- cs->onTorchStatusChanged(
- String8(camera_id),
- status);
-}
-} // extern "C"
-
-// ----------------------------------------------------------------------------
-
static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
CameraService::CameraService() :
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
- mNumberOfCameras(0), mNumberOfNormalCameras(0),
+ mNumberOfCameras(0),
mSoundRef(0), mInitialized(false) {
ALOGI("CameraService started (pid=%d)", getpid());
-
- this->camera_device_status_change = android::camera_device_status_change;
- this->torch_mode_status_change = android::torch_mode_status_change;
-
mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
}
@@ -211,72 +145,43 @@ void CameraService::onFirstRef()
status_t CameraService::enumerateProviders() {
status_t res;
- Mutex::Autolock l(mServiceLock);
- if (nullptr == mCameraProviderManager.get()) {
- mCameraProviderManager = new CameraProviderManager();
- res = mCameraProviderManager->initialize(this);
- if (res != OK) {
- ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
- __FUNCTION__, strerror(-res), res);
- return res;
- }
- }
+ std::vector<std::string> deviceIds;
+ {
+ Mutex::Autolock l(mServiceLock);
- mNumberOfCameras = mCameraProviderManager->getCameraCount();
- mNumberOfNormalCameras =
- mCameraProviderManager->getAPI1CompatibleCameraCount();
+ if (nullptr == mCameraProviderManager.get()) {
+ mCameraProviderManager = new CameraProviderManager();
+ res = mCameraProviderManager->initialize(this);
+ if (res != OK) {
+ ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
- // Setup vendor tags before we call get_camera_info the first time
- // because HAL might need to setup static vendor keys in get_camera_info
- // TODO: maybe put this into CameraProviderManager::initialize()?
- mCameraProviderManager->setUpVendorTags();
- if (nullptr == mFlashlight.get()) {
- mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
- }
+ // Setup vendor tags before we call get_camera_info the first time
+ // because HAL might need to setup static vendor keys in get_camera_info
+ // TODO: maybe put this into CameraProviderManager::initialize()?
+ mCameraProviderManager->setUpVendorTags();
- res = mFlashlight->findFlashUnits();
- if (res != OK) {
- ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
- }
-
- for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
- String8 id8 = String8(cameraId.c_str());
- bool cameraFound = false;
- {
+ if (nullptr == mFlashlight.get()) {
+ mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
+ }
- Mutex::Autolock lock(mCameraStatesLock);
- auto iter = mCameraStates.find(id8);
- if (iter != mCameraStates.end()) {
- cameraFound = true;
- }
+ res = mFlashlight->findFlashUnits();
+ if (res != OK) {
+ ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
}
- if (!cameraFound) {
- hardware::camera::common::V1_0::CameraResourceCost cost;
- res = mCameraProviderManager->getResourceCost(cameraId, &cost);
- if (res != OK) {
- ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
- continue;
- }
- std::set<String8> conflicting;
- for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
- conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
- }
+ deviceIds = mCameraProviderManager->getCameraDeviceIds();
+ }
- {
- Mutex::Autolock lock(mCameraStatesLock);
- mCameraStates.emplace(id8,
- std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
- }
- }
+ for (auto& cameraId : deviceIds) {
+ String8 id8 = String8(cameraId.c_str());
onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
-
- if (mFlashlight->hasFlashUnit(id8)) {
- mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
- }
}
return OK;
@@ -312,6 +217,54 @@ void CameraService::onNewProviderRegistered() {
enumerateProviders();
}
+void CameraService::updateCameraNumAndIds() {
+ Mutex::Autolock l(mServiceLock);
+ mNumberOfCameras = mCameraProviderManager->getCameraCount();
+ mNormalDeviceIds =
+ mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
+}
+
+void CameraService::addStates(const String8 id) {
+ std::string cameraId(id.c_str());
+ hardware::camera::common::V1_0::CameraResourceCost cost;
+ status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
+ if (res != OK) {
+ ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
+ return;
+ }
+ std::set<String8> conflicting;
+ for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
+ conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
+ }
+
+ {
+ Mutex::Autolock lock(mCameraStatesLock);
+ mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
+ conflicting));
+ }
+
+ if (mFlashlight->hasFlashUnit(id)) {
+ Mutex::Autolock al(mTorchStatusMutex);
+ mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+ }
+
+ updateCameraNumAndIds();
+ logDeviceAdded(id, "Device added");
+}
+
+void CameraService::removeStates(const String8 id) {
+ updateCameraNumAndIds();
+ if (mFlashlight->hasFlashUnit(id)) {
+ Mutex::Autolock al(mTorchStatusMutex);
+ mTorchStatusMap.removeItem(id);
+ }
+
+ {
+ Mutex::Autolock lock(mCameraStatesLock);
+ mCameraStates.erase(id);
+ }
+}
+
void CameraService::onDeviceStatusChanged(const String8& id,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
@@ -323,8 +276,13 @@ void CameraService::onDeviceStatusChanged(const String8& id,
if (state == nullptr) {
if (newStatus == StatusInternal::PRESENT) {
- ALOGW("%s: Unknown camera ID %s, probably newly registered?",
+ ALOGI("%s: Unknown camera ID %s, a new camera is added",
__FUNCTION__, id.string());
+
+ // First add as absent to make sure clients are notified below
+ addStates(id);
+
+ updateStatus(newStatus, id);
} else {
ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
}
@@ -341,15 +299,16 @@ void CameraService::onDeviceStatusChanged(const String8& id,
if (newStatus == StatusInternal::NOT_PRESENT) {
logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
newStatus));
+
+ // Set the device status to NOT_PRESENT, clients will no longer be able to connect
+ // to this device until the status changes
+ updateStatus(StatusInternal::NOT_PRESENT, id);
+
sp<BasicClient> clientToDisconnect;
{
// Don't do this in updateStatus to avoid deadlock over mServiceLock
Mutex::Autolock lock(mServiceLock);
- // Set the device status to NOT_PRESENT, clients will no longer be able to connect
- // to this device until the status changes
- updateStatus(StatusInternal::NOT_PRESENT, id);
-
// Remove cached shim parameters
state->setShimParams(CameraParameters());
@@ -371,6 +330,7 @@ void CameraService::onDeviceStatusChanged(const String8& id,
clientToDisconnect->disconnect();
}
+ removeStates(id);
} else {
if (oldStatus == StatusInternal::NOT_PRESENT) {
logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
@@ -451,7 +411,7 @@ Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
Mutex::Autolock l(mServiceLock);
switch (type) {
case CAMERA_TYPE_BACKWARD_COMPATIBLE:
- *numCameras = mNumberOfNormalCameras;
+ *numCameras = static_cast<int>(mNormalDeviceIds.size());
break;
case CAMERA_TYPE_ALL:
*numCameras = mNumberOfCameras;
@@ -481,7 +441,8 @@ Status CameraService::getCameraInfo(int cameraId,
}
Status ret = Status::ok();
- status_t err = mCameraProviderManager->getCameraInfo(std::to_string(cameraId), cameraInfo);
+ status_t err = mCameraProviderManager->getCameraInfo(
+ cameraIdIntToStrLocked(cameraId), cameraInfo);
if (err != OK) {
ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Error retrieving camera info from device %d: %s (%d)", cameraId,
@@ -491,13 +452,19 @@ Status CameraService::getCameraInfo(int cameraId,
return ret;
}
-int CameraService::cameraIdToInt(const String8& cameraId) {
- int id;
- bool success = base::ParseInt(cameraId.string(), &id, 0);
- if (!success) {
- return -1;
+std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
+ if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
+ ALOGE("%s: input id %d invalid: valid range (0, %zu)",
+ __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
+ return std::string{};
}
- return id;
+
+ return mNormalDeviceIds[cameraIdInt];
+}
+
+String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
+ Mutex::Autolock lock(mServiceLock);
+ return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
}
Status CameraService::getCameraCharacteristics(const String16& cameraId,
@@ -614,8 +581,8 @@ Status CameraService::filterGetInfoErrorCode(status_t err) {
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
- int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+ int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
+ bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
@@ -625,8 +592,9 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
case CAMERA_DEVICE_API_VERSION_1_0:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
- facing, clientPid, clientUid, getpid(), legacyMode);
+ *client = new CameraClient(cameraService, tmp, packageName,
+ api1CameraId, facing, clientPid, clientUid,
+ getpid(), legacyMode);
} else { // Camera2 API route
ALOGW("Camera using old HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
@@ -641,8 +609,10 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
case CAMERA_DEVICE_API_VERSION_3_4:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
- facing, clientPid, clientUid, servicePid, legacyMode);
+ *client = new Camera2Client(cameraService, tmp, packageName,
+ cameraId, api1CameraId,
+ facing, clientPid, clientUid,
+ servicePid, legacyMode);
} else { // Camera2 API route
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
@@ -664,8 +634,9 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
// Only support higher HAL version device opened as HAL1.0 device.
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
- facing, clientPid, clientUid, servicePid, legacyMode);
+ *client = new CameraClient(cameraService, tmp, packageName,
+ api1CameraId, facing, clientPid, clientUid,
+ servicePid, legacyMode);
} else {
// Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
@@ -765,7 +736,8 @@ Status CameraService::initializeShimMetadata(int cameraId) {
Status ret = Status::ok();
sp<Client> tmp = nullptr;
if (!(ret = connectHelper<ICameraClient,Client>(
- sp<ICameraClient>{nullptr}, id, static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
+ sp<ICameraClient>{nullptr}, id, cameraId,
+ static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
internalPackageName, uid, USE_CALLING_PID,
API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
/*out*/ tmp)
@@ -1222,7 +1194,7 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
Status CameraService::connect(
const sp<ICameraClient>& cameraClient,
- int cameraId,
+ int api1CameraId,
const String16& clientPackageName,
int clientUid,
int clientPid,
@@ -1231,9 +1203,10 @@ Status CameraService::connect(
ATRACE_CALL();
Status ret = Status::ok();
- String8 id = String8::format("%d", cameraId);
+
+ String8 id = cameraIdIntToStr(api1CameraId);
sp<Client> client = nullptr;
- ret = connectHelper<ICameraClient,Client>(cameraClient, id,
+ ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
/*legacyMode*/ false, /*shimUpdateOnly*/ false,
/*out*/client);
@@ -1250,18 +1223,18 @@ Status CameraService::connect(
Status CameraService::connectLegacy(
const sp<ICameraClient>& cameraClient,
- int cameraId, int halVersion,
+ int api1CameraId, int halVersion,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>* device) {
ATRACE_CALL();
- String8 id = String8::format("%d", cameraId);
+ String8 id = cameraIdIntToStr(api1CameraId);
Status ret = Status::ok();
sp<Client> client = nullptr;
- ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion,
+ ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
clientPackageName, clientUid, USE_CALLING_PID, API_1,
/*legacyMode*/ true, /*shimUpdateOnly*/ false,
/*out*/client);
@@ -1289,6 +1262,7 @@ Status CameraService::connectDevice(
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
+ /*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
clientUid, USE_CALLING_PID, API_2,
/*legacyMode*/ false, /*shimUpdateOnly*/ false,
@@ -1306,8 +1280,8 @@ Status CameraService::connectDevice(
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
- apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
+ int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
+ int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
@@ -1390,8 +1364,10 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
}
sp<BasicClient> tmp = nullptr;
- if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
- clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
+ if(!(ret = makeClient(this, cameraCb, clientPackageName,
+ cameraId, api1CameraId, facing,
+ clientPid, clientUid, getpid(), legacyMode,
+ halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
@@ -2102,7 +2078,8 @@ void CameraService::playSound(sound_kind kind) {
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
const String16& clientPackageName,
- const String8& cameraIdStr, int cameraFacing,
+ const String8& cameraIdStr,
+ int api1CameraId, int cameraFacing,
int clientPid, uid_t clientUid,
int servicePid) :
CameraService::BasicClient(cameraService,
@@ -2111,7 +2088,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
cameraIdStr, cameraFacing,
clientPid, clientUid,
servicePid),
- mCameraId(CameraService::cameraIdToInt(cameraIdStr))
+ mCameraId(api1CameraId)
{
int callingPid = getCallingPid();
LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
@@ -2279,9 +2256,13 @@ status_t CameraService::BasicClient::startCameraOps() {
// Transition device availability listeners from PRESENT -> NOT_AVAILABLE
sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
+ int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
+ if (canCastToApiClient(API_2)) {
+ apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
+ }
// Transition device state to OPEN
sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
return OK;
}
@@ -2296,16 +2277,23 @@ status_t CameraService::BasicClient::finishCameraOps() {
mClientPackageName);
mOpsActive = false;
+ // This function is called when a client disconnects. This should
+ // release the camera, but actually only if it was in a proper
+ // functional state, i.e. with status NOT_AVAILABLE
std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
- StatusInternal::ENUMERATING};
+ StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
// Transition to PRESENT if the camera is not in either of the rejected states
sCameraService->updateStatus(StatusInternal::PRESENT,
mCameraIdStr, rejected);
+ int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
+ if (canCastToApiClient(API_2)) {
+ apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
+ }
// Transition device state to CLOSED
sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
}
// Always stop watching, even if no camera op is active
if (mOpsCallback != NULL) {
@@ -2548,7 +2536,7 @@ void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPack
CameraService::CameraState::CameraState(const String8& id, int cost,
const std::set<String8>& conflicting) : mId(id),
- mStatus(StatusInternal::PRESENT), mCost(cost), mConflicting(conflicting) {}
+ mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
CameraService::CameraState::~CameraState() {}
@@ -2724,7 +2712,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
}
dprintf(fd, "\n== Service global info: ==\n\n");
dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
- dprintf(fd, "Number of normal camera devices: %d\n", mNumberOfNormalCameras);
+ dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
+ for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
+ dprintf(fd, " Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
+ }
String8 activeClientString = mActiveClientManager.toString();
dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
@@ -2979,11 +2970,11 @@ void CameraService::CameraState::updateStatus(StatusInternal status,
}
void CameraService::updateProxyDeviceState(int newState,
- const String8& cameraId, int facing, const String16& clientName) {
+ const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
if (proxyBinder == nullptr) return;
String16 id(cameraId);
- proxyBinder->notifyCameraState(id, newState, facing, clientName);
+ proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
}
status_t CameraService::getTorchStatusLocked(
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 6724c49..8d4bcdb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -62,7 +62,6 @@ class CameraService :
public BinderService<CameraService>,
public virtual ::android::hardware::BnCameraService,
public virtual IBinder::DeathRecipient,
- public camera_module_callbacks_t,
public virtual CameraProviderManager::StatusListener
{
friend class BinderService<CameraService>;
@@ -190,7 +189,8 @@ public:
int newState,
const String8& cameraId,
int facing,
- const String16& clientName);
+ const String16& clientName,
+ int apiLevel);
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
@@ -334,6 +334,7 @@ public:
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
const String8& cameraIdStr,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
@@ -555,6 +556,11 @@ private:
// Eumerate all camera providers in the system
status_t enumerateProviders();
+ // Add/remove a new camera to camera and torch state lists or remove an unplugged one
+ // Caller must not hold mServiceLock
+ void addStates(const String8 id);
+ void removeStates(const String8 id);
+
// Check if we can connect, before we acquire the service lock.
// The returned originalClientPid is the PID of the original process that wants to connect to
// camera.
@@ -578,7 +584,7 @@ private:
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int halVersion, const String16& clientPackageName,
+ int api1CameraId, int halVersion, const String16& clientPackageName,
int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device);
@@ -643,9 +649,16 @@ private:
void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc);
/**
- * Returns the integer corresponding to the given camera ID string, or -1 on failure.
+ * Returns the underlying camera Id string mapped to a camera id int
+ * Empty string is returned when the cameraIdInt is invalid.
+ */
+ String8 cameraIdIntToStr(int cameraIdInt);
+
+ /**
+ * Returns the underlying camera Id string mapped to a camera id int
+ * Empty string is returned when the cameraIdInt is invalid.
*/
- static int cameraIdToInt(const String8& cameraId);
+ std::string cameraIdIntToStrLocked(int cameraIdInt);
/**
* Remove a single client corresponding to the given camera id from the list of active clients.
@@ -713,8 +726,14 @@ private:
*/
void dumpEventLog(int fd);
+ /**
+ * This method will acquire mServiceLock
+ */
+ void updateCameraNumAndIds();
+
int mNumberOfCameras;
- int mNumberOfNormalCameras;
+
+ std::vector<std::string> mNormalDeviceIds;
// sounds
sp<MediaPlayer> newMediaPlayer(const char *file);
@@ -824,8 +843,8 @@ private:
static binder::Status makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
- int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
+ int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
+ bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*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 dd1cf2c..65faac9 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -49,16 +49,17 @@ static int getCallingPid() {
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
- int cameraId,
+ const String8& cameraDeviceId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid,
bool legacyMode):
Camera2ClientBase(cameraService, cameraClient, clientPackageName,
- String8::format("%d", cameraId), cameraFacing,
+ cameraDeviceId, api1CameraId, cameraFacing,
clientPid, clientUid, servicePid),
- mParameters(cameraId, cameraFacing)
+ mParameters(api1CameraId, cameraFacing)
{
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index c17cbd4..44929c3 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -91,7 +91,8 @@ public:
Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
- int cameraId,
+ const String8& cameraDeviceId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index e2c8b8b..2358c1e 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -42,7 +42,7 @@ CameraClient::CameraClient(const sp<CameraService>& cameraService,
int clientPid, int clientUid,
int servicePid, bool legacyMode):
Client(cameraService, cameraClient, clientPackageName,
- String8::format("%d", cameraId), cameraFacing, clientPid,
+ String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
clientUid, servicePid)
{
int callingPid = getCallingPid();
@@ -264,7 +264,8 @@ binder::Status CameraClient::disconnect() {
mHardware->stopPreview();
sCameraService->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName,
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
mHardware->cancelPicture();
// Release the hardware resources.
mHardware->release();
@@ -427,7 +428,8 @@ status_t CameraClient::startPreviewMode() {
if (result == NO_ERROR) {
sCameraService->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName,
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
}
return result;
}
@@ -470,7 +472,8 @@ void CameraClient::stopPreview() {
mHardware->stopPreview();
sCameraService->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName,
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
mPreviewBuffer.clear();
}
@@ -981,7 +984,8 @@ void CameraClient::handleShutter(void) {
// idle now, until preview is restarted
sCameraService->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName);
+ mCameraIdStr, mCameraFacing, mClientPackageName,
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
mLock.unlock();
}
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 7373b81..d66dec4 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -761,12 +761,17 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {
focusingAreas.clear();
focusingAreas.add(Parameters::Area(0,0,0,0,0));
- camera_metadata_ro_entry_t availableFocalLengths =
- staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
- if (!availableFocalLengths.count) return NO_INIT;
+ if (fastInfo.isExternalCamera) {
+ params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, -1.0);
+ } else {
+ camera_metadata_ro_entry_t availableFocalLengths =
+ staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
+ if (!availableFocalLengths.count) return NO_INIT;
+
+ float minFocalLength = availableFocalLengths.data.f[0];
+ params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
+ }
- float minFocalLength = availableFocalLengths.data.f[0];
- params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
float horizFov, vertFov;
res = calculatePictureFovs(&horizFov, &vertFov);
@@ -1104,9 +1109,15 @@ status_t Parameters::buildFastInfo() {
focusDistanceCalibration.data.u8[0] !=
ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED);
+
+ camera_metadata_ro_entry_t hwLevel = staticInfo(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
+ if (!hwLevel.count) return NO_INIT;
+ fastInfo.isExternalCamera =
+ hwLevel.data.u8[0] == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
+
camera_metadata_ro_entry_t availableFocalLengths =
- staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
- if (!availableFocalLengths.count) return NO_INIT;
+ staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, /*required*/false);
+ if (!availableFocalLengths.count && !fastInfo.isExternalCamera) return NO_INIT;
SortedVector<int32_t> availableFormats = getAvailableOutputFormats();
if (!availableFormats.size()) return NO_INIT;
@@ -1191,10 +1202,14 @@ status_t Parameters::buildFastInfo() {
// Find smallest (widest-angle) focal length to use as basis of still
// picture FOV reporting.
- fastInfo.minFocalLength = availableFocalLengths.data.f[0];
- for (size_t i = 1; i < availableFocalLengths.count; i++) {
- if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
- fastInfo.minFocalLength = availableFocalLengths.data.f[i];
+ if (fastInfo.isExternalCamera) {
+ fastInfo.minFocalLength = -1.0;
+ } else {
+ fastInfo.minFocalLength = availableFocalLengths.data.f[0];
+ for (size_t i = 1; i < availableFocalLengths.count; i++) {
+ if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
+ fastInfo.minFocalLength = availableFocalLengths.data.f[i];
+ }
}
}
@@ -2921,8 +2936,13 @@ status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) {
if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
sc.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
sc.width <= limit.width && sc.height <= limit.height) {
- Size sz = {sc.width, sc.height};
- sizes->push(sz);
+ int64_t minFrameDuration = getMinFrameDurationNs(
+ {sc.width, sc.height}, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
+ if (minFrameDuration > MAX_PREVIEW_RECORD_DURATION_NS) {
+ // Filter slow sizes from preview/record
+ continue;
+ }
+ sizes->push({sc.width, sc.height});
}
}
@@ -3132,6 +3152,16 @@ Parameters::CropRegion Parameters::calculateCropRegion(bool previewOnly) const {
status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)
const {
+ if (fastInfo.isExternalCamera) {
+ if (horizFov != NULL) {
+ *horizFov = -1.0;
+ }
+ if (vertFov != NULL) {
+ *vertFov = -1.0;
+ }
+ return OK;
+ }
+
camera_metadata_ro_entry_t sensorSize =
staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
if (!sensorSize.count) return NO_INIT;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index f0bde5b..97f8ea7 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -209,6 +209,11 @@ struct Parameters {
static const int32_t FPS_MARGIN = 1;
// Max FPS for default parameters
static const int32_t MAX_DEFAULT_FPS = 30;
+ // Minimum FPS for a size to be listed in supported preview/video sizes
+ // Set to slightly less than 30.0 to have some tolerance margin
+ static constexpr double MIN_PREVIEW_RECORD_FPS = 29.97;
+ // Maximum frame duration for a size to be listed in supported preview/video sizes
+ static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / MIN_PREVIEW_RECORD_FPS;
// Full static camera info, object owned by someone else, such as
// Camera2Device.
@@ -235,6 +240,7 @@ struct Parameters {
}
};
DefaultKeyedVector<uint8_t, OverrideModes> sceneModeOverrides;
+ bool isExternalCamera;
float minFocalLength;
bool useFlexibleYuv;
Size maxJpegSize;
@@ -383,6 +389,7 @@ private:
Vector<Size> availablePreviewSizes;
Vector<Size> availableVideoSizes;
// Get size list (that are no larger than limit) from static metadata.
+ // This method filtered size with minFrameDuration < MAX_PREVIEW_RECORD_DURATION_NS
status_t getFilteredSizes(Size limit, Vector<Size> *sizes);
// Get max size (from the size array) that matches the given aspect ratio.
Size getMaxSizeForRatio(float ratio, const int32_t* sizeArray, size_t count);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 2297ed3..98d0534 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -49,6 +49,7 @@ CameraDeviceClientBase::CameraDeviceClientBase(
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
@@ -62,6 +63,8 @@ CameraDeviceClientBase::CameraDeviceClientBase(
clientUid,
servicePid),
mRemoteCallback(remoteCallback) {
+ // We don't need it for API2 clients, but Camera2ClientBase requires it.
+ (void) api1CameraId;
}
// Interface used by CameraService
@@ -75,7 +78,8 @@ CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
uid_t clientUid,
int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
- cameraId, cameraFacing, clientPid, clientUid, servicePid),
+ cameraId, /*API1 camera ID*/ -1,
+ cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0) {
@@ -620,11 +624,19 @@ binder::Status CameraDeviceClient::createStream(
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- if (!checkPhysicalCameraId(physicalCameraId)) {
- String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
+ if (physicalCameraId.size() > 0) {
+ std::vector<std::string> physicalCameraIds;
+ std::string physicalId(physicalCameraId.string());
+ bool logicalCamera =
+ CameraProviderManager::isLogicalCamera(mDevice->info(), &physicalCameraIds);
+ if (!logicalCamera ||
+ std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalId) ==
+ physicalCameraIds.end()) {
+ String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
mCameraIdStr.string(), physicalCameraId.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
}
std::vector<sp<Surface>> surfaces;
std::vector<sp<IBinder>> binders;
@@ -1140,43 +1152,6 @@ binder::Status CameraDeviceClient::createSurfaceFromGbp(
return binder::Status::ok();
}
-bool CameraDeviceClient::checkPhysicalCameraId(const String8& physicalCameraId) {
- if (0 == physicalCameraId.size()) {
- return true;
- }
-
- CameraMetadata staticInfo = mDevice->info();
- camera_metadata_entry_t entryCap;
- bool isLogicalCam = false;
-
- entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
- for (size_t i = 0; i < entryCap.count; ++i) {
- uint8_t capability = entryCap.data.u8[i];
- if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
- isLogicalCam = true;
- }
- }
- if (!isLogicalCam) {
- return false;
- }
-
- camera_metadata_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
- const uint8_t* ids = entryIds.data.u8;
- size_t start = 0;
- for (size_t i = 0; i < entryIds.count; ++i) {
- if (ids[i] == '\0') {
- if (start != i) {
- String8 currentId((const char*)ids+start);
- if (currentId == physicalCameraId) {
- return true;
- }
- }
- start = i+1;
- }
- }
- return false;
-}
-
bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
/*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 5bec39c..5aaf5aa 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -45,6 +45,7 @@ protected:
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 5c6711a..ce006a7 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -48,15 +48,16 @@ Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
- cameraId, cameraFacing, clientPid, clientUid, servicePid),
+ cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
- mDeviceActive(false)
+ mDeviceActive(false), mApi1CameraId(api1CameraId)
{
ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
String8(clientPackageName).string(), clientPid, clientUid);
@@ -252,7 +253,9 @@ void Camera2ClientBase<TClientBase>::notifyIdle() {
if (mDeviceActive) {
getCameraService()->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr,
- TClientBase::mCameraFacing, TClientBase::mClientPackageName);
+ TClientBase::mCameraFacing, TClientBase::mClientPackageName,
+ ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
}
mDeviceActive = false;
@@ -268,7 +271,9 @@ void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& re
if (!mDeviceActive) {
getCameraService()->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr,
- TClientBase::mCameraFacing, TClientBase::mClientPackageName);
+ TClientBase::mCameraFacing, TClientBase::mClientPackageName,
+ ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
}
mDeviceActive = true;
@@ -331,7 +336,7 @@ void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameN
template <typename TClientBase>
int Camera2ClientBase<TClientBase>::getCameraId() const {
- return std::stoi(TClientBase::mCameraIdStr.string());
+ return mApi1CameraId;
}
template <typename TClientBase>
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 4da422a..e74fbdf 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -49,6 +49,7 @@ public:
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
+ int api1CameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
@@ -140,6 +141,8 @@ protected:
bool mDeviceActive;
+ const int mApi1CameraId; // -1 if client is API2
+
private:
template<typename TProviderPtr>
status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4bc78dd..21cfd44 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -20,11 +20,13 @@
#include "CameraProviderManager.h"
+#include <algorithm>
#include <chrono>
#include <inttypes.h>
#include <hidl/ServiceManagement.h>
#include <functional>
#include <camera_metadata_hidden.h>
+#include <android-base/parseint.h>
namespace android {
@@ -39,9 +41,6 @@ const std::string kLegacyProviderName("legacy/0");
const std::string kExternalProviderName("external/0");
#endif
-// Slash-separated list of provider types to consider for use via the old camera API
-const std::string kStandardProviderTypes("internal/legacy");
-
} // anonymous namespace
CameraProviderManager::HardwareServiceInteractionProxy
@@ -83,18 +82,7 @@ int CameraProviderManager::getCameraCount() const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
int count = 0;
for (auto& provider : mProviders) {
- count += provider->mUniqueDeviceCount;
- }
- return count;
-}
-
-int CameraProviderManager::getAPI1CompatibleCameraCount() const {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- int count = 0;
- for (auto& provider : mProviders) {
- if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
- count += provider->mUniqueAPI1CompatibleCameraIds.size();
- }
+ count += provider->mUniqueCameraIds.size();
}
return count;
}
@@ -114,12 +102,33 @@ std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds
std::lock_guard<std::mutex> lock(mInterfaceMutex);
std::vector<std::string> deviceIds;
for (auto& provider : mProviders) {
- if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
- for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
- deviceIds.push_back(id);
- }
- }
+ std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
+
+ // API1 app doesn't handle logical and physical camera devices well. So
+ // for each [logical, physical1, physical2, ...] id combo, only take the
+ // first id advertised by HAL, and filter out the rest.
+ filterLogicalCameraIdsLocked(providerDeviceIds);
+
+ deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
}
+
+ std::sort(deviceIds.begin(), deviceIds.end(),
+ [](const std::string& a, const std::string& b) -> bool {
+ uint32_t aUint = 0, bUint = 0;
+ bool aIsUint = base::ParseUint(a, &aUint);
+ bool bIsUint = base::ParseUint(b, &bUint);
+
+ // Uint device IDs first
+ if (aIsUint && bIsUint) {
+ return aUint < bUint;
+ } else if (aIsUint) {
+ return true;
+ } else if (bIsUint) {
+ return false;
+ }
+ // Simple string compare if both id are not uint
+ return a < b;
+ });
return deviceIds;
}
@@ -172,11 +181,7 @@ status_t CameraProviderManager::getCameraInfo(const std::string &id,
status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
CameraMetadata* characteristics) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
-
- auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
- if (deviceInfo == nullptr) return NAME_NOT_FOUND;
-
- return deviceInfo->getCameraCharacteristics(characteristics);
+ return getCameraCharacteristicsLocked(id, characteristics);
}
status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
@@ -391,6 +396,37 @@ metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
return ret;
}
+bool CameraProviderManager::isLogicalCamera(const CameraMetadata& staticInfo,
+ std::vector<std::string>* physicalCameraIds) {
+ bool isLogicalCam = false;
+ camera_metadata_ro_entry_t entryCap;
+
+ entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ for (size_t i = 0; i < entryCap.count; ++i) {
+ uint8_t capability = entryCap.data.u8[i];
+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+ isLogicalCam = true;
+ break;
+ }
+ }
+ if (!isLogicalCam) {
+ return false;
+ }
+
+ camera_metadata_ro_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+ const uint8_t* ids = entryIds.data.u8;
+ size_t start = 0;
+ for (size_t i = 0; i < entryIds.count; ++i) {
+ if (ids[i] == '\0') {
+ if (start != i) {
+ physicalCameraIds->push_back((const char*)ids+start);
+ }
+ start = i+1;
+ }
+ }
+ return true;
+}
+
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == newProvider) {
@@ -484,6 +520,8 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
}
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), mInterface->isRemote());
+ // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
+ // before setCallback returns
hardware::Return<Status> status = mInterface->setCallback(this);
if (!status.isOk()) {
ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
@@ -540,17 +578,10 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
}
}
- for (auto& device : mDevices) {
- mUniqueCameraIds.insert(device->mId);
- if (device->isAPI1Compatible()) {
- mUniqueAPI1CompatibleCameraIds.insert(device->mId);
- }
- }
- mUniqueDeviceCount = mUniqueCameraIds.size();
-
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
+ mInitialized = true;
return OK;
}
@@ -598,15 +629,36 @@ status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
}
if (deviceInfo == nullptr) return BAD_VALUE;
deviceInfo->mStatus = initialStatus;
+ bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
mDevices.push_back(std::move(deviceInfo));
+ mUniqueCameraIds.insert(id);
+ if (isAPI1Compatible) {
+ mUniqueAPI1CompatibleCameraIds.push_back(id);
+ }
+
if (parsedId != nullptr) {
*parsedId = id;
}
return OK;
}
+void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
+ for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
+ if ((*it)->mId == id) {
+ mUniqueCameraIds.erase(id);
+ if ((*it)->isAPI1Compatible()) {
+ mUniqueAPI1CompatibleCameraIds.erase(std::remove(
+ mUniqueAPI1CompatibleCameraIds.begin(),
+ mUniqueAPI1CompatibleCameraIds.end(), id));
+ }
+ mDevices.erase(it);
+ break;
+ }
+ }
+}
+
status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
@@ -666,6 +718,7 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusCh
CameraDeviceStatus newStatus) {
sp<StatusListener> listener;
std::string id;
+ bool initialized = false;
{
std::lock_guard<std::mutex> lock(mLock);
bool known = false;
@@ -688,11 +741,17 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusCh
return hardware::Void();
}
addDevice(cameraDeviceName, newStatus, &id);
+ } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
+ removeDevice(id);
}
listener = mManager->getStatusListener();
+ initialized = mInitialized;
}
// Call without lock held to allow reentrancy into provider manager
- if (listener != nullptr) {
+ // Don't send the callback if providerInfo hasn't been initialized.
+ // CameraService will initialize device status after provider is
+ // initialized
+ if (listener != nullptr && initialized) {
listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
}
return hardware::Void();
@@ -1396,5 +1455,51 @@ status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
return OK;
}
+status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
+ CameraMetadata* characteristics) const {
+ auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
+
+ return deviceInfo->getCameraCharacteristics(characteristics);
+}
+
+void CameraProviderManager::filterLogicalCameraIdsLocked(
+ std::vector<std::string>& deviceIds) const
+{
+ std::unordered_set<std::string> removedIds;
+
+ for (auto& deviceId : deviceIds) {
+ CameraMetadata info;
+ status_t res = getCameraCharacteristicsLocked(deviceId, &info);
+ if (res != OK) {
+ ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
+ deviceId.c_str());
+ return;
+ }
+
+ // idCombo contains the ids of a logical camera and its physical cameras
+ std::vector<std::string> idCombo;
+ bool logicalCamera = CameraProviderManager::isLogicalCamera(info, &idCombo);
+ if (!logicalCamera) {
+ continue;
+ }
+ idCombo.push_back(deviceId);
+
+ for (auto& id : deviceIds) {
+ auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
+ if (foundId == idCombo.end()) {
+ continue;
+ }
+
+ idCombo.erase(foundId);
+ removedIds.insert(idCombo.begin(), idCombo.end());
+ break;
+ }
+ }
+
+ deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
+ [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
+ deviceIds.end());
+}
} // namespace android
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 0f1f07b..b8b8b8c 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -18,7 +18,7 @@
#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
#include <vector>
-#include <set>
+#include <unordered_set>
#include <string>
#include <mutex>
@@ -125,16 +125,14 @@ public:
*/
int getCameraCount() const;
+ std::vector<std::string> getCameraDeviceIds() const;
+
/**
* Retrieve the number of API1 compatible cameras; these are internal and
* backwards-compatible. This is the set of cameras that will be
- * accessible via the old camera API, with IDs in range of
- * [0, getAPI1CompatibleCameraCount()-1]. This value is not expected to change dynamically.
+ * accessible via the old camera API.
+ * The return value may change dynamically due to external camera hotplug.
*/
- int getAPI1CompatibleCameraCount() const;
-
- std::vector<std::string> getCameraDeviceIds() const;
-
std::vector<std::string> getAPI1CompatibleCameraDeviceIds() const;
/**
@@ -232,6 +230,13 @@ public:
hardware::hidl_version minVersion = hardware::hidl_version{0,0},
hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
+ /*
+ * Check if a camera with staticInfo is a logical camera. And if yes, return
+ * the physical camera ids.
+ */
+ static bool isLogicalCamera(const CameraMetadata& staticInfo,
+ std::vector<std::string>* physicalCameraIds);
+
private:
// All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
mutable std::mutex mInterfaceMutex;
@@ -314,9 +319,9 @@ private:
static status_t setTorchMode(InterfaceT& interface, bool enabled);
};
std::vector<std::unique_ptr<DeviceInfo>> mDevices;
- std::set<std::string> mUniqueCameraIds;
+ std::unordered_set<std::string> mUniqueCameraIds;
int mUniqueDeviceCount;
- std::set<std::string> mUniqueAPI1CompatibleCameraIds;
+ std::vector<std::string> mUniqueAPI1CompatibleCameraIds;
// HALv1-specific camera fields, including the actual device interface
struct DeviceInfo1 : public DeviceInfo {
@@ -366,6 +371,8 @@ private:
CameraProviderManager *mManager;
+ bool mInitialized = false;
+
// Templated method to instantiate the right kind of DeviceInfo and call the
// right CameraProvider getCameraDeviceInterface_* method.
template<class DeviceInfoT>
@@ -387,6 +394,8 @@ private:
// Generate vendor tag id
static metadata_vendor_id_t generateVendorTagId(const std::string &name);
+
+ void removeDevice(std::string id);
};
// Utility to find a DeviceInfo by ID; pointer is only valid while mInterfaceMutex is held
@@ -412,6 +421,9 @@ private:
static const char* torchStatusToString(
const hardware::camera::common::V1_0::TorchModeStatus&);
+ status_t getCameraCharacteristicsLocked(const std::string &id,
+ CameraMetadata* characteristics) const;
+ void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;
};
} // namespace android
--
2.7.4