1 /* 2 * Copyright (C) 2019 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 com.android.car; 18 19 import android.annotation.Nullable; 20 import android.car.occupantawareness.DriverMonitoringDetection; 21 import android.car.occupantawareness.GazeDetection; 22 import android.car.occupantawareness.OccupantAwarenessDetection; 23 import android.car.occupantawareness.OccupantAwarenessDetection.ConfidenceLevel; 24 import android.car.occupantawareness.Point3D; 25 import android.car.occupantawareness.SystemStatusEvent; 26 import android.car.occupantawareness.SystemStatusEvent.DetectionTypeFlags; 27 import android.car.occupantawareness.SystemStatusEvent.SystemStatus; 28 import android.hardware.automotive.occupant_awareness.IOccupantAwareness; 29 import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus; 30 import android.util.Slog; 31 32 /*package*/ final class OccupantAwarenessUtils { 33 private static final String TAG = CarLog.tagFor(OccupantAwarenessUtils.class); 34 OccupantAwarenessUtils()35 private OccupantAwarenessUtils() {} 36 37 /** Converts status flags into to a SystemStatusEvent. */ convertToStatusEvent(int inputDetectionFlags, byte inputStatus)38 static SystemStatusEvent convertToStatusEvent(int inputDetectionFlags, byte inputStatus) { 39 // Parse the system status from the hardware layer. 40 @SystemStatus int outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_READY; 41 42 switch (inputStatus) { 43 case OccupantAwarenessStatus.READY: 44 outputStatus = SystemStatusEvent.SYSTEM_STATUS_READY; 45 break; 46 47 case OccupantAwarenessStatus.NOT_SUPPORTED: 48 outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_SUPPORTED; 49 break; 50 51 case OccupantAwarenessStatus.NOT_INITIALIZED: 52 outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_READY; 53 break; 54 55 case OccupantAwarenessStatus.FAILURE: 56 outputStatus = SystemStatusEvent.SYSTEM_STATUS_SYSTEM_FAILURE; 57 break; 58 59 default: 60 Slog.e(TAG, "Invalid status code: " + inputStatus); 61 break; 62 } 63 64 // Parse the detection flags from the hardware layer. 65 @DetectionTypeFlags int outputFlags = SystemStatusEvent.DETECTION_TYPE_NONE; 66 67 switch (inputDetectionFlags) { 68 case IOccupantAwareness.CAP_NONE: 69 outputFlags = SystemStatusEvent.DETECTION_TYPE_NONE; 70 break; 71 72 case IOccupantAwareness.CAP_PRESENCE_DETECTION: 73 outputFlags = SystemStatusEvent.DETECTION_TYPE_PRESENCE; 74 break; 75 76 case IOccupantAwareness.CAP_GAZE_DETECTION: 77 outputFlags = SystemStatusEvent.DETECTION_TYPE_GAZE; 78 break; 79 80 case IOccupantAwareness.CAP_DRIVER_MONITORING_DETECTION: 81 outputFlags = SystemStatusEvent.DETECTION_TYPE_DRIVER_MONITORING; 82 break; 83 84 default: 85 Slog.e(TAG, "Invalid status code: " + inputDetectionFlags); 86 break; 87 } 88 89 return new SystemStatusEvent(outputStatus, outputFlags); 90 } 91 92 /** Converts an input confidence to a ConfidenceLevel. */ convertToConfidenceScore( @ndroid.hardware.automotive.occupant_awareness.ConfidenceLevel int inputConfidence)93 static @ConfidenceLevel int convertToConfidenceScore( 94 @android.hardware.automotive.occupant_awareness.ConfidenceLevel int inputConfidence) { 95 switch (inputConfidence) { 96 case android.hardware.automotive.occupant_awareness.ConfidenceLevel.MAX: 97 return OccupantAwarenessDetection.CONFIDENCE_LEVEL_MAX; 98 99 case android.hardware.automotive.occupant_awareness.ConfidenceLevel.HIGH: 100 return OccupantAwarenessDetection.CONFIDENCE_LEVEL_HIGH; 101 102 case android.hardware.automotive.occupant_awareness.ConfidenceLevel.LOW: 103 return OccupantAwarenessDetection.CONFIDENCE_LEVEL_LOW; 104 105 case android.hardware.automotive.occupant_awareness.ConfidenceLevel.NONE: 106 default: 107 return OccupantAwarenessDetection.CONFIDENCE_LEVEL_NONE; 108 } 109 } 110 111 /** 112 * Converts an input point to a Point3D. Returns null if the source vector was null or empty. 113 */ convertToPoint3D(@ullable double[] vector)114 static Point3D convertToPoint3D(@Nullable double[] vector) { 115 if (vector != null && vector.length == 3) { 116 return new Point3D(vector[0], vector[1], vector[2]); 117 } else { 118 return null; 119 } 120 } 121 122 /** Converts an input timestamp to milliseconds since boot. */ convertTimestamp(long inputTimestamp)123 static long convertTimestamp(long inputTimestamp) { 124 return inputTimestamp; 125 } 126 127 /** 128 * Converts an input @android.hardware.automotive.occupant_awareness.Role to a 129 * VehicleOccupantRole. 130 */ convertToRole(int inputRole)131 static @OccupantAwarenessDetection.VehicleOccupantRole int convertToRole(int inputRole) { 132 if (inputRole == android.hardware.automotive.occupant_awareness.Role.INVALID 133 || inputRole == android.hardware.automotive.occupant_awareness.Role.UNKNOWN) { 134 return OccupantAwarenessDetection.VEHICLE_OCCUPANT_NONE; 135 } else if (inputRole == android.hardware.automotive.occupant_awareness.Role.ALL_OCCUPANTS) { 136 return OccupantAwarenessDetection.VEHICLE_OCCUPANT_ALL_OCCUPANTS; 137 } 138 139 int outputRole = OccupantAwarenessDetection.VEHICLE_OCCUPANT_NONE; 140 141 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.DRIVER) > 0) { 142 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_DRIVER; 143 } 144 145 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.FRONT_PASSENGER) > 0) { 146 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_FRONT_PASSENGER; 147 } 148 149 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_LEFT) 150 > 0) { 151 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_LEFT; 152 } 153 154 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_CENTER) 155 > 0) { 156 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_CENTER; 157 } 158 159 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_RIGHT) 160 > 0) { 161 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_RIGHT; 162 } 163 164 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_LEFT) 165 > 0) { 166 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_LEFT; 167 } 168 169 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_CENTER) 170 > 0) { 171 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_CENTER; 172 } 173 174 if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_RIGHT) 175 > 0) { 176 outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_RIGHT; 177 } 178 179 return outputRole; 180 } 181 182 /** Converts an input detection to a GazeDetection. */ convertToGazeDetection( android.hardware.automotive.occupant_awareness.GazeDetection inputDetection)183 static GazeDetection convertToGazeDetection( 184 android.hardware.automotive.occupant_awareness.GazeDetection inputDetection) { 185 186 return new GazeDetection( 187 convertToConfidenceScore(inputDetection.gazeConfidence), 188 convertToPoint3D(inputDetection.headPosition), 189 convertToPoint3D(inputDetection.headPosition), 190 convertToPoint3D(inputDetection.headAngleUnitVector), 191 convertToPoint3D(inputDetection.gazeAngleUnitVector), 192 inputDetection.gazeTarget, 193 inputDetection.timeOnTargetMillis); 194 } 195 196 /** Converts an input detection to a DriverMonitoringDetection. */ convertToDriverMonitoringDetection( android.hardware.automotive.occupant_awareness.DriverMonitoringDetection inputDetection)197 static DriverMonitoringDetection convertToDriverMonitoringDetection( 198 android.hardware.automotive.occupant_awareness.DriverMonitoringDetection 199 inputDetection) { 200 return new DriverMonitoringDetection( 201 convertToConfidenceScore(inputDetection.confidenceScore), 202 inputDetection.isLookingOnRoad, 203 inputDetection.gazeDurationMillis); 204 } 205 206 /** Converts a PresenceDetection to a boolean indicating if an occupant was present. */ convertToPresence( android.hardware.automotive.occupant_awareness.PresenceDetection inputDetection)207 static boolean convertToPresence( 208 android.hardware.automotive.occupant_awareness.PresenceDetection inputDetection) { 209 return inputDetection.isOccupantDetected; 210 } 211 212 /** Converts an OccupantDetection to OccupantAwarenessDetection. */ convertToDetectionEvent( long timestamp, android.hardware.automotive.occupant_awareness.OccupantDetection inputDetection)213 static OccupantAwarenessDetection convertToDetectionEvent( 214 long timestamp, 215 android.hardware.automotive.occupant_awareness.OccupantDetection inputDetection) { 216 // Populate presence, if data is available for this frame. 217 boolean isPresent = false; 218 if (inputDetection.presenceData != null && inputDetection.presenceData.length > 0) { 219 isPresent = convertToPresence(inputDetection.presenceData[0]); 220 } 221 222 // Populate gaze, if data is available for this frame. 223 GazeDetection gazeDetection = null; 224 if (inputDetection.gazeData != null && inputDetection.gazeData.length > 0) { 225 gazeDetection = convertToGazeDetection(inputDetection.gazeData[0]); 226 } 227 228 // Populate driver monitoring, if data is available for this frame. 229 DriverMonitoringDetection driverMonitoringDetection = null; 230 if (inputDetection.attentionData != null && inputDetection.attentionData.length > 0) { 231 driverMonitoringDetection = 232 convertToDriverMonitoringDetection(inputDetection.attentionData[0]); 233 } 234 235 return new OccupantAwarenessDetection( 236 convertToRole(inputDetection.role), 237 timestamp, 238 isPresent, 239 gazeDetection, 240 driverMonitoringDetection); 241 } 242 } 243