CarValue.java
/*
* Copyright 2021 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 androidx.car.app.hardware.common;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.car.app.annotations.CarProtocol;
import androidx.car.app.annotations.RequiresCarApi;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Objects;
/**
* A data value object returned from car hardware with associated metadata including status,
* timestamp, and the actual value.
*
* @param <T> data type which is returned by the {@link CarValue}
*/
@CarProtocol
@RequiresCarApi(3)
public final class CarValue<T> {
/**
* Defines the possible status codes when trying to access car hardware properties, sensors,
* and actions.
*
* @hide
*/
@IntDef({
STATUS_UNKNOWN,
STATUS_SUCCESS,
STATUS_UNIMPLEMENTED,
STATUS_UNAVAILABLE,
})
@Retention(RetentionPolicy.SOURCE)
@RestrictTo(LIBRARY)
public @interface StatusCode {
}
/**
* {@link CarValue} has unknown status.
*/
@StatusCode
public static final int STATUS_UNKNOWN = 0;
/**
* {@link CarValue} was obtained successfully.
*/
@StatusCode
public static final int STATUS_SUCCESS = 1;
/**
* {@link CarValue} attempted for unimplemented property, sensor, or action.
*
* <p>For example, the car hardware might not be able to return a value such as speed or
* energy level and will set the status to this value.
*/
@StatusCode
public static final int STATUS_UNIMPLEMENTED = 2;
/**
* {@link CarValue} attempted for unavailable property, sensor, or action.
*
* <p>For example, the car hardware might not be able to return a value such as climate at the
* current time because the engine is off and will set the status to this value.
*/
@StatusCode
public static final int STATUS_UNAVAILABLE = 3;
@Keep
@Nullable
private final T mValue;
@Keep
private final long mTimestampMillis;
@Keep
@StatusCode
private final int mStatus;
private static <T> CarValue<T> unimplemented() {
return new CarValue<>(null, 0, CarValue.STATUS_UNIMPLEMENTED);
}
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<Integer> UNIMPLEMENTED_INTEGER = unimplemented();
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<Boolean> UNIMPLEMENTED_BOOLEAN = unimplemented();
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<Float> UNIMPLEMENTED_FLOAT = unimplemented();
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<String> UNIMPLEMENTED_STRING = unimplemented();
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<List<Float>> UNIMPLEMENTED_FLOAT_LIST = unimplemented();
/** @hide */
@RestrictTo(LIBRARY)
public static final CarValue<List<Integer>> UNIMPLEMENTED_INTEGER_LIST = unimplemented();
/**
* Returns a the data value or {@code null} if the status is not successful.
*
* @see #getStatus
*/
@Nullable
public T getValue() {
return mValue;
}
/**
* Returns the time in milliseconds at which the event happened.
*
* <p>For a given property, sensor, or action, each new value's timestamp should be
* monotonically increasing using the same time base as SystemClock.elapsedRealtime().
*/
public long getTimestampMillis() {
return mTimestampMillis;
}
/**
* Returns the status of this particular result such as success, unavailable, or unimplemented.
*/
@StatusCode
public int getStatus() {
return mStatus;
}
@Override
@NonNull
public String toString() {
return "[value: "
+ mValue
+ ", timestamp: "
+ mTimestampMillis
+ ", Status: "
+ mStatus
+ "]";
}
@Override
public int hashCode() {
return Objects.hash(mValue, mTimestampMillis, mStatus);
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof CarValue<?>)) {
return false;
}
CarValue<?> otherCarValue = (CarValue<?>) other;
return Objects.equals(mValue, otherCarValue.mValue)
&& mTimestampMillis == otherCarValue.mTimestampMillis
&& mStatus == otherCarValue.mStatus;
}
/**
* Constructs a new instance of a {@link CarValue}.
*
* @param value data to be returned with the result
* @param timestampMillis the time in milliseconds when the value was generated (see
* {@link #getTimestampMillis})
* @param status the status code associated with this value
*/
public CarValue(@Nullable T value, long timestampMillis, @StatusCode int status) {
mValue = value;
mTimestampMillis = timestampMillis;
mStatus = status;
}
/** Constructs an empty instance, used by serialization code. */
private CarValue() {
mValue = null;
mTimestampMillis = 0;
mStatus = STATUS_UNKNOWN;
}
}