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