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.experimental;
18 
19 import android.annotation.FloatRange;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import com.android.internal.util.Preconditions;
24 
25 import java.util.Objects;
26 
27 /**
28  * Event about a change in the driver's distraction.
29  *
30  * @hide
31  */
32 public class DriverDistractionChangeEvent implements Parcelable {
33 
34     private final long mElapsedRealtimeTimestamp;
35 
36     @FloatRange(from = 0.0f, to = 1.0f)
37     private final float mAwarenessPercentage;
38 
39     /**
40      * Creator for {@link Parcelable}.
41      */
42     public static final Parcelable.Creator<DriverDistractionChangeEvent> CREATOR =
43             new Parcelable.Creator<DriverDistractionChangeEvent>() {
44                 public DriverDistractionChangeEvent createFromParcel(Parcel in) {
45                     return new DriverDistractionChangeEvent(in);
46                 }
47 
48                 public DriverDistractionChangeEvent[] newArray(int size) {
49                     return new DriverDistractionChangeEvent[size];
50                 }
51             };
52 
53 
DriverDistractionChangeEvent(Builder builder)54     private DriverDistractionChangeEvent(Builder builder) {
55         mElapsedRealtimeTimestamp = builder.mElapsedRealtimeTimestamp;
56         mAwarenessPercentage = builder.mAwarenessPercentage;
57     }
58 
59     /**
60      * Parcelable constructor.
61      */
DriverDistractionChangeEvent(Parcel in)62     private DriverDistractionChangeEvent(Parcel in) {
63         mElapsedRealtimeTimestamp = in.readLong();
64         mAwarenessPercentage = in.readFloat();
65     }
66 
67     /**
68      * Returns the timestamp for the change event, in milliseconds since boot, including time spent
69      * in sleep.
70      */
getElapsedRealtimeTimestamp()71     public long getElapsedRealtimeTimestamp() {
72         return mElapsedRealtimeTimestamp;
73     }
74 
75     /**
76      * Returns the current driver driver awareness value as a percentage of the required awareness
77      * of the situation.
78      * <ul>
79      * <li>0% indicates that the driver has no situational awareness of the surrounding environment.
80      * <li>100% indicates that the driver has the target amount of situational awareness
81      * necessary for the current driving environment.
82      * </ul>
83      *
84      * <p>If the required awareness of the current driving environment is 0, such as when the car
85      * is in park, then the awareness percentage will be 100%.
86      *
87      * <p>Since this is a percentage, 0% will always correspond with a 0.0 driver awareness level.
88      * However, the rest of the range will get squeezed or compressed in time depending on the
89      * required awareness of the situation.
90      *
91      * <p>For example, suppose that driver awareness can go from 1.0 to 0.0 with 6 seconds of
92      * eyes-off-road time and that the driver has just started looking off-road. Now consider
93      * these two scenarios:
94      * <ol>
95      * <li>Scenario 1: The required awareness of the driving environment is 1.0:
96      * After 0 seconds: 100% awareness
97      * After 3 seconds: 50% awareness
98      * After 4.5 seconds: 25% awareness
99      * After 6 seconds: 0% awareness
100      * <li>Scenario 2: The required awareness of the driving environment is 0.5:
101      * After 0 seconds: 100% awareness
102      * After 3 seconds: 100% awareness
103      * After 4.5 seconds: 50% awareness
104      * After 6 seconds: 0% awareness
105      * </ol>
106      */
107     @FloatRange(from = 0.0f, to = 1.0f)
getAwarenessPercentage()108     public float getAwarenessPercentage() {
109         return mAwarenessPercentage;
110     }
111 
112     @Override
describeContents()113     public int describeContents() {
114         return 0;
115     }
116 
117     @Override
writeToParcel(Parcel dest, int flags)118     public void writeToParcel(Parcel dest, int flags) {
119         dest.writeLong(mElapsedRealtimeTimestamp);
120         dest.writeFloat(mAwarenessPercentage);
121     }
122 
123     @Override
equals(Object o)124     public boolean equals(Object o) {
125         if (this == o) {
126             return true;
127         }
128         if (!(o instanceof DriverDistractionChangeEvent)) {
129             return false;
130         }
131         DriverDistractionChangeEvent that = (DriverDistractionChangeEvent) o;
132         return mElapsedRealtimeTimestamp == that.mElapsedRealtimeTimestamp
133                 && Float.compare(that.mAwarenessPercentage, mAwarenessPercentage) == 0;
134     }
135 
136     @Override
hashCode()137     public int hashCode() {
138         return Objects.hash(mElapsedRealtimeTimestamp, mAwarenessPercentage);
139     }
140 
141     @Override
toString()142     public String toString() {
143         return String.format(
144                 "DriverDistractionChangeEvent{mElapsedRealtimeTimestamp=%s, "
145                         + "mAwarenessPercentage=%s}",
146                 mElapsedRealtimeTimestamp, mAwarenessPercentage);
147     }
148 
149 
150     /**
151      * Builder for {@link DriverDistractionChangeEvent}.
152      */
153     public static class Builder {
154         private long mElapsedRealtimeTimestamp;
155 
156         @FloatRange(from = 0.0f, to = 1.0f)
157         private float mAwarenessPercentage;
158 
159         /**
160          * Set the timestamp for the change event, in milliseconds since boot, including time spent
161          * in sleep.
162          */
setElapsedRealtimeTimestamp(long timestamp)163         public Builder setElapsedRealtimeTimestamp(long timestamp) {
164             mElapsedRealtimeTimestamp = timestamp;
165             return this;
166         }
167 
168         /**
169          * Set the current driver driver awareness value as a percentage of the required awareness
170          * of the situation.
171          */
setAwarenessPercentage( @loatRangefrom = 0.0f, to = 1.0f) float awarenessPercentage)172         public Builder setAwarenessPercentage(
173                 @FloatRange(from = 0.0f, to = 1.0f) float awarenessPercentage) {
174             Preconditions.checkArgument(
175                     awarenessPercentage >= 0 && awarenessPercentage <= 1,
176                     "awarenessPercentage must be between 0 and 1");
177             mAwarenessPercentage = awarenessPercentage;
178             return this;
179         }
180 
181         /**
182          * Build and return the {@link DriverDistractionChangeEvent} object.
183          */
build()184         public DriverDistractionChangeEvent build() {
185             return new DriverDistractionChangeEvent(this);
186         }
187 
188     }
189 
190 }
191