Commit 5146998f authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Download: Create a delegate class to query directory from Android.

This CL adds a delegate class in DownloadDirectoryProvider, so we can
mock this behavior in test.

This is needed for the DownloadContentProvider effort for testing
purposes.

Bug: 970072
Change-Id: I585e51f60d5a356ffe1b5cb0116e615ceababad0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1663249Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Commit-Queue: Xing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#670243}
parent a0c988fc
...@@ -13,6 +13,7 @@ import android.os.Environment; ...@@ -13,6 +13,7 @@ import android.os.Environment;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.PathUtils; import org.chromium.base.PathUtils;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
...@@ -35,6 +36,41 @@ import java.util.ArrayList; ...@@ -35,6 +36,41 @@ import java.util.ArrayList;
* options accordingly. * options accordingly.
*/ */
public class DownloadDirectoryProvider { public class DownloadDirectoryProvider {
private static final String TAG = "DownloadDirectory";
/**
* Delegate class to query directories from Android API. Should be created on main thread
* and used on background thread in {@link AsyncTask}.
*/
public interface Delegate {
/**
* Get the primary download directory in public external storage. The directory will be
* created if it doesn't exist. Should be called on background thread.
* @return The download directory. Can be an invalid directory if failed to create the
* directory.
*/
File getPrimaryDownloadDirectory();
/**
* Get external files directories for {@link Environment#DIRECTORY_DOWNLOADS}.
* @return A list of directories.
*/
File[] getExternalFilesDirs();
}
private static class DownloadDirectoryProviderDelegate implements Delegate {
@Override
public File getPrimaryDownloadDirectory() {
return DownloadDirectoryProvider.getPrimaryDownloadDirectory();
}
@Override
public File[] getExternalFilesDirs() {
return ContextUtils.getApplicationContext().getExternalFilesDirs(
Environment.DIRECTORY_DOWNLOADS);
}
}
/** /**
* Asynchronous task to retrieve all download directories on a background thread. Only one task * Asynchronous task to retrieve all download directories on a background thread. Only one task
* can exist at the same time. * can exist at the same time.
...@@ -43,12 +79,18 @@ public class DownloadDirectoryProvider { ...@@ -43,12 +79,18 @@ public class DownloadDirectoryProvider {
* {@link PathUtils#getAllPrivateDownloadsDirectories}. * {@link PathUtils#getAllPrivateDownloadsDirectories}.
*/ */
private class AllDirectoriesTask extends AsyncTask<ArrayList<DirectoryOption>> { private class AllDirectoriesTask extends AsyncTask<ArrayList<DirectoryOption>> {
private DownloadDirectoryProvider.Delegate mDelegate;
AllDirectoriesTask(DownloadDirectoryProvider.Delegate delegate) {
mDelegate = delegate;
}
@Override @Override
protected ArrayList<DirectoryOption> doInBackground() { protected ArrayList<DirectoryOption> doInBackground() {
ArrayList<DirectoryOption> dirs = new ArrayList<>(); ArrayList<DirectoryOption> dirs = new ArrayList<>();
// Retrieve default directory. // Retrieve default directory.
File defaultDirectory = DownloadUtils.getPrimaryDownloadDirectory(); File defaultDirectory = mDelegate.getPrimaryDownloadDirectory();
// If no default directory, return an error option. // If no default directory, return an error option.
if (defaultDirectory == null) { if (defaultDirectory == null) {
...@@ -67,8 +109,7 @@ public class DownloadDirectoryProvider { ...@@ -67,8 +109,7 @@ public class DownloadDirectoryProvider {
File[] files; File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
files = ContextUtils.getApplicationContext().getExternalFilesDirs( files = mDelegate.getExternalFilesDirs();
Environment.DIRECTORY_DOWNLOADS);
} else { } else {
files = new File[] {Environment.getExternalStorageDirectory()}; files = new File[] {Environment.getExternalStorageDirectory()};
} }
...@@ -192,11 +233,32 @@ public class DownloadDirectoryProvider { ...@@ -192,11 +233,32 @@ public class DownloadDirectoryProvider {
return null; return null;
} }
/**
* Get the primary download directory in public external storage. The directory will be created
* if it doesn't exist. Should be called on background thread.
* @return The download directory. Can be an invalid directory if failed to create the
* directory.
*/
public static File getPrimaryDownloadDirectory() {
File downloadDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
// Create the directory if needed.
if (!downloadDir.exists()) {
try {
downloadDir.mkdirs();
} catch (SecurityException e) {
Log.e(TAG, "Exception when creating download directory.", e);
}
}
return downloadDir;
}
private void updateDirectories() { private void updateDirectories() {
// If asynchronous task is pending, wait for its result. // If asynchronous task is pending, wait for its result.
if (mAllDirectoriesTask != null) return; if (mAllDirectoriesTask != null) return;
mAllDirectoriesTask = new AllDirectoriesTask(); mAllDirectoriesTask = new AllDirectoriesTask(new DownloadDirectoryProviderDelegate());
mAllDirectoriesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); mAllDirectoriesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
......
...@@ -1216,27 +1216,6 @@ public class DownloadUtils { ...@@ -1216,27 +1216,6 @@ public class DownloadUtils {
return primaryPath == null ? false : path.contains(primaryPath); return primaryPath == null ? false : path.contains(primaryPath);
} }
/**
* Get the primary download directory in public external storage. The directory will be created
* if it doesn't exist.
* @return The download directory. Can be an invalid directory if failed to create the
* directory.
*/
public static File getPrimaryDownloadDirectory() {
File downloadDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
// Create the directory if needed.
if (!downloadDir.exists()) {
try {
downloadDir.mkdirs();
} catch (SecurityException e) {
Log.e(TAG, "Exception when creating download directory.", e);
}
}
return downloadDir;
}
/** /**
* Parses an originating URL string and returns a valid Uri that can be inserted into * Parses an originating URL string and returns a valid Uri that can be inserted into
* DownloadProvider. The returned Uri has to be null or non-empty http(s) scheme. * DownloadProvider. The returned Uri has to be null or non-empty http(s) scheme.
......
...@@ -10,6 +10,7 @@ import android.support.annotation.Nullable; ...@@ -10,6 +10,7 @@ import android.support.annotation.Nullable;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.download.DirectoryOption; import org.chromium.chrome.browser.download.DirectoryOption;
import org.chromium.chrome.browser.download.DownloadDirectoryProvider;
import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterObserver; import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterObserver;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterSource; import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterSource;
...@@ -88,7 +89,7 @@ public class StorageSummaryProvider implements OfflineItemFilterObserver { ...@@ -88,7 +89,7 @@ public class StorageSummaryProvider implements OfflineItemFilterObserver {
new AsyncTask<DirectoryOption>() { new AsyncTask<DirectoryOption>() {
@Override @Override
protected DirectoryOption doInBackground() { protected DirectoryOption doInBackground() {
File defaultDownloadDir = DownloadUtils.getPrimaryDownloadDirectory(); File defaultDownloadDir = DownloadDirectoryProvider.getPrimaryDownloadDirectory();
DirectoryOption directoryOption = new DirectoryOption("", DirectoryOption directoryOption = new DirectoryOption("",
defaultDownloadDir.getAbsolutePath(), defaultDownloadDir.getUsableSpace(), defaultDownloadDir.getAbsolutePath(), defaultDownloadDir.getUsableSpace(),
defaultDownloadDir.getTotalSpace(), defaultDownloadDir.getTotalSpace(),
......
...@@ -19,6 +19,7 @@ import org.chromium.base.ObserverList; ...@@ -19,6 +19,7 @@ import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.download.DownloadDirectoryProvider;
import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.widget.MaterialProgressBar; import org.chromium.chrome.browser.widget.MaterialProgressBar;
import org.chromium.chrome.download.R; import org.chromium.chrome.download.R;
...@@ -62,7 +63,7 @@ public class SpaceDisplay extends RecyclerView.AdapterDataObserver { ...@@ -62,7 +63,7 @@ public class SpaceDisplay extends RecyclerView.AdapterDataObserver {
@Override @Override
protected Long doInBackground() { protected Long doInBackground() {
File downloadDirectory = DownloadUtils.getPrimaryDownloadDirectory(); File downloadDirectory = DownloadDirectoryProvider.getPrimaryDownloadDirectory();
// Determine how much space is available on the storage device where downloads // Determine how much space is available on the storage device where downloads
// reside. If the downloads directory doesn't exist, it is likely that the user // reside. If the downloads directory doesn't exist, it is likely that the user
......
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