Commit f3581827 authored by Joy Ming's avatar Joy Ming Committed by Commit Bot

[Downloads location] Switch to using ModalDialogManager.

This CL switches the implementation of the DownloadLocationDialog from
AlertDialog to ModalDialogManager.

Bug: 792775
Change-Id: Ida60fb9cd55f9b2e07a918bfb90e79468552de6d
Reviewed-on: https://chromium-review.googlesource.com/915105
Commit-Queue: Joy Ming <jming@chromium.org>
Reviewed-by: default avatarBecky Zhou <huayinz@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#536763}
parent 25b97ef7
...@@ -5,15 +5,14 @@ ...@@ -5,15 +5,14 @@
package org.chromium.chrome.browser.download; package org.chromium.chrome.browser.download;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.text.InputType; import android.text.InputType;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.modaldialog.ModalDialogView;
import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.preferences.download.DownloadDirectoryList; import org.chromium.chrome.browser.preferences.download.DownloadDirectoryList;
...@@ -22,13 +21,12 @@ import org.chromium.chrome.browser.widget.AlertDialogEditText; ...@@ -22,13 +21,12 @@ import org.chromium.chrome.browser.widget.AlertDialogEditText;
import java.io.File; import java.io.File;
import javax.annotation.Nullable;
/** /**
* Dialog that is displayed to ask user where they want to download the file. * Dialog that is displayed to ask user where they want to download the file.
*/ */
public class DownloadLocationDialog public class DownloadLocationDialog extends ModalDialogView implements View.OnFocusChangeListener {
extends AlertDialog implements DialogInterface.OnClickListener, View.OnFocusChangeListener,
DialogInterface.OnCancelListener {
private DownloadLocationDialogListener mListener;
private DownloadDirectoryList mDownloadDirectoryUtil; private DownloadDirectoryList mDownloadDirectoryUtil;
private AlertDialogEditText mFileName; private AlertDialogEditText mFileName;
...@@ -36,64 +34,49 @@ public class DownloadLocationDialog ...@@ -36,64 +34,49 @@ public class DownloadLocationDialog
private CheckBox mDontShowAgain; private CheckBox mDontShowAgain;
/** /**
* Interface for a listener to the events related to the DownloadLocationDialog. * Create a {@link DownloadLocationDialog} with the given properties.
*
* @param controller Controller that listens to the events from the dialog.
* @param context Context from which the dialog emerged.
* @param suggestedPath The path that was automatically generated, used as a starting point.
* @return A {@link DownloadLocationDialog} with the given properties.
*/ */
public interface DownloadLocationDialogListener { public static DownloadLocationDialog create(
/** Controller controller, Context context, File suggestedPath) {
* Notify listeners that the dialog has been completed. Params params = new Params();
* @param returnedPath from the dialog. params.title = context.getString(R.string.download_location_dialog_title);
*/ params.positiveButtonTextId = R.string.duplicate_download_infobar_download_button;
void onComplete(File returnedPath); params.negativeButtonTextId = R.string.cancel;
params.customView =
/** LayoutInflater.from(context).inflate(R.layout.download_location_dialog, null);
* Notify listeners that the dialog has been canceled.
*/ return new DownloadLocationDialog(controller, context, suggestedPath, params);
void onCanceled();
} }
/** private DownloadLocationDialog(
* Create a DownloadLocationDialog that is displayed before a download begins. Controller controller, Context context, File suggestedPath, Params params) {
* super(controller, params);
* @param context of the dialog.
* @param listener to the updates from the dialog.
* @param suggestedPath of the download location.
*/
DownloadLocationDialog(
Context context, DownloadLocationDialogListener listener, File suggestedPath) {
super(context, 0);
mListener = listener;
mDownloadDirectoryUtil = new DownloadDirectoryList(context); mDownloadDirectoryUtil = new DownloadDirectoryList(context);
setButton(BUTTON_POSITIVE, mFileName = (AlertDialogEditText) params.customView.findViewById(R.id.file_name);
context.getText(R.string.duplicate_download_infobar_download_button), this);
setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), this);
setIcon(0);
setTitle(context.getString(R.string.download_location_dialog_title));
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.download_location_dialog, null);
mFileName = (AlertDialogEditText) view.findViewById(R.id.file_name);
mFileName.setText(suggestedPath.getName()); mFileName.setText(suggestedPath.getName());
mFileLocation = (AlertDialogEditText) view.findViewById(R.id.file_location); mFileLocation = (AlertDialogEditText) params.customView.findViewById(R.id.file_location);
// NOTE: This makes the EditText correctly styled but not editable. // NOTE: This makes the EditText correctly styled but not editable.
mFileLocation.setInputType(InputType.TYPE_NULL); mFileLocation.setInputType(InputType.TYPE_NULL);
mFileLocation.setOnFocusChangeListener(this); mFileLocation.setOnFocusChangeListener(this);
setFileLocation(suggestedPath.getParentFile()); setFileLocation(suggestedPath.getParentFile());
// Automatically check "don't show again" the first time the user is seeing the dialog. // Automatically check "don't show again" the first time the user is seeing the dialog.
mDontShowAgain = (CheckBox) view.findViewById(R.id.show_again_checkbox); mDontShowAgain = (CheckBox) params.customView.findViewById(R.id.show_again_checkbox);
boolean isInitial = PrefServiceBridge.getInstance().getPromptForDownloadAndroid() boolean isInitial = PrefServiceBridge.getInstance().getPromptForDownloadAndroid()
== DownloadPromptStatus.SHOW_INITIAL; == DownloadPromptStatus.SHOW_INITIAL;
mDontShowAgain.setChecked(isInitial); mDontShowAgain.setChecked(isInitial);
setView(view);
setCanceledOnTouchOutside(false);
setOnCancelListener(this);
} }
// Helper methods available to DownloadLocationDialogBridge.
/** /**
* Update the string in the file location text view. * Update the string in the file location text view.
* *
...@@ -104,45 +87,29 @@ public class DownloadLocationDialog ...@@ -104,45 +87,29 @@ public class DownloadLocationDialog
mFileLocation.setText(mDownloadDirectoryUtil.getNameForFile(location)); mFileLocation.setText(mDownloadDirectoryUtil.getNameForFile(location));
} }
// DialogInterface.OnClickListener implementation. /**
* @return The text that the user inputted as the name of the file.
@Override */
public void onClick(DialogInterface dialogInterface, int which) { @Nullable
if (which == BUTTON_POSITIVE) { String getFileName() {
// Get new file path information. if (mFileName == null) return null;
String fileName = mFileName.getText().toString(); return mFileName.getText().toString();
File fileLocation =
mDownloadDirectoryUtil.getFileForName(mFileLocation.getText().toString());
if (fileLocation != null) {
mListener.onComplete(new File(fileLocation, fileName));
} else {
// If file location returned null, treat as cancellation.
mListener.onCanceled();
dismiss();
return;
}
// Update preference to show prompt based on whether checkbox is checked.
if (mDontShowAgain.isChecked()) {
PrefServiceBridge.getInstance().setPromptForDownloadAndroid(
DownloadPromptStatus.DONT_SHOW);
} else {
PrefServiceBridge.getInstance().setPromptForDownloadAndroid(
DownloadPromptStatus.SHOW_PREFERENCE);
}
} else {
mListener.onCanceled();
}
dismiss();
} }
// Dialog.OnCancelListener implementation. /**
* @return The file path based on what the user selected as the location of the file.
*/
@Nullable
File getFileLocation() {
if (mFileLocation == null) return null;
return mDownloadDirectoryUtil.getFileForName(mFileLocation.getText().toString());
}
@Override /**
public void onCancel(DialogInterface dialogInterface) { * @return Whether the "don't show again" checkbox is checked.
mListener.onCanceled(); */
dismiss(); boolean getDontShowAgain() {
return mDontShowAgain != null && mDontShowAgain.isChecked();
} }
// View.OnFocusChange implementation. // View.OnFocusChange implementation.
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
package org.chromium.chrome.browser.download; package org.chromium.chrome.browser.download;
import android.app.Activity;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.modaldialog.ModalDialogManager;
import org.chromium.chrome.browser.modaldialog.ModalDialogView;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import java.io.File; import java.io.File;
...@@ -16,13 +18,13 @@ import javax.annotation.Nullable; ...@@ -16,13 +18,13 @@ import javax.annotation.Nullable;
/** /**
* Helper class to handle communication between download location dialog and native. * Helper class to handle communication between download location dialog and native.
*/ */
public class DownloadLocationDialogBridge public class DownloadLocationDialogBridge implements ModalDialogView.Controller {
implements DownloadLocationDialog.DownloadLocationDialogListener {
// TODO(jming): Remove this when switching to a dropdown instead of going to preferences. // TODO(jming): Remove this when switching to a dropdown instead of going to preferences.
private static DownloadLocationDialogBridge sInstance; private static DownloadLocationDialogBridge sInstance;
private long mNativeDownloadLocationDialogBridge; private long mNativeDownloadLocationDialogBridge;
private DownloadLocationDialog mLocationDialog; private DownloadLocationDialog mLocationDialog;
private ModalDialogManager mModalDialogManager;
@Nullable @Nullable
public static DownloadLocationDialogBridge getInstance() { public static DownloadLocationDialogBridge getInstance() {
...@@ -52,38 +54,89 @@ public class DownloadLocationDialogBridge ...@@ -52,38 +54,89 @@ public class DownloadLocationDialogBridge
@CalledByNative @CalledByNative
private void destroy() { private void destroy() {
mNativeDownloadLocationDialogBridge = 0; mNativeDownloadLocationDialogBridge = 0;
if (mLocationDialog != null) mLocationDialog.dismiss(); if (mModalDialogManager != null) mModalDialogManager.dismissDialog(mLocationDialog);
sInstance = null; sInstance = null;
} }
@CalledByNative @CalledByNative
public void showDialog(WebContents webContents, String suggestedPath) { public void showDialog(WebContents webContents, String suggestedPath) {
Activity windowAndroidActivity = webContents.getTopLevelNativeWindow().getActivity().get(); // TODO(jming): Remove WebContents requirement.
if (windowAndroidActivity == null) return; ChromeActivity activity =
(ChromeActivity) webContents.getTopLevelNativeWindow().getActivity().get();
// If the activity has gone away, just clean up the native pointer.
if (activity == null) {
onCancel();
return;
}
mModalDialogManager = activity.getModalDialogManager();
if (mLocationDialog != null) return; if (mLocationDialog != null) return;
mLocationDialog = mLocationDialog = DownloadLocationDialog.create(this, activity, new File(suggestedPath));
new DownloadLocationDialog(windowAndroidActivity, this, new File(suggestedPath));
// TODO(jming): Use ModalDialogManager. mModalDialogManager.showDialog(mLocationDialog, ModalDialogManager.APP_MODAL);
mLocationDialog.show();
} }
@Override @Override
public void onComplete(File returnedPath) { public void onClick(@ModalDialogView.ButtonType int buttonType) {
if (mNativeDownloadLocationDialogBridge == 0) return; switch (buttonType) {
case ModalDialogView.BUTTON_POSITIVE:
handleResponses(mLocationDialog.getFileName(), mLocationDialog.getFileLocation(),
mLocationDialog.getDontShowAgain());
mModalDialogManager.dismissDialog(mLocationDialog);
break;
case ModalDialogView.BUTTON_NEGATIVE:
// Intentional fall-through.
default:
cancel();
mModalDialogManager.dismissDialog(mLocationDialog);
}
nativeOnComplete(mNativeDownloadLocationDialogBridge, returnedPath.getAbsolutePath());
mLocationDialog = null; mLocationDialog = null;
} }
@Override @Override
public void onCanceled() { public void onCancel() {
if (mNativeDownloadLocationDialogBridge == 0) return; cancel();
nativeOnCanceled(mNativeDownloadLocationDialogBridge);
mLocationDialog = null; mLocationDialog = null;
} }
/**
* Pass along information from location dialog to native.
*
* @param fileName Name the user gave the file.
* @param fileLocation Location the user wants the file saved to.
* @param dontShowAgain Whether the user wants the "Save download to..." dialog shown again.
*/
private void handleResponses(String fileName, File fileLocation, boolean dontShowAgain) {
// If there's no file location, treat as a cancellation.
if (fileLocation == null) {
cancel();
return;
}
// Update native with new path.
if (mNativeDownloadLocationDialogBridge != 0) {
File filePath = new File(fileLocation, fileName);
nativeOnComplete(mNativeDownloadLocationDialogBridge, filePath.getAbsolutePath());
}
// Update preference to show prompt based on whether checkbox is checked.
if (dontShowAgain) {
PrefServiceBridge.getInstance().setPromptForDownloadAndroid(
DownloadPromptStatus.DONT_SHOW);
} else {
PrefServiceBridge.getInstance().setPromptForDownloadAndroid(
DownloadPromptStatus.SHOW_PREFERENCE);
}
}
private void cancel() {
if (mNativeDownloadLocationDialogBridge != 0) {
nativeOnCanceled(mNativeDownloadLocationDialogBridge);
}
}
public native void nativeOnComplete( public native void nativeOnComplete(
long nativeDownloadLocationDialogBridge, String returnedPath); long nativeDownloadLocationDialogBridge, String returnedPath);
public native void nativeOnCanceled(long nativeDownloadLocationDialogBridge); public native void nativeOnCanceled(long nativeDownloadLocationDialogBridge);
......
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