summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2015-04-30 14:35:42 -0700
committerRuben Brunk <rubenbrunk@google.com>2015-05-01 18:26:52 +0000
commit0bbf8b213ad96051357e3ad6d6d2808bfa31a59a (patch)
tree17da4c285aa0b41a76123dbbf2c47b7018d41444 /services
parent1de1e25cba872bd4c077c2e394f8ca9c70b65856 (diff)
downloadframeworks_av-0bbf8b213ad96051357e3ad6d6d2808bfa31a59a.zip
frameworks_av-0bbf8b213ad96051357e3ad6d6d2808bfa31a59a.tar.gz
frameworks_av-0bbf8b213ad96051357e3ad6d6d2808bfa31a59a.tar.bz2
camera2: Fix fuzztesting segfault in connect.
Bug: 20721655 Change-Id: I0d974cad19683a8c86a76dac7f61ac0010bd977a
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp16
-rw-r--r--services/camera/libcameraservice/CameraService.h9
2 files changed, 23 insertions, 2 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 8c5c43a..e28464d 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -890,9 +890,12 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
if (current != nullptr) {
auto clientSp = current->getValue();
if (clientSp.get() != nullptr) { // should never be needed
- if (clientSp->getRemote() == remoteCallback) {
+ if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
+ ALOGW("CameraService connect called from same client, but with a different"
+ " API level, evicting prior client...");
+ } else if (clientSp->getRemote() == remoteCallback) {
ALOGI("CameraService::connect X (PID %d) (second call from same"
- "app binder, returning the same client)", clientPid);
+ " app binder, returning the same client)", clientPid);
*client = clientSp;
return NO_ERROR;
}
@@ -1754,6 +1757,11 @@ int CameraService::BasicClient::getClientPid() const {
return mClientPid;
}
+bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
+ // Defaults to API2.
+ return level == API_2;
+}
+
status_t CameraService::BasicClient::startCameraOps() {
int32_t res;
// Notify app ops that the camera is not available
@@ -1866,6 +1874,10 @@ void CameraService::Client::disconnect() {
BasicClient::disconnect();
}
+bool CameraService::Client::canCastToApiClient(apiLevel level) const {
+ return level == API_1;
+}
+
CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
mClient(client) {
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 84e61c5..a8b4c4a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -65,6 +65,7 @@ public:
class Client;
class BasicClient;
+ // The effective API level. The Camera2 API running in LEGACY mode counts as API_1.
enum apiLevel {
API_1 = 1,
API_2 = 2
@@ -215,6 +216,10 @@ public:
// Get the PID of the application client using this
virtual int getClientPid() const;
+
+ // Check what API level is used for this client. This is used to determine which
+ // superclass this can be cast to.
+ virtual bool canCastToApiClient(apiLevel level) const;
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
@@ -323,6 +328,10 @@ public:
virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
const CaptureResultExtras& resultExtras);
+
+ // Check what API level is used for this client. This is used to determine which
+ // superclass this can be cast to.
+ virtual bool canCastToApiClient(apiLevel level) const;
protected:
// Convert client from cookie.
static sp<CameraService::Client> getClientFromCookie(void* user);