summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhijun He <zhijunhe@google.com>2014-06-16 16:38:35 -0700
committerZhijun He <zhijunhe@google.com>2014-06-19 15:41:09 -0700
commitb10cdadf0fb945e23ca77008d4af76584bd0e39a (patch)
treed1fd0cc1c42aec025e8f6fc52f890b96e7203653
parentab5cdbaf65ca509681d2726aacdf3ac8bfb6b3fa (diff)
downloadframeworks_av-b10cdadf0fb945e23ca77008d4af76584bd0e39a.zip
frameworks_av-b10cdadf0fb945e23ca77008d4af76584bd0e39a.tar.gz
frameworks_av-b10cdadf0fb945e23ca77008d4af76584bd0e39a.tar.bz2
cameraservice: Implement HAL1 and higher HAL API coexistence
A higher hal version device like HAL3.2 can be opened as HAL1.0 device if HAL supports it. This only applies to camera API1. Change-Id: I4ae9f59f4317158cc1bd7ed7726e4032cdd1fa07
-rw-r--r--camera/Camera.cpp26
-rw-r--r--camera/ICameraService.cpp44
-rw-r--r--include/camera/Camera.h4
-rw-r--r--include/camera/ICameraService.h17
-rw-r--r--services/camera/libcameraservice/CameraService.cpp125
-rw-r--r--services/camera/libcameraservice/CameraService.h8
-rw-r--r--services/camera/libcameraservice/api1/CameraClient.cpp2
-rw-r--r--services/camera/libcameraservice/device1/CameraHardwareInterface.h18
8 files changed, 217 insertions, 27 deletions
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 22199fa..85f44f0 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -77,6 +77,32 @@ sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}
+status_t Camera::connectLegacy(int cameraId, int halVersion,
+ const String16& clientPackageName,
+ int clientUid,
+ sp<Camera>& camera)
+{
+ ALOGV("%s: connect legacy camera device", __FUNCTION__);
+ sp<Camera> c = new Camera(cameraId);
+ sp<ICameraClient> cl = c;
+ status_t status = NO_ERROR;
+ const sp<ICameraService>& cs = CameraBaseT::getCameraService();
+
+ if (cs != 0) {
+ status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
+ clientUid, /*out*/c->mCamera);
+ }
+ if (status == OK && c->mCamera != 0) {
+ c->mCamera->asBinder()->linkToDeath(c);
+ c->mStatus = NO_ERROR;
+ camera = c;
+ } else {
+ ALOGW("An error occurred while connecting to camera: %d", cameraId);
+ c.clear();
+ }
+ return status;
+}
+
status_t Camera::reconnect()
{
ALOGV("reconnect");
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 79c33f9..5485205 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -186,6 +186,29 @@ public:
return status;
}
+ // connect to camera service (android.hardware.Camera)
+ virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
+ int halVersion,
+ const String16 &clientPackageName, int clientUid,
+ /*out*/sp<ICamera>& device)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+ data.writeStrongBinder(cameraClient->asBinder());
+ data.writeInt32(cameraId);
+ data.writeInt32(halVersion);
+ data.writeString16(clientPackageName);
+ data.writeInt32(clientUid);
+ remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
+
+ if (readExceptionCode(reply)) return -EPROTO;
+ status_t status = reply.readInt32();
+ if (reply.readInt32() != 0) {
+ device = interface_cast<ICamera>(reply.readStrongBinder());
+ }
+ return status;
+ }
+
// connect to camera service (pro client)
virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
const String16 &clientPackageName, int clientUid,
@@ -446,6 +469,27 @@ status_t BnCameraService::onTransact(
reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
return NO_ERROR;
} break;
+ case CONNECT_LEGACY: {
+ CHECK_INTERFACE(ICameraService, data, reply);
+ sp<ICameraClient> cameraClient =
+ interface_cast<ICameraClient>(data.readStrongBinder());
+ int32_t cameraId = data.readInt32();
+ int32_t halVersion = data.readInt32();
+ const String16 clientName = data.readString16();
+ int32_t clientUid = data.readInt32();
+ sp<ICamera> camera;
+ status_t status = connectLegacy(cameraClient, cameraId, halVersion,
+ clientName, clientUid, /*out*/camera);
+ reply->writeNoException();
+ reply->writeInt32(status);
+ if (camera != NULL) {
+ reply->writeInt32(1);
+ reply->writeStrongBinder(camera->asBinder());
+ } else {
+ reply->writeInt32(0);
+ }
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 79682b8..2b60842 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -74,6 +74,10 @@ public:
const String16& clientPackageName,
int clientUid);
+ static status_t connectLegacy(int cameraId, int halVersion,
+ const String16& clientPackageName,
+ int clientUid, sp<Camera>& camera);
+
virtual ~Camera();
status_t reconnect();
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index d7e5dac..f7f06bb 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -52,6 +52,7 @@ public:
GET_CAMERA_VENDOR_TAG_DESCRIPTOR,
GET_LEGACY_PARAMETERS,
SUPPORTS_CAMERA_API,
+ CONNECT_LEGACY,
};
enum {
@@ -63,6 +64,10 @@ public:
API_VERSION_2 = 2,
};
+ enum {
+ CAMERA_HAL_API_VERSION_UNSPECIFIED = -1
+ };
+
public:
DECLARE_META_INTERFACE(CameraService);
@@ -125,6 +130,18 @@ public:
*/
virtual status_t supportsCameraApi(
int cameraId, int apiVersion) = 0;
+
+ /**
+ * Connect the device as a legacy device for a given HAL version.
+ * For halVersion, use CAMERA_API_DEVICE_VERSION_* for a particular
+ * version, or CAMERA_HAL_API_VERSION_UNSPECIFIED for a service-selected version.
+ */
+ virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient,
+ int cameraId, int halVersion,
+ const String16& clientPackageName,
+ int clientUid,
+ /*out*/
+ sp<ICamera>& device) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 73eccbf..b8227a7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -659,7 +659,8 @@ status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClien
int clientUid,
int callingPid,
/*out*/
- sp<Client>& client) {
+ sp<Client>& client,
+ int halVersion) {
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
@@ -672,28 +673,48 @@ status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClien
cameraId);
}
- switch(deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- client = new CameraClient(this, cameraClient,
- clientPackageName, cameraId,
- facing, callingPid, clientUid, getpid());
- break;
- case CAMERA_DEVICE_API_VERSION_2_0:
- case CAMERA_DEVICE_API_VERSION_2_1:
- case CAMERA_DEVICE_API_VERSION_3_0:
- case CAMERA_DEVICE_API_VERSION_3_1:
- case CAMERA_DEVICE_API_VERSION_3_2:
- client = new Camera2Client(this, cameraClient,
- clientPackageName, cameraId,
- facing, callingPid, clientUid, getpid(),
- deviceVersion);
- break;
- case -1:
- ALOGE("Invalid camera id %d", cameraId);
- return BAD_VALUE;
- default:
- ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return INVALID_OPERATION;
+ if (halVersion < 0 || halVersion == deviceVersion) {
+ // Default path: HAL version is unspecified by caller, create CameraClient
+ // based on device version reported by the HAL.
+ switch(deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_1_0:
+ client = new CameraClient(this, cameraClient,
+ clientPackageName, cameraId,
+ facing, callingPid, clientUid, getpid());
+ break;
+ case CAMERA_DEVICE_API_VERSION_2_0:
+ case CAMERA_DEVICE_API_VERSION_2_1:
+ case CAMERA_DEVICE_API_VERSION_3_0:
+ case CAMERA_DEVICE_API_VERSION_3_1:
+ case CAMERA_DEVICE_API_VERSION_3_2:
+ client = new Camera2Client(this, cameraClient,
+ clientPackageName, cameraId,
+ facing, callingPid, clientUid, getpid(),
+ deviceVersion);
+ break;
+ case -1:
+ ALOGE("Invalid camera id %d", cameraId);
+ return BAD_VALUE;
+ default:
+ ALOGE("Unknown camera device HAL version: %d", deviceVersion);
+ return INVALID_OPERATION;
+ }
+ } else {
+ // A particular HAL version is requested by caller. Create CameraClient
+ // based on the requested HAL version.
+ if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
+ halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
+ // Only support higher HAL version device opened as HAL1.0 device.
+ client = new CameraClient(this, cameraClient,
+ clientPackageName, cameraId,
+ facing, callingPid, clientUid, getpid());
+ } 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"
+ " opened as HAL %x device", halVersion, deviceVersion,
+ CAMERA_DEVICE_API_VERSION_1_0);
+ return INVALID_OPERATION;
+ }
}
status_t status = connectFinishUnsafe(client, client->getRemote());
@@ -762,6 +783,63 @@ status_t CameraService::connect(
return OK;
}
+status_t CameraService::connectLegacy(
+ const sp<ICameraClient>& cameraClient,
+ int cameraId, int halVersion,
+ const String16& clientPackageName,
+ int clientUid,
+ /*out*/
+ sp<ICamera>& device) {
+
+ if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_3) {
+ ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
+ __FUNCTION__, mModule->common.module_api_version);
+ return INVALID_OPERATION;
+ }
+
+ String8 clientName8(clientPackageName);
+ int callingPid = getCallingPid();
+
+ LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
+ clientName8.string(), cameraId);
+
+ status_t status = validateConnect(cameraId, /*inout*/clientUid);
+ if (status != OK) {
+ return status;
+ }
+
+ sp<Client> client;
+ {
+ Mutex::Autolock lock(mServiceLock);
+ sp<BasicClient> clientTmp;
+ if (!canConnectUnsafe(cameraId, clientPackageName,
+ cameraClient->asBinder(),
+ /*out*/clientTmp)) {
+ return -EBUSY;
+ } else if (client.get() != NULL) {
+ device = static_cast<Client*>(clientTmp.get());
+ return OK;
+ }
+
+ status = connectHelperLocked(cameraClient,
+ cameraId,
+ clientPackageName,
+ clientUid,
+ callingPid,
+ client,
+ halVersion);
+ if (status != OK) {
+ return status;
+ }
+
+ }
+ // important: release the mutex here so the client can call back
+ // into the service from its destructor (can be at the end of the call)
+
+ device = client;
+ return OK;
+}
+
status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
const sp<IBinder>& remoteCallback) {
status_t status = client->initialize(mModule);
@@ -1196,6 +1274,7 @@ status_t CameraService::onTransact(
case BnCameraService::CONNECT:
case BnCameraService::CONNECT_PRO:
case BnCameraService::CONNECT_DEVICE:
+ case BnCameraService::CONNECT_LEGACY:
const int pid = getCallingPid();
const int self_pid = getpid();
if (pid != self_pid) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b2b65b8..28590eb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -83,6 +83,11 @@ public:
/*out*/
sp<ICamera>& device);
+ virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
+ int halVersion, const String16& clientPackageName, int clientUid,
+ /*out*/
+ sp<ICamera>& device);
+
virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb,
int cameraId, const String16& clientPackageName, int clientUid,
/*out*/
@@ -450,7 +455,8 @@ private:
int clientUid,
int callingPid,
/*out*/
- sp<Client>& client);
+ sp<Client>& client,
+ int halVersion = CAMERA_HAL_API_VERSION_UNSPECIFIED);
};
} // namespace android
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 30b7bb8..517226d 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -79,7 +79,7 @@ status_t CameraClient::initialize(camera_module_t *module) {
ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
mHardware.clear();
- return NO_INIT;
+ return res;
}
mHardware->setCallbacks(notifyCallback,
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 87b2807..925b645 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -92,8 +92,22 @@ public:
status_t initialize(hw_module_t *module)
{
ALOGI("Opening camera %s", mName.string());
- int rc = module->methods->open(module, mName.string(),
- (hw_device_t **)&mDevice);
+ camera_module_t *cameraModule = reinterpret_cast<camera_module_t *>(module);
+ camera_info info;
+ status_t res = cameraModule->get_camera_info(atoi(mName.string()), &info);
+ if (res != OK) return res;
+
+ int rc = OK;
+ if (module->module_api_version >= CAMERA_MODULE_API_VERSION_2_3 &&
+ info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
+ // Open higher version camera device as HAL1.0 device.
+ rc = cameraModule->open_legacy(module, mName.string(),
+ CAMERA_DEVICE_API_VERSION_1_0,
+ (hw_device_t **)&mDevice);
+ } else {
+ rc = module->methods->open(module, mName.string(),
+ (hw_device_t **)&mDevice);
+ }
if (rc != OK) {
ALOGE("Could not open camera %s: %d", mName.string(), rc);
return rc;