summaryrefslogtreecommitdiffstats
path: root/services/camera/libcameraservice/CameraService.cpp
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2013-03-04 17:25:57 -0800
committerIgor Murashkin <iam@google.com>2013-03-11 16:32:24 -0700
commite6800cea0678dbc0bf697b44c3e4548b0253085c (patch)
tree5c4cbf3e5ebfff2774270bf9289efd5ce7f53ad0 /services/camera/libcameraservice/CameraService.cpp
parentfa4cf9d310685b4c25877cba772ff7da84caf517 (diff)
downloadframeworks_av-e6800cea0678dbc0bf697b44c3e4548b0253085c.zip
frameworks_av-e6800cea0678dbc0bf697b44c3e4548b0253085c.tar.gz
frameworks_av-e6800cea0678dbc0bf697b44c3e4548b0253085c.tar.bz2
Camera: Make ProCamera connect take the same paths as Camera connect
* ProCamera uses the app ops manager * Refactored connect calls to be as common as possible * Removed some useless not implemented function calls in ProClient Change-Id: I5dab30d20f0c202a494a07b2cfe4c1fa04a2a076
Diffstat (limited to 'services/camera/libcameraservice/CameraService.cpp')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp215
1 files changed, 88 insertions, 127 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index d46ca88..7636143 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -176,18 +176,12 @@ bool CameraService::isValidCameraId(int cameraId) {
return false;
}
-sp<ICamera> CameraService::connect(
- const sp<ICameraClient>& cameraClient,
- int cameraId,
- const String16& clientPackageName,
- int clientUid) {
+bool CameraService::validateConnect(int cameraId,
+ /*inout*/
+ int& clientUid) const {
- String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
- LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
- clientName8.string(), cameraId);
-
if (clientUid == USE_CALLING_UID) {
clientUid = getCallingUid();
} else {
@@ -195,20 +189,19 @@ sp<ICamera> CameraService::connect(
if (callingPid != getpid()) {
ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
callingPid);
- return NULL;
+ return false;
}
}
if (!mModule) {
ALOGE("Camera HAL module not loaded");
- return NULL;
+ return false;
}
- sp<Client> client;
if (cameraId < 0 || cameraId >= mNumberOfCameras) {
ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
callingPid, cameraId);
- return NULL;
+ return false;
}
char value[PROPERTY_VALUE_MAX];
@@ -216,24 +209,32 @@ sp<ICamera> CameraService::connect(
if (strcmp(value, "1") == 0) {
// Camera is disabled by DevicePolicyManager.
ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
- return NULL;
+ return false;
}
- Mutex::Autolock lock(mServiceLock);
+ return true;
+}
+
+bool CameraService::canConnectUnsafe(int cameraId,
+ const String16& clientPackageName,
+ const sp<IBinder>& remoteCallback,
+ sp<Client> &client) {
+ String8 clientName8(clientPackageName);
+ int callingPid = getCallingPid();
+
if (mClient[cameraId] != 0) {
client = mClient[cameraId].promote();
if (client != 0) {
- if (cameraClient->asBinder() ==
- client->getRemoteCallback()->asBinder()) {
-
+ if (remoteCallback == client->getRemoteCallback()->asBinder()) {
LOG1("CameraService::connect X (pid %d) (the same client)",
callingPid);
- return client;
+ return true;
} else {
- // TODOSC: need to support 1 regular client, multiple shared clients here
- ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
- callingPid);
- return NULL;
+ // TODOSC: need to support 1 regular client,
+ // multiple shared clients here
+ ALOGW("CameraService::connect X (pid %d) rejected"
+ " (existing client).", callingPid);
+ return false;
}
}
mClient[cameraId].clear();
@@ -249,16 +250,47 @@ sp<ICamera> CameraService::connect(
would be fine
*/
if (mBusy[cameraId]) {
-
ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
" (camera %d is still busy).", callingPid,
clientName8.string(), cameraId);
+ return false;
+ }
+
+ return true;
+}
+
+sp<ICamera> CameraService::connect(
+ const sp<ICameraClient>& cameraClient,
+ int cameraId,
+ const String16& clientPackageName,
+ int clientUid) {
+
+ String8 clientName8(clientPackageName);
+ int callingPid = getCallingPid();
+
+ LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
+ clientName8.string(), cameraId);
+
+ if (!validateConnect(cameraId, /*inout*/clientUid)) {
+ return NULL;
+ }
+
+ sp<Client> client;
+
+ Mutex::Autolock lock(mServiceLock);
+ if (!canConnectUnsafe(cameraId, clientPackageName,
+ cameraClient->asBinder(),
+ /*out*/client)) {
return NULL;
+ } else if (client.get() != NULL) {
+ return client;
}
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
+ // If there are other non-exclusive users of the camera,
+ // this will tear them down before we can reuse the camera
if (isValidCameraId(cameraId)) {
updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE, cameraId);
}
@@ -285,21 +317,30 @@ sp<ICamera> CameraService::connect(
return NULL;
}
- if (client->initialize(mModule) != OK) {
+ if (!connectFinishUnsafe(client, client->asBinder())) {
// this is probably not recoverable.. but maybe the client can try again
updateStatus(ICameraServiceListener::STATUS_AVAILABLE, cameraId);
return NULL;
}
- cameraClient->asBinder()->linkToDeath(this);
-
mClient[cameraId] = client;
LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
return client;
}
+bool CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
+ const sp<IBinder>& clientBinder) {
+ if (client->initialize(mModule) != OK) {
+ return false;
+ }
+
+ clientBinder->linkToDeath(this);
+
+ return true;
+}
+
sp<IProCameraUser> CameraService::connect(
const sp<IProCameraCallbacks>& cameraCb,
int cameraId,
@@ -309,38 +350,24 @@ sp<IProCameraUser> CameraService::connect(
String8 clientName8(clientPackageName);
int callingPid = getCallingPid();
- // TODO: use clientPackageName and clientUid with appOpsMangr
-
- LOG1("CameraService::connectPro E (pid %d, id %d)", callingPid, cameraId);
-
- if (!mModule) {
- ALOGE("Camera HAL module not loaded");
- return NULL;
- }
+ LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
+ clientName8.string(), cameraId);
- sp<ProClient> client;
- if (cameraId < 0 || cameraId >= mNumberOfCameras) {
- ALOGE("CameraService::connectPro X (pid %d) rejected (invalid cameraId %d).",
- callingPid, cameraId);
+ if (!validateConnect(cameraId, /*inout*/clientUid)) {
return NULL;
}
- char value[PROPERTY_VALUE_MAX];
- property_get("sys.secpolicy.camera.disabled", value, "0");
- if (strcmp(value, "1") == 0) {
- // Camera is disabled by DevicePolicyManager.
- ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
- return NULL;
+ Mutex::Autolock lock(mServiceLock);
+ {
+ sp<Client> client;
+ if (!canConnectUnsafe(cameraId, clientPackageName,
+ cameraCb->asBinder(),
+ /*out*/client)) {
+ return NULL;
+ }
}
- // TODO: allow concurrent connections with a ProCamera
- if (mBusy[cameraId]) {
-
- ALOGW("CameraService::connectPro X (pid %d, \"%s\") rejected"
- " (camera %d is still busy).", callingPid,
- clientName8.string(), cameraId);
- return NULL;
- }
+ sp<ProClient> client;
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
@@ -363,16 +390,15 @@ sp<IProCameraUser> CameraService::connect(
return NULL;
}
- if (client->initialize(mModule) != OK) {
+ if (!connectFinishUnsafe(client, client->asBinder())) {
return NULL;
}
mProClientList[cameraId].push(client);
- cameraCb->asBinder()->linkToDeath(this);
-
LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
getpid());
+
return client;
}
@@ -654,7 +680,6 @@ CameraService::Client::~Client() {
mDestructionStarted = true;
mCameraService->releaseSound();
- finishCameraOps();
// unconditionally disconnect. function is idempotent
Client::disconnect();
}
@@ -691,6 +716,11 @@ status_t CameraService::BasicClient::startCameraOps() {
mOpsCallback = new OpsCallback(this);
+ {
+ ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
+ __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+ }
+
mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
mClientPackageName, mOpsCallback);
res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
@@ -812,79 +842,10 @@ CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
}
CameraService::ProClient::~ProClient() {
- mDestructionStarted = true;
-
- ProClient::disconnect();
-}
-
-status_t CameraService::ProClient::connect(const sp<IProCameraCallbacks>& callbacks) {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-
- return INVALID_OPERATION;
-}
-
-void CameraService::ProClient::disconnect() {
- BasicClient::disconnect();
-}
-
-status_t CameraService::ProClient::initialize(camera_module_t* module)
-{
- ALOGW("%s: not implemented yet", __FUNCTION__);
- return OK;
-}
-
-status_t CameraService::ProClient::exclusiveTryLock() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
- return INVALID_OPERATION;
-}
-
-status_t CameraService::ProClient::exclusiveLock() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
- return INVALID_OPERATION;
-}
-
-status_t CameraService::ProClient::exclusiveUnlock() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
- return INVALID_OPERATION;
-}
-
-bool CameraService::ProClient::hasExclusiveLock() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
- return false;
-}
-
-void CameraService::ProClient::onExclusiveLockStolen() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-}
-
-status_t CameraService::ProClient::submitRequest(camera_metadata_t* request, bool streaming) {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-
- free_camera_metadata(request);
-
- return INVALID_OPERATION;
-}
-
-status_t CameraService::ProClient::cancelRequest(int requestId) {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-
- return INVALID_OPERATION;
-}
-
-status_t CameraService::ProClient::requestStream(int streamId) {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-
- return INVALID_OPERATION;
-}
-
-status_t CameraService::ProClient::cancelStream(int streamId) {
- ALOGE("%s: not implemented yet", __FUNCTION__);
-
- return INVALID_OPERATION;
}
void CameraService::ProClient::notifyError() {
- ALOGE("%s: not implemented yet", __FUNCTION__);
+ mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
}
// ----------------------------------------------------------------------------