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 |