Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3afb2cc authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera: Change error for app ops reject, propagate binder errors

INVALID_OPERATION surfaces as an non-specific device-level error to
applications in the onError callback. This is not a condition apps
targeting camera2 in L will generally have to deal with.

Instead, return -EACCESS which maps to throwing
CameraAccessException.CAMERA_DISABLED, same as disabling camera access
with DevicePolicyManager.

The old camera API converts any error code to -EACCESS at the JNI layer,
so this doesn't change anything for the older API.

Also update the various native ICameraService binder connect calls to
check for the transact error code, and return it if it is not OK.
Without this, PERMISSION_DENIED transact errors from the camera
service cannot be distinguished from CAMERA_DISABLED errors in
some codepaths.

Bug: 21604925
Change-Id: Ifccc8989b8c20653429e2d3e51dba7abb2be9c35
parent afd49243
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -97,7 +97,8 @@ status_t Camera::connectLegacy(int cameraId, int halVersion,
        c->mStatus = NO_ERROR;
        camera = c;
    } else {
        ALOGW("An error occurred while connecting to camera: %d", cameraId);
        ALOGW("An error occurred while connecting to camera %d: %d (%s)",
                cameraId, status, strerror(-status));
        c.clear();
    }
    return status;
+15 −6
Original line number Diff line number Diff line
@@ -175,10 +175,13 @@ public:
        data.writeInt32(cameraId);
        data.writeString16(clientPackageName);
        data.writeInt32(clientUid);
        remote()->transact(BnCameraService::CONNECT, data, &reply);

        status_t status;
        status = remote()->transact(BnCameraService::CONNECT, data, &reply);
        if (status != OK) return status;

        if (readExceptionCode(reply)) return -EPROTO;
        status_t status = reply.readInt32();
        status = reply.readInt32();
        if (reply.readInt32() != 0) {
            device = interface_cast<ICamera>(reply.readStrongBinder());
        }
@@ -198,10 +201,13 @@ public:
        data.writeInt32(halVersion);
        data.writeString16(clientPackageName);
        data.writeInt32(clientUid);
        remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);

        status_t status;
        status = remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
        if (status != OK) return status;

        if (readExceptionCode(reply)) return -EPROTO;
        status_t status = reply.readInt32();
        status = reply.readInt32();
        if (reply.readInt32() != 0) {
            device = interface_cast<ICamera>(reply.readStrongBinder());
        }
@@ -237,10 +243,13 @@ public:
        data.writeInt32(cameraId);
        data.writeString16(clientPackageName);
        data.writeInt32(clientUid);
        remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);

        status_t status;
        status = remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
        if (status != OK) return status;

        if (readExceptionCode(reply)) return -EPROTO;
        status_t status = reply.readInt32();
        status = reply.readInt32();
        if (reply.readInt32() != 0) {
            device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
        }
+2 −1
Original line number Diff line number Diff line
@@ -1864,7 +1864,8 @@ status_t CameraService::BasicClient::startCameraOps() {
    if (res == AppOpsManager::MODE_IGNORED) {
        ALOGI("Camera %d: Access for \"%s\" has been restricted",
                mCameraId, String8(mClientPackageName).string());
        return INVALID_OPERATION;
        // Return the same error as for device policy manager rejection
        return -EACCES;
    }

    mOpsActive = true;