318 lines
10 KiB
Java
318 lines
10 KiB
Java
/*
|
|
* 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.Log;
|
|
|
|
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).
|
|
*
|
|
* <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 frameworks/base/cmds/statsd/src/HashableDimensionKey.cpp.
|
|
/** Indicates that this holds a String. */
|
|
public static final int STRING_VALUE_TYPE = 2;
|
|
/** Indicates that this holds an int. */
|
|
public static final int INT_VALUE_TYPE = 3;
|
|
/** Indicates that this holds a long. */
|
|
public static final int LONG_VALUE_TYPE = 4;
|
|
/** Indicates that this holds a boolean. */
|
|
public static final int BOOLEAN_VALUE_TYPE = 5;
|
|
/** Indicates that this holds a float. */
|
|
public static final int FLOAT_VALUE_TYPE = 6;
|
|
/** Indicates that this holds a List of StatsDimensionsValues. */
|
|
public static final int TUPLE_VALUE_TYPE = 7;
|
|
|
|
private final StatsDimensionsValueParcel mInner;
|
|
|
|
/**
|
|
* Creates a {@code StatsDimensionValue} from a parcel.
|
|
*
|
|
* @hide
|
|
*/
|
|
public StatsDimensionsValue(Parcel in) {
|
|
mInner = StatsDimensionsValueParcel.CREATOR.createFromParcel(in);
|
|
}
|
|
|
|
/**
|
|
* Creates a {@code StatsDimensionsValue} from a StatsDimensionsValueParcel
|
|
*
|
|
* @hide
|
|
*/
|
|
public StatsDimensionsValue(StatsDimensionsValueParcel parcel) {
|
|
mInner = parcel;
|
|
}
|
|
|
|
/**
|
|
* Return the field, i.e. the tag of a statsd atom.
|
|
*
|
|
* @return the field
|
|
*/
|
|
public int getField() {
|
|
return mInner.field;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the String held, if any.
|
|
*
|
|
* @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE},
|
|
* null otherwise
|
|
*/
|
|
public String getStringValue() {
|
|
if (mInner.valueType == STRING_VALUE_TYPE) {
|
|
return mInner.stringValue;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not string.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the int held, if any.
|
|
*
|
|
* @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise
|
|
*/
|
|
public int getIntValue() {
|
|
if (mInner.valueType == INT_VALUE_TYPE) {
|
|
return mInner.intValue;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not int.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the long held, if any.
|
|
*
|
|
* @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise
|
|
*/
|
|
public long getLongValue() {
|
|
if (mInner.valueType == LONG_VALUE_TYPE) {
|
|
return mInner.longValue;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not long.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the boolean held, if any.
|
|
*
|
|
* @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE},
|
|
* false otherwise
|
|
*/
|
|
public boolean getBooleanValue() {
|
|
if (mInner.valueType == BOOLEAN_VALUE_TYPE) {
|
|
return mInner.boolValue;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not boolean.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the float held, if any.
|
|
*
|
|
* @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise
|
|
*/
|
|
public float getFloatValue() {
|
|
if (mInner.valueType == FLOAT_VALUE_TYPE) {
|
|
return mInner.floatValue;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not float.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 (mInner.valueType == TUPLE_VALUE_TYPE) {
|
|
int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
|
|
List<StatsDimensionsValue> tupleValues = new ArrayList<>(length);
|
|
for (int i = 0; i < length; i++) {
|
|
tupleValues.add(new StatsDimensionsValue(mInner.tupleValue[i]));
|
|
}
|
|
return tupleValues;
|
|
} else {
|
|
Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not tuple.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 mInner.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 mInner.valueType == valueType;
|
|
}
|
|
|
|
/**
|
|
* 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() {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(mInner.field);
|
|
sb.append(":");
|
|
switch (mInner.valueType) {
|
|
case STRING_VALUE_TYPE:
|
|
sb.append(mInner.stringValue);
|
|
break;
|
|
case INT_VALUE_TYPE:
|
|
sb.append(String.valueOf(mInner.intValue));
|
|
break;
|
|
case LONG_VALUE_TYPE:
|
|
sb.append(String.valueOf(mInner.longValue));
|
|
break;
|
|
case BOOLEAN_VALUE_TYPE:
|
|
sb.append(String.valueOf(mInner.boolValue));
|
|
break;
|
|
case FLOAT_VALUE_TYPE:
|
|
sb.append(String.valueOf(mInner.floatValue));
|
|
break;
|
|
case TUPLE_VALUE_TYPE:
|
|
sb.append("{");
|
|
int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
|
|
for (int i = 0; i < length; i++) {
|
|
StatsDimensionsValue child = new StatsDimensionsValue(mInner.tupleValue[i]);
|
|
sb.append(child.toString());
|
|
sb.append("|");
|
|
}
|
|
sb.append("}");
|
|
break;
|
|
default:
|
|
Log.w(TAG, "Incorrect value type");
|
|
break;
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
/**
|
|
* Parcelable Creator for StatsDimensionsValue.
|
|
*/
|
|
public static final @android.annotation.NonNull
|
|
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) {
|
|
mInner.writeToParcel(out, flags);
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of the type of value stored.
|
|
*/
|
|
private String getValueTypeAsString() {
|
|
switch (mInner.valueType) {
|
|
case STRING_VALUE_TYPE:
|
|
return "string";
|
|
case INT_VALUE_TYPE:
|
|
return "int";
|
|
case LONG_VALUE_TYPE:
|
|
return "long";
|
|
case BOOLEAN_VALUE_TYPE:
|
|
return "boolean";
|
|
case FLOAT_VALUE_TYPE:
|
|
return "float";
|
|
case TUPLE_VALUE_TYPE:
|
|
return "tuple";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
}
|
|
}
|