• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 android.app.time;
18 
19 import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.app.time.Capabilities.CapabilityState;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 import android.os.UserHandle;
28 
29 import java.util.Objects;
30 
31 /**
32  * Time zone-related capabilities for a user.
33  *
34  * <p>For configuration settings capabilities, the associated settings value can be found via
35  * {@link TimeManager#getTimeZoneCapabilitiesAndConfig()} and may be changed using {@link
36  * TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)} (if the user's capabilities
37  * allow).
38  *
39  * @hide
40  */
41 @SystemApi
42 public final class TimeZoneCapabilities implements Parcelable {
43 
44     public static final @NonNull Creator<TimeZoneCapabilities> CREATOR = new Creator<>() {
45         public TimeZoneCapabilities createFromParcel(Parcel in) {
46             return TimeZoneCapabilities.createFromParcel(in);
47         }
48 
49         public TimeZoneCapabilities[] newArray(int size) {
50             return new TimeZoneCapabilities[size];
51         }
52     };
53 
54     /**
55      * The user the capabilities are for. This is used for object equality and debugging but there
56      * is no accessor.
57      */
58     @NonNull
59     private final UserHandle mUserHandle;
60     private final @CapabilityState int mConfigureAutoDetectionEnabledCapability;
61 
62     /**
63      * The values of the user's "Use location" value, AKA the Master Location Switch.
64      *
65      * <p>This is only exposed for SettingsUI and so is not part of the SDK API.
66      *
67      * <p>This is not treated as a CapabilityState as it's a boolean value that all user's have.
68      */
69     private final boolean mUseLocationEnabled;
70 
71     private final @CapabilityState int mConfigureGeoDetectionEnabledCapability;
72     private final @CapabilityState int mSetManualTimeZoneCapability;
73     private final @CapabilityState int mConfigureNotificationsEnabledCapability;
74 
TimeZoneCapabilities(@onNull Builder builder)75     private TimeZoneCapabilities(@NonNull Builder builder) {
76         this.mUserHandle = Objects.requireNonNull(builder.mUserHandle);
77         this.mConfigureAutoDetectionEnabledCapability =
78                 builder.mConfigureAutoDetectionEnabledCapability;
79         this.mUseLocationEnabled = builder.mUseLocationEnabled;
80         this.mConfigureGeoDetectionEnabledCapability =
81                 builder.mConfigureGeoDetectionEnabledCapability;
82         this.mSetManualTimeZoneCapability = builder.mSetManualTimeZoneCapability;
83         this.mConfigureNotificationsEnabledCapability =
84                 builder.mConfigureNotificationsEnabledCapability;
85     }
86 
87     @NonNull
createFromParcel(@onNull Parcel in)88     private static TimeZoneCapabilities createFromParcel(@NonNull Parcel in) {
89         UserHandle userHandle = UserHandle.readFromParcel(in);
90         return new TimeZoneCapabilities.Builder(userHandle)
91                 .setConfigureAutoDetectionEnabledCapability(in.readInt())
92                 .setUseLocationEnabled(in.readBoolean())
93                 .setConfigureGeoDetectionEnabledCapability(in.readInt())
94                 .setSetManualTimeZoneCapability(in.readInt())
95                 .setConfigureNotificationsEnabledCapability(in.readInt())
96                 .build();
97     }
98 
99     @Override
writeToParcel(@onNull Parcel dest, int flags)100     public void writeToParcel(@NonNull Parcel dest, int flags) {
101         UserHandle.writeToParcel(mUserHandle, dest);
102         dest.writeInt(mConfigureAutoDetectionEnabledCapability);
103         dest.writeBoolean(mUseLocationEnabled);
104         dest.writeInt(mConfigureGeoDetectionEnabledCapability);
105         dest.writeInt(mSetManualTimeZoneCapability);
106         dest.writeInt(mConfigureNotificationsEnabledCapability);
107     }
108 
109     /**
110      * Returns the capability state associated with the user's ability to modify the automatic time
111      * zone detection setting. The setting can be updated via {@link
112      * TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)}.
113      */
114     @CapabilityState
getConfigureAutoDetectionEnabledCapability()115     public int getConfigureAutoDetectionEnabledCapability() {
116         return mConfigureAutoDetectionEnabledCapability;
117     }
118 
119     /**
120      * Returns {@code true} if the device's location can be used by the Android system, and
121      * therefore the platform components running on behalf of the user. At the time of writing, the
122      * user can change this via the "Use location" setting on the Location settings screen.
123      *
124      * Not part of the SDK API because it is intended for use by SettingsUI, which can display
125      * text about needing it to be on for location-based time zone detection.
126      *
127      * @hide
128      */
isUseLocationEnabled()129     public boolean isUseLocationEnabled() {
130         return mUseLocationEnabled;
131     }
132 
133     /**
134      * Returns the capability state associated with the user's ability to modify the geolocation
135      * detection setting. The setting can be updated via {@link
136      * TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)}.
137      */
138     @CapabilityState
getConfigureGeoDetectionEnabledCapability()139     public int getConfigureGeoDetectionEnabledCapability() {
140         return mConfigureGeoDetectionEnabledCapability;
141     }
142 
143     /**
144      * Returns the capability state associated with the user's ability to manually set the time zone
145      * on a device.
146      *
147      * <p>The time zone will be ignored in all cases unless the value is {@link
148      * Capabilities#CAPABILITY_POSSESSED}. See also
149      * {@link TimeZoneConfiguration#isAutoDetectionEnabled()}.
150      */
151     @CapabilityState
getSetManualTimeZoneCapability()152     public int getSetManualTimeZoneCapability() {
153         return mSetManualTimeZoneCapability;
154     }
155 
156     /**
157      * Returns the capability state associated with the user's ability to modify the time zone
158      * notification setting. The setting can be updated via {@link
159      * TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)}.
160      *
161      * @hide
162      */
163     @CapabilityState
getConfigureNotificationsEnabledCapability()164     public int getConfigureNotificationsEnabledCapability() {
165         return mConfigureNotificationsEnabledCapability;
166     }
167 
168     /**
169      * Tries to create a new {@link TimeZoneConfiguration} from the {@code config} and the set of
170      * {@code requestedChanges}, if {@code this} capabilities allow. The new configuration is
171      * returned. If the capabilities do not permit one or more of the requested changes then {@code
172      * null} is returned.
173      *
174      * @hide
175      */
176     @Nullable
tryApplyConfigChanges( @onNull TimeZoneConfiguration config, @NonNull TimeZoneConfiguration requestedChanges)177     public TimeZoneConfiguration tryApplyConfigChanges(
178             @NonNull TimeZoneConfiguration config,
179             @NonNull TimeZoneConfiguration requestedChanges) {
180         TimeZoneConfiguration.Builder newConfigBuilder = new TimeZoneConfiguration.Builder(config);
181         if (requestedChanges.hasIsAutoDetectionEnabled()) {
182             if (this.getConfigureAutoDetectionEnabledCapability() < CAPABILITY_NOT_APPLICABLE) {
183                 return null;
184             }
185             newConfigBuilder.setAutoDetectionEnabled(requestedChanges.isAutoDetectionEnabled());
186         }
187 
188         if (requestedChanges.hasIsGeoDetectionEnabled()) {
189             if (this.getConfigureGeoDetectionEnabledCapability() < CAPABILITY_NOT_APPLICABLE) {
190                 return null;
191             }
192             newConfigBuilder.setGeoDetectionEnabled(requestedChanges.isGeoDetectionEnabled());
193         }
194 
195         if (requestedChanges.hasIsNotificationsEnabled()) {
196             if (this.getConfigureNotificationsEnabledCapability() < CAPABILITY_NOT_APPLICABLE) {
197                 return null;
198             }
199             newConfigBuilder.setNotificationsEnabled(requestedChanges.areNotificationsEnabled());
200         }
201         return newConfigBuilder.build();
202     }
203 
204     @Override
describeContents()205     public int describeContents() {
206         return 0;
207     }
208 
209     @Override
equals(@ullable Object o)210     public boolean equals(@Nullable Object o) {
211         if (this == o) {
212             return true;
213         }
214         if (o == null || getClass() != o.getClass()) {
215             return false;
216         }
217         TimeZoneCapabilities that = (TimeZoneCapabilities) o;
218         return mUserHandle.equals(that.mUserHandle)
219                 && mConfigureAutoDetectionEnabledCapability
220                 == that.mConfigureAutoDetectionEnabledCapability
221                 && mUseLocationEnabled == that.mUseLocationEnabled
222                 && mConfigureGeoDetectionEnabledCapability
223                 == that.mConfigureGeoDetectionEnabledCapability
224                 && mSetManualTimeZoneCapability == that.mSetManualTimeZoneCapability
225                 && mConfigureNotificationsEnabledCapability
226                 == that.mConfigureNotificationsEnabledCapability;
227     }
228 
229     @Override
hashCode()230     public int hashCode() {
231         return Objects.hash(mUserHandle, mConfigureAutoDetectionEnabledCapability,
232                 mConfigureGeoDetectionEnabledCapability, mSetManualTimeZoneCapability,
233                 mConfigureNotificationsEnabledCapability);
234     }
235 
236     @Override
toString()237     public String toString() {
238         return "TimeZoneDetectorCapabilities{"
239                 + "mUserHandle=" + mUserHandle
240                 + ", mConfigureAutoDetectionEnabledCapability="
241                 + mConfigureAutoDetectionEnabledCapability
242                 + ", mUseLocationEnabled=" + mUseLocationEnabled
243                 + ", mConfigureGeoDetectionEnabledCapability="
244                 + mConfigureGeoDetectionEnabledCapability
245                 + ", mSetManualTimeZoneCapability=" + mSetManualTimeZoneCapability
246                 + ", mConfigureNotificationsEnabledCapability="
247                 + mConfigureNotificationsEnabledCapability
248                 + '}';
249     }
250 
251     /**
252      * A builder of {@link TimeZoneCapabilities} objects.
253      *
254      * @hide
255      */
256     public static class Builder {
257 
258         @NonNull
259         private UserHandle mUserHandle;
260         private @CapabilityState int mConfigureAutoDetectionEnabledCapability;
261         private Boolean mUseLocationEnabled;
262         private @CapabilityState int mConfigureGeoDetectionEnabledCapability;
263         private @CapabilityState int mSetManualTimeZoneCapability;
264         private @CapabilityState int mConfigureNotificationsEnabledCapability;
265 
Builder(@onNull UserHandle userHandle)266         public Builder(@NonNull UserHandle userHandle) {
267             mUserHandle = Objects.requireNonNull(userHandle);
268         }
269 
Builder(@onNull TimeZoneCapabilities capabilitiesToCopy)270         public Builder(@NonNull TimeZoneCapabilities capabilitiesToCopy) {
271             Objects.requireNonNull(capabilitiesToCopy);
272             mUserHandle = capabilitiesToCopy.mUserHandle;
273             mConfigureAutoDetectionEnabledCapability =
274                     capabilitiesToCopy.mConfigureAutoDetectionEnabledCapability;
275             mUseLocationEnabled = capabilitiesToCopy.mUseLocationEnabled;
276             mConfigureGeoDetectionEnabledCapability =
277                     capabilitiesToCopy.mConfigureGeoDetectionEnabledCapability;
278             mSetManualTimeZoneCapability =
279                     capabilitiesToCopy.mSetManualTimeZoneCapability;
280             mConfigureNotificationsEnabledCapability =
281                     capabilitiesToCopy.mConfigureNotificationsEnabledCapability;
282         }
283 
284         /** Sets the value for the "configure automatic time zone detection enabled" capability. */
setConfigureAutoDetectionEnabledCapability(@apabilityState int value)285         public Builder setConfigureAutoDetectionEnabledCapability(@CapabilityState int value) {
286             this.mConfigureAutoDetectionEnabledCapability = value;
287             return this;
288         }
289 
290         /** Sets the values for "use location". See {@link #isUseLocationEnabled()}. */
setUseLocationEnabled(boolean useLocation)291         public Builder setUseLocationEnabled(boolean useLocation) {
292             mUseLocationEnabled = useLocation;
293             return this;
294         }
295 
296         /**
297          * Sets the value for the "configure geolocation time zone detection enabled" capability.
298          */
setConfigureGeoDetectionEnabledCapability(@apabilityState int value)299         public Builder setConfigureGeoDetectionEnabledCapability(@CapabilityState int value) {
300             this.mConfigureGeoDetectionEnabledCapability = value;
301             return this;
302         }
303 
304         /** Sets the value for the "set manual time zone" capability. */
setSetManualTimeZoneCapability(@apabilityState int value)305         public Builder setSetManualTimeZoneCapability(@CapabilityState int value) {
306             this.mSetManualTimeZoneCapability = value;
307             return this;
308         }
309 
310         /**
311          * Sets the value for the "configure time notifications enabled" capability.
312          */
setConfigureNotificationsEnabledCapability(@apabilityState int value)313         public Builder setConfigureNotificationsEnabledCapability(@CapabilityState int value) {
314             this.mConfigureNotificationsEnabledCapability = value;
315             return this;
316         }
317 
318         /** Returns the {@link TimeZoneCapabilities}. */
319         @NonNull
build()320         public TimeZoneCapabilities build() {
321             verifyCapabilitySet(mConfigureAutoDetectionEnabledCapability,
322                     "configureAutoDetectionEnabledCapability");
323             Objects.requireNonNull(mUseLocationEnabled, "useLocationEnabled");
324             verifyCapabilitySet(mConfigureGeoDetectionEnabledCapability,
325                     "configureGeoDetectionEnabledCapability");
326             verifyCapabilitySet(mSetManualTimeZoneCapability,
327                     "setManualTimeZoneCapability");
328             verifyCapabilitySet(mConfigureNotificationsEnabledCapability,
329                     "configureNotificationsEnabledCapability");
330             return new TimeZoneCapabilities(this);
331         }
332 
verifyCapabilitySet(int value, String name)333         private void verifyCapabilitySet(int value, String name) {
334             if (value == 0) {
335                 throw new IllegalStateException(name + " not set");
336             }
337         }
338     }
339 }
340