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.NonNull;
20 
21 /**
22  * An interface for companion objects used to inspect views.
23  *
24  * Inspection companions only need to handle the properties and node name of the specific class
25  * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
26  * one instance of each inspection companion, and handles visiting them in the correct inheritance
27  * order for each type it inspects.
28  *
29  * Properties are read from the top of the type tree to the bottom, so that classes that override
30  * a property in their parent class can overwrite it in the reader. In general, properties will
31  * cleanly inherit through their getters, and the inspector runtime will read the properties of a
32  * parent class via the parent's inspection companion, and the child companion will only read
33  * properties added or changed since the parent was defined.
34  *
35  * @param <T> The type of inspectable this is the companion to
36  */
37 public interface InspectionCompanion<T> {
38     /**
39      * Map the string names of the properties this companion knows about to integer IDs.
40      *
41      * Each companion is responsible for storing the integer IDs of all its properties. This is the
42      * only method that is allowed to modify the stored IDs.
43      *
44      * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
45      * undefined behavior.
46      *
47      * @param propertyMapper A {@link PropertyMapper} maps string names to IDs.
48      */
mapProperties(@onNull PropertyMapper propertyMapper)49     void mapProperties(@NonNull PropertyMapper propertyMapper);
50 
51     /**
52      * Read the values of an instance of this companion's type into a {@link PropertyReader}.
53      *
54      * This method needs to return the property IDs stored by
55      * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
56      * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
57      * called before {mapProperties}.
58      *
59      * @param inspectable A object of type {T} to read the properties of.
60      * @param propertyReader An object which receives the property IDs and values.
61      */
readProperties(@onNull T inspectable, @NonNull PropertyReader propertyReader)62     void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
63 
64     /**
65      * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
66      * {@link #mapProperties(PropertyMapper)}.
67      */
68     class UninitializedPropertyMapException extends RuntimeException {
UninitializedPropertyMapException()69         public UninitializedPropertyMapException() {
70             super("Unable to read properties of an inspectable before mapping their IDs.");
71         }
72     }
73 }
74