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_POSSESSED;
20 
21 import android.app.TimePickerDialog;
22 import android.app.time.TimeCapabilities;
23 import android.app.time.TimeManager;
24 import android.app.timedetector.ManualTimeSuggestion;
25 import android.app.timedetector.TimeDetector;
26 import android.content.Context;
27 import android.text.TextUtils;
28 import android.text.format.DateFormat;
29 import android.util.Log;
30 import android.widget.TimePicker;
31 
32 import androidx.preference.Preference;
33 
34 import com.android.settings.core.BasePreferenceController;
35 import com.android.settingslib.RestrictedPreference;
36 
37 import java.util.Calendar;
38 
39 public class TimePreferenceController extends BasePreferenceController
40         implements TimePickerDialog.OnTimeSetListener {
41 
42     public interface TimePreferenceHost extends UpdateTimeAndDateCallback {
showTimePicker()43         void showTimePicker();
44     }
45 
46     public static final int DIALOG_TIMEPICKER = 1;
47 
48     private static final String TAG = "TimePreferenceController";
49 
50     private TimePreferenceHost mHost;
51     private TimeManager mTimeManager;
52 
TimePreferenceController(Context context, String preferenceKey)53     public TimePreferenceController(Context context, String preferenceKey) {
54         super(context, preferenceKey);
55         mTimeManager = context.getSystemService(TimeManager.class);
56     }
57 
setHost(TimePreferenceHost host)58     public void setHost(TimePreferenceHost host) {
59         mHost = host;
60     }
61 
62     @Override
getAvailabilityStatus()63     public int getAvailabilityStatus() {
64         return isEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
65     }
66 
67     @Override
updateState(Preference preference)68     public void updateState(Preference preference) {
69         super.updateState(preference);
70 
71         if (preference instanceof RestrictedPreference
72                 && ((RestrictedPreference) preference).isDisabledByAdmin()) {
73             return;
74         }
75         preference.setEnabled(isEnabled());
76     }
77 
78     @Override
getSummary()79     public CharSequence getSummary() {
80         Calendar now = Calendar.getInstance();
81         return DateFormat.getTimeFormat(mContext).format(now.getTime());
82     }
83 
84     @Override
handlePreferenceTreeClick(Preference preference)85     public boolean handlePreferenceTreeClick(Preference preference) {
86         if (!TextUtils.equals(getPreferenceKey(), preference.getKey())) {
87             return false;
88         }
89         mHost.showTimePicker();
90         return true;
91     }
92 
93     @Override
onTimeSet(TimePicker view, int hourOfDay, int minute)94     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
95         if (mContext != null) {
96             setTime(hourOfDay, minute);
97             mHost.updateTimeAndDateDisplay(mContext);
98         }
99         // We don't need to call timeUpdated() here because the TIME_CHANGED
100         // broadcast is sent by the AlarmManager as a side effect of setting the
101         // SystemClock time.
102     }
103 
104     /**
105      * Builds a {@link TimePickerDialog} that can be used to request the current time from the user.
106      */
buildTimePicker(Context parentContext)107     public TimePickerDialog buildTimePicker(Context parentContext) {
108         final Calendar calendar = Calendar.getInstance();
109         return new TimePickerDialog(
110                 parentContext,
111                 this,
112                 calendar.get(Calendar.HOUR_OF_DAY),
113                 calendar.get(Calendar.MINUTE),
114                 DateFormat.is24HourFormat(parentContext));
115     }
116 
setTime(int hourOfDay, int minute)117     void setTime(int hourOfDay, int minute) {
118         Calendar c = Calendar.getInstance();
119 
120         c.set(Calendar.HOUR_OF_DAY, hourOfDay);
121         c.set(Calendar.MINUTE, minute);
122         c.set(Calendar.SECOND, 0);
123         c.set(Calendar.MILLISECOND, 0);
124         long when = c.getTimeInMillis();
125 
126         TimeDetector timeDetector = mContext.getSystemService(TimeDetector.class);
127         ManualTimeSuggestion manualTimeSuggestion =
128                 TimeDetector.createManualTimeSuggestion(when, "Settings: Set time");
129         boolean success = timeDetector.suggestManualTime(manualTimeSuggestion);
130         if (!success) {
131             // This implies the system server is applying tighter bounds than the settings app or
132             // the date/time cannot be set for other reasons, e.g. perhaps "auto time" is turned on.
133             Log.w(TAG, "Unable to set time with suggestion=" + manualTimeSuggestion);
134         }
135     }
136 
137     /**
138      * Returns whether selecting the preference should prompt for the user to enter the date
139      * manually. Exposed as public so that the time controller can easily share the same logic as
140      * the rules are identical for time.
141      */
isEnabled()142     public boolean isEnabled() {
143         TimeCapabilities timeZoneCapabilities =
144                 mTimeManager.getTimeCapabilitiesAndConfig().getCapabilities();
145         int suggestManualTimeCapability = timeZoneCapabilities.getSetManualTimeCapability();
146         return suggestManualTimeCapability == CAPABILITY_POSSESSED;
147     }
148 }
149