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

Commit 39e51723 authored by Austin Borger's avatar Austin Borger
Browse files

Unhide some camera2 data class constructors to tests.

Currently, if apps want to make functionality involving these classes
testable, they need to copy contents out of them / use proxy classes /
wrappers, since they cannot create instances of these (their
constructors are hidden), and also cannot mock them (they're final).

There is already precedent for keeping constructors of similar classes
available (see e.g. TonemapCurve or RggbChannelVector). Un-hiding more
of them would make the API more consistent, easier to test, and I'm not
aware of any major downsides of doing so.

We might also consider unhiding some more of them (e.g. ones about
stream configurations) in the future; these four seem to be the easiest
choices though.

(We're also adding some NonNull / Nullable annotations to make lint
happy.)

Test: Ran GCA
Bug: 202059787
Change-Id: Ie143d1b349e15510fd4d0058dfa9077a613836e4
parent 83a3a1f8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -18147,12 +18147,14 @@ package android.hardware.camera2 {
package android.hardware.camera2.params {
  public final class BlackLevelPattern {
    ctor public BlackLevelPattern(@NonNull int[]);
    method public void copyTo(int[], int);
    method public int getOffsetForIndex(int, int);
    field public static final int COUNT = 4; // 0x4
  }
  public final class Capability {
    ctor public Capability(int, int, int, float, float);
    method @NonNull public android.util.Size getMaxStreamingSize();
    method public int getMode();
    method @NonNull public android.util.Range<java.lang.Float> getZoomRatioRange();
@@ -18167,6 +18169,7 @@ package android.hardware.camera2.params {
  }
  public final class DeviceStateSensorOrientationMap {
    ctor public DeviceStateSensorOrientationMap(@NonNull long[]);
    method public int getSensorOrientation(long);
    field public static final long FOLDED = 4L; // 0x4L
    field public static final long NORMAL = 0L; // 0x0L
@@ -18201,6 +18204,8 @@ package android.hardware.camera2.params {
  }
  public final class Face {
    ctor public Face(@NonNull android.graphics.Rect, int, int, @NonNull android.graphics.Point, @NonNull android.graphics.Point, @NonNull android.graphics.Point);
    ctor public Face(@NonNull android.graphics.Rect, int);
    method public android.graphics.Rect getBounds();
    method public int getId();
    method public android.graphics.Point getLeftEyePosition();
+6 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.hardware.camera2.params;

import android.annotation.NonNull;
import android.annotation.Nullable;

import java.util.Arrays;
@@ -43,13 +44,16 @@ public final class BlackLevelPattern {
     * a 2x2 pattern corresponding to the color filter arrangement.  Offsets are
     * given in row-column scan order.</p>
     *
     * <p>This constructor is public to allow for easier application testing by
     * creating custom object instances. It's not necessary to construct these
     * objects during normal use of the camera API.</p>
     *
     * @param offsets an array containing a 2x2 pattern of offsets.
     *
     * @throws IllegalArgumentException if the given array has an incorrect length.
     * @throws NullPointerException if the given array is null.
     * @hide
     */
    public BlackLevelPattern(int[] offsets) {
    public BlackLevelPattern(@NonNull int[] offsets) {
        if (offsets == null) {
            throw new NullPointerException("Null offsets array passed to constructor");
        }
+8 −1
Original line number Diff line number Diff line
@@ -48,6 +48,14 @@ public final class Capability {
    /**
     * Create a new Capability object.
     *
     * <p>The mode argument can be any integer value. maxStreamingWidth and maxStreamingHeight
     * must be non-negative, while minZoomRatio and maxZoomRatio must be strictly
     * positive.</p>
     *
     * <p>This constructor is public to allow for easier application testing by
     * creating custom object instances. It's not necessary to construct these
     * objects during normal use of the camera API.</p>
     *
     * @param mode supported mode for a camera capability.
     * @param maxStreamingWidth The width of the maximum streaming size for this mode
     * @param maxStreamingHeight The height of the maximum streaming size for this mode
@@ -55,7 +63,6 @@ public final class Capability {
     * @param maxZoomRatio the maximum zoom ratio this mode supports
     *
     * @throws IllegalArgumentException if any of the argument is not valid
     * @hide
     */
    public Capability(int mode, int maxStreamingWidth, int maxStreamingHeight,
            float minZoomRatio, float maxZoomRatio) {
+13 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.hardware.camera2.params;

import android.annotation.LongDef;
import android.annotation.NonNull;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.utils.HashCodeHelpers;

@@ -72,8 +73,19 @@ public final class DeviceStateSensorOrientationMap {
    /**
     * Create a new immutable DeviceStateOrientationMap instance.
     *
     * <p>The array is a list of pairs of elements (angle, deviceState):</p>
     *
     * <code>[angle0, state0, angle1, state1,..., angleN, stateN]</code>
     *
     * <p>Each pair describes the camera sensor orientation when the device is in the
     * matching deviceState. The angle is in degrees, and must be a multiple of 90.</p>
     *
     * <p>This constructor takes over the array; do not write to the array afterwards.</p>
     *
     * <p>This constructor is public to allow for easier application testing by
     * creating custom object instances. It's not necessary to construct these
     * objects during normal use of the camera API.</p>
     *
     * @param elements
     *          An array of elements describing the map
     *
@@ -82,10 +94,8 @@ public final class DeviceStateSensorOrientationMap {
     *            invalid element values
     * @throws NullPointerException
     *            if {@code elements} is {@code null}
     *
     * @hide
     */
    public DeviceStateSensorOrientationMap(final long[] elements) {
    public DeviceStateSensorOrientationMap(@NonNull final long[] elements) {
        mElements = Objects.requireNonNull(elements, "elements must not be null");
        if ((elements.length % 2) != 0) {
            throw new IllegalArgumentException("Device state sensor orientation map length " +
+48 −32
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@

package android.hardware.camera2.params;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.camera2.CameraCharacteristics;
@@ -49,12 +51,12 @@ public final class Face {
     */
    public static final int SCORE_MAX = 100;

    private final Rect mBounds;
    private final int mScore;
    private final int mId;
    private final Point mLeftEye;
    private final Point mRightEye;
    private final Point mMouth;
    private Rect mBounds;
    private int mScore;
    private int mId;
    private Point mLeftEye;
    private Point mRightEye;
    private Point mMouth;

    /**
     * Create a new face with all fields set.
@@ -67,6 +69,10 @@ public final class Face {
     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
     *
     * <p>This constructor is public to allow for easier application testing by
     * creating custom object instances. It's not necessary to construct these
     * objects during normal use of the camera API.</p>
     *
     * @param bounds Bounds of the face.
     * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
     * @param id A unique ID per face visible to the tracker.
@@ -81,29 +87,11 @@ public final class Face {
     *             or if id is {@value #ID_UNSUPPORTED} and
     *               leftEyePosition/rightEyePosition/mouthPosition aren't all null,
     *             or else if id is negative.
     *
     * @hide
     */
    public Face(Rect bounds, int score, int id,
            Point leftEyePosition, Point rightEyePosition, Point mouthPosition) {
        checkNotNull("bounds", bounds);
        if (score < SCORE_MIN || score > SCORE_MAX) {
            throw new IllegalArgumentException("Confidence out of range");
        } else if (id < 0 && id != ID_UNSUPPORTED) {
            throw new IllegalArgumentException("Id out of range");
        }
        if (id == ID_UNSUPPORTED) {
            checkNull("leftEyePosition", leftEyePosition);
            checkNull("rightEyePosition", rightEyePosition);
            checkNull("mouthPosition", mouthPosition);
        }

        mBounds = bounds;
        mScore = score;
        mId = id;
        mLeftEye = leftEyePosition;
        mRightEye = rightEyePosition;
        mMouth = mouthPosition;
    public Face(@NonNull Rect bounds, int score, int id,
            @NonNull Point leftEyePosition, @NonNull Point rightEyePosition,
            @NonNull Point mouthPosition) {
        init(bounds, score, id, leftEyePosition, rightEyePosition, mouthPosition);
    }

    /**
@@ -118,6 +106,10 @@ public final class Face {
     * the face id of each face is expected to be {@value #ID_UNSUPPORTED}, the leftEyePosition,
     * rightEyePosition, and mouthPositions are expected to be {@code null} for each face.</p>
     *
     * <p>This constructor is public to allow for easier application testing by
     * creating custom object instances. It's not necessary to construct these
     * objects during normal use of the camera API.</p>
     *
     * @param bounds Bounds of the face.
     * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
     *
@@ -125,14 +117,38 @@ public final class Face {
     *             if bounds is {@code null},
     *             or if the confidence is not in the range of
     *             {@value #SCORE_MIN}-{@value #SCORE_MAX}.
     *
     * @hide
     */
    public Face(Rect bounds, int score) {
        this(bounds, score, ID_UNSUPPORTED,
    public Face(@NonNull Rect bounds, int score) {
        init(bounds, score, ID_UNSUPPORTED,
                /*leftEyePosition*/null, /*rightEyePosition*/null, /*mouthPosition*/null);
    }

    /**
     * Initialize the object (shared by constructors).
     */
    private void init(@NonNull Rect bounds, int score, int id,
            @Nullable Point leftEyePosition, @Nullable Point rightEyePosition,
            @Nullable Point mouthPosition) {
        checkNotNull("bounds", bounds);
        if (score < SCORE_MIN || score > SCORE_MAX) {
            throw new IllegalArgumentException("Confidence out of range");
        } else if (id < 0 && id != ID_UNSUPPORTED) {
            throw new IllegalArgumentException("Id out of range");
        }
        if (id == ID_UNSUPPORTED) {
            checkNull("leftEyePosition", leftEyePosition);
            checkNull("rightEyePosition", rightEyePosition);
            checkNull("mouthPosition", mouthPosition);
        }

        mBounds = bounds;
        mScore = score;
        mId = id;
        mLeftEye = leftEyePosition;
        mRightEye = rightEyePosition;
        mMouth = mouthPosition;
    }

    /**
     * Bounds of the face.
     *