blob: ab092092399554995d1d67d8f137201de025ef77 [file] [log] [blame]
/*
* Copyright (C) 2019 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 com.android.car;
import android.annotation.Nullable;
import android.car.occupantawareness.DriverMonitoringDetection;
import android.car.occupantawareness.GazeDetection;
import android.car.occupantawareness.OccupantAwarenessDetection;
import android.car.occupantawareness.OccupantAwarenessDetection.ConfidenceLevel;
import android.car.occupantawareness.Point3D;
import android.car.occupantawareness.SystemStatusEvent;
import android.car.occupantawareness.SystemStatusEvent.DetectionTypeFlags;
import android.car.occupantawareness.SystemStatusEvent.SystemStatus;
import android.hardware.automotive.occupant_awareness.IOccupantAwareness;
import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus;
import android.util.Slog;
/*package*/ final class OccupantAwarenessUtils {
private static final String TAG = CarLog.tagFor(OccupantAwarenessUtils.class);
private OccupantAwarenessUtils() {}
/** Converts status flags into to a SystemStatusEvent. */
static SystemStatusEvent convertToStatusEvent(int inputDetectionFlags, byte inputStatus) {
// Parse the system status from the hardware layer.
@SystemStatus int outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_READY;
switch (inputStatus) {
case OccupantAwarenessStatus.READY:
outputStatus = SystemStatusEvent.SYSTEM_STATUS_READY;
break;
case OccupantAwarenessStatus.NOT_SUPPORTED:
outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_SUPPORTED;
break;
case OccupantAwarenessStatus.NOT_INITIALIZED:
outputStatus = SystemStatusEvent.SYSTEM_STATUS_NOT_READY;
break;
case OccupantAwarenessStatus.FAILURE:
outputStatus = SystemStatusEvent.SYSTEM_STATUS_SYSTEM_FAILURE;
break;
default:
Slog.e(TAG, "Invalid status code: " + inputStatus);
break;
}
// Parse the detection flags from the hardware layer.
@DetectionTypeFlags int outputFlags = SystemStatusEvent.DETECTION_TYPE_NONE;
switch (inputDetectionFlags) {
case IOccupantAwareness.CAP_NONE:
outputFlags = SystemStatusEvent.DETECTION_TYPE_NONE;
break;
case IOccupantAwareness.CAP_PRESENCE_DETECTION:
outputFlags = SystemStatusEvent.DETECTION_TYPE_PRESENCE;
break;
case IOccupantAwareness.CAP_GAZE_DETECTION:
outputFlags = SystemStatusEvent.DETECTION_TYPE_GAZE;
break;
case IOccupantAwareness.CAP_DRIVER_MONITORING_DETECTION:
outputFlags = SystemStatusEvent.DETECTION_TYPE_DRIVER_MONITORING;
break;
default:
Slog.e(TAG, "Invalid status code: " + inputDetectionFlags);
break;
}
return new SystemStatusEvent(outputStatus, outputFlags);
}
/** Converts an input confidence to a ConfidenceLevel. */
static @ConfidenceLevel int convertToConfidenceScore(
@android.hardware.automotive.occupant_awareness.ConfidenceLevel int inputConfidence) {
switch (inputConfidence) {
case android.hardware.automotive.occupant_awareness.ConfidenceLevel.MAX:
return OccupantAwarenessDetection.CONFIDENCE_LEVEL_MAX;
case android.hardware.automotive.occupant_awareness.ConfidenceLevel.HIGH:
return OccupantAwarenessDetection.CONFIDENCE_LEVEL_HIGH;
case android.hardware.automotive.occupant_awareness.ConfidenceLevel.LOW:
return OccupantAwarenessDetection.CONFIDENCE_LEVEL_LOW;
case android.hardware.automotive.occupant_awareness.ConfidenceLevel.NONE:
default:
return OccupantAwarenessDetection.CONFIDENCE_LEVEL_NONE;
}
}
/**
* Converts an input point to a Point3D. Returns null if the source vector was null or empty.
*/
static Point3D convertToPoint3D(@Nullable double[] vector) {
if (vector != null && vector.length == 3) {
return new Point3D(vector[0], vector[1], vector[2]);
} else {
return null;
}
}
/** Converts an input timestamp to milliseconds since boot. */
static long convertTimestamp(long inputTimestamp) {
return inputTimestamp;
}
/**
* Converts an input @android.hardware.automotive.occupant_awareness.Role to a
* VehicleOccupantRole.
*/
static @OccupantAwarenessDetection.VehicleOccupantRole int convertToRole(int inputRole) {
if (inputRole == android.hardware.automotive.occupant_awareness.Role.INVALID
|| inputRole == android.hardware.automotive.occupant_awareness.Role.UNKNOWN) {
return OccupantAwarenessDetection.VEHICLE_OCCUPANT_NONE;
} else if (inputRole == android.hardware.automotive.occupant_awareness.Role.ALL_OCCUPANTS) {
return OccupantAwarenessDetection.VEHICLE_OCCUPANT_ALL_OCCUPANTS;
}
int outputRole = OccupantAwarenessDetection.VEHICLE_OCCUPANT_NONE;
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.DRIVER) > 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_DRIVER;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.FRONT_PASSENGER) > 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_FRONT_PASSENGER;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_LEFT)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_LEFT;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_CENTER)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_CENTER;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_2_PASSENGER_RIGHT)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_2_PASSENGER_RIGHT;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_LEFT)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_LEFT;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_CENTER)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_CENTER;
}
if ((inputRole & android.hardware.automotive.occupant_awareness.Role.ROW_3_PASSENGER_RIGHT)
> 0) {
outputRole |= OccupantAwarenessDetection.VEHICLE_OCCUPANT_ROW_3_PASSENGER_RIGHT;
}
return outputRole;
}
/** Converts an input detection to a GazeDetection. */
static GazeDetection convertToGazeDetection(
android.hardware.automotive.occupant_awareness.GazeDetection inputDetection) {
return new GazeDetection(
convertToConfidenceScore(inputDetection.gazeConfidence),
convertToPoint3D(inputDetection.headPosition),
convertToPoint3D(inputDetection.headPosition),
convertToPoint3D(inputDetection.headAngleUnitVector),
convertToPoint3D(inputDetection.gazeAngleUnitVector),
inputDetection.gazeTarget,
inputDetection.timeOnTargetMillis);
}
/** Converts an input detection to a DriverMonitoringDetection. */
static DriverMonitoringDetection convertToDriverMonitoringDetection(
android.hardware.automotive.occupant_awareness.DriverMonitoringDetection
inputDetection) {
return new DriverMonitoringDetection(
convertToConfidenceScore(inputDetection.confidenceScore),
inputDetection.isLookingOnRoad,
inputDetection.gazeDurationMillis);
}
/** Converts a PresenceDetection to a boolean indicating if an occupant was present. */
static boolean convertToPresence(
android.hardware.automotive.occupant_awareness.PresenceDetection inputDetection) {
return inputDetection.isOccupantDetected;
}
/** Converts an OccupantDetection to OccupantAwarenessDetection. */
static OccupantAwarenessDetection convertToDetectionEvent(
long timestamp,
android.hardware.automotive.occupant_awareness.OccupantDetection inputDetection) {
// Populate presence, if data is available for this frame.
boolean isPresent = false;
if (inputDetection.presenceData != null && inputDetection.presenceData.length > 0) {
isPresent = convertToPresence(inputDetection.presenceData[0]);
}
// Populate gaze, if data is available for this frame.
GazeDetection gazeDetection = null;
if (inputDetection.gazeData != null && inputDetection.gazeData.length > 0) {
gazeDetection = convertToGazeDetection(inputDetection.gazeData[0]);
}
// Populate driver monitoring, if data is available for this frame.
DriverMonitoringDetection driverMonitoringDetection = null;
if (inputDetection.attentionData != null && inputDetection.attentionData.length > 0) {
driverMonitoringDetection =
convertToDriverMonitoringDetection(inputDetection.attentionData[0]);
}
return new OccupantAwarenessDetection(
convertToRole(inputDetection.role),
timestamp,
isPresent,
gazeDetection,
driverMonitoringDetection);
}
}