From 305b72c92568a2dd2ece08caebd610ec8bd473f4 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 27 Feb 2017 12:46:04 -0800 Subject: [PATCH] Added auto-fill support for DatePicker and TimePicker. Also fixed some getAutoFillType() implementations to return null when the view is disabled. Bug: 33550221 Bug: 35840787 Test: CtsAutoFillServiceTestCases (with new tests) pass Test: m update-api Change-Id: I46acc1fb106cf2153515cc1c9567b34cfabd1c62 --- api/current.txt | 4 ++ api/system-current.txt | 4 ++ api/test-current.txt | 4 ++ .../android/view/autofill/AutoFillType.java | 38 ++++++++--- .../android/view/autofill/AutoFillValue.java | 48 +++++++++++--- core/java/android/widget/CompoundButton.java | 2 +- core/java/android/widget/DatePicker.java | 60 +++++++++++++++++ .../widget/DatePickerCalendarDelegate.java | 10 ++- .../widget/DatePickerSpinnerDelegate.java | 4 ++ core/java/android/widget/RadioGroup.java | 2 +- core/java/android/widget/TimePicker.java | 64 +++++++++++++++++++ .../widget/TimePickerClockDelegate.java | 3 + .../widget/TimePickerSpinnerDelegate.java | 3 + 13 files changed, 222 insertions(+), 24 deletions(-) diff --git a/api/current.txt b/api/current.txt index 445c576cf091e..d38ef3dc6ab55 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47095,10 +47095,12 @@ package android.view.autofill { public final class AutoFillType implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillType forDate(); method public static android.view.autofill.AutoFillType forList(); method public static android.view.autofill.AutoFillType forText(int); method public static android.view.autofill.AutoFillType forToggle(); method public int getSubType(); + method public boolean isDate(); method public boolean isList(); method public boolean isText(); method public boolean isToggle(); @@ -47108,9 +47110,11 @@ package android.view.autofill { public final class AutoFillValue implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillValue forDate(long); method public static android.view.autofill.AutoFillValue forList(int); method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence); method public static android.view.autofill.AutoFillValue forToggle(boolean); + method public long getDateValue(); method public int getListValue(); method public java.lang.CharSequence getTextValue(); method public boolean getToggleValue(); diff --git a/api/system-current.txt b/api/system-current.txt index e00507ee884cb..94f3c01a301fe 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -50443,10 +50443,12 @@ package android.view.autofill { public final class AutoFillType implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillType forDate(); method public static android.view.autofill.AutoFillType forList(); method public static android.view.autofill.AutoFillType forText(int); method public static android.view.autofill.AutoFillType forToggle(); method public int getSubType(); + method public boolean isDate(); method public boolean isList(); method public boolean isText(); method public boolean isToggle(); @@ -50456,9 +50458,11 @@ package android.view.autofill { public final class AutoFillValue implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillValue forDate(long); method public static android.view.autofill.AutoFillValue forList(int); method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence); method public static android.view.autofill.AutoFillValue forToggle(boolean); + method public long getDateValue(); method public int getListValue(); method public java.lang.CharSequence getTextValue(); method public boolean getToggleValue(); diff --git a/api/test-current.txt b/api/test-current.txt index 500a0569bfd2e..4b47ed28956a7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -47459,10 +47459,12 @@ package android.view.autofill { public final class AutoFillType implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillType forDate(); method public static android.view.autofill.AutoFillType forList(); method public static android.view.autofill.AutoFillType forText(int); method public static android.view.autofill.AutoFillType forToggle(); method public int getSubType(); + method public boolean isDate(); method public boolean isList(); method public boolean isText(); method public boolean isToggle(); @@ -47472,9 +47474,11 @@ package android.view.autofill { public final class AutoFillValue implements android.os.Parcelable { method public int describeContents(); + method public static android.view.autofill.AutoFillValue forDate(long); method public static android.view.autofill.AutoFillValue forList(int); method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence); method public static android.view.autofill.AutoFillValue forToggle(boolean); + method public long getDateValue(); method public int getListValue(); method public java.lang.CharSequence getTextValue(); method public boolean getToggleValue(); diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java index 5d85bfdac095b..e974705178335 100644 --- a/core/java/android/view/autofill/AutoFillType.java +++ b/core/java/android/view/autofill/AutoFillType.java @@ -40,18 +40,13 @@ public final class AutoFillType implements Parcelable { private static class DefaultTypesHolder { static final AutoFillType TOGGLE = new AutoFillType(TYPE_TOGGLE, 0); static final AutoFillType LIST = new AutoFillType(TYPE_LIST, 0); + static final AutoFillType DATE = new AutoFillType(TYPE_DATE, 0); } private static final int TYPE_TEXT = 1; private static final int TYPE_TOGGLE = 2; private static final int TYPE_LIST = 3; - - // TODO(b/33197203): add others, like date picker? That would be trick, because they're set as: - // updateDate(int year, int month, int dayOfMonth) - // So, we would have to either use a long representing the Date.time(), or a custom long - // representing: - // year * 10000 + month * 100 + day - // Then a custom getDatePickerValue(Bundle) that returns an immutable object with these 3 fields + private static final int TYPE_DATE = 4; private final int mType; private final int mSubType; @@ -65,7 +60,7 @@ public final class AutoFillType implements Parcelable { * Checks if this is a type for a text field, which is filled by a {@link CharSequence}. * *

{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through - * {@link AutoFillValue#forText(CharSequence)}, and the value of a bundle passed to auto-fill a + * {@link AutoFillValue#forText(CharSequence)}, and the value passed to auto-fill a * {@link View} can be fetched through {@link AutoFillValue#getTextValue()}. * *

Sub-type for this type is the value defined by {@link TextView#getInputType()}. @@ -78,7 +73,7 @@ public final class AutoFillType implements Parcelable { * Checks if this is a a type for a togglable field, which is filled by a {@code boolean}. * *

{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through - * {@link AutoFillValue#forToggle(boolean)}, and the value of a bundle passed to auto-fill a + * {@link AutoFillValue#forToggle(boolean)}, and the value passed to auto-fill a * {@link View} can be fetched through {@link AutoFillValue#getToggleValue()}. * *

This type has no sub-types. @@ -92,7 +87,7 @@ public final class AutoFillType implements Parcelable { * representing the element index inside the list (starting at {@code 0}. * *

{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through - * {@link AutoFillValue#forList(int)}, and the value of a bundle passed to auto-fill a + * {@link AutoFillValue#forList(int)}, and the value passed to auto-fill a * {@link View} can be fetched through {@link AutoFillValue#getListValue()}. * *

This type has no sub-types. @@ -101,6 +96,20 @@ public final class AutoFillType implements Parcelable { return mType == TYPE_LIST; } + /** + * Checks if this is a type for a date and time, which is represented by a long representing + * the number of milliseconds since the standard base time known as "the epoch", namely + * January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()}. + * + *

{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through + * {@link AutoFillValue#forDate(long)}, and the values passed to + * auto-fill a {@link View} can be fetched through {@link AutoFillValue#getDateValue()}. + * + *

This type has no sub-types. + */ + public boolean isDate() { + return mType == TYPE_DATE; + } /** * Gets the optional sub-type, representing the {@link View}'s semantic. @@ -206,4 +215,13 @@ public final class AutoFillType implements Parcelable { public static AutoFillType forList() { return DefaultTypesHolder.LIST; } + + /** + * Creates a type that represents a date. + * + *

See {@link #isDate()} for more info. + */ + public static AutoFillType forDate() { + return DefaultTypesHolder.DATE; + } } diff --git a/core/java/android/view/autofill/AutoFillValue.java b/core/java/android/view/autofill/AutoFillValue.java index d9afa3ba2dee5..c24e04e50154b 100644 --- a/core/java/android/view/autofill/AutoFillValue.java +++ b/core/java/android/view/autofill/AutoFillValue.java @@ -35,11 +35,13 @@ public final class AutoFillValue implements Parcelable { private final String mText; private final int mListIndex; private final boolean mToggle; + private final long mDate; - private AutoFillValue(CharSequence text, int listIndex, boolean toggle) { + private AutoFillValue(CharSequence text, int listIndex, boolean toggle, long date) { mText = (text == null) ? null : text.toString(); mListIndex = listIndex; mToggle = toggle; + mDate = date; } /** @@ -69,6 +71,17 @@ public final class AutoFillValue implements Parcelable { return mListIndex; } + /** + * Gets the value representing the the number of milliseconds since the standard base time known + * as "the epoch", namely January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()} + * of a date field. + * + *

See {@link AutoFillType#isDate()} for more info. + */ + public long getDateValue() { + return mDate; + } + ///////////////////////////////////// // Object "contract" methods. // ///////////////////////////////////// @@ -77,9 +90,10 @@ public final class AutoFillValue implements Parcelable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + mListIndex; result = prime * result + ((mText == null) ? 0 : mText.hashCode()); + result = prime * result + mListIndex; result = prime * result + (mToggle ? 1231 : 1237); + result = prime * result + (int) (mDate ^ (mDate >>> 32)); return result; } @@ -89,13 +103,14 @@ public final class AutoFillValue implements Parcelable { if (obj == null) return false; if (getClass() != obj.getClass()) return false; final AutoFillValue other = (AutoFillValue) obj; - if (mListIndex != other.mListIndex) return false; if (mText == null) { if (other.mText != null) return false; } else { if (!mText.equals(other.mText)) return false; } + if (mListIndex != other.mListIndex) return false; if (mToggle != other.mToggle) return false; + if (mDate != other.mDate) return false; return true; } @@ -113,7 +128,7 @@ public final class AutoFillValue implements Parcelable { return mText.length() + "_chars"; } - return "[listIndex=" + mListIndex + ", toggle=" + mToggle + "]"; + return "[l=" + mListIndex + ", t=" + mToggle + ", d=" + mDate + "]"; } ///////////////////////////////////// @@ -130,12 +145,14 @@ public final class AutoFillValue implements Parcelable { parcel.writeString(mText); parcel.writeInt(mListIndex); parcel.writeInt(mToggle ? 1 : 0); + parcel.writeLong(mDate); } private AutoFillValue(Parcel parcel) { mText = parcel.readString(); mListIndex = parcel.readInt(); mToggle = parcel.readInt() == 1; + mDate = parcel.readLong(); } public static final Parcelable.Creator CREATOR = @@ -157,31 +174,42 @@ public final class AutoFillValue implements Parcelable { // TODO(b/33197203): add unit tests for each supported type (new / get should return same value) /** - * Creates a new {@link AutoFillValue} to auto-fill a text field. + * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a text field. * *

See {@link AutoFillType#isText()} for more info. */ // TODO(b/33197203): use cache @Nullable public static AutoFillValue forText(@Nullable CharSequence value) { - return value == null ? null : new AutoFillValue(value, 0, false); + return value == null ? null : new AutoFillValue(value, 0, false, 0); } /** - * Creates a new {@link AutoFillValue} to auto-fill a toggable field. + * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a toggable + * field. * *

See {@link AutoFillType#isToggle()} for more info. */ public static AutoFillValue forToggle(boolean value) { - return new AutoFillValue(null, 0, value); + return new AutoFillValue(null, 0, value, 0); } /** - * Creates a new {@link AutoFillValue} to auto-fill a selection list field. + * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a selection + * list. * *

See {@link AutoFillType#isList()} for more info. */ public static AutoFillValue forList(int value) { - return new AutoFillValue(null, value, false); + return new AutoFillValue(null, value, false, 0); + } + + /** + * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a date. + * + *

See {@link AutoFillType#isDate()} for more info. + */ + public static AutoFillValue forDate(long date) { + return new AutoFillValue(null, 0, false, date); } } diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index 887c59a2d71cd..141b52fd2ce3f 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -591,7 +591,7 @@ public abstract class CompoundButton extends Button implements Checkable { @Override public AutoFillType getAutoFillType() { - return AutoFillType.forToggle(); + return isEnabled() ? AutoFillType.forToggle() : null; } @Override diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 517e20cd19473..0ffefd091b068 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -31,7 +31,11 @@ import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.SparseArray; import android.view.View; +import android.view.ViewStructure; import android.view.accessibility.AccessibilityEvent; +import android.view.autofill.AutoFillManager; +import android.view.autofill.AutoFillType; +import android.view.autofill.AutoFillValue; import com.android.internal.R; @@ -170,6 +174,13 @@ public class DatePicker extends FrameLayout { if (firstDayOfWeek != 0) { setFirstDayOfWeek(firstDayOfWeek); } + + mDelegate.setAutoFillChangeListener((v, y, m, d) -> { + final AutoFillManager afm = context.getSystemService(AutoFillManager.class); + if (afm != null) { + afm.valueChanged(this); + } + }); } private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs, @@ -503,12 +514,15 @@ public class DatePicker extends FrameLayout { OnDateChangedListener onDateChangedListener); void setOnDateChangedListener(OnDateChangedListener onDateChangedListener); + void setAutoFillChangeListener(OnDateChangedListener onDateChangedListener); void updateDate(int year, int month, int dayOfMonth); + void updateDate(long date); int getYear(); int getMonth(); int getDayOfMonth(); + long getDate(); void setFirstDayOfWeek(int firstDayOfWeek); int getFirstDayOfWeek(); @@ -558,6 +572,7 @@ public class DatePicker extends FrameLayout { // Callbacks protected OnDateChangedListener mOnDateChangedListener; + protected OnDateChangedListener mAutoFillChangeListener; protected ValidationCallback mValidationCallback; public AbstractDatePickerDelegate(DatePicker delegator, Context context) { @@ -579,11 +594,29 @@ public class DatePicker extends FrameLayout { mOnDateChangedListener = callback; } + @Override + public void setAutoFillChangeListener(OnDateChangedListener callback) { + mAutoFillChangeListener = callback; + } + @Override public void setValidationCallback(ValidationCallback callback) { mValidationCallback = callback; } + @Override + public void updateDate(long date) { + Calendar cal = Calendar.getInstance(mCurrentLocale); + cal.setTimeInMillis(date); + updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), + cal.get(Calendar.DAY_OF_MONTH)); + } + + @Override + public long getDate() { + return mCurrentDate.getTimeInMillis(); + } + protected void onValidationChanged(boolean valid) { if (mValidationCallback != null) { mValidationCallback.onValidationChanged(valid); @@ -723,4 +756,31 @@ public class DatePicker extends FrameLayout { public interface ValidationCallback { void onValidationChanged(boolean valid); } + + // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable) + + @Override + public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) { + // This view is self-sufficient for auto-fill, so it needs to call + // onProvideAutoFillStructure() to fill itself, but it does not need to call + // dispatchProvideAutoFillStructure() to fill its children. + onProvideAutoFillStructure(structure, flags); + } + + @Override + public void autoFill(AutoFillValue value) { + if (!isEnabled()) return; + + mDelegate.updateDate(value.getDateValue()); + } + + @Override + public AutoFillType getAutoFillType() { + return isEnabled() ? AutoFillType.forDate() : null; + } + + @Override + public AutoFillValue getAutoFillValue() { + return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null; + } } diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java index 907250aa55982..ca1bf582e6036 100755 --- a/core/java/android/widget/DatePickerCalendarDelegate.java +++ b/core/java/android/widget/DatePickerCalendarDelegate.java @@ -390,10 +390,16 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate { private void onDateChanged(boolean fromUser, boolean callbackToClient) { final int year = mCurrentDate.get(Calendar.YEAR); - if (callbackToClient && mOnDateChangedListener != null) { + if (callbackToClient + && (mOnDateChangedListener != null || mAutoFillChangeListener != null)) { final int monthOfYear = mCurrentDate.get(Calendar.MONTH); final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH); - mOnDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth); + if (mOnDateChangedListener != null) { + mOnDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth); + } + if (mAutoFillChangeListener != null) { + mAutoFillChangeListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth); + } } mDayPickerView.setDate(mCurrentDate.getTimeInMillis()); diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java index 702b2a5f822a9..fc2d1faca019c 100644 --- a/core/java/android/widget/DatePickerSpinnerDelegate.java +++ b/core/java/android/widget/DatePickerSpinnerDelegate.java @@ -576,6 +576,10 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(), getDayOfMonth()); } + if (mAutoFillChangeListener != null) { + mAutoFillChangeListener.onDateChanged(mDelegator, getYear(), getMonth(), + getDayOfMonth()); + } } /** diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java index bba3a11042e07..be5fc5381ac70 100644 --- a/core/java/android/widget/RadioGroup.java +++ b/core/java/android/widget/RadioGroup.java @@ -436,7 +436,7 @@ public class RadioGroup extends LinearLayout { @Override public AutoFillType getAutoFillType() { - return AutoFillType.forList(); + return isEnabled() ? AutoFillType.forList() : null; } @Override diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 9f38b04d4e099..1df202e96a3bf 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -23,12 +23,17 @@ import android.annotation.TestApi; import android.annotation.Widget; import android.content.Context; import android.content.res.TypedArray; +import android.icu.util.Calendar; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.MathUtils; import android.view.View; +import android.view.ViewStructure; import android.view.accessibility.AccessibilityEvent; +import android.view.autofill.AutoFillManager; +import android.view.autofill.AutoFillType; +import android.view.autofill.AutoFillValue; import com.android.internal.R; @@ -132,6 +137,12 @@ public class TimePicker extends FrameLayout { this, context, attrs, defStyleAttr, defStyleRes); break; } + mDelegate.setAutoFillChangeListener((v, h, m) -> { + final AutoFillManager afm = context.getSystemService(AutoFillManager.class); + if (afm != null) { + afm.valueChanged(this); + } + }); } /** @@ -348,12 +359,16 @@ public class TimePicker extends FrameLayout { void setMinute(@IntRange(from = 0, to = 59) int minute); int getMinute(); + void setDate(long date); + long getDate(); + void setIs24Hour(boolean is24Hour); boolean is24Hour(); boolean validateInput(); void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener); + void setAutoFillChangeListener(OnTimeChangedListener autoFillChangeListener); void setEnabled(boolean enabled); boolean isEnabled(); @@ -398,6 +413,7 @@ public class TimePicker extends FrameLayout { protected final Locale mLocale; protected OnTimeChangedListener mOnTimeChangedListener; + protected OnTimeChangedListener mAutoFillChangeListener; public AbstractTimePickerDelegate(@NonNull TimePicker delegator, @NonNull Context context) { mDelegator = delegator; @@ -410,6 +426,27 @@ public class TimePicker extends FrameLayout { mOnTimeChangedListener = callback; } + @Override + public void setAutoFillChangeListener(OnTimeChangedListener callback) { + mAutoFillChangeListener = callback; + } + + @Override + public void setDate(long date) { + Calendar cal = Calendar.getInstance(mLocale); + cal.setTimeInMillis(date); + setHour(cal.get(Calendar.HOUR_OF_DAY)); + setMinute(cal.get(Calendar.MINUTE)); + } + + @Override + public long getDate() { + Calendar cal = Calendar.getInstance(mLocale); + cal.set(Calendar.HOUR_OF_DAY, getHour()); + cal.set(Calendar.MINUTE, getMinute()); + return cal.getTimeInMillis(); + } + protected static class SavedState extends View.BaseSavedState { private final int mHour; private final int mMinute; @@ -474,4 +511,31 @@ public class TimePicker extends FrameLayout { }; } } + + // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable) + + @Override + public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) { + // This view is self-sufficient for auto-fill, so it needs to call + // onProvideAutoFillStructure() to fill itself, but it does not need to call + // dispatchProvideAutoFillStructure() to fill its children. + onProvideAutoFillStructure(structure, flags); + } + + @Override + public void autoFill(AutoFillValue value) { + if (!isEnabled()) return; + + mDelegate.setDate(value.getDateValue()); + } + + @Override + public AutoFillType getAutoFillType() { + return isEnabled() ? AutoFillType.forDate() : null; + } + + @Override + public AutoFillValue getAutoFillValue() { + return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null; + } } diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 3a0906393b978..61ae7823bcf14 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -671,6 +671,9 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { if (mOnTimeChangedListener != null) { mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute()); } + if (mAutoFillChangeListener != null) { + mAutoFillChangeListener.onTimeChanged(mDelegator, getHour(), getMinute()); + } } private void tryVibrate() { diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java index 20a55129a19d3..813c30e344c05 100644 --- a/core/java/android/widget/TimePickerSpinnerDelegate.java +++ b/core/java/android/widget/TimePickerSpinnerDelegate.java @@ -495,6 +495,9 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate { mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute()); } + if (mAutoFillChangeListener != null) { + mAutoFillChangeListener.onTimeChanged(mDelegator, getHour(), getMinute()); + } } private void updateHourControl() {