• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static java.lang.Integer.toHexString;
20 
21 import android.annotation.Nullable;
22 import android.car.VehicleAreaDoor;
23 import android.car.VehicleAreaMirror;
24 import android.car.VehicleAreaSeat;
25 import android.car.VehicleAreaType;
26 import android.car.VehicleAreaWheel;
27 import android.car.VehicleAreaWindow;
28 import android.car.VehiclePropertyIds;
29 import android.util.Slog;
30 
31 import com.android.car.internal.property.CarPropertyHelper;
32 import com.android.car.internal.property.PropIdAreaId;
33 
34 import java.util.List;
35 
36 // Copied from frameworks/base and kept only used codes
37 /**
38  * <p>Various utilities for debugging and logging.</p>
39  */
40 public final class DebugUtils {
41     public static final String TAG = DebugUtils.class.getSimpleName();
42 
DebugUtils()43     private DebugUtils() {
44     }
45 
46     /**
47      * Gets human-readable representation of constants (static final values).
48      *
49      * @see #constantToString(Class, String, int)
50      */
constantToString(Class<?> clazz, int value)51     public static String constantToString(Class<?> clazz, int value) {
52         return constantToString(clazz, "", value);
53     }
54 
55     /**
56      * Use prefixed constants (static final values) on given class to turn value
57      * into human-readable string.
58      */
constantToString(Class<?> clazz, String prefix, int value)59     public static String constantToString(Class<?> clazz, String prefix, int value) {
60         String constantString = ConstantDebugUtils.toName(clazz, prefix, value);
61         return constantString != null ? constantString : prefix + value;
62     }
63 
64     /**
65      * Use prefixed constants (public static final int values) on a given class to turn flags into
66      * human-readable string.
67      */
flagsToString(Class<?> bitFlagClazz, String prefix, int flagsToConvert)68     public static String flagsToString(Class<?> bitFlagClazz, String prefix, int flagsToConvert) {
69         String flagsString = flagsToOptionalString(bitFlagClazz, prefix, flagsToConvert);
70         return flagsString != null ? flagsString : "0x" + Integer.toHexString(flagsToConvert);
71     }
72 
73     /**
74      * Use constants (public static final int values) on given class to turn flags into
75      * human-readable string if possible. If no conversion found, returns {@code null}.
76      */
flagsToOptionalString(Class<?> bitFlagClazz, int flagsToConvert)77     public static @Nullable String flagsToOptionalString(Class<?> bitFlagClazz,
78             int flagsToConvert) {
79         return flagsToOptionalString(bitFlagClazz, "", flagsToConvert);
80     }
81 
82     /**
83      * Use prefixed constants (public static final int values) on a given class to turn flags into
84      * human-readable string if possible. If no conversion found, returns {@code null}.
85      */
flagsToOptionalString(Class<?> bitFlagClazz, String prefix, int flagsToConvert)86     public static @Nullable String flagsToOptionalString(Class<?> bitFlagClazz, String prefix,
87             int flagsToConvert) {
88         boolean inputFlagsWasZero = flagsToConvert == 0;
89         int flagsToConvertCopy = flagsToConvert;
90         final StringBuilder result = new StringBuilder();
91 
92         List<Integer> bitFlags = ConstantDebugUtils.getValues(bitFlagClazz, prefix);
93         for (int i = 0; i < bitFlags.size(); i++) {
94             int bitFlag = bitFlags.get(i);
95 
96             if (bitFlag == 0 && inputFlagsWasZero) {
97                 return ConstantDebugUtils.toName(bitFlagClazz, prefix, bitFlag);
98             }
99             if (bitFlag != 0 && (flagsToConvertCopy & bitFlag) == bitFlag) {
100                 flagsToConvertCopy &= ~bitFlag;
101                 result.append(ConstantDebugUtils.toName(bitFlagClazz, prefix, bitFlag)).append('|');
102             }
103         }
104 
105         if (result.isEmpty()) {
106             return null;
107         } else if (flagsToConvertCopy != 0) {
108             result.append("0x").append(Integer.toHexString(flagsToConvertCopy));
109         } else {
110             result.deleteCharAt(result.length() - 1);
111         }
112 
113         return result.toString();
114     }
115 
116     /**
117      * Gets a user-friendly string representation of an {@code areaId} for the given
118      * {@code propertyId}.
119      */
toAreaIdString(int propertyId, int areaId)120     public static String toAreaIdString(int propertyId, int areaId) {
121         int areaType;
122         try {
123             areaType = CarPropertyHelper.getAreaType(propertyId);
124         } catch (IllegalArgumentException e) {
125             Slog.w(TAG, "Property ID: " + VehiclePropertyIds.toString(propertyId)
126                     + " has invalid area type for area ID: " + areaId, e);
127             areaType = -1;
128         }
129 
130         switch (areaType) {
131             case VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL -> {
132                 if (areaId == 0) {
133                     return "GLOBAL";
134                 }
135                 return "INVALID_GLOBAL_AREA_ID(0x" + toHexString(areaId) + ")";
136             }
137             case VehicleAreaType.VEHICLE_AREA_TYPE_DOOR -> {
138                 return areaIdToString(VehicleAreaDoor.class, "DOOR_", areaId);
139             }
140             case VehicleAreaType.VEHICLE_AREA_TYPE_MIRROR -> {
141                 return areaIdToString(VehicleAreaMirror.class, "MIRROR_", areaId);
142             }
143             case VehicleAreaType.VEHICLE_AREA_TYPE_SEAT -> {
144                 return areaIdToString(VehicleAreaSeat.class, "SEAT_", areaId);
145             }
146             case VehicleAreaType.VEHICLE_AREA_TYPE_WHEEL -> {
147                 return areaIdToString(VehicleAreaWheel.class, "WHEEL_", areaId);
148             }
149             case VehicleAreaType.VEHICLE_AREA_TYPE_WINDOW -> {
150                 return areaIdToString(VehicleAreaWindow.class, "WINDOW_", areaId);
151             }
152             case VehicleAreaType.VEHICLE_AREA_TYPE_VENDOR -> {
153                 return "VENDOR_AREA_ID(0x" + toHexString(areaId) + ")";
154             }
155             default -> {
156                 return "UNKNOWN_AREA_TYPE_AREA_ID(0x" + toHexString(areaId) + ")";
157             }
158         }
159     }
160 
161     /**
162      * Gets human-readable representation of a {@code PropIdAreaId} structure.
163      */
toDebugString(PropIdAreaId propIdAreaId)164     public static String toDebugString(PropIdAreaId propIdAreaId) {
165         return "PropIdAreaId{propId=" + VehiclePropertyIds.toString(propIdAreaId.propId)
166             + ", areaId=" + toAreaIdString(propIdAreaId.propId, propIdAreaId.areaId) + "}";
167     }
168 
169     /**
170      * Gets human-readable representation of a list of {@code PropIdAreaId} structure.
171      */
toDebugString(List<PropIdAreaId> propIdAreaIds)172     public static String toDebugString(List<PropIdAreaId> propIdAreaIds) {
173         StringBuilder sb = new StringBuilder();
174         sb.append("propIdAreaIds: [");
175         boolean first = true;
176         for (int i = 0; i < propIdAreaIds.size(); i++) {
177             var propIdAreaId = propIdAreaIds.get(i);
178             if (first) {
179                 first = false;
180             } else {
181                 sb.append(", ");
182             }
183             sb.append(toDebugString(propIdAreaId));
184         }
185         return sb.append("]").toString();
186     }
187 
areaIdToString(Class<?> areaTypeClazz, String prefix, int areaId)188     private static String areaIdToString(Class<?> areaTypeClazz, String prefix, int areaId) {
189         String areaIdString = flagsToOptionalString(areaTypeClazz, prefix, areaId);
190         if (areaIdString != null) {
191             return areaIdString;
192         }
193         return "UNKNOWN_" + prefix + "AREA_ID(0x" + toHexString(areaId) + ")";
194     }
195 }
196