1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.internal.util;
18 
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Modifier;
21 
22 // Copied from frameworks/base and kept only used codes
23 /**
24  * <p>Various utilities for debugging and logging.</p>
25  *
26  * @hide
27  */
28 public final class DebugUtils {
DebugUtils()29     private DebugUtils() {}
30 
31     /**
32      * Use prefixed constants (static final values) on given class to turn value
33      * into human-readable string.
34      *
35      * @hide
36      */
valueToString(Class<?> clazz, String prefix, int value)37     public static String valueToString(Class<?> clazz, String prefix, int value) {
38         for (Field field : clazz.getDeclaredFields()) {
39             final int modifiers = field.getModifiers();
40             if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
41                     && field.getType().equals(int.class) && field.getName().startsWith(prefix)) {
42                 try {
43                     if (value == field.getInt(null)) {
44                         return constNameWithoutPrefix(prefix, field);
45                     }
46                 } catch (IllegalAccessException ignored) {
47                 }
48             }
49         }
50         return Integer.toString(value);
51     }
52 
53     /**
54      * Use prefixed constants (static final values) on given class to turn flags
55      * into human-readable string.
56      *
57      * @hide
58      */
flagsToString(Class<?> clazz, String prefix, int flagsToConvert)59     public static String flagsToString(Class<?> clazz, String prefix, int flagsToConvert) {
60         int flags = flagsToConvert;
61         final StringBuilder res = new StringBuilder();
62         boolean flagsWasZero = flags == 0;
63 
64         for (Field field : clazz.getDeclaredFields()) {
65             final int modifiers = field.getModifiers();
66             if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
67                     && field.getType().equals(int.class) && field.getName().startsWith(prefix)) {
68                 try {
69                     final int value = field.getInt(null);
70                     if (value == 0 && flagsWasZero) {
71                         return constNameWithoutPrefix(prefix, field);
72                     }
73                     if (value != 0 && (flags & value) == value) {
74                         flags &= ~value;
75                         res.append(constNameWithoutPrefix(prefix, field)).append('|');
76                     }
77                 } catch (IllegalAccessException ignored) {
78                 }
79             }
80         }
81         if (flags != 0 || res.length() == 0) {
82             res.append(Integer.toHexString(flags));
83         } else {
84             res.deleteCharAt(res.length() - 1);
85         }
86         return res.toString();
87     }
88 
89     /**
90      * Gets human-readable representation of constants (static final values).
91      *
92      * @see #constantToString(Class, String, int)
93      *
94      * @hide
95      */
constantToString(Class<?> clazz, int value)96     public static String constantToString(Class<?> clazz, int value) {
97         return constantToString(clazz, "", value);
98     }
99 
100     /**
101      * Gets human-readable representation of constants (static final values).
102      *
103      * @hide
104      */
constantToString(Class<?> clazz, String prefix, int value)105     public static String constantToString(Class<?> clazz, String prefix, int value) {
106         for (Field field : clazz.getDeclaredFields()) {
107             final int modifiers = field.getModifiers();
108             try {
109                 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
110                         && field.getType().equals(int.class) && field.getName().startsWith(prefix)
111                         && field.getInt(null) == value) {
112                     return constNameWithoutPrefix(prefix, field);
113                 }
114             } catch (IllegalAccessException ignored) {
115             }
116         }
117         return prefix + Integer.toString(value);
118     }
119 
constNameWithoutPrefix(String prefix, Field field)120     private static String constNameWithoutPrefix(String prefix, Field field) {
121         return field.getName().substring(prefix.length());
122     }
123 }
124