1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.download; 6 7 import android.app.Activity; 8 import android.app.DownloadManager; 9 import android.content.Intent; 10 11 import org.chromium.base.ApplicationStatus; 12 import org.chromium.base.ContextUtils; 13 import org.chromium.chrome.R; 14 import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; 15 import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; 16 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; 17 import org.chromium.components.offline_items_collection.LaunchLocation; 18 import org.chromium.components.offline_items_collection.LegacyHelpers; 19 import org.chromium.components.offline_items_collection.OpenParams; 20 21 /** 22 * Class for displaying a snackbar when a download completes. 23 */ 24 public class DownloadSnackbarController implements SnackbarManager.SnackbarController { 25 public static final int INVALID_NOTIFICATION_ID = -1; 26 private static final int SNACKBAR_DURATION_MS = 7000; 27 28 private static class ActionDataInfo { 29 public final DownloadInfo downloadInfo; 30 public final int notificationId; 31 public final long systemDownloadId; 32 public final boolean usesAndroidDownloadManager; 33 ActionDataInfo(DownloadInfo downloadInfo, int notificationId, long systemDownloadId, boolean usesAndroidDownloadManager)34 ActionDataInfo(DownloadInfo downloadInfo, int notificationId, long systemDownloadId, 35 boolean usesAndroidDownloadManager) { 36 this.downloadInfo = downloadInfo; 37 this.notificationId = notificationId; 38 this.systemDownloadId = systemDownloadId; 39 this.usesAndroidDownloadManager = usesAndroidDownloadManager; 40 } 41 } 42 43 @Override onAction(Object actionData)44 public void onAction(Object actionData) { 45 if (!(actionData instanceof ActionDataInfo)) { 46 DownloadManagerService.openDownloadsPage( 47 ContextUtils.getApplicationContext(), DownloadOpenSource.SNACK_BAR); 48 return; 49 } 50 51 DownloadManagerService manager = DownloadManagerService.getDownloadManagerService(); 52 final ActionDataInfo download = (ActionDataInfo) actionData; 53 if (LegacyHelpers.isLegacyDownload(download.downloadInfo.getContentId())) { 54 if (download.usesAndroidDownloadManager) { 55 ContextUtils.getApplicationContext().startActivity( 56 new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS) 57 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 58 } else { 59 manager.openDownloadedContent(download.downloadInfo, download.systemDownloadId, 60 DownloadOpenSource.SNACK_BAR); 61 } 62 } else { 63 OfflineContentAggregatorNotificationBridgeUiFactory.instance().openItem( 64 new OpenParams(LaunchLocation.PROGRESS_BAR), 65 download.downloadInfo.getContentId()); 66 } 67 68 if (download.notificationId != INVALID_NOTIFICATION_ID) { 69 manager.getDownloadNotifier().removeDownloadNotification( 70 download.notificationId, download.downloadInfo); 71 } 72 } 73 74 @Override onDismissNoAction(Object actionData)75 public void onDismissNoAction(Object actionData) { 76 } 77 78 /** 79 * Called to display the download failed snackbar. 80 * 81 * @param errorMessage The message to show on the snackbar. 82 * @param showAllDownloads Whether to show all downloads in case the failure is caused by 83 * duplicated files. 84 */ onDownloadFailed( String errorMessage, boolean showAllDownloads, boolean isOffTheRecord)85 public void onDownloadFailed( 86 String errorMessage, boolean showAllDownloads, boolean isOffTheRecord) { 87 if (isShowingDownloadInfoBar(isOffTheRecord)) return; 88 if (getSnackbarManager() == null) return; 89 // TODO(qinmin): Coalesce snackbars if multiple downloads finish at the same time. 90 Snackbar snackbar = Snackbar.make(errorMessage, this, Snackbar.TYPE_NOTIFICATION, 91 Snackbar.UMA_DOWNLOAD_FAILED) 92 .setSingleLine(false) 93 .setDuration(SNACKBAR_DURATION_MS); 94 if (showAllDownloads) { 95 snackbar.setAction( 96 ContextUtils.getApplicationContext().getString(R.string.open_downloaded_label), 97 null); 98 } 99 getSnackbarManager().showSnackbar(snackbar); 100 } 101 102 /** 103 * Displays a snackbar that says alerts the user that some downloads may be missing because a 104 * missing SD card was detected. 105 */ onDownloadDirectoryNotFound()106 void onDownloadDirectoryNotFound() { 107 if (getSnackbarManager() == null) return; 108 109 Snackbar snackbar = Snackbar.make(ContextUtils.getApplicationContext().getString( 110 R.string.download_location_no_sd_card_snackbar), 111 this, Snackbar.TYPE_NOTIFICATION, 112 Snackbar.UMA_MISSING_FILES_NO_SD_CARD) 113 .setSingleLine(false) 114 .setDuration(SNACKBAR_DURATION_MS); 115 getSnackbarManager().showSnackbar(snackbar); 116 } 117 getActivity()118 private Activity getActivity() { 119 if (ApplicationStatus.hasVisibleActivities()) { 120 return ApplicationStatus.getLastTrackedFocusedActivity(); 121 } else { 122 return null; 123 } 124 } 125 getSnackbarManager()126 public SnackbarManager getSnackbarManager() { 127 Activity activity = getActivity(); 128 if (activity != null && activity instanceof SnackbarManager.SnackbarManageable) { 129 return ((SnackbarManager.SnackbarManageable) activity).getSnackbarManager(); 130 } 131 return null; 132 } 133 isShowingDownloadInfoBar(boolean isOffTheRecord)134 private boolean isShowingDownloadInfoBar(boolean isOffTheRecord) { 135 DownloadInfoBarController infoBarController = 136 DownloadManagerService.getDownloadManagerService().getInfoBarController( 137 isOffTheRecord); 138 return infoBarController == null ? false : infoBarController.isShowing(); 139 } 140 } 141