/*
 * Copyright 2018 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 android.os;

import android.annotation.SystemApi;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

Container for statsd dimension value information, corresponding to a stats_log.proto's DimensionValue. This consists of a field (an int representing a statsd atom field) and a value (which may be one of a number of types).

Only a single value is held, and it is necessarily one of the following types: String, int, long, boolean, float, or tuple (i.e. List of StatsDimensionsValue). The type of value held can be retrieved using getValueType(), which returns one of the following ints, depending on the type of value:

Alternatively, this can be determined using isValueType(int) with one of these constants as a parameter. The value itself can be retrieved using the correct get...Value() function for its type.

The field is always an int, and always exists; it can be obtained using getField().

@hide
/** * Container for statsd dimension value information, corresponding to a * stats_log.proto's DimensionValue. * * This consists of a field (an int representing a statsd atom field) * and a value (which may be one of a number of types). * * <p> * Only a single value is held, and it is necessarily one of the following types: * {@link String}, int, long, boolean, float, * or tuple (i.e. {@link List} of {@code StatsDimensionsValue}). * * The type of value held can be retrieved using {@link #getValueType()}, which returns one of the * following ints, depending on the type of value: * <ul> * <li>{@link #STRING_VALUE_TYPE}</li> * <li>{@link #INT_VALUE_TYPE}</li> * <li>{@link #LONG_VALUE_TYPE}</li> * <li>{@link #BOOLEAN_VALUE_TYPE}</li> * <li>{@link #FLOAT_VALUE_TYPE}</li> * <li>{@link #TUPLE_VALUE_TYPE}</li> * </ul> * Alternatively, this can be determined using {@link #isValueType(int)} with one of these constants * as a parameter. * The value itself can be retrieved using the correct get...Value() function for its type. * * <p> * The field is always an int, and always exists; it can be obtained using {@link #getField()}. * * * @hide */
@SystemApi public final class StatsDimensionsValue implements Parcelable { private static final String TAG = "StatsDimensionsValue"; // Values of the value type correspond to stats_log.proto's DimensionValue fields. // Keep constants in sync with services/include/android/os/StatsDimensionsValue.h.
Indicates that this holds a String.
/** Indicates that this holds a String. */
public static final int STRING_VALUE_TYPE = 2;
Indicates that this holds an int.
/** Indicates that this holds an int. */
public static final int INT_VALUE_TYPE = 3;
Indicates that this holds a long.
/** Indicates that this holds a long. */
public static final int LONG_VALUE_TYPE = 4;
Indicates that this holds a boolean.
/** Indicates that this holds a boolean. */
public static final int BOOLEAN_VALUE_TYPE = 5;
Indicates that this holds a float.
/** Indicates that this holds a float. */
public static final int FLOAT_VALUE_TYPE = 6;
Indicates that this holds a List of StatsDimensionsValues.
/** Indicates that this holds a List of StatsDimensionsValues. */
public static final int TUPLE_VALUE_TYPE = 7;
Value of a stats_log.proto DimensionsValue.field.
/** Value of a stats_log.proto DimensionsValue.field. */
private final int mField;
Type of stats_log.proto DimensionsValue.value, according to the VALUE_TYPEs above.
/** Type of stats_log.proto DimensionsValue.value, according to the VALUE_TYPEs above. */
private final int mValueType;
Value of a stats_log.proto DimensionsValue.value. String, Integer, Long, Boolean, Float, or StatsDimensionsValue[].
/** * Value of a stats_log.proto DimensionsValue.value. * String, Integer, Long, Boolean, Float, or StatsDimensionsValue[]. */
private final Object mValue; // immutable or array of immutables
Creates a StatsDimensionValue from a parcel.
@hide
/** * Creates a {@code StatsDimensionValue} from a parcel. * * @hide */
public StatsDimensionsValue(Parcel in) { mField = in.readInt(); mValueType = in.readInt(); mValue = readValueFromParcel(mValueType, in); }
Return the field, i.e. the tag of a statsd atom.
Returns:the field
/** * Return the field, i.e. the tag of a statsd atom. * * @return the field */
public int getField() { return mField; }
Retrieve the String held, if any.
Returns:the String held if getValueType() == STRING_VALUE_TYPE, null otherwise
/** * Retrieve the String held, if any. * * @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE}, * null otherwise */
public String getStringValue() { try { if (mValueType == STRING_VALUE_TYPE) return (String) mValue; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return null; }
Retrieve the int held, if any.
Returns:the int held if getValueType() == INT_VALUE_TYPE, 0 otherwise
/** * Retrieve the int held, if any. * * @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise */
public int getIntValue() { try { if (mValueType == INT_VALUE_TYPE) return (Integer) mValue; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return 0; }
Retrieve the long held, if any.
Returns:the long held if getValueType() == LONG_VALUE_TYPE, 0 otherwise
/** * Retrieve the long held, if any. * * @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise */
public long getLongValue() { try { if (mValueType == LONG_VALUE_TYPE) return (Long) mValue; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return 0; }
Retrieve the boolean held, if any.
Returns:the boolean held if getValueType() == BOOLEAN_VALUE_TYPE, false otherwise
/** * Retrieve the boolean held, if any. * * @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE}, * false otherwise */
public boolean getBooleanValue() { try { if (mValueType == BOOLEAN_VALUE_TYPE) return (Boolean) mValue; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return false; }
Retrieve the float held, if any.
Returns:the float held if getValueType() == FLOAT_VALUE_TYPE, 0 otherwise
/** * Retrieve the float held, if any. * * @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise */
public float getFloatValue() { try { if (mValueType == FLOAT_VALUE_TYPE) return (Float) mValue; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return 0; }
Retrieve the tuple, in the form of a List of StatsDimensionsValue, held, if any.
Returns:the List of StatsDimensionsValue held if getValueType() == TUPLE_VALUE_TYPE, null otherwise
/** * Retrieve the tuple, in the form of a {@link List} of {@link StatsDimensionsValue}, held, * if any. * * @return the {@link List} of {@link StatsDimensionsValue} held * if {@link #getValueType()} == {@link #TUPLE_VALUE_TYPE}, * null otherwise */
public List<StatsDimensionsValue> getTupleValueList() { if (mValueType != TUPLE_VALUE_TYPE) { return null; } try { StatsDimensionsValue[] orig = (StatsDimensionsValue[]) mValue; List<StatsDimensionsValue> copy = new ArrayList<>(orig.length); // Shallow copy since StatsDimensionsValue is immutable anyway for (int i = 0; i < orig.length; i++) { copy.add(orig[i]); } return copy; } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); return null; } }
Returns the constant representing the type of value stored, namely one of
Returns:the constant representing the type of value stored
/** * Returns the constant representing the type of value stored, namely one of * <ul> * <li>{@link #STRING_VALUE_TYPE}</li> * <li>{@link #INT_VALUE_TYPE}</li> * <li>{@link #LONG_VALUE_TYPE}</li> * <li>{@link #BOOLEAN_VALUE_TYPE}</li> * <li>{@link #FLOAT_VALUE_TYPE}</li> * <li>{@link #TUPLE_VALUE_TYPE}</li> * </ul> * * @return the constant representing the type of value stored */
public int getValueType() { return mValueType; }
Returns whether the type of value stored is equal to the given type.
Params:
  • valueType – int representing the type of value stored, as used in getValueType
Returns:true if getValueType() is equal to valueType.
/** * Returns whether the type of value stored is equal to the given type. * * @param valueType int representing the type of value stored, as used in {@link #getValueType} * @return true if {@link #getValueType()} is equal to {@code valueType}. */
public boolean isValueType(int valueType) { return mValueType == valueType; }
Returns a String representing the information in this StatsDimensionValue. No guarantees are made about the format of this String.
Returns:String representation
@hide
/** * Returns a String representing the information in this StatsDimensionValue. * No guarantees are made about the format of this String. * * @return String representation * * @hide */
// Follows the format of statsd's dimension.h toString. public String toString() { try { StringBuilder sb = new StringBuilder(); sb.append(mField); sb.append(":"); if (mValueType == TUPLE_VALUE_TYPE) { sb.append("{"); StatsDimensionsValue[] sbvs = (StatsDimensionsValue[]) mValue; for (int i = 0; i < sbvs.length; i++) { sb.append(sbvs[i].toString()); sb.append("|"); } sb.append("}"); } else { sb.append(mValue.toString()); } return sb.toString(); } catch (ClassCastException e) { Slog.w(TAG, "Failed to successfully get value", e); } return ""; }
Parcelable Creator for StatsDimensionsValue.
/** * Parcelable Creator for StatsDimensionsValue. */
public static final Parcelable.Creator<StatsDimensionsValue> CREATOR = new Parcelable.Creator<StatsDimensionsValue>() { public StatsDimensionsValue createFromParcel(Parcel in) { return new StatsDimensionsValue(in); } public StatsDimensionsValue[] newArray(int size) { return new StatsDimensionsValue[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { out.writeInt(mField); out.writeInt(mValueType); writeValueToParcel(mValueType, mValue, out, flags); }
Writes mValue to a parcel. Returns true if succeeds.
/** Writes mValue to a parcel. Returns true if succeeds. */
private static boolean writeValueToParcel(int valueType, Object value, Parcel out, int flags) { try { switch (valueType) { case STRING_VALUE_TYPE: out.writeString((String) value); return true; case INT_VALUE_TYPE: out.writeInt((Integer) value); return true; case LONG_VALUE_TYPE: out.writeLong((Long) value); return true; case BOOLEAN_VALUE_TYPE: out.writeBoolean((Boolean) value); return true; case FLOAT_VALUE_TYPE: out.writeFloat((Float) value); return true; case TUPLE_VALUE_TYPE: { StatsDimensionsValue[] values = (StatsDimensionsValue[]) value; out.writeInt(values.length); for (int i = 0; i < values.length; i++) { values[i].writeToParcel(out, flags); } return true; } default: Slog.w(TAG, "readValue of an impossible type " + valueType); return false; } } catch (ClassCastException e) { Slog.w(TAG, "writeValue cast failed", e); return false; } }
Reads mValue from a parcel.
/** Reads mValue from a parcel. */
private static Object readValueFromParcel(int valueType, Parcel parcel) { switch (valueType) { case STRING_VALUE_TYPE: return parcel.readString(); case INT_VALUE_TYPE: return parcel.readInt(); case LONG_VALUE_TYPE: return parcel.readLong(); case BOOLEAN_VALUE_TYPE: return parcel.readBoolean(); case FLOAT_VALUE_TYPE: return parcel.readFloat(); case TUPLE_VALUE_TYPE: { final int sz = parcel.readInt(); StatsDimensionsValue[] values = new StatsDimensionsValue[sz]; for (int i = 0; i < sz; i++) { values[i] = new StatsDimensionsValue(parcel); } return values; } default: Slog.w(TAG, "readValue of an impossible type " + valueType); return null; } } }