1 /*
2  * Copyright 2023 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 androidx.appsearch.safeparcel;
18 
19 import android.os.Parcel;
20 
21 import androidx.annotation.RestrictTo;
22 
23 import org.jspecify.annotations.NonNull;
24 
25 /**
26  * Implements {@link SafeParcelable}.
27  *
28  * <p>In Jetpack, the annotations from {@SafeParcelable} are moved here so {@code NULL} can be
29  * package private.
30  *
31  * <p>This class is put in androidx.appsearch.app. Thus we can restrict the scope to avoid making it
32  * public.
33  *
34  * <p>DON'T modify this class unless it is necessary. E.g. port new annotations from SafeParcelable.
35  */
36 // @exportToFramework:skipFile()
37 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
38 public abstract class AbstractSafeParcelable implements SafeParcelable {
39     // Note: the field name and value are accessed using reflection for backwards compatibility, and
40     // must not be changed.
41     static final String NULL = "SAFE_PARCELABLE_NULL_STRING";
42 
43     /** Use this annotation on members that you wish to be marshalled in the SafeParcelable. */
44     public @interface Field {
45         /**
46          * Valid values for id are between 1 and 65535. This field id is marshalled into a Parcel
47          * . To
48          * maintain backwards compatibility, never reuse old id's. It is okay to no longer use
49          * old id's
50          * and add new ones in subsequent versions of a SafeParcelable.
51          */
id()52         int id();
53 
54         /**
55          * This specifies the name of the getter method for retrieving the value of this field. This
56          * must be specified for fields that do not have at least package visibility because the
57          * "creator" class will be unable to access the value when attempting to marshall this
58          * field.
59          * The getter method should take no parameters and return the type of this field (unless
60          * overridden by the "type" attribute below).
61          */
getter()62         String getter() default NULL;
63 
64         /**
65          * For advanced uses, this specifies the type for the field when marshalling and
66          * unmarshalling
67          * by the "creator" class to be something different than the declared type of the member
68          * variable. This is useful if you want to incorporate an object that is not
69          * SafeParcelable (or
70          * a system Parcelable object). Be sure to enter the fully qualified name for the class
71          * (i.e.,
72          * android.os.Bundle and not Bundle). For example,
73          *
74          * <pre>
75          *   &#64;Class(creator="MyAdvancedCreator")
76          *   public class MyAdvancedSafeParcelable implements SafeParcelable {
77          *       public static final Parcelable.Creator&#60;MyAdvancedSafeParcelable&#62; CREATOR =
78          *               new MyAdvancedCreator();
79          *
80          *       &#64;Field(id=1, getter="getObjectAsBundle", type="android.os.Bundle")
81          *       private final MyCustomObject myObject;
82          *
83          *       &#64;Constructor
84          *       MyAdvancedSafeParcelable(
85          *               &#64;Param(id=1) Bundle objectAsBundle) {
86          *           myObject = myConvertFromBundleToObject(objectAsBundle);
87          *       }
88          *
89          *       Bundle getObjectAsBundle() {
90          *           // The code here can convert your custom object to one that can be parcelled.
91          *           return myConvertFromObjectToBundle(myObject);
92          *       }
93          *
94          *       ...
95          *   }
96          * </pre>
97          */
type()98         String type() default NULL;
99 
100         /**
101          * This can be used to specify the default value for primitive types (e.g., boolean, int,
102          * long),
103          * primitive type object wrappers (e.g., Boolean, Integer, Long) and String in the case a
104          * value
105          * for a field was not explicitly set in the marshalled Parcel. This performs compile-time
106          * checks for the type of the field and inserts the appropriate quotes or double quotes
107          * around
108          * strings and chars or removes them completely for booleans and numbers. To insert a
109          * generic
110          * string for initializing field, use {@link #defaultValueUnchecked()}. You can specify
111          * at most
112          * one of {@link #defaultValue()} or {@link #defaultValueUnchecked()}. For example,
113          *
114          * <pre>
115          *   &#64;Field(id=2, defaultValue="true")
116          *   boolean myBoolean;
117          *
118          *   &#64;Field(id=3, defaultValue="13")
119          *   Integer myInteger;
120          *
121          *   &#64;Field(id=4, defaultValue="foo")
122          *   String myString;
123          * </pre>
124          */
defaultValue()125         String defaultValue() default NULL;
126 
127         /**
128          * This can be used to specify the default value for any object and the string value is
129          * literally added to the generated creator class code unchecked. You can specify at most
130          * one of
131          * {@link #defaultValue()} or {@link #defaultValueUnchecked()}. You must fully qualify any
132          * classes you reference within the string. For example,
133          *
134          * <pre>
135          *   &#64;Field(id=2, defaultValueUnchecked="new android.os.Bundle()")
136          *   Bundle myBundle;
137          * </pre>
138          */
defaultValueUnchecked()139         String defaultValueUnchecked() default NULL;
140     }
141 
142     /**
143      * There may be exactly one member annotated with VersionField, which represents the version of
144      * this safe parcelable. The attributes are the same as those of {@link Field}. Note you can use
145      * any type you want for your version field, although most people use int's.
146      */
147     public @interface VersionField {
id()148         int id();
149 
getter()150         String getter() default NULL;
151 
type()152         String type() default NULL;
153     }
154 
155     /**
156      * Use this to indicate the member field that holds whether a field was set or not. The member
157      * field type currently supported is a HashSet&#60;Integer&#62; which is the set of safe
158      * parcelable field id's that have been explicitly set.
159      *
160      * <p>This annotation should also be used to annotate one of the parameters to the constructor
161      * annotated with &#64;Constructor. Note that this annotation should either be present on
162      * exactly
163      * one member field and one constructor parameter or left out completely.
164      */
165     public @interface Indicator {
getter()166         String getter() default NULL;
167     }
168 
169     /**
170      * Use this on a parameter passed in to the Constructor to indicate that a removed field
171      * should be
172      * read on construction. If the field is not present when read, the default value will be used
173      * instead.
174      */
175     public @interface RemovedParam {
id()176         int id();
177 
defaultValue()178         String defaultValue() default NULL;
179 
defaultValueUnchecked()180         String defaultValueUnchecked() default NULL;
181     }
182 
183     /**
184      * Use this to mark tombstones for removed {@link Field Fields} or {@link VersionField
185      * VersionFields}.
186      */
187     public @interface Reserved {
value()188         int[] value();
189     }
190 
191     /**
192      * Use this to indicate the constructor that the creator should use. The constructor annotated
193      * with this must be package or public visibility, so that the generated "creator" class can
194      * invoke this.
195      */
196     public @interface Constructor {
197     }
198 
199     /**
200      * Use this on each parameter passed in to the Constructor to indicate to which field id each
201      * formal parameter corresponds.
202      */
203     public @interface Param {
id()204         int id();
205     }
206 
207     /**
208      * To be implemented by child classes.
209      *
210      * <p>This is purely for code sync purpose. Have {@code writeToParcel} here so we can keep
211      * "@Override" in child classes.
212      */
writeToParcel(@onNull Parcel dest, int flags)213     public void writeToParcel(@NonNull Parcel dest, int flags) {
214     }
215 
216     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
217     @Override
describeContents()218     public final int describeContents() {
219         return 0;
220     }
221 }
222