1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.car.occupantawareness;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import java.lang.annotation.Retention;
28 
29 /**
30  * Detection result for gaze detection for the respective {@link VehicleOccupantRole}.
31  *
32  * @hide
33  */
34 public final class GazeDetection implements Parcelable {
35 
36     /** A unknown gaze region, not otherwise specified. */
37     public static final int VEHICLE_REGION_UNKNOWN = 0;
38 
39     /** Center instrument cluster in front of the driver. */
40     public static final int VEHICLE_REGION_CENTER_INSTRUMENT_CLUSTER = 1;
41 
42     /** The rear-view mirror. */
43     public static final int VEHICLE_REGION_REAR_VIEW_MIRROR = 2;
44 
45     /** The left side mirror. */
46     public static final int VEHICLE_REGION_LEFT_SIDE_MIRROR = 3;
47 
48     /** The right side mirror. */
49     public static final int VEHICLE_REGION_RIGHT_SIDE_MIRROR = 4;
50 
51     /** The forward roadway. */
52     public static final int VEHICLE_REGION_FORWARD_ROADWAY = 5;
53 
54     /** Out-the-window to the right. */
55     public static final int VEHICLE_REGION_LEFT_ROADWAY = 6;
56 
57     /** Out-the-window to the right. */
58     public static final int VEHICLE_REGION_RIGHT_ROADWAY = 7;
59 
60     /** Center head-unit display. */
61     public static final int VEHICLE_REGION_HEAD_UNIT_DISPLAY = 8;
62 
63     /**
64      * Vehicle regions
65      *
66      * @hide
67      */
68     @Retention(SOURCE)
69     @IntDef({
70         VEHICLE_REGION_UNKNOWN,
71         VEHICLE_REGION_CENTER_INSTRUMENT_CLUSTER,
72         VEHICLE_REGION_REAR_VIEW_MIRROR,
73         VEHICLE_REGION_LEFT_SIDE_MIRROR,
74         VEHICLE_REGION_RIGHT_SIDE_MIRROR,
75         VEHICLE_REGION_FORWARD_ROADWAY,
76         VEHICLE_REGION_LEFT_ROADWAY,
77         VEHICLE_REGION_RIGHT_ROADWAY,
78         VEHICLE_REGION_HEAD_UNIT_DISPLAY
79     })
80     public @interface VehicleRegion {}
81 
82     /** {@link OccupantAwarenessDetection.ConfidenceLevel} for the gaze detection. */
83     @OccupantAwarenessDetection.ConfidenceLevel public final int confidenceLevel;
84 
85     /**
86      * Location of the subject's left eye, in millimeters.
87      *
88      * <p>Vehicle origin is defined as part of the Cabin Space API. All units in millimeters. +x is
89      * right (from driver perspective), +y is up, -z is forward.
90      *
91      * <p>May be {@code null} if the underlying detection system does not export eye position data.
92      */
93     public final @Nullable Point3D leftEyePosition;
94 
95     /**
96      * Location of the subject's right eye, in millimeters.
97      *
98      * <p>Vehicle origin is defined as part of the Cabin Space API. All units in millimeters. +x is
99      * right (from driver perspective), +y is up, -z is forward.
100      *
101      * <p>May be {@code null} if the underlying detection system does not export eye position data.
102      */
103     public final @Nullable Point3D rightEyePosition;
104 
105     /**
106      * Direction of the subject's head orientation, as a <a
107      * href="https://en.wikipedia.org/wiki/Unit_vector">unit-vector</a>.
108      *
109      * <p>May be {@code null} if the underlying system does not support head orientation vectors.
110      */
111     public final @Nullable Point3D headAngleUnitVector;
112 
113     /**
114      * Direction of the gaze angle, as a <a
115      * href="https://en.wikipedia.org/wiki/Unit_vector">unit-vector</a>.
116      *
117      * <p>May be {@code null} if the underlying system does not support vectors.
118      */
119     public final @Nullable Point3D gazeAngleUnitVector;
120 
121     /** {@link VehicleRegion} where the subject is currently looking. */
122     @VehicleRegion public final int gazeTarget;
123 
124     /** Duration on the current gaze target, in milliseconds. */
125     public final long durationOnTargetMillis;
126 
GazeDetection( @ccupantAwarenessDetection.ConfidenceLevel int confidenceLevel, @Nullable Point3D leftEyePosition, @Nullable Point3D rightEyePosition, @Nullable Point3D headAngleUnitVector, @Nullable Point3D gazeAngleUnitVector, @VehicleRegion int gazeTarget, long durationOnTargetMillis)127     public GazeDetection(
128             @OccupantAwarenessDetection.ConfidenceLevel int confidenceLevel,
129             @Nullable Point3D leftEyePosition,
130             @Nullable Point3D rightEyePosition,
131             @Nullable Point3D headAngleUnitVector,
132             @Nullable Point3D gazeAngleUnitVector,
133             @VehicleRegion int gazeTarget,
134             long durationOnTargetMillis) {
135 
136         this.confidenceLevel = confidenceLevel;
137         this.leftEyePosition = leftEyePosition;
138         this.rightEyePosition = rightEyePosition;
139         this.headAngleUnitVector = headAngleUnitVector;
140         this.gazeAngleUnitVector = gazeAngleUnitVector;
141         this.gazeTarget = gazeTarget;
142         this.durationOnTargetMillis = durationOnTargetMillis;
143     }
144 
145     @Override
describeContents()146     public int describeContents() {
147         return 0;
148     }
149 
150     @Override
writeToParcel(@onNull Parcel dest, int flags)151     public void writeToParcel(@NonNull Parcel dest, int flags) {
152         dest.writeInt(confidenceLevel);
153         dest.writeParcelable(leftEyePosition, flags);
154         dest.writeParcelable(rightEyePosition, flags);
155         dest.writeParcelable(headAngleUnitVector, flags);
156         dest.writeParcelable(gazeAngleUnitVector, flags);
157         dest.writeInt(gazeTarget);
158         dest.writeLong(durationOnTargetMillis);
159     }
160 
161     @Override
toString()162     public String toString() {
163         return "GazeDetection{"
164                 + "confidenceLevel=" + confidenceLevel
165                 + ", leftEyePosition=" + (leftEyePosition == null ? "(null)" : leftEyePosition)
166                 + ", rightEyePosition=" + (rightEyePosition == null ? "(null)" : rightEyePosition)
167                 + ", headAngleUnitVector="
168                 + (headAngleUnitVector == null ? "(null)" : headAngleUnitVector)
169                 + ", gazeAngleUnitVector="
170                 + (gazeAngleUnitVector == null ? "(null)" : gazeAngleUnitVector)
171                 + ", gazeTarget=" + gazeTarget
172                 + ", durationOnTargetMillis=" + durationOnTargetMillis
173                 + "}";
174     }
175 
176     public static final @NonNull Parcelable.Creator<GazeDetection> CREATOR =
177             new Parcelable.Creator<GazeDetection>() {
178                 public GazeDetection createFromParcel(Parcel in) {
179                     return new GazeDetection(in);
180                 }
181 
182                 public GazeDetection[] newArray(int size) {
183                     return new GazeDetection[size];
184                 }
185             };
186 
GazeDetection(Parcel in)187     private GazeDetection(Parcel in) {
188         confidenceLevel = in.readInt();
189         leftEyePosition = in.readParcelable(Point3D.class.getClassLoader());
190         rightEyePosition = in.readParcelable(Point3D.class.getClassLoader());
191         headAngleUnitVector = in.readParcelable(Point3D.class.getClassLoader());
192         gazeAngleUnitVector = in.readParcelable(Point3D.class.getClassLoader());
193         gazeTarget = in.readInt();
194         durationOnTargetMillis = in.readLong();
195     }
196 }
197