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