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.Notification; | 7 import android.app.Notification; |
8 import android.app.NotificationManager; | 8 import android.app.NotificationManager; |
9 import android.app.PendingIntent; | 9 import android.app.PendingIntent; |
10 import android.app.Service; | 10 import android.app.Service; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 public static final String ACTION_DOWNLOAD_RESUME_ALL = | 55 public static final String ACTION_DOWNLOAD_RESUME_ALL = |
56 "org.chromium.chrome.browser.download.DOWNLOAD_RESUME_ALL"; | 56 "org.chromium.chrome.browser.download.DOWNLOAD_RESUME_ALL"; |
57 static final int INVALID_DOWNLOAD_PERCENTAGE = -1; | 57 static final int INVALID_DOWNLOAD_PERCENTAGE = -1; |
58 @VisibleForTesting | 58 @VisibleForTesting |
59 static final String PENDING_DOWNLOAD_NOTIFICATIONS = "PendingDownloadNotific ations"; | 59 static final String PENDING_DOWNLOAD_NOTIFICATIONS = "PendingDownloadNotific ations"; |
60 static final String NOTIFICATION_NAMESPACE = "DownloadNotificationService"; | 60 static final String NOTIFICATION_NAMESPACE = "DownloadNotificationService"; |
61 private static final String TAG = "DownloadNotification"; | 61 private static final String TAG = "DownloadNotification"; |
62 private static final String NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNot ificationId"; | 62 private static final String NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNot ificationId"; |
63 // Notification Id starting value, to avoid conflicts from IDs used in prior versions. | 63 // Notification Id starting value, to avoid conflicts from IDs used in prior versions. |
64 private static final int STARTING_NOTIFICATION_ID = 1000000; | 64 private static final int STARTING_NOTIFICATION_ID = 1000000; |
65 private static final String AUTO_RESUMPTION_ATTEMPT_LEFT = "ResumptionAttemp tLeft"; | |
66 private static final int MAX_RESUMPTION_ATTEMPT_LEFT = 5; | |
65 @VisibleForTesting static final int SECONDS_PER_MINUTE = 60; | 67 @VisibleForTesting static final int SECONDS_PER_MINUTE = 60; |
66 @VisibleForTesting static final int SECONDS_PER_HOUR = 60 * 60; | 68 @VisibleForTesting static final int SECONDS_PER_HOUR = 60 * 60; |
67 @VisibleForTesting static final int SECONDS_PER_DAY = 24 * 60 * 60; | 69 @VisibleForTesting static final int SECONDS_PER_DAY = 24 * 60 * 60; |
68 private final IBinder mBinder = new LocalBinder(); | 70 private final IBinder mBinder = new LocalBinder(); |
69 private final List<DownloadSharedPreferenceEntry> mDownloadSharedPreferenceE ntries = | 71 private final List<DownloadSharedPreferenceEntry> mDownloadSharedPreferenceE ntries = |
70 new ArrayList<DownloadSharedPreferenceEntry>(); | 72 new ArrayList<DownloadSharedPreferenceEntry>(); |
71 private final List<String> mDownloadsInProgress = new ArrayList<String>(); | 73 private final List<String> mDownloadsInProgress = new ArrayList<String>(); |
72 private NotificationManager mNotificationManager; | 74 private NotificationManager mNotificationManager; |
73 private SharedPreferences mSharedPrefs; | 75 private SharedPreferences mSharedPrefs; |
74 private Context mContext; | 76 private Context mContext; |
75 private int mNextNotificationId; | 77 private int mNextNotificationId; |
78 private int mNumAutoResumptionAttemptLeft; | |
76 | 79 |
77 /** | 80 /** |
78 * Class for clients to access. | 81 * Class for clients to access. |
79 */ | 82 */ |
80 public class LocalBinder extends Binder { | 83 public class LocalBinder extends Binder { |
81 DownloadNotificationService getService() { | 84 DownloadNotificationService getService() { |
82 return DownloadNotificationService.this; | 85 return DownloadNotificationService.this; |
83 } | 86 } |
84 } | 87 } |
85 | 88 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 */ | 122 */ |
120 private void onBrowserKilled() { | 123 private void onBrowserKilled() { |
121 pauseAllDownloads(); | 124 pauseAllDownloads(); |
122 if (!mDownloadSharedPreferenceEntries.isEmpty()) { | 125 if (!mDownloadSharedPreferenceEntries.isEmpty()) { |
123 boolean allowMeteredConnection = false; | 126 boolean allowMeteredConnection = false; |
124 for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) { | 127 for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) { |
125 if (mDownloadSharedPreferenceEntries.get(i).canDownloadWhileMete red) { | 128 if (mDownloadSharedPreferenceEntries.get(i).canDownloadWhileMete red) { |
126 allowMeteredConnection = true; | 129 allowMeteredConnection = true; |
127 } | 130 } |
128 } | 131 } |
129 DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext) .schedule( | 132 if (mNumAutoResumptionAttemptLeft > 0) { |
130 allowMeteredConnection); | 133 DownloadResumptionScheduler.getDownloadResumptionScheduler(mCont ext).schedule( |
134 allowMeteredConnection); | |
135 } | |
131 } | 136 } |
132 stopSelf(); | 137 stopSelf(); |
133 } | 138 } |
134 | 139 |
135 @Override | 140 @Override |
136 public int onStartCommand(final Intent intent, int flags, int startId) { | 141 public int onStartCommand(final Intent intent, int flags, int startId) { |
137 if (isDownloadOperationIntent(intent)) { | 142 if (isDownloadOperationIntent(intent)) { |
138 handleDownloadOperation(intent); | 143 handleDownloadOperation(intent); |
139 DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext) .cancelTask(); | 144 DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext) .cancelTask(); |
145 // Limit the number of auto resumption attempts in case Chrome falls into a vicious | |
146 // cycle. | |
147 if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) { | |
148 if (mNumAutoResumptionAttemptLeft > 0) { | |
149 mNumAutoResumptionAttemptLeft--; | |
150 updateResumptionAttemptLeft(); | |
151 } | |
152 } else { | |
153 // Reset number of attempts left if the action is triggered by u ser. | |
154 mNumAutoResumptionAttemptLeft = MAX_RESUMPTION_ATTEMPT_LEFT; | |
155 clearResumptionAttemptLeft(); | |
156 } | |
140 } | 157 } |
141 | |
142 // This should restart the service after Chrome gets killed. However, th is | 158 // This should restart the service after Chrome gets killed. However, th is |
143 // doesn't work on Android 4.4.2. | 159 // doesn't work on Android 4.4.2. |
144 return START_STICKY; | 160 return START_STICKY; |
145 } | 161 } |
146 | 162 |
147 @Override | 163 @Override |
148 public IBinder onBind(Intent intent) { | 164 public IBinder onBind(Intent intent) { |
149 return mBinder; | 165 return mBinder; |
150 } | 166 } |
151 | 167 |
152 /** | 168 /** |
169 * Helper method to update the remaining number of background resumption att empts left. | |
170 * @param attamptLeft Number of attempt left. | |
171 */ | |
172 private void updateResumptionAttemptLeft() { | |
173 SharedPreferences.Editor editor = mSharedPrefs.edit(); | |
174 editor.putInt(AUTO_RESUMPTION_ATTEMPT_LEFT, mNumAutoResumptionAttemptLef t); | |
175 editor.apply(); | |
176 } | |
177 | |
178 /** | |
179 * Helper method to clear the remaining number of background resumption atte mpts left. | |
180 */ | |
181 static void clearResumptionAttemptLeft() { | |
182 SharedPreferences SharedPrefs = ContextUtils.getAppSharedPreferences(); | |
183 SharedPreferences.Editor editor = SharedPrefs.edit(); | |
184 editor.remove(AUTO_RESUMPTION_ATTEMPT_LEFT); | |
185 editor.apply(); | |
186 } | |
187 | |
188 /** | |
153 * Add a in-progress download notification. | 189 * Add a in-progress download notification. |
154 * @param downloadGuid GUID of the download. | 190 * @param downloadGuid GUID of the download. |
155 * @param fileName File name of the download. | 191 * @param fileName File name of the download. |
156 * @param percentage Percentage completed. Value should be between 0 to 100 if | 192 * @param percentage Percentage completed. Value should be between 0 to 100 if |
157 * the percentage can be determined, or -1 if it is unknown. | 193 * the percentage can be determined, or -1 if it is unknown. |
158 * @param timeRemainingInMillis Remaining download time in milliseconds. | 194 * @param timeRemainingInMillis Remaining download time in milliseconds. |
159 * @param startTime Time when download started. | 195 * @param startTime Time when download started. |
160 * @param isResumable Whether the download can be resumed. | 196 * @param isResumable Whether the download can be resumed. |
161 * @param canDownloadWhileMetered Whether the download can happen in metered network. | 197 * @param canDownloadWhileMetered Whether the download can happen in metered network. |
162 */ | 198 */ |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 if (!entry.canDownloadWhileMetered && isNetworkMetered) continue; | 577 if (!entry.canDownloadWhileMetered && isNetworkMetered) continue; |
542 if (mDownloadsInProgress.contains(entry.downloadGuid)) continue; | 578 if (mDownloadsInProgress.contains(entry.downloadGuid)) continue; |
543 notifyDownloadProgress(entry.downloadGuid, entry.fileName, | 579 notifyDownloadProgress(entry.downloadGuid, entry.fileName, |
544 INVALID_DOWNLOAD_PERCENTAGE, 0, 0, true, entry.canDownloadWh ileMetered); | 580 INVALID_DOWNLOAD_PERCENTAGE, 0, 0, true, entry.canDownloadWh ileMetered); |
545 service.resumeDownload(entry.buildDownloadItem(), false); | 581 service.resumeDownload(entry.buildDownloadItem(), false); |
546 } | 582 } |
547 } | 583 } |
548 | 584 |
549 /** | 585 /** |
550 * Parse the DownloadSharedPreferenceEntry from the shared preference and re turn a list of them. | 586 * Parse the DownloadSharedPreferenceEntry from the shared preference and re turn a list of them. |
551 * @return a list of parsed DownloadSharedPreferenceEntry. | 587 * @return a list of parsed DownloadSharedPreferenceEntry. |
Ted C
2016/06/27 17:13:07
update the comment here
qinmin
2016/06/27 22:02:33
Done.
| |
552 */ | 588 */ |
553 void parseDownloadSharedPrefs() { | 589 void parseDownloadSharedPrefs() { |
590 mNumAutoResumptionAttemptLeft = mSharedPrefs.getInt(AUTO_RESUMPTION_ATTE MPT_LEFT, | |
591 MAX_RESUMPTION_ATTEMPT_LEFT); | |
554 if (!mSharedPrefs.contains(PENDING_DOWNLOAD_NOTIFICATIONS)) return; | 592 if (!mSharedPrefs.contains(PENDING_DOWNLOAD_NOTIFICATIONS)) return; |
555 Set<String> entries = DownloadManagerService.getStoredDownloadInfo( | 593 Set<String> entries = DownloadManagerService.getStoredDownloadInfo( |
556 mSharedPrefs, PENDING_DOWNLOAD_NOTIFICATIONS); | 594 mSharedPrefs, PENDING_DOWNLOAD_NOTIFICATIONS); |
557 for (String entryString : entries) { | 595 for (String entryString : entries) { |
558 DownloadSharedPreferenceEntry entry = | 596 DownloadSharedPreferenceEntry entry = |
559 DownloadSharedPreferenceEntry.parseFromString(entryString); | 597 DownloadSharedPreferenceEntry.parseFromString(entryString); |
560 if (entry.notificationId > 0) { | 598 if (entry.notificationId > 0) { |
561 mDownloadSharedPreferenceEntries.add( | 599 mDownloadSharedPreferenceEntries.add( |
562 DownloadSharedPreferenceEntry.parseFromString(entryStrin g)); | 600 DownloadSharedPreferenceEntry.parseFromString(entryStrin g)); |
563 } | 601 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 return context.getString(R.string.remaining_duration_minutes, minute s); | 689 return context.getString(R.string.remaining_duration_minutes, minute s); |
652 } else if (minutes > 0) { | 690 } else if (minutes > 0) { |
653 return context.getString(R.string.remaining_duration_one_minute); | 691 return context.getString(R.string.remaining_duration_one_minute); |
654 } else if (seconds == 1) { | 692 } else if (seconds == 1) { |
655 return context.getString(R.string.remaining_duration_one_second); | 693 return context.getString(R.string.remaining_duration_one_second); |
656 } else { | 694 } else { |
657 return context.getString(R.string.remaining_duration_seconds, second s); | 695 return context.getString(R.string.remaining_duration_seconds, second s); |
658 } | 696 } |
659 } | 697 } |
660 } | 698 } |
OLD | NEW |