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.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 |