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

Commit 441d5e9e authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Android (Google) Code Review
Browse files

Merge "camera2: Add system api to specify oom score offset while opening a camera." into sc-dev

parents d05e7856 e69876bb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3144,6 +3144,10 @@ package android.hardware.camera2 {
    field public static final int SESSION_OPERATION_MODE_VENDOR_START = 32768; // 0x8000
  }
  public final class CameraManager {
    method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
  }
  public abstract static class CameraManager.AvailabilityCallback {
    method @RequiresPermission(android.Manifest.permission.CAMERA_OPEN_CLOSE_LISTENER) public void onCameraClosed(@NonNull String);
    method @RequiresPermission(android.Manifest.permission.CAMERA_OPEN_CLOSE_LISTENER) public void onCameraOpened(@NonNull String, @NonNull String);
+1 −0
Original line number Diff line number Diff line
@@ -1133,6 +1133,7 @@ package android.hardware.camera2 {

  public final class CameraManager {
    method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
    method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
  }

  public abstract static class CameraManager.AvailabilityCallback {
+99 −8
Original line number Diff line number Diff line
@@ -560,8 +560,8 @@ public final class CameraManager {
     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
     */
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid)
            throws CameraAccessException {
            CameraDevice.StateCallback callback, Executor executor, final int uid,
            final int oomScoreOffset) throws CameraAccessException {
        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
        CameraDevice device = null;
        Map<String, CameraCharacteristics> physicalIdsToChars =
@@ -589,7 +589,8 @@ public final class CameraManager {
                        "Camera service is currently unavailable");
                }
                cameraUser = cameraService.connectDevice(callbacks, cameraId,
                    mContext.getOpPackageName(),  mContext.getAttributionTag(), uid);
                    mContext.getOpPackageName(),  mContext.getAttributionTag(), uid,
                    oomScoreOffset);
            } catch (ServiceSpecificException e) {
                if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
                    throw new AssertionError("Should've gone down the shim path");
@@ -759,9 +760,78 @@ public final class CameraManager {
        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);
    }

    /**
     * Open a connection to a camera with the given ID. Also specify what oom score must be offset
     * by cameraserver for this client. This api can be useful for system
     * components which want to assume a lower priority (for camera arbitration) than other clients
     * which it might contend for camera devices with. Increasing the oom score of a client reduces
     * its priority when the camera framework manages camera arbitration.
     * Considering typical use cases:
     *
     * 1) oom score(apps hosting activities visible to the user) - oom score(of a foreground app)
     *    is approximately 100.
     *
     * 2) The oom score (process which hosts components which that are perceptible to the user /
     *    native vendor camera clients) - oom (foreground app) is approximately 200.
     *
     * 3) The oom score (process which is cached hosting activities not visible) - oom (foreground
     *    app) is approximately 999.
     *
     * <p>The behavior of this method matches that of
     * {@link #openCamera(String, StateCallback, Handler)}, except that it uses
     * {@link java.util.concurrent.Executor} as an argument instead of
     * {@link android.os.Handler}.</p>
     *
     * @param cameraId
     *             The unique identifier of the camera device to open
     * @param executor
     *             The executor which will be used when invoking the callback.
     * @param callback
     *             The callback which is invoked once the camera is opened
     * @param oomScoreOffset
     *             The value by which the oom score of this client must be offset by the camera
     *             framework in order to assist it with camera arbitration. This value must be > 0.
     *             A positive value lowers the priority of this camera client compared to what the
     *             camera framework would have originally seen.
     *
     * @throws CameraAccessException if the camera is disabled by device policy,
     * has been disconnected, or is being used by a higher-priority camera API client.
     *
     * @throws IllegalArgumentException if cameraId, the callback or the executor was null,
     * or the cameraId does not match any currently or previously available
     * camera device.
     *
     * @throws SecurityException if the application does not have permission to
     * access the camera
     *
     * @see #getCameraIdList
     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
     *
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(allOf = {
            android.Manifest.permission.SYSTEM_CAMERA,
            android.Manifest.permission.CAMERA,
    })
    public void openCamera(@NonNull String cameraId, int oomScoreOffset,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull final CameraDevice.StateCallback callback) throws CameraAccessException {
        if (executor == null) {
            throw new IllegalArgumentException("executor was null");
        }
        if (oomScoreOffset < 0) {
            throw new IllegalArgumentException(
                    "oomScoreOffset < 0, cannot increase priority of camera client");
        }
        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset);
    }

    /**
     * Open a connection to a camera with the given ID, on behalf of another application
     * specified by clientUid.
     * specified by clientUid. Also specify the minimum oom score and process state the application
     * should have, as seen by the cameraserver.
     *
     * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
     * the caller to specify the UID to use for permission/etc verification. This can only be
@@ -771,13 +841,13 @@ public final class CameraManager {
     * @param clientUid
     *             The UID of the application on whose behalf the camera is being opened.
     *             Must be USE_CALLING_UID unless the caller is a trusted service.
     *
     * @param oomScoreOffset
     *             The minimum oom score that cameraservice must see for this client.
     * @hide
     */
    public void openCameraForUid(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
            int clientUid)
            throws CameraAccessException {
            int clientUid, int oomScoreOffset) throws CameraAccessException {

        if (cameraId == null) {
            throw new IllegalArgumentException("cameraId was null");
@@ -788,7 +858,28 @@ public final class CameraManager {
            throw new IllegalArgumentException("No cameras available on device");
        }

        openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
        openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset);
    }

    /**
     * Open a connection to a camera with the given ID, on behalf of another application
     * specified by clientUid.
     *
     * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
     * the caller to specify the UID to use for permission/etc verification. This can only be
     * done by services trusted by the camera subsystem to act on behalf of applications and
     * to forward the real UID.</p>
     *
     * @param clientUid
     *             The UID of the application on whose behalf the camera is being opened.
     *             Must be USE_CALLING_UID unless the caller is a trusted service.
     *
     * @hide
     */
    public void openCameraForUid(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
            int clientUid) throws CameraAccessException {
            openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ public class CameraBinderTest extends AndroidTestCase {
                    mUtils.getCameraService().connectDevice(
                        dummyCallbacks, String.valueOf(cameraId),
                        clientPackageName, clientAttributionTag,
                        ICameraService.USE_CALLING_UID);
                        ICameraService.USE_CALLING_UID, 0 /*oomScoreOffset*/);
            assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);

            Log.v(TAG, String.format("Camera %s connected", cameraId));
+2 −1
Original line number Diff line number Diff line
@@ -243,7 +243,8 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
        mMockCb = spy(dummyCallbacks);

        mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
                clientPackageName, clientAttributionTag, ICameraService.USE_CALLING_UID);
                clientPackageName, clientAttributionTag, ICameraService.USE_CALLING_UID,
                /*oomScoreOffset*/0);
        assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
        mHandlerThread = new HandlerThread(TAG);
        mHandlerThread.start();