Commit 21903fda authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Download later: Fix time picker on older Android versions.

Android's TimePickerDialog behaves differently on older Android
versions.

This CL adds a class DownloadTimePickerDialog, which overrides
Android API to fix the compatibility issue. Now we always reset the
positive and negative button listeners in show() function override.

Also applies styles to date picker and time picker.

Bug: 1107611
Change-Id: I9fa6b5b17f145b0f592beae2d0a06b3f06fc8a1b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2320969
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarHesen Zhang <hesen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792493}
parent d522180f
...@@ -36,6 +36,7 @@ android_library("java") { ...@@ -36,6 +36,7 @@ android_library("java") {
"java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java", "java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java",
"java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogController.java", "java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogController.java",
"java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java", "java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java",
"java/src/org/chromium/chrome/browser/download/dialogs/DownloadTimePickerDialog.java",
"java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java", "java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java",
"java/src/org/chromium/chrome/browser/download/home/DownloadManagerUiConfig.java", "java/src/org/chromium/chrome/browser/download/home/DownloadManagerUiConfig.java",
"java/src/org/chromium/chrome/browser/download/home/FaviconProvider.java", "java/src/org/chromium/chrome/browser/download/home/FaviconProvider.java",
......
...@@ -87,4 +87,9 @@ ...@@ -87,4 +87,9 @@
<style name="TextAppearance.DownloadDialogTitle" parent="TextAppearance.AlertDialogTitleStyle"> <style name="TextAppearance.DownloadDialogTitle" parent="TextAppearance.AlertDialogTitleStyle">
<item name="android:textSize">20sp</item> <item name="android:textSize">20sp</item>
</style> </style>
<style name="Theme.DownloadDateTimePickerDialog" parent="Theme.Chromium.ModalDialog">
<item name="android:windowMinWidthMajor">@null</item>
<item name="android:windowMinWidthMinor">@null</item>
</style>
</resources> </resources>
...@@ -5,11 +5,9 @@ ...@@ -5,11 +5,9 @@
package org.chromium.chrome.browser.download.dialogs; package org.chromium.chrome.browser.download.dialogs;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.widget.DatePicker; import android.widget.DatePicker;
import android.widget.TimePicker;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
...@@ -27,11 +25,11 @@ import java.util.Calendar; ...@@ -27,11 +25,11 @@ import java.util.Calendar;
* will see the date picker and time picker in a sequence when trying to select a time. * will see the date picker and time picker in a sequence when trying to select a time.
*/ */
public class DownloadDateTimePickerDialogImpl public class DownloadDateTimePickerDialogImpl
implements DownloadDateTimePickerDialog, TimePickerDialog.OnTimeSetListener { implements DownloadDateTimePickerDialog, DownloadTimePickerDialog.Controller {
private static final String TAG = "DownloadTimePicker"; private static final String TAG = "DateTimeDialog";
private static final long INVALID_TIMESTAMP = -1; private static final long INVALID_TIMESTAMP = -1;
private DatePickerDialog mDatePickerDialog; private DatePickerDialog mDatePickerDialog;
private TimePickerDialog mTimePickerDialog; private DownloadTimePickerDialog mTimePickerDialog;
private Controller mController; private Controller mController;
private final Calendar mCalendar = Calendar.getInstance(); private final Calendar mCalendar = Calendar.getInstance();
...@@ -53,7 +51,8 @@ public class DownloadDateTimePickerDialogImpl ...@@ -53,7 +51,8 @@ public class DownloadDateTimePickerDialogImpl
// Setup the date picker. Use null DatePickerDialog.OnDateSetListener due to Android API // Setup the date picker. Use null DatePickerDialog.OnDateSetListener due to Android API
// issue. // issue.
mDatePickerDialog = new DatePickerDialog(context, null, mCalendar.get(Calendar.YEAR), mDatePickerDialog = new DatePickerDialog(context,
R.style.Theme_DownloadDateTimePickerDialog, null, mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH)); mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
long minDate = long minDate =
getLong(model, DownloadDateTimePickerDialogProperties.MIN_TIME, INVALID_TIMESTAMP); getLong(model, DownloadDateTimePickerDialogProperties.MIN_TIME, INVALID_TIMESTAMP);
...@@ -68,14 +67,8 @@ public class DownloadDateTimePickerDialogImpl ...@@ -68,14 +67,8 @@ public class DownloadDateTimePickerDialogImpl
mDatePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mDatePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
context.getResources().getString(R.string.cancel), this::onDatePickerClicked); context.getResources().getString(R.string.cancel), this::onDatePickerClicked);
// Setup the time picker. mTimePickerDialog = new DownloadTimePickerDialog(
mTimePickerDialog = new TimePickerDialog(context, this, mCalendar.get(Calendar.HOUR), context, this, mCalendar.get(Calendar.HOUR), mCalendar.get(Calendar.MINUTE));
mCalendar.get(Calendar.MINUTE), false /*is24HourView*/);
mTimePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE,
context.getResources().getString(R.string.download_date_time_picker_next_text),
this::onTimePickerClicked);
mTimePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
context.getResources().getString(R.string.cancel), this::onTimePickerClicked);
// Start the flow. // Start the flow.
mDatePickerDialog.show(); mDatePickerDialog.show();
...@@ -87,16 +80,6 @@ public class DownloadDateTimePickerDialogImpl ...@@ -87,16 +80,6 @@ public class DownloadDateTimePickerDialogImpl
if (mTimePickerDialog != null) mTimePickerDialog.dismiss(); if (mTimePickerDialog != null) mTimePickerDialog.dismiss();
} }
// TimePickerDialog.OnTimeSetListener.
@Override
public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) {
mCalendar.set(Calendar.HOUR, hourOfDay);
mCalendar.set(Calendar.MINUTE, minute);
// Click on the clock will complete the selection as well.
onComplete();
}
private void onDatePickerClicked(DialogInterface dialogInterface, int which) { private void onDatePickerClicked(DialogInterface dialogInterface, int which) {
switch (which) { switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
...@@ -116,19 +99,6 @@ public class DownloadDateTimePickerDialogImpl ...@@ -116,19 +99,6 @@ public class DownloadDateTimePickerDialogImpl
} }
} }
private void onTimePickerClicked(DialogInterface dialogInterface, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
// Handled in TimePickerDialog.OnTimeSetListener.
break;
case DialogInterface.BUTTON_NEGATIVE:
onCancel();
break;
default:
Log.e(TAG, "Unsupported button type clicked in time picker, type: %d", which);
}
}
private void onCancel() { private void onCancel() {
assert mController != null; assert mController != null;
mCalendar.clear(); mCalendar.clear();
...@@ -146,4 +116,18 @@ public class DownloadDateTimePickerDialogImpl ...@@ -146,4 +116,18 @@ public class DownloadDateTimePickerDialogImpl
Long value = model.get(key); Long value = model.get(key);
return (value != null) ? value : defaultValue; return (value != null) ? value : defaultValue;
} }
// DownloadTimePickerDialog.Controller overrides.
@Override
public void onDownloadTimePicked(int hour, int minute) {
mCalendar.set(Calendar.HOUR, hour);
mCalendar.set(Calendar.MINUTE, minute);
onComplete();
}
@Override
public void onDownloadTimePickerCanceled() {
onCancel();
}
} }
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download.dialogs;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.widget.Button;
import android.widget.TimePicker;
import androidx.annotation.NonNull;
import org.chromium.chrome.browser.download.R;
/**
* A {@link TimePickerDialog} subclass for download time selection. Works on all Android versions.
*/
class DownloadTimePickerDialog extends TimePickerDialog {
interface Controller {
void onDownloadTimePicked(int hour, int minute);
void onDownloadTimePickerCanceled();
}
private int mHour;
private int mMinute;
private final Controller mController;
DownloadTimePickerDialog(
Context context, @NonNull Controller controller, int hourOfDay, int minute) {
super(context, R.style.Theme_DownloadDateTimePickerDialog, null, hourOfDay, minute,
false /*is24HourView*/);
mHour = hourOfDay;
mMinute = minute;
mController = controller;
}
// TimePickerDialog overrides.
@Override
public void show() {
super.show();
// Override button click listeners. Notice the default behavior varies on different Android
// versions.
Button button = getButton(DialogInterface.BUTTON_POSITIVE);
assert button != null;
button.setText(R.string.download_date_time_picker_next_text);
button.setOnClickListener((view) -> {
mController.onDownloadTimePicked(mHour, mMinute);
dismiss();
});
button = getButton(DialogInterface.BUTTON_NEGATIVE);
button.setText(R.string.cancel);
button.setOnClickListener((view) -> {
mController.onDownloadTimePickerCanceled();
dismiss();
});
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
mHour = hourOfDay;
mMinute = minute;
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment