summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/ICameraService.cpp11
-rw-r--r--include/camera/ICameraService.h10
-rw-r--r--services/camera/libcameraservice/CameraService.cpp102
-rw-r--r--services/camera/libcameraservice/CameraService.h8
4 files changed, 115 insertions, 16 deletions
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 7c9720f..b359f57 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -94,11 +94,18 @@ public:
{
}
- // get number of cameras available
+ // get number of cameras available that support standard camera operations
virtual int32_t getNumberOfCameras()
{
+ return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE);
+ }
+
+ // get number of cameras available of a given type
+ virtual int32_t getNumberOfCameras(int type)
+ {
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+ data.writeInt32(type);
remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
if (readExceptionCode(reply)) return 0;
@@ -337,7 +344,7 @@ status_t BnCameraService::onTransact(
case GET_NUMBER_OF_CAMERAS: {
CHECK_INTERFACE(ICameraService, data, reply);
reply->writeNoException();
- reply->writeInt32(getNumberOfCameras());
+ reply->writeInt32(getNumberOfCameras(data.readInt32()));
return NO_ERROR;
} break;
case GET_CAMERA_INFO: {
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index 5f85635..1b68b5f 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -64,6 +64,11 @@ public:
};
enum {
+ CAMERA_TYPE_BACKWARD_COMPATIBLE = 0,
+ CAMERA_TYPE_ALL = 1,
+ };
+
+ enum {
CAMERA_HAL_API_VERSION_UNSPECIFIED = -1
};
@@ -81,7 +86,12 @@ public:
public:
DECLARE_META_INTERFACE(CameraService);
+ // Get the number of cameras that support basic color camera operation
+ // (type CAMERA_TYPE_BACKWARD_COMPATIBLE)
virtual int32_t getNumberOfCameras() = 0;
+ // Get the number of cameras of the specified type, one of CAMERA_TYPE_*
+ // enums
+ virtual int32_t getNumberOfCameras(int cameraType) = 0;
virtual status_t getCameraInfo(int cameraId,
/*out*/
struct CameraInfo* cameraInfo) = 0;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 92df4e3..43a8ec4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -171,6 +171,7 @@ void CameraService::onFirstRef()
}
mNumberOfCameras = mModule->getNumberOfCameras();
+ mNumberOfNormalCameras = mNumberOfCameras;
mFlashlight = new CameraFlashlight(*mModule, *this);
status_t res = mFlashlight->findFlashUnits();
@@ -179,27 +180,41 @@ void CameraService::onFirstRef()
ALOGE("Failed to find flash units.");
}
+ int latestStrangeCameraId = INT_MAX;
for (int i = 0; i < mNumberOfCameras; i++) {
String8 cameraId = String8::format("%d", i);
+ // Get camera info
+
+ struct camera_info info;
+ bool haveInfo = true;
+ status_t rc = mModule->getCameraInfo(i, &info);
+ if (rc != NO_ERROR) {
+ ALOGE("%s: Received error loading camera info for device %d, cost and"
+ " conflicting devices fields set to defaults for this device.",
+ __FUNCTION__, i);
+ haveInfo = false;
+ }
+
+ // Check for backwards-compatibility support
+ if (haveInfo) {
+ if (checkCameraCapabilities(i, info, &latestStrangeCameraId) != OK) {
+ delete mModule;
+ mModule = nullptr;
+ return;
+ }
+ }
+
// Defaults to use for cost and conflicting devices
int cost = 100;
char** conflicting_devices = nullptr;
size_t conflicting_devices_length = 0;
// If using post-2.4 module version, query the cost + conflicting devices from the HAL
- if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
- struct camera_info info;
- status_t rc = mModule->getCameraInfo(i, &info);
- if (rc == NO_ERROR) {
- cost = info.resource_cost;
- conflicting_devices = info.conflicting_devices;
- conflicting_devices_length = info.conflicting_devices_length;
- } else {
- ALOGE("%s: Received error loading camera info for device %d, cost and"
- " conflicting devices fields set to defaults for this device.",
- __FUNCTION__, i);
- }
+ if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && haveInfo) {
+ cost = info.resource_cost;
+ conflicting_devices = info.conflicting_devices;
+ conflicting_devices_length = info.conflicting_devices_length;
}
std::set<String8> conflicting;
@@ -382,9 +397,21 @@ void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
}
}
-
int32_t CameraService::getNumberOfCameras() {
- return mNumberOfCameras;
+ return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE);
+}
+
+int32_t CameraService::getNumberOfCameras(int type) {
+ switch (type) {
+ case CAMERA_TYPE_BACKWARD_COMPATIBLE:
+ return mNumberOfNormalCameras;
+ case CAMERA_TYPE_ALL:
+ return mNumberOfCameras;
+ default:
+ ALOGW("%s: Unknown camera type %d, returning 0",
+ __FUNCTION__, type);
+ return 0;
+ }
}
status_t CameraService::getCameraInfo(int cameraId,
@@ -1494,6 +1521,53 @@ bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
}
+/**
+ * Check camera capabilities, such as support for basic color operation
+ */
+int CameraService::checkCameraCapabilities(int id, camera_info info, int *latestStrangeCameraId) {
+
+ // Assume all devices pre-v3.3 are backward-compatible
+ bool isBackwardCompatible = true;
+ if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0
+ && info.device_version >= CAMERA_DEVICE_API_VERSION_3_3) {
+ isBackwardCompatible = false;
+ status_t res;
+ camera_metadata_ro_entry_t caps;
+ res = find_camera_metadata_ro_entry(
+ info.static_camera_characteristics,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ &caps);
+ if (res != 0) {
+ ALOGW("%s: Unable to find camera capabilities for camera device %d",
+ __FUNCTION__, id);
+ caps.count = 0;
+ }
+ for (size_t i = 0; i < caps.count; i++) {
+ if (caps.data.u8[i] ==
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
+ isBackwardCompatible = true;
+ break;
+ }
+ }
+ }
+
+ if (!isBackwardCompatible) {
+ mNumberOfNormalCameras--;
+ *latestStrangeCameraId = id;
+ } else {
+ if (id > *latestStrangeCameraId) {
+ ALOGE("%s: Normal camera ID %d higher than strange camera ID %d. "
+ "This is not allowed due backward-compatibility requirements",
+ __FUNCTION__, id, *latestStrangeCameraId);
+ logServiceError("Invalid order of camera devices", ENODEV);
+ mNumberOfCameras = 0;
+ mNumberOfNormalCameras = 0;
+ return INVALID_OPERATION;
+ }
+ }
+ return OK;
+}
+
std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
const String8& cameraId) const {
std::shared_ptr<CameraState> state;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 3298772..7f4d43f 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -100,7 +100,9 @@ public:
/////////////////////////////////////////////////////////////////////
// ICameraService
+ virtual int32_t getNumberOfCameras(int type);
virtual int32_t getNumberOfCameras();
+
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
virtual status_t getCameraCharacteristics(int cameraId,
@@ -509,6 +511,11 @@ private:
std::set<userid_t> mAllowedUsers;
/**
+ * Check camera capabilities, such as support for basic color operation
+ */
+ int checkCameraCapabilities(int id, camera_info info, int *latestStrangeCameraId);
+
+ /**
* Get the camera state for a given camera id.
*
* This acquires mCameraStatesLock.
@@ -610,6 +617,7 @@ private:
void dumpEventLog(int fd);
int mNumberOfCameras;
+ int mNumberOfNormalCameras;
// sounds
MediaPlayer* newMediaPlayer(const char *file);