1 /* 2 * Copyright 2018 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 android.view.inspector; 18 19 import android.annotation.AnyRes; 20 import android.annotation.ColorInt; 21 import android.annotation.ColorLong; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.graphics.Color; 25 26 /** 27 * An interface for reading the properties of an inspectable object. 28 * 29 * {@code PropertyReader} is defined as an interface that will be called by 30 * {@link InspectionCompanion#readProperties(Object, PropertyReader)}. This approach allows a 31 * client inspector to read the values of primitive properties without the overhead of 32 * instantiating a class to hold the property values for each inspection pass. If an inspectable 33 * remains unchanged between reading passes, it should be possible for a {@code PropertyReader} to 34 * avoid new allocations for subsequent reading passes. 35 * 36 * It has separate methods for all primitive types to avoid autoboxing overhead if a concrete 37 * implementation is able to work with primitives. Implementations should be prepared to accept 38 * {null} as the value of {@link PropertyReader#readObject(int, Object)}. 39 * 40 * @see InspectionCompanion#readProperties(Object, PropertyReader) 41 */ 42 public interface PropertyReader { 43 /** 44 * Read a primitive boolean property. 45 * 46 * @param id Identifier of the property from a {@link PropertyMapper} 47 * @param value Value of the property 48 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code boolean} 49 */ readBoolean(int id, boolean value)50 void readBoolean(int id, boolean value); 51 52 /** 53 * Read a primitive byte property. 54 * 55 * @param id Identifier of the property from a {@link PropertyMapper} 56 * @param value Value of the property 57 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code byte} 58 */ readByte(int id, byte value)59 void readByte(int id, byte value); 60 61 /** 62 * Read a primitive character property. 63 * 64 * @param id Identifier of the property from a {@link PropertyMapper} 65 * @param value Value of the property 66 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code char} 67 */ readChar(int id, char value)68 void readChar(int id, char value); 69 70 /** 71 * Read a read a primitive double property. 72 * 73 * @param id Identifier of the property from a {@link PropertyMapper} 74 * @param value Value of the property 75 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code double} 76 */ readDouble(int id, double value)77 void readDouble(int id, double value); 78 79 /** 80 * Read a primitive float property. 81 * 82 * @param id Identifier of the property from a {@link PropertyMapper} 83 * @param value Value of the property 84 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code float} 85 */ readFloat(int id, float value)86 void readFloat(int id, float value); 87 88 /** 89 * Read a primitive integer property. 90 * 91 * @param id Identifier of the property from a {@link PropertyMapper} 92 * @param value Value of the property 93 * @throws PropertyTypeMismatchException If the property ID is not mapped as an {@code int} 94 */ readInt(int id, int value)95 void readInt(int id, int value); 96 97 /** 98 * Read a primitive long property. 99 * 100 * @param id Identifier of the property from a {@link PropertyMapper} 101 * @param value Value of the property 102 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code long} 103 */ readLong(int id, long value)104 void readLong(int id, long value); 105 106 /** 107 * Read a primitive short property. 108 * 109 * @param id Identifier of the property from a {@link PropertyMapper} 110 * @param value Value of the property 111 * @throws PropertyTypeMismatchException If the property ID is not mapped as a {@code short} 112 */ readShort(int id, short value)113 void readShort(int id, short value); 114 115 /** 116 * Read any object as a property. 117 * 118 * If value is null, the property is marked as empty. 119 * 120 * @param id Identifier of the property from a {@link PropertyMapper} 121 * @param value Value of the property 122 * @throws PropertyTypeMismatchException If the property ID is not mapped as an object 123 */ readObject(int id, @Nullable Object value)124 void readObject(int id, @Nullable Object value); 125 126 /** 127 * Read a color packed into a {@link ColorInt} as a property. 128 * 129 * @param id Identifier of the property from a {@link PropertyMapper} 130 * @param value Value of the property 131 * @throws PropertyTypeMismatchException If the property ID is not mapped as a color 132 */ readColor(int id, @ColorInt int value)133 void readColor(int id, @ColorInt int value); 134 135 /** 136 * Read a color packed into a {@code ColorLong} as a property. 137 * 138 * @param id Identifier of the property from a {@link PropertyMapper} 139 * @param value Value of the property packed as a {@code ColorLong}. See the 140 * {@link Color} class for details of the packing. 141 * @throws PropertyTypeMismatchException If the property ID is not mapped as a color 142 */ readColor(int id, @ColorLong long value)143 void readColor(int id, @ColorLong long value); 144 145 /** 146 * Read a {@link Color} object as a property. 147 * 148 * @param id Identifier of the property from a {@link PropertyMapper} 149 * @param value Value of the property 150 * @throws PropertyTypeMismatchException If the property ID is not mapped as a color 151 */ readColor(int id, @Nullable Color value)152 void readColor(int id, @Nullable Color value); 153 154 /** 155 * Read {@link android.view.Gravity} packed into an primitive {@code int}. 156 * 157 * @param id Identifier of the property from a {@link PropertyMapper} 158 * @param value Value of the property 159 * @throws PropertyTypeMismatchException If the property ID is not mapped as a gravity property 160 */ readGravity(int id, int value)161 void readGravity(int id, int value); 162 163 /** 164 * Read an enumeration packed into a primitive {@code int}. 165 * 166 * @param id Identifier of the property from a {@link PropertyMapper} 167 * @param value Value of the property 168 * @throws PropertyTypeMismatchException If the property ID is not mapped as an object 169 */ readIntEnum(int id, int value)170 void readIntEnum(int id, int value); 171 172 /** 173 * Read a flag packed into a primitive {@code int}. 174 * 175 * @param id Identifier of the property from a {@link PropertyMapper} 176 * @param value Value of the property 177 * @throws PropertyTypeMismatchException If the property ID is not mapped as an object 178 */ readIntFlag(int id, int value)179 void readIntFlag(int id, int value); 180 181 /** 182 * Read an integer that contains a resource ID. 183 * 184 * @param id Identifier of the property from a {@link PropertyMapper} 185 * @param value Value of the property 186 * @throws PropertyTypeMismatchException If the property ID is not mapped as a resource ID. 187 */ readResourceId(int id, @AnyRes int value)188 void readResourceId(int id, @AnyRes int value); 189 190 /** 191 * Thrown if a client calls a typed read method for a property of a different type. 192 */ 193 class PropertyTypeMismatchException extends RuntimeException { PropertyTypeMismatchException( int id, @NonNull String expectedPropertyType, @NonNull String actualPropertyType, @Nullable String propertyName)194 public PropertyTypeMismatchException( 195 int id, 196 @NonNull String expectedPropertyType, 197 @NonNull String actualPropertyType, 198 @Nullable String propertyName) { 199 super(formatMessage(id, expectedPropertyType, actualPropertyType, propertyName)); 200 } 201 PropertyTypeMismatchException( int id, @NonNull String expectedPropertyType, @NonNull String actualPropertyType)202 public PropertyTypeMismatchException( 203 int id, 204 @NonNull String expectedPropertyType, 205 @NonNull String actualPropertyType) { 206 super(formatMessage(id, expectedPropertyType, actualPropertyType, null)); 207 } 208 formatMessage( int id, @NonNull String expectedPropertyType, @NonNull String actualPropertyType, @Nullable String propertyName)209 private static @NonNull String formatMessage( 210 int id, 211 @NonNull String expectedPropertyType, 212 @NonNull String actualPropertyType, 213 @Nullable String propertyName) { 214 215 if (propertyName == null) { 216 return String.format( 217 "Attempted to read property with ID 0x%08X as type %s, " 218 + "but the ID is of type %s.", 219 id, 220 expectedPropertyType, 221 actualPropertyType 222 ); 223 } else { 224 return String.format( 225 "Attempted to read property \"%s\" with ID 0x%08X as type %s, " 226 + "but the ID is of type %s.", 227 propertyName, 228 id, 229 expectedPropertyType, 230 actualPropertyType 231 ); 232 } 233 } 234 } 235 } 236