/* * Copyright (C) 2016 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.health; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.util.Arrays; /** * Constants and stuff for the android.os.health package. * * @hide */ public class HealthKeys { /** * No valid key will ever be 0. */ public static final int UNKNOWN_KEY = 0; /* * Base key for each of the different classes. There is * nothing intrinsic to the operation of the value of the * keys. It's just segmented for better debugging. The * classes don't mix them anway. */ public static final int BASE_UID = 10000; public static final int BASE_PID = 20000; public static final int BASE_PROCESS = 30000; public static final int BASE_PACKAGE = 40000; public static final int BASE_SERVICE = 50000; /* * The types of values supported by HealthStats. */ public static final int TYPE_TIMER = 0; public static final int TYPE_MEASUREMENT = 1; public static final int TYPE_STATS = 2; public static final int TYPE_TIMERS = 3; public static final int TYPE_MEASUREMENTS = 4; public static final int TYPE_COUNT = 5; /** * Annotation to mark public static final int fields that are to be used * as field keys in HealthStats. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface Constant { /** * One of the TYPE_* constants above. */ int type(); } /** * Class to gather the constants defined in a class full of constants and * build the key indices used by HealthStatsWriter and HealthStats. * * @hide */ public static class Constants { private final String mDataType; private final int[][] mKeys = new int[TYPE_COUNT][]; /** * Pass in a class to gather the public static final int fields that are * tagged with the @Constant annotation. */ public Constants(Class clazz) { // Save the class name for debugging mDataType = clazz.getSimpleName(); // Iterate through the list of fields on this class, and build the // constant arrays for these fields. final Field[] fields = clazz.getDeclaredFields(); final Class annotationClass = Constant.class; final int N = fields.length; final SortedIntArray[] keys = new SortedIntArray[mKeys.length]; for (int i=0; i= keys.length) { throw new RuntimeException("Unknown Constant type " + type + " on " + field); } try { keys[type].addValue(field.getInt(null)); } catch (IllegalAccessException ex) { throw new RuntimeException("Can't read constant value type=" + type + " field=" + field, ex); } } } for (int i=0; i= 0) { return index; } else { throw new RuntimeException("Unknown Constant " + key + " (of type " + type + " )"); } } /** * Get the array of keys for the given field type. */ public int[] getKeys(int type) { return mKeys[type]; } } /** * An array of fixed size that will be sorted. */ private static class SortedIntArray { int mCount; int[] mArray; /** * Construct with the maximum number of values. */ SortedIntArray(int maxCount) { mArray = new int[maxCount]; } /** * Add a value. */ void addValue(int value) { mArray[mCount++] = value; } /** * Get the array of values that have been added, with the values in * numerically increasing order. */ int[] getArray() { if (mCount == mArray.length) { Arrays.sort(mArray); return mArray; } else { final int[] result = new int[mCount]; System.arraycopy(mArray, 0, result, 0, mCount); Arrays.sort(result); return result; } } } }