1 /*
2  * Copyright 2020 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.wear.watchface.data;
18 
19 import android.annotation.SuppressLint;
20 import android.content.ComponentName;
21 import android.graphics.Rect;
22 import android.os.Bundle;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.support.wearable.complications.ComplicationData;
26 
27 import androidx.annotation.RestrictTo;
28 import androidx.versionedparcelable.ParcelField;
29 import androidx.versionedparcelable.ParcelUtils;
30 import androidx.versionedparcelable.VersionedParcelable;
31 import androidx.versionedparcelable.VersionedParcelize;
32 import androidx.wear.watchface.complications.data.ComplicationExperimental;
33 
34 import org.jspecify.annotations.NonNull;
35 import org.jspecify.annotations.Nullable;
36 
37 import java.util.List;
38 
39 /**
40  * Data sent over AIDL for {@link IWatchFaceCommand#setComplicationDetails}.
41  *
42  */
43 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
44 @VersionedParcelize
45 @SuppressLint("BanParcelableUsage") // TODO(b/169214666): Remove Parcelable
46 public final class ComplicationStateWireFormat implements VersionedParcelable, Parcelable {
47     @ParcelField(1)
48     @NonNull Rect mBounds;
49 
50     @ParcelField(2)
51     int mBoundsType;
52 
53     @ParcelField(3)
54     @ComplicationData.ComplicationType
55     int @NonNull [] mSupportedTypes;
56 
57     @ParcelField(4)
58     @Nullable List<ComponentName> mDefaultDataSourcesToTry;
59 
60     @ParcelField(5)
61     int mFallbackSystemProvider;
62 
63     @ParcelField(6)
64     @ComplicationData.ComplicationType
65     int mDefaultType;
66 
67     @ParcelField(7)
68     boolean mIsEnabled;
69 
70     @ParcelField(8)
71     boolean mIsInitiallyEnabled;
72 
73     @ParcelField(9)
74     @ComplicationData.ComplicationType
75     int mCurrentType;
76 
77     @ParcelField(10)
78     boolean mFixedComplicationProvider;
79 
80     @ParcelField(11)
81     @NonNull Bundle mComplicationConfigExtras;
82 
83     // Not supported in library v1.0.
84     @ParcelField(12)
85     @ComplicationData.ComplicationType
86     int mPrimaryDataSourceDefaultType = ComplicationData.TYPE_NOT_CONFIGURED;
87 
88     // Not supported in library v1.0.
89     @ParcelField(13)
90     @ComplicationData.ComplicationType
91     int mSecondaryDataSourceDefaultType = ComplicationData.TYPE_NOT_CONFIGURED;
92 
93     // Not supported in library v1.0.
94     @ParcelField(14)
95     int mNameResourceId;
96 
97     // Not supported in library v1.0.
98     @ParcelField(15)
99     int mScreenReaderNameResourceId;
100 
101     // Only valid for edge complications. Not supported in library v1.0.
102     @ParcelField(16)
103     @Nullable BoundingArcWireFormat mBoundingArc;
104 
105     @ParcelField(value = 17, defaultValue = "null")
106     @Nullable Rect mBoundsWithMargins;
107 
108     // NB 0 is not a valid resource id.
109     private static final int NULL_NAME_RESOURCE_ID = 0;
110 
111     /** Used by VersionedParcelable. */
ComplicationStateWireFormat()112     ComplicationStateWireFormat() {}
113 
114     @ComplicationExperimental
ComplicationStateWireFormat( @onNull Rect bounds, @NonNull Rect boundsWithMargins, int boundsType, @ComplicationData.ComplicationType int @NonNull [] supportedTypes, @Nullable List<ComponentName> defaultDataSourcesToTry, int fallbackSystemProvider, @ComplicationData.ComplicationType int defaultDataSourceType, @ComplicationData.ComplicationType int primaryDataSourceDefaultType, @ComplicationData.ComplicationType int secondaryDataSourceDefaultType, boolean isEnabled, boolean isInitiallyEnabled, @ComplicationData.ComplicationType int currentType, boolean fixedComplicationProvider, @NonNull Bundle complicationConfigExtras, @Nullable Integer nameResourceId, @Nullable Integer screenReaderNameResourceId, @Nullable BoundingArcWireFormat boundingArc)115     public ComplicationStateWireFormat(
116             @NonNull Rect bounds,
117             @NonNull Rect boundsWithMargins,
118             int boundsType,
119             @ComplicationData.ComplicationType int @NonNull [] supportedTypes,
120             @Nullable List<ComponentName> defaultDataSourcesToTry,
121             int fallbackSystemProvider,
122             @ComplicationData.ComplicationType int defaultDataSourceType,
123             @ComplicationData.ComplicationType int primaryDataSourceDefaultType,
124             @ComplicationData.ComplicationType int secondaryDataSourceDefaultType,
125             boolean isEnabled,
126             boolean isInitiallyEnabled,
127             @ComplicationData.ComplicationType int currentType,
128             boolean fixedComplicationProvider,
129             @NonNull Bundle complicationConfigExtras,
130             @Nullable Integer nameResourceId,
131             @Nullable Integer screenReaderNameResourceId,
132             @Nullable BoundingArcWireFormat boundingArc) {
133         mBounds = bounds;
134         mBoundsWithMargins = boundsWithMargins;
135         mBoundsType = boundsType;
136         mSupportedTypes = supportedTypes;
137         mDefaultDataSourcesToTry = defaultDataSourcesToTry;
138         mFallbackSystemProvider = fallbackSystemProvider;
139         mDefaultType = defaultDataSourceType;
140         mPrimaryDataSourceDefaultType = primaryDataSourceDefaultType;
141         mSecondaryDataSourceDefaultType = secondaryDataSourceDefaultType;
142         mIsEnabled = isEnabled;
143         mIsInitiallyEnabled = isInitiallyEnabled;
144         mCurrentType = currentType;
145         mFixedComplicationProvider = fixedComplicationProvider;
146         mComplicationConfigExtras = complicationConfigExtras;
147         mNameResourceId = (nameResourceId != null) ? nameResourceId : NULL_NAME_RESOURCE_ID;
148         mScreenReaderNameResourceId =
149                 (screenReaderNameResourceId != null)
150                         ? screenReaderNameResourceId
151                         : NULL_NAME_RESOURCE_ID;
152         mBoundingArc = boundingArc;
153     }
154 
155     // TODO(b/230364881): Deprecate when BoundingArc is no longer experimental.
ComplicationStateWireFormat( @onNull Rect bounds, int boundsType, @ComplicationData.ComplicationType int @NonNull [] supportedTypes, @Nullable List<ComponentName> defaultDataSourcesToTry, int fallbackSystemProvider, @ComplicationData.ComplicationType int defaultDataSourceType, @ComplicationData.ComplicationType int primaryDataSourceDefaultType, @ComplicationData.ComplicationType int secondaryDataSourceDefaultType, boolean isEnabled, boolean isInitiallyEnabled, @ComplicationData.ComplicationType int currentType, boolean fixedComplicationProvider, @NonNull Bundle complicationConfigExtras, @Nullable Integer nameResourceId, @Nullable Integer screenReaderNameResourceId)156     public ComplicationStateWireFormat(
157             @NonNull Rect bounds,
158             int boundsType,
159             @ComplicationData.ComplicationType int @NonNull [] supportedTypes,
160             @Nullable List<ComponentName> defaultDataSourcesToTry,
161             int fallbackSystemProvider,
162             @ComplicationData.ComplicationType int defaultDataSourceType,
163             @ComplicationData.ComplicationType int primaryDataSourceDefaultType,
164             @ComplicationData.ComplicationType int secondaryDataSourceDefaultType,
165             boolean isEnabled,
166             boolean isInitiallyEnabled,
167             @ComplicationData.ComplicationType int currentType,
168             boolean fixedComplicationProvider,
169             @NonNull Bundle complicationConfigExtras,
170             @Nullable Integer nameResourceId,
171             @Nullable Integer screenReaderNameResourceId) {
172         mBounds = bounds;
173         mBoundsWithMargins = bounds;
174         mBoundsType = boundsType;
175         mSupportedTypes = supportedTypes;
176         mDefaultDataSourcesToTry = defaultDataSourcesToTry;
177         mFallbackSystemProvider = fallbackSystemProvider;
178         mDefaultType = defaultDataSourceType;
179         mPrimaryDataSourceDefaultType = primaryDataSourceDefaultType;
180         mSecondaryDataSourceDefaultType = secondaryDataSourceDefaultType;
181         mIsEnabled = isEnabled;
182         mIsInitiallyEnabled = isInitiallyEnabled;
183         mCurrentType = currentType;
184         mFixedComplicationProvider = fixedComplicationProvider;
185         mComplicationConfigExtras = complicationConfigExtras;
186         mNameResourceId = (nameResourceId != null) ? nameResourceId : NULL_NAME_RESOURCE_ID;
187         mScreenReaderNameResourceId =
188                 (screenReaderNameResourceId != null)
189                         ? screenReaderNameResourceId
190                         : NULL_NAME_RESOURCE_ID;
191     }
192 
193     /**
194      * @deprecated Use the other constructor instead.
195      */
196     @Deprecated
ComplicationStateWireFormat( @onNull Rect bounds, int boundsType, @ComplicationData.ComplicationType int @NonNull [] supportedTypes, @Nullable List<ComponentName> defaultDataSourcesToTry, int fallbackSystemProvider, @ComplicationData.ComplicationType int defaultDataSourceType, boolean isEnabled, boolean isInitiallyEnabled, @ComplicationData.ComplicationType int currentType, boolean fixedComplicationProvider, @NonNull Bundle complicationConfigExtras)197     public ComplicationStateWireFormat(
198             @NonNull Rect bounds,
199             int boundsType,
200             @ComplicationData.ComplicationType int @NonNull [] supportedTypes,
201             @Nullable List<ComponentName> defaultDataSourcesToTry,
202             int fallbackSystemProvider,
203             @ComplicationData.ComplicationType int defaultDataSourceType,
204             boolean isEnabled,
205             boolean isInitiallyEnabled,
206             @ComplicationData.ComplicationType int currentType,
207             boolean fixedComplicationProvider,
208             @NonNull Bundle complicationConfigExtras) {
209         mBounds = bounds;
210         mBoundsWithMargins = bounds;
211         mBoundsType = boundsType;
212         mSupportedTypes = supportedTypes;
213         mDefaultDataSourcesToTry = defaultDataSourcesToTry;
214         mFallbackSystemProvider = fallbackSystemProvider;
215         mDefaultType = defaultDataSourceType;
216         mIsEnabled = isEnabled;
217         mIsInitiallyEnabled = isInitiallyEnabled;
218         mCurrentType = currentType;
219         mFixedComplicationProvider = fixedComplicationProvider;
220         mComplicationConfigExtras = complicationConfigExtras;
221     }
222 
getBounds()223     public @NonNull Rect getBounds() {
224         return mBounds;
225     }
226 
getBoundsWithMargins()227     public @Nullable Rect getBoundsWithMargins() {
228         return mBoundsWithMargins;
229     }
230 
getBoundsType()231     public int getBoundsType() {
232         return mBoundsType;
233     }
234 
235     @ComplicationData.ComplicationType
getSupportedTypes()236     public int @NonNull [] getSupportedTypes() {
237         return mSupportedTypes;
238     }
239 
240     /**
241      * Along with {@link #getFallbackSystemProvider} this is the wire format for
242      * DefaultComplicationDataSourcePolicy.
243      *
244      * @deprecated Use {@link #getDefaultDataSourcesToTry} instead.
245      */
246     @Deprecated
getDefaultProvidersToTry()247     public @Nullable List<ComponentName> getDefaultProvidersToTry() {
248         return mDefaultDataSourcesToTry;
249     }
250 
251     /**
252      * Along with {@link #getFallbackSystemProvider} this is the wire format for
253      * DefaultComplicationDataSourcePolicy.
254      */
getDefaultDataSourcesToTry()255     public @Nullable List<ComponentName> getDefaultDataSourcesToTry() {
256         return mDefaultDataSourcesToTry;
257     }
258 
259     /**
260      * Along with {@link #getDefaultDataSourcesToTry} this is the wire format for
261      * DefaultComplicationDataSourcePolicy.
262      */
getFallbackSystemProvider()263     public int getFallbackSystemProvider() {
264         return mFallbackSystemProvider;
265     }
266 
267     /**
268      * @deprecated Use {@link #getDefaultDataSourceType} instead.
269      */
270     @Deprecated
271     @ComplicationData.ComplicationType
getDefaultProviderType()272     public int getDefaultProviderType() {
273         return mDefaultType;
274     }
275 
276     /**
277      * @return The {@link ComplicationData.ComplicationType} for {@link #getFallbackSystemProvider}.
278      */
279     @ComplicationData.ComplicationType
getDefaultDataSourceType()280     public int getDefaultDataSourceType() {
281         return mDefaultType;
282     }
283 
284     /**
285      * @return The {@link ComplicationData.ComplicationType} for the first entry from {@link
286      *     #getDefaultDataSourcesToTry}.
287      */
288     @ComplicationData.ComplicationType
getPrimaryDataSourceDefaultType()289     public int getPrimaryDataSourceDefaultType() {
290         // Not supported in library v1.0. TYPE_NOT_CONFIGURED is not a valid API choice indicating
291         // and old client.
292         return (mPrimaryDataSourceDefaultType == ComplicationData.TYPE_NOT_CONFIGURED)
293                 ? mDefaultType
294                 : mPrimaryDataSourceDefaultType;
295     }
296 
297     /**
298      * @return The {@link ComplicationData.ComplicationType} for the second entry from {@link
299      *     #getDefaultDataSourcesToTry}.
300      */
301     @ComplicationData.ComplicationType
getSecondaryDataSourceDefaultType()302     public int getSecondaryDataSourceDefaultType() {
303         // Not supported in library v1.0. TYPE_NOT_CONFIGURED is not a valid API choice indicating
304         // and old client.
305         return (mSecondaryDataSourceDefaultType == ComplicationData.TYPE_NOT_CONFIGURED)
306                 ? mDefaultType
307                 : mSecondaryDataSourceDefaultType;
308     }
309 
isEnabled()310     public boolean isEnabled() {
311         return mIsEnabled;
312     }
313 
isInitiallyEnabled()314     public boolean isInitiallyEnabled() {
315         return mIsInitiallyEnabled;
316     }
317 
isFixedComplicationProvider()318     public boolean isFixedComplicationProvider() {
319         return mFixedComplicationProvider;
320     }
321 
322     @ComplicationData.ComplicationType
getCurrentType()323     public int getCurrentType() {
324         return mCurrentType;
325     }
326 
getComplicationConfigExtras()327     public @NonNull Bundle getComplicationConfigExtras() {
328         return mComplicationConfigExtras;
329     }
330 
getNameResourceId()331     public @Nullable Integer getNameResourceId() {
332         return mNameResourceId != NULL_NAME_RESOURCE_ID ? mNameResourceId : null;
333     }
334 
getScreenReaderNameResourceId()335     public @Nullable Integer getScreenReaderNameResourceId() {
336         return mScreenReaderNameResourceId != NULL_NAME_RESOURCE_ID
337                 ? mScreenReaderNameResourceId
338                 : null;
339     }
340 
341     @ComplicationExperimental
getBoundingArc()342     public @Nullable BoundingArcWireFormat getBoundingArc() {
343         return mBoundingArc;
344     }
345 
346     /** Serializes this ComplicationDetails to the specified {@link Parcel}. */
347     @Override
writeToParcel(@onNull Parcel parcel, int flags)348     public void writeToParcel(@NonNull Parcel parcel, int flags) {
349         parcel.writeParcelable(ParcelUtils.toParcelable(this), flags);
350     }
351 
352     @Override
describeContents()353     public int describeContents() {
354         return 0;
355     }
356 
357     public static final Parcelable.Creator<ComplicationStateWireFormat> CREATOR =
358             new Parcelable.Creator<ComplicationStateWireFormat>() {
359                 @SuppressWarnings("deprecation")
360                 @Override
361                 public ComplicationStateWireFormat createFromParcel(Parcel source) {
362                     return ParcelUtils.fromParcelable(
363                             source.readParcelable(getClass().getClassLoader()));
364                 }
365 
366                 @Override
367                 public ComplicationStateWireFormat[] newArray(int size) {
368                     return new ComplicationStateWireFormat[size];
369                 }
370             };
371 }
372