• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceScreen;
35 
36 import com.android.settings.R;
37 import com.android.settings.core.TogglePreferenceController;
38 import com.android.settingslib.core.lifecycle.LifecycleObserver;
39 import com.android.settingslib.core.lifecycle.events.OnStart;
40 import com.android.settingslib.core.lifecycle.events.OnStop;
41 
42 import java.util.concurrent.Executor;
43 
44 public final class TimeZoneNotificationsPreferenceController
45         extends TogglePreferenceController
46         implements LifecycleObserver, OnStart, OnStop, TimeManager.TimeZoneDetectorListener {
47 
48     private static final String TAG = "TZNotificationsSettings";
49 
50     private final TimeManager mTimeManager;
51     private @Nullable TimeZoneCapabilitiesAndConfig mTimeZoneCapabilitiesAndConfig;
52     private @Nullable Preference mPreference;
53 
TimeZoneNotificationsPreferenceController(@onNull Context context, @NonNull String preferenceKey)54     public TimeZoneNotificationsPreferenceController(@NonNull Context context,
55             @NonNull String preferenceKey) {
56         super(context, preferenceKey);
57         mTimeManager = context.getSystemService(TimeManager.class);
58     }
59 
60     /**
61      * Registers this controller with a category controller so that the category can be optionally
62      * displayed, i.e. if all the child controllers are not available, the category heading won't be
63      * available.
64      */
registerIn(@onNull NotificationsPreferenceCategoryController categoryController)65     public void registerIn(@NonNull NotificationsPreferenceCategoryController categoryController) {
66         categoryController.addChildController(this);
67     }
68 
69     @Override
isChecked()70     public boolean isChecked() {
71         if (!isAutoTimeZoneEnabled()) {
72             return false;
73         }
74 
75         // forceRefresh set to true as the notifications toggle may have been turned off by
76         // switching off automatic time zone
77         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
78                 getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ true);
79         TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
80         return configuration.areNotificationsEnabled();
81     }
82 
83 
84     @Override
setChecked(boolean isChecked)85     public boolean setChecked(boolean isChecked) {
86         TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
87                 .setNotificationsEnabled(isChecked)
88                 .build();
89         return mTimeManager.updateTimeZoneConfiguration(configuration);
90     }
91 
92     @Override
displayPreference(@onNull PreferenceScreen screen)93     public void displayPreference(@NonNull PreferenceScreen screen) {
94         super.displayPreference(screen);
95         mPreference = screen.findPreference(getPreferenceKey());
96     }
97 
98     @Override
onStart()99     public void onStart() {
100         // Register for updates to the user's time zone capabilities or configuration which could
101         // require UI changes.
102         Executor mainExecutor = mContext.getMainExecutor();
103         mTimeManager.addTimeZoneDetectorListener(mainExecutor, this);
104         // Setup the initial state.
105         refreshUi();
106     }
107 
108     @Override
onStop()109     public void onStop() {
110         mTimeManager.removeTimeZoneDetectorListener(this);
111     }
112 
113     @Override
isSliceable()114     public boolean isSliceable() {
115         return true;
116     }
117 
118     @Override
getSliceHighlightMenuRes()119     public int getSliceHighlightMenuRes() {
120         return R.string.menu_key_system;
121     }
122 
123     @Override
updateState(@onNull Preference preference)124     public void updateState(@NonNull Preference preference) {
125         super.updateState(preference);
126 
127         // enable / disable the toggle based on automatic time zone being enabled or not
128         preference.setEnabled(isAutoTimeZoneEnabled());
129     }
130 
131 
132     @Override
getAvailabilityStatus()133     public int getAvailabilityStatus() {
134         TimeZoneCapabilities timeZoneCapabilities =
135                 getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ false).getCapabilities();
136         int capability = timeZoneCapabilities.getConfigureNotificationsEnabledCapability();
137 
138         // The preference can be present and enabled, present and disabled or not present.
139         if (capability == CAPABILITY_NOT_SUPPORTED || capability == CAPABILITY_NOT_ALLOWED) {
140             return UNSUPPORTED_ON_DEVICE;
141         } else if (capability == CAPABILITY_NOT_APPLICABLE || capability == CAPABILITY_POSSESSED) {
142             return isAutoTimeZoneEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
143         } else {
144             Log.e(TAG, "Unknown capability=" + capability);
145             return UNSUPPORTED_ON_DEVICE;
146         }
147     }
148 
149     /**
150      * Implementation of {@link TimeManager.TimeZoneDetectorListener#onChange()}. Called by the
151      * system server after a change that affects {@link TimeZoneCapabilitiesAndConfig}.
152      */
153     @Override
onChange()154     public void onChange() {
155         refreshUi();
156     }
157 
158     @Override
159     @NonNull
getSummary()160     public CharSequence getSummary() {
161         return mContext.getString(R.string.time_zone_change_notifications_toggle_summary);
162     }
163 
refreshUi()164     private void refreshUi() {
165         // Force a refresh of cached user capabilities and config.
166         getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ true);
167         refreshSummary(mPreference);
168     }
169 
170     /**
171      * Returns the current user capabilities and configuration. {@code forceRefresh} can be {@code
172      * true} to discard any cached copy.
173      */
getTimeZoneCapabilitiesAndConfig(boolean forceRefresh)174     private TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig(boolean forceRefresh) {
175         if (forceRefresh || mTimeZoneCapabilitiesAndConfig == null) {
176             mTimeZoneCapabilitiesAndConfig = mTimeManager.getTimeZoneCapabilitiesAndConfig();
177         }
178         return mTimeZoneCapabilitiesAndConfig;
179     }
180 
181     /**
182      * Returns whether the user can select this preference or not, as it is a sub toggle of
183      * automatic time zone.
184      */
isAutoTimeZoneEnabled()185     private boolean isAutoTimeZoneEnabled() {
186         return mTimeManager.getTimeZoneCapabilitiesAndConfig().getConfiguration()
187                 .isAutoDetectionEnabled();
188     }
189 }
190