Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.download; | 5 package org.chromium.chrome.browser.download; |
| 6 | 6 |
| 7 import android.app.ActivityManager; | 7 import android.app.ActivityManager; |
| 8 import android.app.DownloadManager; | 8 import android.app.DownloadManager; |
| 9 import android.app.Notification; | 9 import android.app.Notification; |
| 10 import android.app.NotificationManager; | 10 import android.app.NotificationManager; |
| 11 import android.app.PendingIntent; | 11 import android.app.PendingIntent; |
| 12 import android.app.Service; | 12 import android.app.Service; |
| 13 import android.content.ComponentName; | 13 import android.content.ComponentName; |
| 14 import android.content.Context; | 14 import android.content.Context; |
| 15 import android.content.Intent; | 15 import android.content.Intent; |
| 16 import android.content.SharedPreferences; | 16 import android.content.SharedPreferences; |
| 17 import android.content.res.Resources; | 17 import android.content.res.Resources; |
| 18 import android.graphics.Bitmap; | 18 import android.graphics.Bitmap; |
| 19 import android.graphics.BitmapFactory; | 19 import android.graphics.BitmapFactory; |
| 20 import android.graphics.Canvas; | 20 import android.graphics.Canvas; |
| 21 import android.graphics.Paint; | 21 import android.graphics.Paint; |
| 22 import android.graphics.Rect; | 22 import android.graphics.Rect; |
| 23 import android.graphics.drawable.shapes.OvalShape; | 23 import android.graphics.drawable.shapes.OvalShape; |
| 24 import android.os.Binder; | 24 import android.os.Binder; |
| 25 import android.os.Build; | 25 import android.os.Build; |
| 26 import android.os.IBinder; | 26 import android.os.IBinder; |
| 27 import android.support.v4.app.NotificationCompat; | |
| 28 import android.text.TextUtils; | 27 import android.text.TextUtils; |
| 29 | 28 |
| 30 import org.chromium.base.ApiCompatibilityUtils; | 29 import org.chromium.base.ApiCompatibilityUtils; |
| 31 import org.chromium.base.ContextUtils; | 30 import org.chromium.base.ContextUtils; |
| 32 import org.chromium.base.Log; | 31 import org.chromium.base.Log; |
| 33 import org.chromium.base.VisibleForTesting; | 32 import org.chromium.base.VisibleForTesting; |
| 34 import org.chromium.base.library_loader.ProcessInitException; | 33 import org.chromium.base.library_loader.ProcessInitException; |
| 35 import org.chromium.chrome.R; | 34 import org.chromium.chrome.R; |
| 36 import org.chromium.chrome.browser.ChromeApplication; | 35 import org.chromium.chrome.browser.ChromeApplication; |
| 37 import org.chromium.chrome.browser.init.BrowserParts; | 36 import org.chromium.chrome.browser.init.BrowserParts; |
| 38 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | 37 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
| 39 import org.chromium.chrome.browser.init.EmptyBrowserParts; | 38 import org.chromium.chrome.browser.init.EmptyBrowserParts; |
| 39 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; | |
| 40 import org.chromium.chrome.browser.notifications.NotificationConstants; | 40 import org.chromium.chrome.browser.notifications.NotificationConstants; |
| 41 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri dge; | 41 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri dge; |
| 42 import org.chromium.chrome.browser.util.IntentUtils; | 42 import org.chromium.chrome.browser.util.IntentUtils; |
| 43 | 43 |
| 44 import java.util.ArrayList; | 44 import java.util.ArrayList; |
| 45 import java.util.List; | 45 import java.util.List; |
| 46 import java.util.concurrent.TimeUnit; | 46 import java.util.concurrent.TimeUnit; |
| 47 | 47 |
| 48 | 48 |
| 49 /** | 49 /** |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 } else if (indeterminate) { | 291 } else if (indeterminate) { |
| 292 contentText = DownloadUtils.getStringForBytes( | 292 contentText = DownloadUtils.getStringForBytes( |
| 293 mContext, DownloadUtils.BYTES_DOWNLOADED_STRINGS, bytesRecei ved); | 293 mContext, DownloadUtils.BYTES_DOWNLOADED_STRINGS, bytesRecei ved); |
| 294 } else { | 294 } else { |
| 295 contentText = timeRemainingInMillis < 0 | 295 contentText = timeRemainingInMillis < 0 |
| 296 ? mContext.getResources().getString(R.string.download_starte d) | 296 ? mContext.getResources().getString(R.string.download_starte d) |
| 297 : formatRemainingTime(mContext, timeRemainingInMillis); | 297 : formatRemainingTime(mContext, timeRemainingInMillis); |
| 298 } | 298 } |
| 299 int resId = isDownloadPending ? R.drawable.ic_download_pending | 299 int resId = isDownloadPending ? R.drawable.ic_download_pending |
| 300 : android.R.drawable.stat_sys_download; | 300 : android.R.drawable.stat_sys_download; |
| 301 NotificationCompat.Builder builder = buildNotification(resId, fileName, contentText); | 301 ChromeNotificationBuilder builder = buildNotification(resId, fileName, c ontentText); |
| 302 builder.setOngoing(true); | 302 builder.setOngoing(true); |
| 303 builder.setPriority(Notification.PRIORITY_HIGH); | 303 builder.setPriority(Notification.PRIORITY_HIGH); |
| 304 | 304 |
| 305 // Avoid animations while the download isn't progressing. | 305 // Avoid animations while the download isn't progressing. |
| 306 if (!isDownloadPending) { | 306 if (!isDownloadPending) { |
| 307 builder.setProgress(100, percentage, indeterminate); | 307 builder.setProgress(100, percentage, indeterminate); |
| 308 } | 308 } |
| 309 | 309 |
| 310 if (!indeterminate && !isOfflinePage) { | 310 if (!indeterminate && !isOfflinePage) { |
| 311 String percentText = DownloadUtils.getPercentageString(percentage); | 311 String percentText = DownloadUtils.getPercentageString(percentage); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 // If download is interrupted due to network disconnection, show downloa d pending state. | 394 // If download is interrupted due to network disconnection, show downloa d pending state. |
| 395 if (isAutoResumable) { | 395 if (isAutoResumable) { |
| 396 notifyDownloadPending(entry.downloadGuid, entry.fileName, entry.isOf fTheRecord, | 396 notifyDownloadPending(entry.downloadGuid, entry.fileName, entry.isOf fTheRecord, |
| 397 entry.canDownloadWhileMetered, entry.isOfflinePage()); | 397 entry.canDownloadWhileMetered, entry.isOfflinePage()); |
| 398 mDownloadsInProgress.remove(downloadGuid); | 398 mDownloadsInProgress.remove(downloadGuid); |
| 399 return; | 399 return; |
| 400 } | 400 } |
| 401 | 401 |
| 402 String contentText = mContext.getResources().getString( | 402 String contentText = mContext.getResources().getString( |
| 403 R.string.download_notification_paused); | 403 R.string.download_notification_paused); |
| 404 NotificationCompat.Builder builder = buildNotification( | 404 ChromeNotificationBuilder builder = |
| 405 R.drawable.ic_download_pause, entry.fileName, contentText); | 405 buildNotification(R.drawable.ic_download_pause, entry.fileName, contentText); |
| 406 | 406 |
| 407 // Clicking on an in-progress download sends the user to see all their d ownloads. | 407 // Clicking on an in-progress download sends the user to see all their d ownloads. |
| 408 Intent downloadHomeIntent = buildActionIntent( | 408 Intent downloadHomeIntent = buildActionIntent( |
| 409 mContext, DownloadManager.ACTION_NOTIFICATION_CLICKED, null, fal se, false); | 409 mContext, DownloadManager.ACTION_NOTIFICATION_CLICKED, null, fal se, false); |
| 410 builder.setContentIntent(PendingIntent.getBroadcast(mContext, entry.noti ficationId, | 410 builder.setContentIntent(PendingIntent.getBroadcast(mContext, entry.noti ficationId, |
| 411 downloadHomeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); | 411 downloadHomeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); |
| 412 builder.setAutoCancel(false); | 412 builder.setAutoCancel(false); |
| 413 | 413 |
| 414 Intent resumeIntent = buildActionIntent(mContext, ACTION_DOWNLOAD_RESUME , | 414 Intent resumeIntent = buildActionIntent(mContext, ACTION_DOWNLOAD_RESUME , |
| 415 entry.downloadGuid, entry.isOffTheRecord, entry.isOfflinePage()) ; | 415 entry.downloadGuid, entry.isOffTheRecord, entry.isOfflinePage()) ; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 446 * @param isOfflinePage Whether the download is for offline page. | 446 * @param isOfflinePage Whether the download is for offline page. |
| 447 * @param isSupportedMimeType Whether the MIME type can be viewed inside bro wser. | 447 * @param isSupportedMimeType Whether the MIME type can be viewed inside bro wser. |
| 448 * @return ID of the successful download notification. Used for removing the notification when | 448 * @return ID of the successful download notification. Used for removing the notification when |
| 449 * user click on the snackbar. | 449 * user click on the snackbar. |
| 450 */ | 450 */ |
| 451 @VisibleForTesting | 451 @VisibleForTesting |
| 452 public int notifyDownloadSuccessful( | 452 public int notifyDownloadSuccessful( |
| 453 String downloadGuid, String filePath, String fileName, long systemDo wnloadId, | 453 String downloadGuid, String filePath, String fileName, long systemDo wnloadId, |
| 454 boolean isOfflinePage, boolean isSupportedMimeType) { | 454 boolean isOfflinePage, boolean isSupportedMimeType) { |
| 455 int notificationId = getNotificationId(downloadGuid); | 455 int notificationId = getNotificationId(downloadGuid); |
| 456 NotificationCompat.Builder builder = buildNotification( | 456 ChromeNotificationBuilder builder = buildNotification(R.drawable.offline _pin, fileName, |
| 457 R.drawable.offline_pin, fileName, | |
| 458 mContext.getResources().getString(R.string.download_notification _completed)); | 457 mContext.getResources().getString(R.string.download_notification _completed)); |
| 459 ComponentName component = new ComponentName( | 458 ComponentName component = new ComponentName( |
| 460 mContext.getPackageName(), DownloadBroadcastReceiver.class.getNa me()); | 459 mContext.getPackageName(), DownloadBroadcastReceiver.class.getNa me()); |
| 461 Intent intent; | 460 Intent intent; |
| 462 if (isOfflinePage) { | 461 if (isOfflinePage) { |
| 463 intent = buildActionIntent(mContext, ACTION_DOWNLOAD_OPEN, downloadG uid, false, true); | 462 intent = buildActionIntent(mContext, ACTION_DOWNLOAD_OPEN, downloadG uid, false, true); |
| 464 } else { | 463 } else { |
| 465 intent = new Intent(DownloadManager.ACTION_NOTIFICATION_CLICKED); | 464 intent = new Intent(DownloadManager.ACTION_NOTIFICATION_CLICKED); |
| 466 long[] idArray = {systemDownloadId}; | 465 long[] idArray = {systemDownloadId}; |
| 467 intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_ID S, idArray); | 466 intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_ID S, idArray); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 493 // If the download is not in history db, fileName could be empty. Get it from | 492 // If the download is not in history db, fileName could be empty. Get it from |
| 494 // SharedPreferences. | 493 // SharedPreferences. |
| 495 if (TextUtils.isEmpty(fileName)) { | 494 if (TextUtils.isEmpty(fileName)) { |
| 496 DownloadSharedPreferenceEntry entry = | 495 DownloadSharedPreferenceEntry entry = |
| 497 mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceE ntry(downloadGuid); | 496 mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceE ntry(downloadGuid); |
| 498 if (entry == null) return; | 497 if (entry == null) return; |
| 499 fileName = entry.fileName; | 498 fileName = entry.fileName; |
| 500 } | 499 } |
| 501 | 500 |
| 502 int notificationId = getNotificationId(downloadGuid); | 501 int notificationId = getNotificationId(downloadGuid); |
| 503 NotificationCompat.Builder builder = buildNotification( | 502 ChromeNotificationBuilder builder = |
| 504 android.R.drawable.stat_sys_download_done, fileName, | 503 buildNotification(android.R.drawable.stat_sys_download_done, fil eName, |
| 505 mContext.getResources().getString(R.string.download_notification _failed)); | 504 mContext.getResources().getString(R.string.download_noti fication_failed)); |
| 506 updateNotification(notificationId, builder.build()); | 505 updateNotification(notificationId, builder.build()); |
| 507 mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid ); | 506 mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid ); |
| 508 mDownloadsInProgress.remove(downloadGuid); | 507 mDownloadsInProgress.remove(downloadGuid); |
| 509 } | 508 } |
| 510 | 509 |
| 511 /** | 510 /** |
| 512 * Called to pause all the download notifications. | 511 * Called to pause all the download notifications. |
| 513 */ | 512 */ |
| 514 @VisibleForTesting | 513 @VisibleForTesting |
| 515 void pauseAllDownloads() { | 514 void pauseAllDownloads() { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 return intent; | 562 return intent; |
| 564 } | 563 } |
| 565 | 564 |
| 566 /** | 565 /** |
| 567 * Builds a notification to be displayed. | 566 * Builds a notification to be displayed. |
| 568 * @param iconId Id of the notification icon. | 567 * @param iconId Id of the notification icon. |
| 569 * @param title Title of the notification. | 568 * @param title Title of the notification. |
| 570 * @param contentText Notification content text to be displayed. | 569 * @param contentText Notification content text to be displayed. |
| 571 * @return notification builder that builds the notification to be displayed | 570 * @return notification builder that builds the notification to be displayed |
| 572 */ | 571 */ |
| 573 private NotificationCompat.Builder buildNotification( | 572 private ChromeNotificationBuilder buildNotification( |
| 574 int iconId, String title, String contentText) { | 573 int iconId, String title, String contentText) { |
| 575 NotificationCompat.Builder builder = new NotificationCompat.Builder(mCon text) | 574 ChromeNotificationBuilder builder = |
| 576 .setContentTitle(DownloadUtils.getAbbreviatedFileName(title, MAX _FILE_NAME_LENGTH)) | 575 ((ChromeApplication) mContext) |
| 577 .setSmallIcon(iconId) | 576 .getChromeNotificationBuilder(true, NotificationConstant s.TYPE_ID_GENERAL, |
|
Peter Beverloo
2017/02/20 01:06:45
nit: true -> true /* preferCompat */ (elsewhere to
awdf
2017/02/24 00:38:46
Done.
| |
| 578 .setLocalOnly(true) | 577 NotificationConstants.TYPE_NAME_GENERAL) |
| 579 .setAutoCancel(true) | 578 .setContentTitle( |
| 580 .setContentText(contentText) | 579 DownloadUtils.getAbbreviatedFileName(title, MAX_ FILE_NAME_LENGTH)) |
| 581 .setGroup(NotificationConstants.GROUP_DOWNLOADS); | 580 .setSmallIcon(iconId) |
| 581 .setLocalOnly(true) | |
| 582 .setAutoCancel(true) | |
| 583 .setContentText(contentText) | |
| 584 .setGroup(NotificationConstants.GROUP_DOWNLOADS); | |
| 582 return builder; | 585 return builder; |
| 583 } | 586 } |
| 584 | 587 |
| 585 private Bitmap getLargeNotificationIcon(Bitmap bitmap) { | 588 private Bitmap getLargeNotificationIcon(Bitmap bitmap) { |
| 586 Resources resources = mContext.getResources(); | 589 Resources resources = mContext.getResources(); |
| 587 int height = (int) resources.getDimension(android.R.dimen.notification_l arge_icon_height); | 590 int height = (int) resources.getDimension(android.R.dimen.notification_l arge_icon_height); |
| 588 int width = (int) resources.getDimension(android.R.dimen.notification_la rge_icon_width); | 591 int width = (int) resources.getDimension(android.R.dimen.notification_la rge_icon_width); |
| 589 final OvalShape circle = new OvalShape(); | 592 final OvalShape circle = new OvalShape(); |
| 590 circle.resize(width, height); | 593 circle.resize(width, height); |
| 591 final Paint paint = new Paint(); | 594 final Paint paint = new Paint(); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 877 return context.getString(R.string.remaining_duration_minutes, minute s); | 880 return context.getString(R.string.remaining_duration_minutes, minute s); |
| 878 } else if (minutes > 0) { | 881 } else if (minutes > 0) { |
| 879 return context.getString(R.string.remaining_duration_one_minute); | 882 return context.getString(R.string.remaining_duration_one_minute); |
| 880 } else if (seconds == 1) { | 883 } else if (seconds == 1) { |
| 881 return context.getString(R.string.remaining_duration_one_second); | 884 return context.getString(R.string.remaining_duration_one_second); |
| 882 } else { | 885 } else { |
| 883 return context.getString(R.string.remaining_duration_seconds, second s); | 886 return context.getString(R.string.remaining_duration_seconds, second s); |
| 884 } | 887 } |
| 885 } | 888 } |
| 886 } | 889 } |
| OLD | NEW |