Commit 262aa607 authored by David Trainor's avatar David Trainor Committed by Commit Bot

Add 3 dot menu to download home items

Add the ability to share and delete items through a new three dot menu
on all download items in download home.

Bug: 777630
Change-Id: Icd8f19e2d4630ab4e96d21e7c02021fa30690046
Reviewed-on: https://chromium-review.googlesource.com/802138
Commit-Queue: David Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521937}
parent a83f42ce
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
android:layout_below="@+id/filename_completed_view" /> android:layout_below="@+id/filename_completed_view" />
</RelativeLayout> </RelativeLayout>
<include layout="@layout/list_menu_button" />
<!-- Shown for downloads that haven't been completed. --> <!-- Shown for downloads that haven't been completed. -->
<RelativeLayout <RelativeLayout
android:id="@+id/progress_layout" android:id="@+id/progress_layout"
...@@ -109,6 +111,7 @@ ...@@ -109,6 +111,7 @@
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:padding="8dp" android:padding="8dp"
android:paddingEnd="@dimen/selectable_list_layout_row_padding"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:contentDescription="@string/download_notification_cancel_button" android:contentDescription="@string/download_notification_cancel_button"
android:src="@drawable/btn_close" android:src="@drawable/btn_close"
......
...@@ -42,6 +42,24 @@ public interface BackendProvider { ...@@ -42,6 +42,24 @@ public interface BackendProvider {
void updateLastAccessTime(String downloadGuid, boolean isOffTheRecord); void updateLastAccessTime(String downloadGuid, boolean isOffTheRecord);
} }
/**
* Processes actions from the UI that require front end management before hitting the backend.
* This should eventually get merged into a proper delegate with other UI actions, but currently
* that is not possible.
*/
public static interface UIDelegate {
/**
* Requests that {@code item} be deleted. This might not hit the backend quiet yet if the
* user can undo the action.
*/
void deleteItem(DownloadHistoryItemWrapper item);
/**
* Requests that {@code item} be shared.
*/
void shareItem(DownloadHistoryItemWrapper item);
}
/** Returns the {@link DownloadDelegate} that works with the Downloads backend. */ /** Returns the {@link DownloadDelegate} that works with the Downloads backend. */
DownloadDelegate getDownloadDelegate(); DownloadDelegate getDownloadDelegate();
...@@ -54,6 +72,9 @@ public interface BackendProvider { ...@@ -54,6 +72,9 @@ public interface BackendProvider {
/** Returns the {@link SelectionDelegate} that tracks selected items. */ /** Returns the {@link SelectionDelegate} that tracks selected items. */
SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate(); SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate();
/** Returns the {@link UIDelegate} responsible for handling download system UI events. */
UIDelegate getUIDelegate();
/** Destroys the BackendProvider. */ /** Destroys the BackendProvider. */
void destroy(); void destroy();
} }
...@@ -263,7 +263,7 @@ public class DownloadHistoryAdapter extends DateDividedAdapter ...@@ -263,7 +263,7 @@ public class DownloadHistoryAdapter extends DateDividedAdapter
if (wrapper.hasBeenExternallyRemoved()) { if (wrapper.hasBeenExternallyRemoved()) {
sDeletedFileTracker.add(wrapper); sDeletedFileTracker.add(wrapper);
wrapper.remove(); wrapper.removePermanently();
mFilePathsToItemsMap.removeItem(wrapper); mFilePathsToItemsMap.removeItem(wrapper);
RecordUserAction.record("Android.DownloadManager.Item.ExternallyDeleted"); RecordUserAction.record("Android.DownloadManager.Item.ExternallyDeleted");
return true; return true;
......
...@@ -111,6 +111,26 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem { ...@@ -111,6 +111,26 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem {
return filter == getFilterType() || filter == DownloadFilter.FILTER_ALL; return filter == getFilterType() || filter == DownloadFilter.FILTER_ALL;
} }
/** Called when this download should be shared. */
void share() {
mBackendProvider.getUIDelegate().shareItem(this);
}
/**
* Starts the delete process, which may or may not immediately delete the item or bring up a UI
* surface first.
*/
void startRemove() {
mBackendProvider.getUIDelegate().deleteItem(this);
}
/**
* @return Whether or not this item can be interacted with or not. This will change based on
* the current selection state of the owning list. */
boolean isInteractive() {
return !mBackendProvider.getSelectionDelegate().isSelectionEnabled();
}
/** @return Item that is being wrapped. */ /** @return Item that is being wrapped. */
abstract Object getItem(); abstract Object getItem();
...@@ -197,7 +217,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem { ...@@ -197,7 +217,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem {
* *
* @return Whether the file associated with the download item was deleted. * @return Whether the file associated with the download item was deleted.
*/ */
abstract boolean remove(); abstract boolean removePermanently();
protected void recordOpenSuccess() { protected void recordOpenSuccess() {
RecordUserAction.record("Android.DownloadManager.Item.OpenSucceeded"); RecordUserAction.record("Android.DownloadManager.Item.OpenSucceeded");
...@@ -362,7 +382,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem { ...@@ -362,7 +382,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem {
} }
@Override @Override
public boolean remove() { public boolean removePermanently() {
// Tell the DownloadManager to remove the file from history. // Tell the DownloadManager to remove the file from history.
mBackendProvider.getDownloadDelegate().removeDownload(getId(), isOffTheRecord()); mBackendProvider.getDownloadDelegate().removeDownload(getId(), isOffTheRecord());
mBackendProvider.getThumbnailProvider().removeThumbnailsFromDisk(getId()); mBackendProvider.getThumbnailProvider().removeThumbnailsFromDisk(getId());
...@@ -552,7 +572,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem { ...@@ -552,7 +572,7 @@ public abstract class DownloadHistoryItemWrapper extends TimedItem {
} }
@Override @Override
public boolean remove() { public boolean removePermanently() {
getOfflineContentProvider().removeItem(mItem.id); getOfflineContentProvider().removeItem(mItem.id);
return true; return true;
} }
......
...@@ -22,6 +22,8 @@ import org.chromium.base.ApiCompatibilityUtils; ...@@ -22,6 +22,8 @@ import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.chrome.browser.widget.ListMenuButton;
import org.chromium.chrome.browser.widget.ListMenuButton.Item;
import org.chromium.chrome.browser.widget.MaterialProgressBar; import org.chromium.chrome.browser.widget.MaterialProgressBar;
import org.chromium.chrome.browser.widget.ThumbnailProvider; import org.chromium.chrome.browser.widget.ThumbnailProvider;
import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.chrome.browser.widget.TintedImageButton;
...@@ -29,13 +31,14 @@ import org.chromium.chrome.browser.widget.selection.SelectableItemView; ...@@ -29,13 +31,14 @@ import org.chromium.chrome.browser.widget.selection.SelectableItemView;
import org.chromium.components.offline_items_collection.OfflineItem.Progress; import org.chromium.components.offline_items_collection.OfflineItem.Progress;
import org.chromium.ui.UiUtils; import org.chromium.ui.UiUtils;
import java.util.List;
import java.util.Locale; import java.util.Locale;
/** /**
* The view for a downloaded item displayed in the Downloads list. * The view for a downloaded item displayed in the Downloads list.
*/ */
public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrapper> public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrapper>
implements ThumbnailProvider.ThumbnailRequest { implements ThumbnailProvider.ThumbnailRequest, ListMenuButton.Delegate {
private final int mMargin; private final int mMargin;
private final int mMarginSubsection; private final int mMarginSubsection;
private final int mIconBackgroundColor; private final int mIconBackgroundColor;
...@@ -57,6 +60,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -57,6 +60,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
private View mLayoutCompleted; private View mLayoutCompleted;
private TextView mFilenameCompletedView; private TextView mFilenameCompletedView;
private TextView mDescriptionCompletedView; private TextView mDescriptionCompletedView;
private ListMenuButton mMoreButton;
// Controls for in-progress downloads. // Controls for in-progress downloads.
private View mLayoutInProgress; private View mLayoutInProgress;
...@@ -93,6 +97,22 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -93,6 +97,22 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
} }
} }
// ListMenuButton.Delegate implementation.
@Override
public Item[] getItems() {
return new Item[] {new Item(getContext(), R.string.share, true),
new Item(getContext(), R.string.delete, true)};
}
@Override
public void onItemSelected(Item item) {
if (item.getTextId() == R.string.share) {
mItem.share();
} else if (item.getTextId() == R.string.delete) {
mItem.startRemove();
}
}
@Override @Override
protected void onFinishInflate() { protected void onFinishInflate() {
super.onFinishInflate(); super.onFinishInflate();
...@@ -104,6 +124,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -104,6 +124,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
mFilenameCompletedView = (TextView) findViewById(R.id.filename_completed_view); mFilenameCompletedView = (TextView) findViewById(R.id.filename_completed_view);
mDescriptionCompletedView = (TextView) findViewById(R.id.description_view); mDescriptionCompletedView = (TextView) findViewById(R.id.description_view);
mMoreButton = (ListMenuButton) findViewById(R.id.more);
mFilenameInProgressView = (TextView) findViewById(R.id.filename_progress_view); mFilenameInProgressView = (TextView) findViewById(R.id.filename_progress_view);
mDownloadStatusView = (TextView) findViewById(R.id.status_view); mDownloadStatusView = (TextView) findViewById(R.id.status_view);
...@@ -112,22 +133,15 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -112,22 +133,15 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
mPauseResumeButton = (TintedImageButton) findViewById(R.id.pause_button); mPauseResumeButton = (TintedImageButton) findViewById(R.id.pause_button);
mCancelButton = findViewById(R.id.cancel_button); mCancelButton = findViewById(R.id.cancel_button);
mPauseResumeButton.setOnClickListener(new View.OnClickListener() { mMoreButton.setDelegate(this);
@Override mPauseResumeButton.setOnClickListener(view -> {
public void onClick(View v) { if (mItem.isPaused()) {
if (mItem.isPaused()) { mItem.resume();
mItem.resume(); } else if (!mItem.isComplete()) {
} else if (!mItem.isComplete()) { mItem.pause();
mItem.pause();
}
}
});
mCancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mItem.cancel();
} }
}); });
mCancelButton.setOnClickListener(view -> mItem.cancel());
} }
@Override @Override
...@@ -199,6 +213,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -199,6 +213,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
if (item.isComplete()) { if (item.isComplete()) {
showLayout(mLayoutCompleted); showLayout(mLayoutCompleted);
mMoreButton.setVisibility(View.VISIBLE);
} else { } else {
showLayout(mLayoutInProgress); showLayout(mLayoutInProgress);
mDownloadStatusView.setText(item.getStatusString()); mDownloadStatusView.setText(item.getStatusString());
...@@ -235,6 +250,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -235,6 +250,7 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
ApiCompatibilityUtils.setMarginEnd( ApiCompatibilityUtils.setMarginEnd(
(MarginLayoutParams) mDownloadPercentageView.getLayoutParams(), mMargin); (MarginLayoutParams) mDownloadPercentageView.getLayoutParams(), mMargin);
} }
mMoreButton.setVisibility(View.GONE);
} }
setLongClickable(item.isComplete()); setLongClickable(item.isComplete());
...@@ -248,6 +264,12 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -248,6 +264,12 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
updateIconView(); updateIconView();
} }
@Override
public void onSelectionStateChange(List<DownloadHistoryItemWrapper> selectedItems) {
super.onSelectionStateChange(selectedItems);
mMoreButton.setClickable(mItem.isInteractive());
}
@Override @Override
public void onClick() { public void onClick() {
if (mItem != null && mItem.isComplete()) mItem.open(); if (mItem != null && mItem.isComplete()) mItem.open();
...@@ -310,6 +332,10 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap ...@@ -310,6 +332,10 @@ public class DownloadItemView extends SelectableItemView<DownloadHistoryItemWrap
new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT); new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT);
params.weight = 1; params.weight = 1;
mLayoutContainer.addView(layoutToShow, params); mLayoutContainer.addView(layoutToShow, params);
// Move the menu button to the back of mLayoutContainer.
mLayoutContainer.removeView(mMoreButton);
mLayoutContainer.addView(mMoreButton);
} }
} }
} }
...@@ -17,6 +17,7 @@ import android.view.MenuItem; ...@@ -17,6 +17,7 @@ import android.view.MenuItem;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.chromium.base.CollectionUtil;
import org.chromium.base.DiscardableReferencePool; import org.chromium.base.DiscardableReferencePool;
import org.chromium.base.FileUtils; import org.chromium.base.FileUtils;
import org.chromium.base.ObserverList; import org.chromium.base.ObserverList;
...@@ -56,7 +57,8 @@ import java.util.Set; ...@@ -56,7 +57,8 @@ import java.util.Set;
public class DownloadManagerUi public class DownloadManagerUi
implements OnMenuItemClickListener, SearchDelegate, implements OnMenuItemClickListener, SearchDelegate,
SelectableBottomSheetContentManager<DownloadHistoryItemWrapper> { SelectableBottomSheetContentManager<DownloadHistoryItemWrapper>,
BackendProvider.UIDelegate {
/** /**
* Interface to observe the changes in the download manager ui. This should be implemented by * Interface to observe the changes in the download manager ui. This should be implemented by
* the ui components that is shown, in order to let them get proper notifications. * the ui components that is shown, in order to let them get proper notifications.
...@@ -74,14 +76,17 @@ public class DownloadManagerUi ...@@ -74,14 +76,17 @@ public class DownloadManagerUi
} }
private static class DownloadBackendProvider implements BackendProvider { private static class DownloadBackendProvider implements BackendProvider {
private SelectionDelegate<DownloadHistoryItemWrapper> mSelectionDelegate; private final SelectionDelegate<DownloadHistoryItemWrapper> mSelectionDelegate;
private final UIDelegate mUIDelegate;
private ThumbnailProvider mThumbnailProvider; private ThumbnailProvider mThumbnailProvider;
DownloadBackendProvider(DiscardableReferencePool referencePool) { DownloadBackendProvider(DiscardableReferencePool referencePool, UIDelegate uiDelegate) {
mSelectionDelegate = new DownloadItemSelectionDelegate(); mSelectionDelegate = new DownloadItemSelectionDelegate();
mThumbnailProvider = new ThumbnailProviderImpl(referencePool); mThumbnailProvider = new ThumbnailProviderImpl(referencePool);
mUIDelegate = uiDelegate;
} }
// BackendProvider implementation.
@Override @Override
public DownloadDelegate getDownloadDelegate() { public DownloadDelegate getDownloadDelegate() {
return DownloadManagerService.getDownloadManagerService(); return DownloadManagerService.getDownloadManagerService();
...@@ -103,6 +108,11 @@ public class DownloadManagerUi ...@@ -103,6 +108,11 @@ public class DownloadManagerUi
return mSelectionDelegate; return mSelectionDelegate;
} }
@Override
public UIDelegate getUIDelegate() {
return mUIDelegate;
}
@Override @Override
public void destroy() { public void destroy() {
mThumbnailProvider.destroy(); mThumbnailProvider.destroy();
...@@ -134,7 +144,7 @@ public class DownloadManagerUi ...@@ -134,7 +144,7 @@ public class DownloadManagerUi
// is called. Determine which files are not deleted by the #remove() call. // is called. Determine which files are not deleted by the #remove() call.
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
DownloadHistoryItemWrapper wrappedItem = items.get(i); DownloadHistoryItemWrapper wrappedItem = items.get(i);
if (!wrappedItem.remove()) filesToDelete.add(wrappedItem.getFile()); if (!wrappedItem.removePermanently()) filesToDelete.add(wrappedItem.getFile());
} }
// Delete the files associated with the download items (if necessary) using a single // Delete the files associated with the download items (if necessary) using a single
...@@ -190,7 +200,7 @@ public class DownloadManagerUi ...@@ -190,7 +200,7 @@ public class DownloadManagerUi
mActivity = activity; mActivity = activity;
ChromeApplication application = (ChromeApplication) activity.getApplication(); ChromeApplication application = (ChromeApplication) activity.getApplication();
mBackendProvider = sProviderForTests == null mBackendProvider = sProviderForTests == null
? new DownloadBackendProvider(application.getReferencePool()) ? new DownloadBackendProvider(application.getReferencePool(), this)
: sProviderForTests; : sProviderForTests;
mSnackbarManager = snackbarManager; mSnackbarManager = snackbarManager;
...@@ -251,6 +261,17 @@ public class DownloadManagerUi ...@@ -251,6 +261,17 @@ public class DownloadManagerUi
mNativePage = delegate; mNativePage = delegate;
} }
// BackendProvider.UIDelegate implementation.
@Override
public void deleteItem(DownloadHistoryItemWrapper item) {
deleteItems(CollectionUtil.newArrayList(item));
}
@Override
public void shareItem(DownloadHistoryItemWrapper item) {
startShareIntent(DownloadUtils.createShareIntent(CollectionUtil.newArrayList(item)));
}
/** /**
* Called when the bottom sheet content/activity/native page is destroyed. * Called when the bottom sheet content/activity/native page is destroyed.
*/ */
...@@ -315,10 +336,19 @@ public class DownloadManagerUi ...@@ -315,10 +336,19 @@ public class DownloadManagerUi
mActivity.finish(); mActivity.finish();
return true; return true;
} else if (item.getItemId() == R.id.selection_mode_delete_menu_id) { } else if (item.getItemId() == R.id.selection_mode_delete_menu_id) {
deleteSelectedItems(); List<DownloadHistoryItemWrapper> items =
mBackendProvider.getSelectionDelegate().getSelectedItems();
mBackendProvider.getSelectionDelegate().clearSelection();
deleteItems(items);
return true; return true;
} else if (item.getItemId() == R.id.selection_mode_share_menu_id) { } else if (item.getItemId() == R.id.selection_mode_share_menu_id) {
shareSelectedItems(); List<DownloadHistoryItemWrapper> items =
mBackendProvider.getSelectionDelegate().getSelectedItems();
// TODO(twellington): ideally the intent chooser would be started with
// startActivityForResult() and the selection would only be cleared
// after receiving an OK response. See crbug.com/638916.
mBackendProvider.getSelectionDelegate().clearSelection();
startShareIntent(DownloadUtils.createShareIntent(items));
return true; return true;
} else if (item.getItemId() == R.id.info_menu_id) { } else if (item.getItemId() == R.id.info_menu_id) {
enableStorageInfoHeader(!mHistoryAdapter.shouldShowStorageInfoHeader()); enableStorageInfoHeader(!mHistoryAdapter.shouldShowStorageInfoHeader());
...@@ -392,20 +422,6 @@ public class DownloadManagerUi ...@@ -392,20 +422,6 @@ public class DownloadManagerUi
mHistoryAdapter.onEndSearch(); mHistoryAdapter.onEndSearch();
} }
private void shareSelectedItems() {
List<DownloadHistoryItemWrapper> selectedItems =
mBackendProvider.getSelectionDelegate().getSelectedItems();
assert selectedItems.size() > 0;
mActivity.startActivity(Intent.createChooser(createShareIntent(),
mActivity.getString(R.string.share_link_chooser_title)));
// TODO(twellington): ideally the intent chooser would be started with
// startActivityForResult() and the selection would only be cleared after
// receiving an OK response. See crbug.com/638916.
mBackendProvider.getSelectionDelegate().clearSelection();
}
private void enableStorageInfoHeader(boolean show) { private void enableStorageInfoHeader(boolean show) {
// Finish any running or pending animations right away. // Finish any running or pending animations right away.
if (mRecyclerView.getItemAnimator() != null) { if (mRecyclerView.getItemAnimator() != null) {
...@@ -416,30 +432,33 @@ public class DownloadManagerUi ...@@ -416,30 +432,33 @@ public class DownloadManagerUi
mToolbar.updateInfoMenuItem(true, show); mToolbar.updateInfoMenuItem(true, show);
} }
/** private void startShareIntent(Intent intent) {
* @return An Intent to share the selected items. mActivity.startActivity(Intent.createChooser(
*/ intent, mActivity.getString(R.string.share_link_chooser_title)));
@VisibleForTesting
public Intent createShareIntent() {
List<DownloadHistoryItemWrapper> selectedItems =
mBackendProvider.getSelectionDelegate().getSelectedItems();
return DownloadUtils.createShareIntent(selectedItems);
} }
private void deleteSelectedItems() { private void deleteItems(List<DownloadHistoryItemWrapper> items) {
List<DownloadHistoryItemWrapper> selectedItems = // Build a full list of items to remove for the selected items.
mBackendProvider.getSelectionDelegate().getSelectedItems(); List<DownloadHistoryItemWrapper> itemsToDelete = new ArrayList<>();
final List<DownloadHistoryItemWrapper> itemsToDelete = getItemsForDeletion();
mBackendProvider.getSelectionDelegate().clearSelection(); Set<String> filePathsToRemove = new HashSet<>();
CollectionUtil.forEach(items, item -> {
if (!filePathsToRemove.contains(item.getFilePath())) {
Set<DownloadHistoryItemWrapper> itemsForFilePath =
mHistoryAdapter.getItemsForFilePath(item.getFilePath());
if (itemsForFilePath != null) itemsToDelete.addAll(itemsForFilePath);
filePathsToRemove.add(item.getFilePath());
}
});
if (itemsToDelete.isEmpty()) return; if (itemsToDelete.isEmpty()) return;
mHistoryAdapter.markItemsForDeletion(itemsToDelete); mHistoryAdapter.markItemsForDeletion(itemsToDelete);
boolean singleItemDeleted = selectedItems.size() == 1; boolean singleItemDeleted = items.size() == 1;
String snackbarText = singleItemDeleted ? selectedItems.get(0).getDisplayFileName() : String snackbarText = singleItemDeleted
String.format(Locale.getDefault(), "%d", selectedItems.size()); ? items.get(0).getDisplayFileName()
: String.format(Locale.getDefault(), "%d", items.size());
int snackbarTemplateId = singleItemDeleted ? R.string.undo_bar_delete_message int snackbarTemplateId = singleItemDeleted ? R.string.undo_bar_delete_message
: R.string.undo_bar_multiple_downloads_delete_message; : R.string.undo_bar_multiple_downloads_delete_message;
...@@ -451,26 +470,6 @@ public class DownloadManagerUi ...@@ -451,26 +470,6 @@ public class DownloadManagerUi
mSnackbarManager.showSnackbar(snackbar); mSnackbarManager.showSnackbar(snackbar);
} }
private List<DownloadHistoryItemWrapper> getItemsForDeletion() {
List<DownloadHistoryItemWrapper> selectedItems =
mBackendProvider.getSelectionDelegate().getSelectedItems();
List<DownloadHistoryItemWrapper> itemsToRemove = new ArrayList<>();
Set<String> filePathsToRemove = new HashSet<>();
for (DownloadHistoryItemWrapper item : selectedItems) {
if (!filePathsToRemove.contains(item.getFilePath())) {
Set<DownloadHistoryItemWrapper> itemsForFilePath =
mHistoryAdapter.getItemsForFilePath(item.getFilePath());
if (itemsForFilePath != null) {
itemsToRemove.addAll(itemsForFilePath);
}
filePathsToRemove.add(item.getFilePath());
}
}
return itemsToRemove;
}
private void dismissUndoDeletionSnackbars() { private void dismissUndoDeletionSnackbars() {
mSnackbarManager.dismissSnackbars(mUndoDeletionSnackbarController); mSnackbarManager.dismissSnackbars(mUndoDeletionSnackbarController);
} }
......
...@@ -419,7 +419,8 @@ public class DownloadActivityTest { ...@@ -419,7 +419,8 @@ public class DownloadActivityTest {
// Select an image, download item #6. // Select an image, download item #6.
toggleItemSelection(2); toggleItemSelection(2);
Intent shareIntent = mUi.createShareIntent(); Intent shareIntent = DownloadUtils.createShareIntent(
mUi.getBackendProvider().getSelectionDelegate().getSelectedItems());
Assert.assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction()); Assert.assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "image/png", shareIntent.getType()); Assert.assertEquals("Incorrect intent mime type", "image/png", shareIntent.getType());
Assert.assertNotNull( Assert.assertNotNull(
...@@ -433,7 +434,8 @@ public class DownloadActivityTest { ...@@ -433,7 +434,8 @@ public class DownloadActivityTest {
// Select another image, download item #0. // Select another image, download item #0.
toggleItemSelection(9); toggleItemSelection(9);
shareIntent = mUi.createShareIntent(); shareIntent = DownloadUtils.createShareIntent(
mUi.getBackendProvider().getSelectionDelegate().getSelectedItems());
Assert.assertEquals( Assert.assertEquals(
"Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction()); "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "image/*", shareIntent.getType()); Assert.assertEquals("Incorrect intent mime type", "image/*", shareIntent.getType());
...@@ -446,7 +448,8 @@ public class DownloadActivityTest { ...@@ -446,7 +448,8 @@ public class DownloadActivityTest {
// Select non-image item, download item #4. // Select non-image item, download item #4.
toggleItemSelection(6); toggleItemSelection(6);
shareIntent = mUi.createShareIntent(); shareIntent = DownloadUtils.createShareIntent(
mUi.getBackendProvider().getSelectionDelegate().getSelectedItems());
Assert.assertEquals( Assert.assertEquals(
"Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction()); "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType()); Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
...@@ -459,7 +462,8 @@ public class DownloadActivityTest { ...@@ -459,7 +462,8 @@ public class DownloadActivityTest {
// Select an offline page #3. // Select an offline page #3.
toggleItemSelection(3); toggleItemSelection(3);
shareIntent = mUi.createShareIntent(); shareIntent = DownloadUtils.createShareIntent(
mUi.getBackendProvider().getSelectionDelegate().getSelectedItems());
Assert.assertEquals( Assert.assertEquals(
"Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction()); "Incorrect intent action", Intent.ACTION_SEND_MULTIPLE, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType()); Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
......
...@@ -188,6 +188,17 @@ public class StubbedProvider implements BackendProvider { ...@@ -188,6 +188,17 @@ public class StubbedProvider implements BackendProvider {
public void cancelRetrieval(ThumbnailRequest request) {} public void cancelRetrieval(ThumbnailRequest request) {}
} }
/** Stubs out the UIDelegate. */
public class StubbedUIDelegate implements UIDelegate {
@Override
public void deleteItem(DownloadHistoryItemWrapper item) {
mHandler.post(() -> item.removePermanently());
}
@Override
public void shareItem(DownloadHistoryItemWrapper item) {}
}
private static final long ONE_GIGABYTE = 1024L * 1024L * 1024L; private static final long ONE_GIGABYTE = 1024L * 1024L * 1024L;
private final Handler mHandler; private final Handler mHandler;
...@@ -195,6 +206,7 @@ public class StubbedProvider implements BackendProvider { ...@@ -195,6 +206,7 @@ public class StubbedProvider implements BackendProvider {
private final StubbedOfflineContentProvider mOfflineContentProvider; private final StubbedOfflineContentProvider mOfflineContentProvider;
private final SelectionDelegate<DownloadHistoryItemWrapper> mSelectionDelegate; private final SelectionDelegate<DownloadHistoryItemWrapper> mSelectionDelegate;
private final StubbedThumbnailProvider mStubbedThumbnailProvider; private final StubbedThumbnailProvider mStubbedThumbnailProvider;
private final StubbedUIDelegate mStubbedUIDelegate;
public StubbedProvider() { public StubbedProvider() {
mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper());
...@@ -202,6 +214,7 @@ public class StubbedProvider implements BackendProvider { ...@@ -202,6 +214,7 @@ public class StubbedProvider implements BackendProvider {
mOfflineContentProvider = new StubbedOfflineContentProvider(); mOfflineContentProvider = new StubbedOfflineContentProvider();
mSelectionDelegate = new DownloadItemSelectionDelegate(); mSelectionDelegate = new DownloadItemSelectionDelegate();
mStubbedThumbnailProvider = new StubbedThumbnailProvider(); mStubbedThumbnailProvider = new StubbedThumbnailProvider();
mStubbedUIDelegate = new StubbedUIDelegate();
} }
@Override @Override
...@@ -224,6 +237,11 @@ public class StubbedProvider implements BackendProvider { ...@@ -224,6 +237,11 @@ public class StubbedProvider implements BackendProvider {
return mStubbedThumbnailProvider; return mStubbedThumbnailProvider;
} }
@Override
public UIDelegate getUIDelegate() {
return mStubbedUIDelegate;
}
@Override @Override
public void destroy() {} public void destroy() {}
......
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