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