• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 com.android.settings.datetime;
18 
19 import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
20 import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
21 import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
22 import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
23 
24 import android.app.time.TimeManager;
25 import android.app.time.TimeZoneCapabilities;
26 import android.app.time.TimeZoneCapabilitiesAndConfig;
27 import android.app.time.TimeZoneConfiguration;
28 import android.content.Context;
29 import android.util.Log;
30 
31 import androidx.preference.Preference;
32 
33 import com.android.internal.annotations.VisibleForTesting;
34 import com.android.settings.R;
35 import com.android.settings.core.TogglePreferenceController;
36 
37 public class AutoTimeZonePreferenceController extends TogglePreferenceController {
38 
39     private static final String TAG = "AutoTimeZonePreferenceController";
40 
41     private boolean mIsFromSUW;
42     private UpdateTimeAndDateCallback mCallback;
43     private final TimeManager mTimeManager;
44 
AutoTimeZonePreferenceController(Context context, String preferenceKey)45     public AutoTimeZonePreferenceController(Context context, String preferenceKey) {
46         super(context, preferenceKey);
47         mTimeManager = context.getSystemService(TimeManager.class);
48         // This is a no-op implementation of UpdateTimeAndDateCallback to avoid a NPE when
49         // setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
50         // controller is instantiated outside of the context of the real Date & Time settings
51         // screen.
52         mCallback = (c) -> {};
53     }
54 
55     /**
56      * Set the Time and Date callback
57      */
setTimeAndDateCallback( UpdateTimeAndDateCallback callback)58     public AutoTimeZonePreferenceController setTimeAndDateCallback(
59             UpdateTimeAndDateCallback callback) {
60         mCallback = callback;
61         return this;
62     }
63 
64     /**
65      * Set if current fragment is launched via SUW
66      */
setFromSUW(boolean isFromSUW)67     public AutoTimeZonePreferenceController setFromSUW(boolean isFromSUW) {
68         mIsFromSUW = isFromSUW;
69         return this;
70     }
71 
72     @Override
getAvailabilityStatus()73     public int getAvailabilityStatus() {
74         if (mIsFromSUW) {
75             return DISABLED_DEPENDENT_SETTING;
76         }
77 
78         TimeZoneCapabilities timeZoneCapabilities =
79                 getTimeZoneCapabilitiesAndConfig().getCapabilities();
80         int capability = timeZoneCapabilities.getConfigureAutoDetectionEnabledCapability();
81 
82         // The preference has three states: visible, not visible, and visible but disabled.
83         // This method handles the "is visible?" check.
84         switch (capability) {
85             case CAPABILITY_NOT_SUPPORTED:
86                 return DISABLED_DEPENDENT_SETTING;
87             case CAPABILITY_POSSESSED:
88             case CAPABILITY_NOT_ALLOWED:
89                 // This case is expected for enterprise restrictions, where the toggle should be
90                 // present but disabled. Disabling is handled declaratively via the
91                 // settings:userRestriction attribute in .xml. The client-side logic is expected to
92                 // concur with the capabilities logic in the system server.
93             case CAPABILITY_NOT_APPLICABLE:
94                 // CAPABILITY_NOT_APPLICABLE is not currently expected, so this is return value is
95                 // arbitrary.
96                 return AVAILABLE;
97             default:
98                 Log.e(TAG, "Unknown capability=" + capability);
99                 return UNSUPPORTED_ON_DEVICE;
100         }
101     }
102 
103     @Override
isChecked()104     public boolean isChecked() {
105         return isEnabled();
106     }
107 
108     @Override
setChecked(boolean isChecked)109     public boolean setChecked(boolean isChecked) {
110         TimeZoneConfiguration.Builder configuration = new TimeZoneConfiguration.Builder()
111                 .setAutoDetectionEnabled(isChecked);
112 
113         // "Use location for time zone" is only used if "Automatic time zone" is enabled. If
114         // the user toggles off automatic time zone, set the toggle off and disable the toggle.
115         int geoDetectionCapability = mTimeManager
116                 .getTimeZoneCapabilitiesAndConfig()
117                 .getCapabilities()
118                 .getConfigureGeoDetectionEnabledCapability();
119 
120         if (!isChecked
121                 && (geoDetectionCapability == CAPABILITY_NOT_APPLICABLE
122                 || geoDetectionCapability == CAPABILITY_POSSESSED)) {
123             configuration.setGeoDetectionEnabled(false);
124         }
125 
126         boolean result = mTimeManager.updateTimeZoneConfiguration(configuration.build());
127 
128         mCallback.updateTimeAndDateDisplay(mContext);
129         return result;
130     }
131 
132     @Override
getSliceHighlightMenuRes()133     public int getSliceHighlightMenuRes() {
134         return R.string.menu_key_system;
135     }
136 
137     @Override
updateState(Preference preference)138     public void updateState(Preference preference) {
139         super.updateState(preference);
140         refreshSummary(preference);
141     }
142 
143     @Override
getSummary()144     public CharSequence getSummary() {
145         // If auto time zone cannot enable telephony fallback and is capable of location, then auto
146         // time zone must use location.
147         if (LocationProviderStatusPreferenceController.hasLocationTimeZoneNoTelephonyFallback(
148                 mTimeManager.getTimeZoneCapabilitiesAndConfig().getDetectorStatus())) {
149             return mContext.getString(R.string.auto_zone_requires_location_summary);
150         }
151 
152         // If the user has a dedicated toggle to control location use, explain what it does.
153         return mContext.getString(R.string.zone_auto_title_summary);
154     }
155 
156     @VisibleForTesting
isEnabled()157     boolean isEnabled() {
158         return mTimeManager
159                 .getTimeZoneCapabilitiesAndConfig()
160                 .getConfiguration()
161                 .isAutoDetectionEnabled();
162     }
163 
getTimeZoneCapabilitiesAndConfig()164     private TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig() {
165         return mTimeManager.getTimeZoneCapabilitiesAndConfig();
166     }
167 }
168