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

Commit 0f16bd07 authored by Austin Borger's avatar Austin Borger Committed by Android (Google) Code Review
Browse files

Merge "Pass full AttributionSourceState across Java/Cpp boundaries." into main

parents 8fecf0ae e6b081d5
Loading
Loading
Loading
Loading
+50 −14
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource.ScopedParcelState;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Point;
@@ -45,6 +46,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -293,10 +295,14 @@ public class Camera {
    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
    @TestApi
    public static int getNumberOfCameras(@NonNull Context context) {
        return _getNumberOfCameras(context.getDeviceId(), getDevicePolicyFromContext(context));
        try (ScopedParcelState clientAttribution =
                context.getAttributionSource().asScopedParcelState()) {
            return _getNumberOfCameras(
                    clientAttribution.getParcel(), getDevicePolicyFromContext(context));
        }
    }

    private static native int _getNumberOfCameras(int deviceId, int devicePolicy);
    private static native int _getNumberOfCameras(Parcel clientAttributionParcel, int devicePolicy);

    /**
     * Returns the information about a particular camera.
@@ -321,8 +327,16 @@ public class Camera {
    @TestApi
    public static void getCameraInfo(int cameraId, @NonNull Context context,
            int rotationOverride, CameraInfo cameraInfo) {
        _getCameraInfo(cameraId, rotationOverride, context.getDeviceId(),
                getDevicePolicyFromContext(context), cameraInfo);
        try (ScopedParcelState clientAttribution =
                context.getAttributionSource().asScopedParcelState()) {
            _getCameraInfo(
                    cameraId,
                    rotationOverride,
                    clientAttribution.getParcel(),
                    getDevicePolicyFromContext(context),
                    cameraInfo);
        }

        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
        IAudioService audioService = IAudioService.Stub.asInterface(b);
        try {
@@ -336,8 +350,12 @@ public class Camera {
        }
    }

    private native static void _getCameraInfo(int cameraId, int rotationOverride,
            int deviceId, int devicePolicy, CameraInfo cameraInfo);
    private native static void _getCameraInfo(
            int cameraId,
            int rotationOverride,
            Parcel clientAttributionParcel,
            int devicePolicy,
            CameraInfo cameraInfo);

    private static int getDevicePolicyFromContext(Context context) {
        if (context.getDeviceId() == DEVICE_ID_DEFAULT
@@ -545,9 +563,18 @@ public class Camera {
        }

        boolean forceSlowJpegMode = shouldForceSlowJpegMode();
        return native_setup(new WeakReference<>(this), cameraId,
                ActivityThread.currentOpPackageName(), rotationOverride, forceSlowJpegMode,
                context.getDeviceId(), getDevicePolicyFromContext(context));

        try (ScopedParcelState clientAttribution =
                context.getAttributionSource().asScopedParcelState()) {
            return native_setup(
                    new WeakReference<>(this),
                    cameraId,
                    ActivityThread.currentOpPackageName(),
                    rotationOverride,
                    forceSlowJpegMode,
                    clientAttribution.getParcel(),
                    getDevicePolicyFromContext(context));
        }
    }

    private boolean shouldForceSlowJpegMode() {
@@ -630,8 +657,14 @@ public class Camera {
    }

    @UnsupportedAppUsage
    private native int native_setup(Object cameraThis, int cameraId, String packageName,
            int rotationOverride, boolean forceSlowJpegMode, int deviceId, int devicePolicy);
    private native int native_setup(
            Object cameraThis,
            int cameraId,
            String packageName,
            int rotationOverride,
            boolean forceSlowJpegMode,
            Parcel clientAttributionParcel,
            int devicePolicy);

    private native final void native_release();

@@ -2267,9 +2300,11 @@ public class Camera {
        private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
        private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
        private static final String KEY_AUTO_EXPOSURE_LOCK = "auto-exposure-lock";
        private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
        private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED =
                "auto-exposure-lock-supported";
        private static final String KEY_AUTO_WHITEBALANCE_LOCK = "auto-whitebalance-lock";
        private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED = "auto-whitebalance-lock-supported";
        private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED =
                "auto-whitebalance-lock-supported";
        private static final String KEY_METERING_AREAS = "metering-areas";
        private static final String KEY_MAX_NUM_METERING_AREAS = "max-num-metering-areas";
        private static final String KEY_ZOOM = "zoom";
@@ -2286,7 +2321,8 @@ public class Camera {
        private static final String KEY_RECORDING_HINT = "recording-hint";
        private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
        private static final String KEY_VIDEO_STABILIZATION = "video-stabilization";
        private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported";
        private static final String KEY_VIDEO_STABILIZATION_SUPPORTED =
                "video-stabilization-supported";

        // Parameter key suffix for supported values.
        private static final String SUPPORTED_VALUES_SUFFIX = "-values";
+121 −62
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
import android.content.AttributionSourceState;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Point;
@@ -106,6 +107,7 @@ public final class CameraManager {
    private final boolean DEBUG = false;

    private static final int USE_CALLING_UID = -1;
    private static final int USE_CALLING_PID = -1;

    @SuppressWarnings("unused")
    private static final int API_VERSION_1 = 1;
@@ -418,9 +420,12 @@ public final class CameraManager {
    public boolean isConcurrentSessionConfigurationSupported(
            @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig)
            throws CameraAccessException {
        return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported(
                cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion,
                mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
        return CameraManagerGlobal.get()
                .isConcurrentSessionConfigurationSupported(
                        cameraIdAndSessionConfig,
                        mContext.getApplicationInfo().targetSdkVersion,
                        getClientAttribution(),
                        getDevicePolicyFromContext(mContext));
    }

    /**
@@ -660,11 +665,14 @@ public final class CameraManager {
        }
        try {
            for (String physicalCameraId : physicalCameraIds) {
                AttributionSourceState clientAttribution = getClientAttribution();
                clientAttribution.deviceId = DEVICE_ID_DEFAULT;
                CameraMetadataNative physicalCameraInfo =
                        cameraService.getCameraCharacteristics(physicalCameraId,
                        cameraService.getCameraCharacteristics(
                                physicalCameraId,
                                mContext.getApplicationInfo().targetSdkVersion,
                                /*rotationOverride*/ ICameraService.ROTATION_OVERRIDE_NONE,
                                DEVICE_ID_DEFAULT,
                                clientAttribution,
                                DEVICE_POLICY_DEFAULT);
                StreamConfiguration[] configs = physicalCameraInfo.get(
                        CameraCharacteristics.
@@ -756,9 +764,13 @@ public final class CameraManager {
                        "Camera service is currently unavailable");
            }
            try {
                CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
                        mContext.getApplicationInfo().targetSdkVersion, rotationOverride,
                        mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
                CameraMetadataNative info =
                        cameraService.getCameraCharacteristics(
                                cameraId,
                                mContext.getApplicationInfo().targetSdkVersion,
                                rotationOverride,
                                getClientAttribution(),
                                getDevicePolicyFromContext(mContext));
                characteristics = prepareCameraCharacteristics(cameraId, info, cameraService);
            } catch (ServiceSpecificException e) {
                throw ExceptionUtils.throwAsPublicException(e);
@@ -950,16 +962,34 @@ public final class CameraManager {
        return CameraDeviceSetupImpl.isCameraDeviceSetupSupported(chars);
    }

    /**
     * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
     *
     * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
     * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
     * arguments.</p>
     *
     * @hide
     */
    public AttributionSourceState getClientAttribution() {
        // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
        AttributionSourceState contextAttribution =
                mContext.getAttributionSource().asState();
        AttributionSourceState clientAttribution =
                new AttributionSourceState();
        clientAttribution.uid = USE_CALLING_UID;
        clientAttribution.pid = USE_CALLING_PID;
        clientAttribution.deviceId = contextAttribution.deviceId;
        clientAttribution.next = new AttributionSourceState[0];
        return clientAttribution;
    }

    /**
     * Helper for opening a connection to a camera with the given ID.
     *
     * @param cameraId The unique identifier of the camera device to open
     * @param callback The callback for the camera. Must not be null.
     * @param executor The executor to invoke the callback with. Must not be null.
     * @param uid      The UID of the application actually opening the camera.
     *                 Must be USE_CALLING_UID unless the caller is a service
     *                 that is trusted to open the device on behalf of an
     *                 application and to forward the real UID.
     *
     * @throws CameraAccessException if the camera is disabled by device policy,
     * too many camera devices are already open, or the cameraId does not match
@@ -974,7 +1004,7 @@ public final class CameraManager {
     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
     */
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid,
            CameraDevice.StateCallback callback, Executor executor,
            final int oomScoreOffset, int rotationOverride) throws CameraAccessException {
        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
        CameraDevice device = null;
@@ -1005,10 +1035,18 @@ public final class CameraManager {
                        "Camera service is currently unavailable");
                }

                cameraUser = cameraService.connectDevice(callbacks, cameraId,
                    mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
                    oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
                        rotationOverride, mContext.getDeviceId(),
                AttributionSourceState clientAttribution =
                        getClientAttribution();
                cameraUser =
                        cameraService.connectDevice(
                                callbacks,
                                cameraId,
                                mContext.getOpPackageName(),
                                mContext.getAttributionTag(),
                                oomScoreOffset,
                                mContext.getApplicationInfo().targetSdkVersion,
                                rotationOverride,
                                clientAttribution,
                                getDevicePolicyFromContext(mContext));
            } catch (ServiceSpecificException e) {
                if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
@@ -1135,8 +1173,8 @@ public final class CameraManager {
    public void openCamera(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
            throws CameraAccessException {
        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
                USE_CALLING_UID);

        openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler));
    }

    /**
@@ -1172,8 +1210,8 @@ public final class CameraManager {
    public void openCamera(@NonNull String cameraId, boolean overrideToPortrait,
            @Nullable Handler handler,
            @NonNull final CameraDevice.StateCallback callback) throws CameraAccessException {
        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
                         USE_CALLING_UID, /*oomScoreOffset*/0,
        openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
                         /*oomScoreOffset*/0,
                         overrideToPortrait
                                 ? ICameraService.ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT
                                 : ICameraService.ROTATION_OVERRIDE_NONE);
@@ -1221,7 +1259,7 @@ public final class CameraManager {
        if (executor == null) {
            throw new IllegalArgumentException("executor was null");
        }
        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);
        openCameraImpl(cameraId, callback, executor);
    }

    /**
@@ -1289,13 +1327,13 @@ public final class CameraManager {
            throw new IllegalArgumentException(
                    "oomScoreOffset < 0, cannot increase priority of camera client");
        }
        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset,
        openCameraImpl(cameraId, callback, executor, oomScoreOffset,
                getRotationOverride(mContext));
    }

    /**
     * Open a connection to a camera with the given ID, on behalf of another application
     * specified by clientUid. Also specify the minimum oom score and process state the application
     * Open a connection to a camera with the given ID, on behalf of another application.
     * 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
@@ -1303,9 +1341,6 @@ public final class CameraManager {
     * 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.
     * @param oomScoreOffset
     *             The minimum oom score that cameraservice must see for this client.
     * @param rotationOverride
@@ -1313,9 +1348,9 @@ public final class CameraManager {
     *             that should be followed for this camera id connection
     * @hide
     */
    public void openCameraForUid(@NonNull String cameraId,
    public void openCameraImpl(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
            int clientUid, int oomScoreOffset, int rotationOverride)
            int oomScoreOffset, int rotationOverride)
            throws CameraAccessException {

        if (cameraId == null) {
@@ -1327,29 +1362,24 @@ public final class CameraManager {
            throw new IllegalArgumentException("No cameras available on device");
        }

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

    /**
     * Open a connection to a camera with the given ID, on behalf of another application
     * specified by clientUid.
     * Open a connection to a camera with the given ID, on behalf of another application.
     *
     * <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,
    public void openCameraImpl(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor)
            throws CameraAccessException {
        openCameraImpl(cameraId, callback, executor, /*oomScoreOffset*/0,
                getRotationOverride(mContext));
    }

@@ -1397,7 +1427,11 @@ public final class CameraManager {
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No cameras available on device");
        }
        CameraManagerGlobal.get().setTorchMode(cameraId, enabled, mContext.getDeviceId(),
        CameraManagerGlobal.get()
                .setTorchMode(
                        cameraId,
                        enabled,
                        getClientAttribution(),
                        getDevicePolicyFromContext(mContext));
    }

@@ -1461,8 +1495,12 @@ public final class CameraManager {
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No camera available on device");
        }
        CameraManagerGlobal.get().turnOnTorchWithStrengthLevel(cameraId, torchStrength,
                mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
        CameraManagerGlobal.get()
                .turnOnTorchWithStrengthLevel(
                        cameraId,
                        torchStrength,
                        getClientAttribution(),
                        getDevicePolicyFromContext(mContext));
    }

    /**
@@ -1488,7 +1526,10 @@ public final class CameraManager {
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No camera available on device.");
        }
        return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId, mContext.getDeviceId(),
        return CameraManagerGlobal.get()
                .getTorchStrengthLevel(
                        cameraId,
                        getClientAttribution(),
                        getDevicePolicyFromContext(mContext));
    }

@@ -2499,7 +2540,9 @@ public final class CameraManager {

        public boolean isConcurrentSessionConfigurationSupported(
                @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations,
                int targetSdkVersion, int deviceId, int devicePolicy)
                int targetSdkVersion,
                AttributionSourceState clientAttribution,
                int devicePolicy)
                throws CameraAccessException {
            if (cameraIdsAndSessionConfigurations == null) {
                throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null");
@@ -2517,9 +2560,12 @@ public final class CameraManager {
                for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) {
                    Set<DeviceCameraInfo> infos = new ArraySet<>();
                    for (String cameraId : cameraIdsAndSessionConfigurations.keySet()) {
                        infos.add(new DeviceCameraInfo(cameraId,
                        infos.add(
                                new DeviceCameraInfo(
                                        cameraId,
                                        devicePolicy == DEVICE_POLICY_DEFAULT
                                        ? DEVICE_ID_DEFAULT : deviceId));
                                                ? DEVICE_ID_DEFAULT
                                                : clientAttribution.deviceId));
                    }
                    if (combination.containsAll(infos)) {
                        subsetFound = true;
@@ -2541,7 +2587,7 @@ public final class CameraManager {
                }
                try {
                    return mCameraService.isConcurrentSessionConfigurationSupported(
                            cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy);
                            cameraIdsAndConfigs, targetSdkVersion, clientAttribution, devicePolicy);
                } catch (ServiceSpecificException e) {
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
@@ -2580,7 +2626,11 @@ public final class CameraManager {
            return false;
        }

        public void setTorchMode(String cameraId, boolean enabled, int deviceId, int devicePolicy)
        public void setTorchMode(
                String cameraId,
                boolean enabled,
                AttributionSourceState clientAttribution,
                int devicePolicy)
                throws CameraAccessException {
            synchronized (mLock) {
                if (cameraId == null) {
@@ -2594,8 +2644,8 @@ public final class CameraManager {
                }

                try {
                    cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder, deviceId,
                            devicePolicy);
                    cameraService.setTorchMode(
                            cameraId, enabled, mTorchClientBinder, clientAttribution, devicePolicy);
                } catch(ServiceSpecificException e) {
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
@@ -2605,7 +2655,10 @@ public final class CameraManager {
            }
        }

        public void turnOnTorchWithStrengthLevel(String cameraId, int torchStrength, int deviceId,
        public void turnOnTorchWithStrengthLevel(
                String cameraId,
                int torchStrength,
                AttributionSourceState clientAttribution,
                int devicePolicy)
                throws CameraAccessException {
            synchronized (mLock) {
@@ -2620,8 +2673,12 @@ public final class CameraManager {
                }

                try {
                    cameraService.turnOnTorchWithStrengthLevel(cameraId, torchStrength,
                            mTorchClientBinder, deviceId, devicePolicy);
                    cameraService.turnOnTorchWithStrengthLevel(
                            cameraId,
                            torchStrength,
                            mTorchClientBinder,
                            clientAttribution,
                            devicePolicy);
                } catch(ServiceSpecificException e) {
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
@@ -2631,7 +2688,8 @@ public final class CameraManager {
            }
        }

        public int getTorchStrengthLevel(String cameraId, int deviceId, int devicePolicy)
        public int getTorchStrengthLevel(
                String cameraId, AttributionSourceState clientAttribution, int devicePolicy)
                throws CameraAccessException {
            int torchStrength;
            synchronized (mLock) {
@@ -2646,8 +2704,9 @@ public final class CameraManager {
                }

                try {
                    torchStrength = cameraService.getTorchStrengthLevel(cameraId, deviceId,
                            devicePolicy);
                    torchStrength =
                            cameraService.getTorchStrengthLevel(
                                    cameraId, clientAttribution, devicePolicy);
                } catch(ServiceSpecificException e) {
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
+19 −12

File changed.

Preview size limit exceeded, changes collapsed.

+45 −15

File changed.

Preview size limit exceeded, changes collapsed.

+22 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.mediaframeworktest.helpers;

import android.content.AttributionSourceState;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
@@ -2227,4 +2229,24 @@ public class CameraTestUtils extends Assert {
        else
            return new Size(width, height);
    }

    /**
     * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
     *
     * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
     * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
     * arguments.</p>
     */
    public static AttributionSourceState getClientAttribution(Context context) {
        // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
        AttributionSourceState contextAttribution =
                context.getAttributionSource().asState();
        AttributionSourceState clientAttribution =
                new AttributionSourceState();
        clientAttribution.uid = -1; // USE_CALLING_UID
        clientAttribution.pid = -1; // USE_CALLING_PID
        clientAttribution.deviceId = contextAttribution.deviceId;
        clientAttribution.next = new AttributionSourceState[0];
        return clientAttribution;
    }
}
Loading