Move date/time prefs to PreferenceController and add tests.

Bug: 32996243
Test: RunSettingsRoboTests
Change-Id: Ie537bbcc35a96a63251e46f84b57c0a861b9d013
This commit is contained in:
Fan Zhang
2016-11-18 11:10:05 -08:00
parent 9a35bc6552
commit beddff82b0
17 changed files with 1155 additions and 263 deletions

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.content.Context;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import com.android.settings.core.PreferenceController;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
public class AutoTimePreferenceController extends PreferenceController
implements Preference.OnPreferenceChangeListener {
private static final String KEY_AUTO_TIME = "auto_time";
private final UpdateTimeAndDateCallback mCallback;
public AutoTimePreferenceController(Context context, UpdateTimeAndDateCallback callback) {
super(context);
mCallback = callback;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
return false;
}
@Override
public void updateState(Preference preference) {
if (!(preference instanceof RestrictedSwitchPreference)) {
return;
}
((RestrictedSwitchPreference) preference).setDisabledByAdmin(
getEnforcedAdminProperty());
((RestrictedSwitchPreference) preference).setChecked(isEnabled());
}
@Override
public String getPreferenceKey() {
return KEY_AUTO_TIME;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean autoEnabled = (Boolean) newValue;
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AUTO_TIME,
autoEnabled ? 1 : 0);
mCallback.updateTimeAndDateDisplay(mContext);
return true;
}
public boolean isEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.AUTO_TIME, 0) > 0;
}
private RestrictedLockUtils.EnforcedAdmin getEnforcedAdminProperty() {
return RestrictedLockUtils.checkIfAutoTimeRequired(mContext);
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.content.Context;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceController;
public class AutoTimeZonePreferenceController extends PreferenceController
implements Preference.OnPreferenceChangeListener {
private static final String KEY_AUTO_TIME_ZONE = "auto_zone";
private final boolean mIsFromSUW;
private final UpdateTimeAndDateCallback mCallback;
public AutoTimeZonePreferenceController(Context context, UpdateTimeAndDateCallback callback,
boolean isFromSUW) {
super(context);
mCallback = callback;
mIsFromSUW = isFromSUW;
}
@Override
public boolean isAvailable() {
return !(Utils.isWifiOnly(mContext) || mIsFromSUW);
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
return false;
}
@Override
public String getPreferenceKey() {
return KEY_AUTO_TIME_ZONE;
}
@Override
public void updateState(Preference preference) {
if (!(preference instanceof SwitchPreference)) {
return;
}
((SwitchPreference) preference).setChecked(isEnabled());
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean autoZoneEnabled = (Boolean) newValue;
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AUTO_TIME_ZONE,
autoZoneEnabled ? 1 : 0);
mCallback.updateTimeAndDateDisplay(mContext);
return true;
}
public boolean isEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.AUTO_TIME_ZONE, 0) > 0;
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.DatePickerDialog;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.widget.DatePicker;
import com.android.settings.core.PreferenceController;
import java.util.Calendar;
public class DatePreferenceController extends PreferenceController implements
DatePickerDialog.OnDateSetListener {
public interface DatePreferenceHost extends UpdateTimeAndDateCallback {
void showDatePicker();
}
public static final int DIALOG_DATEPICKER = 0;
private static final String KEY_DATE = "date";
private final DatePreferenceHost mHost;
private final AutoTimePreferenceController mAutoTimePreferenceController;
public DatePreferenceController(Context context, DatePreferenceHost host,
AutoTimePreferenceController autoTimePreferenceController) {
super(context);
mHost = host;
mAutoTimePreferenceController = autoTimePreferenceController;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
final Calendar now = Calendar.getInstance();
preference.setSummary(DateFormat.getLongDateFormat(mContext).format(now.getTime()));
preference.setEnabled(!mAutoTimePreferenceController.isEnabled());
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), KEY_DATE)) {
return false;
}
mHost.showDatePicker();
return true;
}
@Override
public String getPreferenceKey() {
return KEY_DATE;
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
setDate(year, month, day);
mHost.updateTimeAndDateDisplay(mContext);
}
public DatePickerDialog buildDatePicker(Activity activity) {
final Calendar calendar = Calendar.getInstance();
final DatePickerDialog d = new DatePickerDialog(
activity,
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
// The system clock can't represent dates outside this range.
calendar.clear();
calendar.set(2007, Calendar.JANUARY, 1);
d.getDatePicker().setMinDate(calendar.getTimeInMillis());
calendar.clear();
calendar.set(2037, Calendar.DECEMBER, 31);
d.getDatePicker().setMaxDate(calendar.getTimeInMillis());
return d;
}
@VisibleForTesting
void setDate(int year, int month, int day) {
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
long when = Math.max(c.getTimeInMillis(), DatePreferenceHost.MIN_DATE);
if (when / 1000 < Integer.MAX_VALUE) {
((AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE)).setTime(when);
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnPause;
import com.android.settings.core.lifecycle.events.OnResume;
public class TimeChangeListenerMixin extends BroadcastReceiver
implements LifecycleObserver, OnPause, OnResume {
private final Context mContext;
private final UpdateTimeAndDateCallback mCallback;
public TimeChangeListenerMixin(Context context, UpdateTimeAndDateCallback callback) {
mContext = context;
mCallback = callback;
}
@Override
public void onResume() {
// Register for time ticks and other reasons for time change
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
mContext.registerReceiver(this, filter, null, null);
}
@Override
public void onPause() {
mContext.unregisterReceiver(this);
}
@Override
public void onReceive(Context context, Intent intent) {
if (mCallback != null) {
mCallback.updateTimeAndDateDisplay(mContext);
}
}
}

View File

@@ -58,8 +58,7 @@ public class TimeFormatPreferenceController extends PreferenceController {
@Override
public void updateState(Preference preference) {
if (!(preference instanceof TwoStatePreference)
|| !TextUtils.equals(KEY_TIME_FORMAT, preference.getKey())) {
if (!(preference instanceof TwoStatePreference)) {
return;
}
((TwoStatePreference) preference).setChecked(is24Hour());

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.TimePickerDialog;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.widget.TimePicker;
import com.android.settings.core.PreferenceController;
import java.util.Calendar;
public class TimePreferenceController extends PreferenceController implements
TimePickerDialog.OnTimeSetListener {
public interface TimePreferenceHost extends UpdateTimeAndDateCallback {
void showTimePicker();
}
public static final int DIALOG_TIMEPICKER = 1;
private static final String KEY_TIME = "time";
private final AutoTimePreferenceController mAutoTimePreferenceController;
private final TimePreferenceHost mHost;
public TimePreferenceController(Context context,
TimePreferenceHost callback,
AutoTimePreferenceController autoTimePreferenceController) {
super(context);
mHost = callback;
mAutoTimePreferenceController = autoTimePreferenceController;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
final Calendar now = Calendar.getInstance();
preference.setSummary(DateFormat.getTimeFormat(mContext).format(now.getTime()));
preference.setEnabled(!mAutoTimePreferenceController.isEnabled());
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(KEY_TIME, preference.getKey())) {
return false;
}
mHost.showTimePicker();
return true;
}
@Override
public String getPreferenceKey() {
return KEY_TIME;
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
if (mContext != null) {
setTime(hourOfDay, minute);
mHost.updateTimeAndDateDisplay(mContext);
}
// We don't need to call timeUpdated() here because the TIME_CHANGED
// broadcast is sent by the AlarmManager as a side effect of setting the
// SystemClock time.
}
public TimePickerDialog buildTimePicker(Activity activity) {
final Calendar calendar = Calendar.getInstance();
return new TimePickerDialog(
activity,
this,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
DateFormat.is24HourFormat(activity));
}
void setTime(int hourOfDay, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long when = Math.max(c.getTimeInMillis(), TimePreferenceHost.MIN_DATE);
if (when / 1000 < Integer.MAX_VALUE) {
((AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE)).setTime(when);
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.datetime;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.core.PreferenceController;
import com.android.settingslib.datetime.ZoneGetter;
import java.util.Calendar;
public class TimeZonePreferenceController extends PreferenceController {
private static final String KEY_TIMEZONE = "timezone";
private final AutoTimeZonePreferenceController mAutoTimeZonePreferenceController;
public TimeZonePreferenceController(Context context,
AutoTimeZonePreferenceController autoTimeZonePreferenceController) {
super(context);
mAutoTimeZonePreferenceController = autoTimeZonePreferenceController;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(getTimeZoneOffsetAndName());
preference.setEnabled(!mAutoTimeZonePreferenceController.isEnabled());
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
return false;
}
@Override
public String getPreferenceKey() {
return KEY_TIMEZONE;
}
@VisibleForTesting
CharSequence getTimeZoneOffsetAndName() {
final Calendar now = Calendar.getInstance();
return ZoneGetter.getTimeZoneOffsetAndName(mContext,
now.getTimeZone(), now.getTime());
}
}

View File

@@ -19,6 +19,8 @@ package com.android.settings.datetime;
import android.content.Context;
public interface UpdateTimeAndDateCallback {
// Minimum time is Nov 5, 2007, 0:00.
long MIN_DATE = 1194220800000L;
void updateTimeAndDateDisplay(Context context);
}