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

Commit b779ac1e authored by Igor Murashkin's avatar Igor Murashkin
Browse files

camera2: Update Face class.

- Move Face to be outer class. Enables Parcelable-izing it later.
- Add static public constants for field values.
- Add @hide constructors.
- Rename methods returning Point to have Position suffix.
- Add new key android.statistics.faces (CaptureResult#STATISTICS_FACES)

Bug: 10360518
Bug: 10549293
Change-Id: I067f06f0426114b2c3a3266ca7e00e6cb1d89046
parent e850c973
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -11129,6 +11129,7 @@ package android.hardware.camera2 {
    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE;
    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP;
    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_IDS;
    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_LANDMARKS;
@@ -11144,14 +11145,16 @@ package android.hardware.camera2 {
    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
  }
  public static class CaptureResult.Face {
    ctor public CaptureResult.Face();
  public final class Face {
    method public android.graphics.Rect getBounds();
    method public int getId();
    method public android.graphics.Point getLeftEye();
    method public android.graphics.Point getMouth();
    method public android.graphics.Point getRightEye();
    method public android.graphics.Point getLeftEyePosition();
    method public android.graphics.Point getMouthPosition();
    method public android.graphics.Point getRightEyePosition();
    method public int getScore();
    field public static final int ID_UNSUPPORTED = -1; // 0xffffffff
    field public static final int SCORE_MAX = 100; // 0x64
    field public static final int SCORE_MIN = 1; // 0x1
  }
  public final class Rational {
+15 −83
Original line number Diff line number Diff line
@@ -51,89 +51,6 @@ public final class CaptureResult extends CameraMetadata {
        return mResults.get(key);
    }

    /**
     * Describes a face detected in an image.
     */
    public static class Face {

        /**
         * <p>Bounds of the face. A rectangle relative to the sensor's
         * {@link CameraProperties#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
         * representing the top-left corner of the active array rectangle.</p>
         */
        public Rect getBounds() {
            return mBounds;
        }

        /** <p>The confidence level for the detection of the face. The range is 1 to
         * 100. 100 is the highest confidence.</p>
         *
         * <p>Depending on the device, even very low-confidence faces may be
         * listed, so applications should filter out faces with low confidence,
         * depending on the use case. For a typical point-and-shoot camera
         * application that wishes to display rectangles around detected faces,
         * filtering out faces with confidence less than 50 is recommended.</p>
         *
         */
        public int getScore() {
            return mScore;
        }

        /**
         * An unique id per face while the face is visible to the tracker. If
         * the face leaves the field-of-view and comes back, it will get a new
         * id. This is an optional field, may not be supported on all devices.
         * If not supported, id will always be set to -1. The optional fields
         * are supported as a set. Either they are all valid, or none of them
         * are.
         */
        public int getId() {
            return mId;
        }

        /**
         * The coordinates of the center of the left eye. The coordinates are in
         * the same space as the ones for {@link #getBounds}. This is an
         * optional field, may not be supported on all devices. If not
         * supported, the value will always be set to null. The optional fields
         * are supported as a set. Either they are all valid, or none of them
         * are.
         */
        public Point getLeftEye() {
            return mLeftEye;
        }

        /**
         * The coordinates of the center of the right eye. The coordinates are
         * in the same space as the ones for {@link #getBounds}.This is an
         * optional field, may not be supported on all devices. If not
         * supported, the value will always be set to null. The optional fields
         * are supported as a set. Either they are all valid, or none of them
         * are.
         */
        public Point getRightEye() {
            return mRightEye;
        }

        /**
         * The coordinates of the center of the mouth.  The coordinates are in
         * the same space as the ones for {@link #getBounds}. This is an optional
         * field, may not be supported on all devices. If not supported, the
         * value will always be set to null. The optional fields are supported
         * as a set. Either they are all valid, or none of them are.
         */
        public Point getMouth() {
            return mMouth;
        }

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

    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
     * The key entries below this point are generated from metadata
     * definitions in /system/media/camera/docs. Do not modify by hand or
@@ -1003,4 +920,19 @@ public final class CaptureResult extends CameraMetadata {
    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
     * End generated code
     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/

    /**
     * <p>
     * List of the {@link Face Faces} detected through camera face detection
     * in this result.
     * </p>
     * <p>
     * Only available if {@link #STATISTICS_FACE_DETECT_MODE} {@code !=}
     * {@link CameraMetadata#STATISTICS_FACE_DETECT_MODE_OFF OFF}.
     * </p>
     *
     * @see Face
     */
    public static final Key<Face[]> STATISTICS_FACES =
            new Key<Face[]>("android.statistics.faces", Face[].class);
}
+252 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package android.hardware.camera2;

import android.graphics.Point;
import android.graphics.Rect;

/**
 * Describes a face detected in an image.
 */
public final class Face {

    /**
     * The ID is {@code -1} when the optional set of fields is unsupported.
     *
     * @see Face#Face(Rect, int)
     * @see #getId()
     */
    public static final int ID_UNSUPPORTED = -1;

    /**
     * The minimum possible value for the confidence level.
     *
     * @see #getScore()
     */
    public static final int SCORE_MIN = 1;

    /**
     * The maximum possible value for the confidence level.
     *
     * @see #getScore()
     */
    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;

    /**
     * Create a new face with all fields set.
     *
     * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
     * rightEyePosition, and mouthPosition may be independently null or not-null.</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.
     * @param leftEyePosition The position of the left eye.
     * @param rightEyePosition The position of the right eye.
     * @param mouthPosition The position of the mouth.
     *
     * @throws IllegalArgumentException
     *             if bounds is {@code null},
     *             or if the confidence is not in the range of
     *             {@value #SCORE_MIN}-{@value #SCORE_MAX},
     *             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;
    }

    /**
     * Create a new face without the optional fields.
     *
     * <p>The id, leftEyePosition, rightEyePosition, and mouthPosition are considered optional.
     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
     *
     * @param bounds Bounds of the face.
     * @param score Confidence level between {@value #SCORE_MIN}-{@value #SCORE_MAX}.
     *
     * @throws IllegalArgumentException
     *             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,
                /*leftEyePosition*/null, /*rightEyePosition*/null, /*mouthPosition*/null);
    }

    /**
     * Bounds of the face.
     *
     * <p>A rectangle relative to the sensor's
     * {@link CameraProperties#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
     * representing the top-left corner of the active array rectangle.</p>
     *
     * <p>There is no constraints on the the Rectangle value other than it
     * is not-{@code null}.</p>
     */
    public Rect getBounds() {
        return mBounds;
    }

    /**
     * The confidence level for the detection of the face.
     *
     * <p>The range is {@value #SCORE_MIN} to {@value #SCORE_MAX}.
     * {@value #SCORE_MAX} is the highest confidence.</p>
     *
     * <p>Depending on the device, even very low-confidence faces may be
     * listed, so applications should filter out faces with low confidence,
     * depending on the use case. For a typical point-and-shoot camera
     * application that wishes to display rectangles around detected faces,
     * filtering out faces with confidence less than half of {@value #SCORE_MAX}
     * is recommended.</p>
     *
     * @see #SCORE_MAX
     * @see #SCORE_MIN
     */
    public int getScore() {
        return mScore;
    }

    /**
     * An unique id per face while the face is visible to the tracker.
     *
     * <p>
     * If the face leaves the field-of-view and comes back, it will get a new
     * id.</p>
     *
     * <p>This is an optional field, may not be supported on all devices.
     * If the id is {@value #ID_UNSUPPORTED} then the leftEyePosition, rightEyePosition, and
     * mouthPositions are guaranteed to be {@code null}. Otherwise, each of leftEyePosition,
     * rightEyePosition, and mouthPosition may be independently null or not-null.</p>
     *
     * <p>This value will either be {@value #ID_UNSUPPORTED} or
     * otherwise greater than {@code 0}.</p>
     *
     * @see #ID_UNSUPPORTED
     */
    public int getId() {
        return mId;
    }

    /**
     * The coordinates of the center of the left eye.
     *
     * <p>The coordinates are in
     * the same space as the ones for {@link #getBounds}. This is an
     * optional field, may not be supported on all devices. If not
     * supported, the value will always be set to null.
     * This value will  always be null only if {@link #getId()} returns
     * {@value #ID_UNSUPPORTED}.</p>
     *
     * @return The left eye position, or {@code null} if unknown.
     */
    public Point getLeftEyePosition() {
        return mLeftEye;
    }

    /**
     * The coordinates of the center of the right eye.
     *
     * <p>The coordinates are
     * in the same space as the ones for {@link #getBounds}.This is an
     * optional field, may not be supported on all devices. If not
     * supported, the value will always be set to null.
     * This value will  always be null only if {@link #getId()} returns
     * {@value #ID_UNSUPPORTED}.</p>
     *
     * @return The right eye position, or {@code null} if unknown.
     */
    public Point getRightEyePosition() {
        return mRightEye;
    }

    /**
     * The coordinates of the center of the mouth.
     *
     * <p>The coordinates are in
     * the same space as the ones for {@link #getBounds}. This is an optional
     * field, may not be supported on all devices. If not
     * supported, the value will always be set to null.
     * This value will  always be null only if {@link #getId()} returns
     * {@value #ID_UNSUPPORTED}.</p> them are.
     * </p>
     *
     * @return The mouth position, or {@code null} if unknown.
     */
    public Point getMouthPosition() {
        return mMouth;
    }

    /**
     * Represent the Face as a string for debugging purposes.
     */
    @Override
    public String toString() {
        return String.format("{ bounds: %s, score: %s, id: %d, " +
                "leftEyePosition: %s, rightEyePosition: %s, mouthPosition: %s }",
                mBounds, mScore, mId, mLeftEye, mRightEye, mMouth);
    }

    private static void checkNotNull(String name, Object obj) {
        if (obj == null) {
            throw new IllegalArgumentException(name + " was required, but it was null");
        }
    }

    private static void checkNull(String name, Object obj) {
        if (obj != null) {
            throw new IllegalArgumentException(name + " was required to be null, but it wasn't");
        }
    }
}