| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.Activity; | 7 import android.app.Activity; |
| 8 import android.app.PendingIntent; | 8 import android.app.PendingIntent; |
| 9 import android.content.ActivityNotFoundException; | 9 import android.content.ActivityNotFoundException; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; | 45 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; |
| 46 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; | 46 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; |
| 47 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri
dge; | 47 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri
dge; |
| 48 import org.chromium.chrome.browser.profiles.Profile; | 48 import org.chromium.chrome.browser.profiles.Profile; |
| 49 import org.chromium.chrome.browser.tab.Tab; | 49 import org.chromium.chrome.browser.tab.Tab; |
| 50 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 50 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
| 51 import org.chromium.chrome.browser.tabmodel.document.TabDelegate; | 51 import org.chromium.chrome.browser.tabmodel.document.TabDelegate; |
| 52 import org.chromium.chrome.browser.util.IntentUtils; | 52 import org.chromium.chrome.browser.util.IntentUtils; |
| 53 import org.chromium.components.feature_engagement_tracker.EventConstants; | 53 import org.chromium.components.feature_engagement_tracker.EventConstants; |
| 54 import org.chromium.components.feature_engagement_tracker.FeatureEngagementTrack
er; | 54 import org.chromium.components.feature_engagement_tracker.FeatureEngagementTrack
er; |
| 55 import org.chromium.components.offline_items_collection.OfflineItem.Progress; |
| 56 import org.chromium.components.offline_items_collection.OfflineItemProgressUnit; |
| 55 import org.chromium.content_public.browser.DownloadState; | 57 import org.chromium.content_public.browser.DownloadState; |
| 56 import org.chromium.content_public.browser.LoadUrlParams; | 58 import org.chromium.content_public.browser.LoadUrlParams; |
| 57 import org.chromium.ui.base.DeviceFormFactor; | 59 import org.chromium.ui.base.DeviceFormFactor; |
| 58 import org.chromium.ui.widget.Toast; | 60 import org.chromium.ui.widget.Toast; |
| 59 | 61 |
| 60 import java.io.File; | 62 import java.io.File; |
| 61 import java.lang.annotation.Retention; | 63 import java.lang.annotation.Retention; |
| 62 import java.lang.annotation.RetentionPolicy; | 64 import java.lang.annotation.RetentionPolicy; |
| 63 import java.text.NumberFormat; | 65 import java.text.NumberFormat; |
| 64 import java.util.ArrayList; | 66 import java.util.ArrayList; |
| 65 import java.util.Calendar; | 67 import java.util.Calendar; |
| 66 import java.util.Date; | 68 import java.util.Date; |
| 67 import java.util.List; | 69 import java.util.List; |
| 68 import java.util.Locale; | 70 import java.util.Locale; |
| 71 import java.util.concurrent.TimeUnit; |
| 69 | 72 |
| 70 /** | 73 /** |
| 71 * A class containing some utility static methods. | 74 * A class containing some utility static methods. |
| 72 */ | 75 */ |
| 73 public class DownloadUtils { | 76 public class DownloadUtils { |
| 74 | 77 |
| 75 /** Strings indicating how many bytes have been downloaded for different uni
ts. */ | 78 /** Strings indicating how many bytes have been downloaded for different uni
ts. */ |
| 76 @VisibleForTesting | 79 @VisibleForTesting |
| 77 static final int[] BYTES_DOWNLOADED_STRINGS = { | 80 static final int[] BYTES_DOWNLOADED_STRINGS = { |
| 78 R.string.file_size_downloaded_kb, | 81 R.string.file_size_downloaded_kb, |
| 79 R.string.file_size_downloaded_mb, | 82 R.string.file_size_downloaded_mb, |
| 80 R.string.file_size_downloaded_gb | 83 R.string.file_size_downloaded_gb |
| 81 }; | 84 }; |
| 82 | 85 |
| 83 private static final String TAG = "download"; | 86 private static final String TAG = "download"; |
| 84 | 87 |
| 85 private static final String DEFAULT_MIME_TYPE = "*/*"; | 88 private static final String DEFAULT_MIME_TYPE = "*/*"; |
| 86 private static final String MIME_TYPE_DELIMITER = "/"; | 89 private static final String MIME_TYPE_DELIMITER = "/"; |
| 87 private static final String MIME_TYPE_VIDEO = "video"; | 90 private static final String MIME_TYPE_VIDEO = "video"; |
| 88 | 91 |
| 89 private static final String EXTRA_IS_OFF_THE_RECORD = | 92 private static final String EXTRA_IS_OFF_THE_RECORD = |
| 90 "org.chromium.chrome.browser.download.IS_OFF_THE_RECORD"; | 93 "org.chromium.chrome.browser.download.IS_OFF_THE_RECORD"; |
| 91 | 94 |
| 92 private static final long BYTES_PER_KILOBYTE = 1024; | 95 private static final long BYTES_PER_KILOBYTE = 1024; |
| 93 private static final long BYTES_PER_MEGABYTE = 1024 * 1024; | 96 private static final long BYTES_PER_MEGABYTE = 1024 * 1024; |
| 94 private static final long BYTES_PER_GIGABYTE = 1024 * 1024 * 1024; | 97 private static final long BYTES_PER_GIGABYTE = 1024 * 1024 * 1024; |
| 95 | 98 |
| 96 @VisibleForTesting | 99 @VisibleForTesting |
| 100 static final long SECONDS_PER_MINUTE = TimeUnit.MINUTES.toSeconds(1); |
| 101 @VisibleForTesting |
| 102 static final long SECONDS_PER_HOUR = TimeUnit.HOURS.toSeconds(1); |
| 103 @VisibleForTesting |
| 104 static final long SECONDS_PER_DAY = TimeUnit.DAYS.toSeconds(1); |
| 105 |
| 106 @VisibleForTesting |
| 97 static final String ELLIPSIS = "\u2026"; | 107 static final String ELLIPSIS = "\u2026"; |
| 98 | 108 |
| 99 /** | 109 /** |
| 100 * Possible sizes of type-based icons. | 110 * Possible sizes of type-based icons. |
| 101 */ | 111 */ |
| 102 @IntDef({ICON_SIZE_24_DP, ICON_SIZE_36_DP}) | 112 @IntDef({ICON_SIZE_24_DP, ICON_SIZE_36_DP}) |
| 103 @Retention(RetentionPolicy.SOURCE) | 113 @Retention(RetentionPolicy.SOURCE) |
| 104 public @interface IconSize {} | 114 public @interface IconSize {} |
| 105 | 115 |
| 106 public static final int ICON_SIZE_24_DP = 24; | 116 public static final int ICON_SIZE_24_DP = 24; |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 * Create a string that represents the percentage of the file that has downl
oaded. | 584 * Create a string that represents the percentage of the file that has downl
oaded. |
| 575 * @param percentage Current percentage of the file. | 585 * @param percentage Current percentage of the file. |
| 576 * @return String representing the percentage of the file that has been down
loaded. | 586 * @return String representing the percentage of the file that has been down
loaded. |
| 577 */ | 587 */ |
| 578 public static String getPercentageString(int percentage) { | 588 public static String getPercentageString(int percentage) { |
| 579 NumberFormat formatter = NumberFormat.getPercentInstance(Locale.getDefau
lt()); | 589 NumberFormat formatter = NumberFormat.getPercentInstance(Locale.getDefau
lt()); |
| 580 return formatter.format(percentage / 100.0); | 590 return formatter.format(percentage / 100.0); |
| 581 } | 591 } |
| 582 | 592 |
| 583 /** | 593 /** |
| 584 * Determine what String to show for a given download. | 594 * Creates a string that shows the time left or number of files left. |
| 595 * @param context The application context. |
| 596 * @param progress The download progress. |
| 597 * @param timeRemainingInMillis The remaining time in milli seconds. |
| 598 * @return Formatted string representing the time left or the number of file
s left. |
| 599 */ |
| 600 public static String getTimeOrFilesLeftString( |
| 601 Context context, Progress progress, long timeRemainingInMillis) { |
| 602 if (progress.unit == OfflineItemProgressUnit.FILES) { |
| 603 return formatRemainingFiles(context, progress); |
| 604 } else { |
| 605 return formatRemainingTime(context, timeRemainingInMillis); |
| 606 } |
| 607 } |
| 608 |
| 609 /** |
| 610 * Creates a string that represents the number of files left to be downloade
d. |
| 611 * @param progress Current download progress. |
| 612 * @return String representing the number of files left. |
| 613 */ |
| 614 public static String formatRemainingFiles(Context context, Progress progress
) { |
| 615 int filesLeft = (int) (progress.max - progress.value); |
| 616 if (filesLeft == 1) { |
| 617 return context.getResources().getString(R.string.one_file_left); |
| 618 } else { |
| 619 return context.getResources().getString(R.string.files_left, filesLe
ft); |
| 620 } |
| 621 } |
| 622 |
| 623 /** |
| 624 * Format remaining time for the given millis, in the following format: |
| 625 * 5 hours; will include 1 unit, can go down to seconds precision. |
| 626 * This is similar to what android.java.text.Formatter.formatShortElapsedTim
e() does. Don't use |
| 627 * ui::TimeFormat::Simple() as it is very expensive. |
| 628 * |
| 629 * @param context the application context. |
| 630 * @param millis the remaining time in milli seconds. |
| 631 * @return the formatted remaining time. |
| 632 */ |
| 633 @VisibleForTesting |
| 634 public static String formatRemainingTime(Context context, long millis) { |
| 635 long secondsLong = millis / 1000; |
| 636 |
| 637 int days = 0; |
| 638 int hours = 0; |
| 639 int minutes = 0; |
| 640 if (secondsLong >= SECONDS_PER_DAY) { |
| 641 days = (int) (secondsLong / SECONDS_PER_DAY); |
| 642 secondsLong -= days * SECONDS_PER_DAY; |
| 643 } |
| 644 if (secondsLong >= SECONDS_PER_HOUR) { |
| 645 hours = (int) (secondsLong / SECONDS_PER_HOUR); |
| 646 secondsLong -= hours * SECONDS_PER_HOUR; |
| 647 } |
| 648 if (secondsLong >= SECONDS_PER_MINUTE) { |
| 649 minutes = (int) (secondsLong / SECONDS_PER_MINUTE); |
| 650 secondsLong -= minutes * SECONDS_PER_MINUTE; |
| 651 } |
| 652 int seconds = (int) secondsLong; |
| 653 |
| 654 if (days >= 2) { |
| 655 days += (hours + 12) / 24; |
| 656 return context.getString(R.string.remaining_duration_days, days); |
| 657 } else if (days > 0) { |
| 658 return context.getString(R.string.remaining_duration_one_day); |
| 659 } else if (hours >= 2) { |
| 660 hours += (minutes + 30) / 60; |
| 661 return context.getString(R.string.remaining_duration_hours, hours); |
| 662 } else if (hours > 0) { |
| 663 return context.getString(R.string.remaining_duration_one_hour); |
| 664 } else if (minutes >= 2) { |
| 665 minutes += (seconds + 30) / 60; |
| 666 return context.getString(R.string.remaining_duration_minutes, minute
s); |
| 667 } else if (minutes > 0) { |
| 668 return context.getString(R.string.remaining_duration_one_minute); |
| 669 } else if (seconds == 1) { |
| 670 return context.getString(R.string.remaining_duration_one_second); |
| 671 } else { |
| 672 return context.getString(R.string.remaining_duration_seconds, second
s); |
| 673 } |
| 674 } |
| 675 |
| 676 /** |
| 677 * Determine what String to show for a given download in download home. |
| 585 * @param item Download to check the status of. | 678 * @param item Download to check the status of. |
| 586 * @return ID of a String resource to use, or 0 if the status couldn't be de
termined. | 679 * @return String representing the current download status. |
| 587 */ | 680 */ |
| 588 public static String getStatusString(DownloadItem item) { | 681 public static String getStatusString(DownloadItem item) { |
| 589 Context context = ContextUtils.getApplicationContext(); | 682 Context context = ContextUtils.getApplicationContext(); |
| 590 DownloadInfo info = item.getDownloadInfo(); | 683 DownloadInfo info = item.getDownloadInfo(); |
| 684 Progress progress = info.getProgress(); |
| 591 | 685 |
| 592 int state = info.state(); | 686 int state = info.state(); |
| 593 if (state == DownloadState.COMPLETE) { | 687 if (state == DownloadState.COMPLETE) { |
| 594 return context.getString(R.string.download_notification_completed); | 688 return context.getString(R.string.download_notification_completed); |
| 595 } | 689 } |
| 596 | 690 |
| 597 DownloadSharedPreferenceHelper helper = DownloadSharedPreferenceHelper.g
etInstance(); | 691 DownloadSharedPreferenceHelper helper = DownloadSharedPreferenceHelper.g
etInstance(); |
| 598 DownloadSharedPreferenceEntry entry = | 692 DownloadSharedPreferenceEntry entry = |
| 599 helper.getDownloadSharedPreferenceEntry(item.getContentId()); | 693 helper.getDownloadSharedPreferenceEntry(item.getContentId()); |
| 600 boolean isDownloadPending = | 694 boolean isDownloadPending = |
| 601 entry != null && state == DownloadState.INTERRUPTED && entry.isA
utoResumable; | 695 entry != null && state == DownloadState.INTERRUPTED && entry.isA
utoResumable; |
| 602 | 696 |
| 603 if (isDownloadPending) { | 697 if (isDownloadPending) { |
| 604 return context.getString(R.string.download_notification_pending); | 698 return context.getString(R.string.download_notification_pending); |
| 605 } else if (isDownloadPaused(item)) { | 699 } else if (isDownloadPaused(item)) { |
| 606 return context.getString(R.string.download_notification_paused); | 700 return context.getString(R.string.download_notification_paused); |
| 607 } | 701 } |
| 608 | 702 |
| 609 if (info.getBytesReceived() == 0 | 703 if (info.getBytesReceived() == 0 |
| 610 || (!item.isIndeterminate() && info.getTimeRemainingInMillis() <
0)) { | 704 || (!item.isIndeterminate() && info.getTimeRemainingInMillis() <
0)) { |
| 611 // We lack enough information about the download to display a useful
string. | 705 // We lack enough information about the download to display a useful
string. |
| 612 return context.getString(R.string.download_started); | 706 return context.getString(R.string.download_started); |
| 613 } else if (item.isIndeterminate()) { | 707 } else if (item.isIndeterminate()) { |
| 614 // Count up the bytes. | 708 // Count up the bytes. |
| 615 long bytes = info.getBytesReceived(); | 709 long bytes = info.getBytesReceived(); |
| 616 return DownloadUtils.getStringForDownloadedBytes(context, bytes); | 710 return DownloadUtils.getStringForDownloadedBytes(context, bytes); |
| 617 } else { | 711 } else { |
| 618 // Count down the time. | 712 // Count down the time or number of files. |
| 619 long msRemaining = info.getTimeRemainingInMillis(); | 713 return getTimeOrFilesLeftString(context, progress, info.getTimeRemai
ningInMillis()); |
| 620 return DownloadNotificationService.formatRemainingTime(context, msRe
maining); | |
| 621 } | 714 } |
| 622 } | 715 } |
| 623 | 716 |
| 624 /** | 717 /** |
| 625 * Query the Download backends about whether a download is paused. | 718 * Query the Download backends about whether a download is paused. |
| 626 * | 719 * |
| 627 * The Java-side contains more information about the status of a download th
an is persisted | 720 * The Java-side contains more information about the status of a download th
an is persisted |
| 628 * by the native backend, so it is queried first. | 721 * by the native backend, so it is queried first. |
| 629 * | 722 * |
| 630 * @param item Download to check the status of. | 723 * @param item Download to check the status of. |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 public static Date getDateAtMidnight(long timestamp) { | 875 public static Date getDateAtMidnight(long timestamp) { |
| 783 Calendar cal = Calendar.getInstance(); | 876 Calendar cal = Calendar.getInstance(); |
| 784 cal.setTimeInMillis(timestamp); | 877 cal.setTimeInMillis(timestamp); |
| 785 cal.set(Calendar.HOUR_OF_DAY, 0); | 878 cal.set(Calendar.HOUR_OF_DAY, 0); |
| 786 cal.set(Calendar.MINUTE, 0); | 879 cal.set(Calendar.MINUTE, 0); |
| 787 cal.set(Calendar.SECOND, 0); | 880 cal.set(Calendar.SECOND, 0); |
| 788 cal.set(Calendar.MILLISECOND, 0); | 881 cal.set(Calendar.MILLISECOND, 0); |
| 789 return cal.getTime(); | 882 return cal.getTime(); |
| 790 } | 883 } |
| 791 } | 884 } |
| OLD | NEW |