| 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.DownloadManager; | 7 import android.app.DownloadManager; |
| 8 import android.content.ActivityNotFoundException; | 8 import android.content.ActivityNotFoundException; |
| 9 import android.content.BroadcastReceiver; | 9 import android.content.BroadcastReceiver; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| 11 import android.content.Intent; | 11 import android.content.Intent; |
| 12 import android.content.IntentFilter; | 12 import android.content.IntentFilter; |
| 13 import android.content.SharedPreferences; | 13 import android.content.SharedPreferences; |
| 14 import android.database.Cursor; | 14 import android.database.Cursor; |
| 15 import android.net.ConnectivityManager; | 15 import android.net.ConnectivityManager; |
| 16 import android.net.NetworkInfo; |
| 16 import android.net.Uri; | 17 import android.net.Uri; |
| 17 import android.os.AsyncTask; | 18 import android.os.AsyncTask; |
| 18 import android.os.Environment; | 19 import android.os.Environment; |
| 19 import android.os.Handler; | 20 import android.os.Handler; |
| 20 import android.support.annotation.Nullable; | 21 import android.support.annotation.Nullable; |
| 21 import android.text.TextUtils; | 22 import android.text.TextUtils; |
| 22 import android.util.LongSparseArray; | 23 import android.util.LongSparseArray; |
| 23 import android.util.Pair; | 24 import android.util.Pair; |
| 24 | 25 |
| 25 import org.chromium.base.ContextUtils; | 26 import org.chromium.base.ContextUtils; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 public void onDownloadInterrupted(final DownloadInfo downloadInfo, boolean i
sAutoResumable) { | 363 public void onDownloadInterrupted(final DownloadInfo downloadInfo, boolean i
sAutoResumable) { |
| 363 int status = DOWNLOAD_STATUS_INTERRUPTED; | 364 int status = DOWNLOAD_STATUS_INTERRUPTED; |
| 364 DownloadItem item = new DownloadItem(false, downloadInfo); | 365 DownloadItem item = new DownloadItem(false, downloadInfo); |
| 365 if (!downloadInfo.isResumable()) { | 366 if (!downloadInfo.isResumable()) { |
| 366 status = DOWNLOAD_STATUS_FAILED; | 367 status = DOWNLOAD_STATUS_FAILED; |
| 367 } else if (isAutoResumable) { | 368 } else if (isAutoResumable) { |
| 368 addAutoResumableDownload(item.getId()); | 369 addAutoResumableDownload(item.getId()); |
| 369 } | 370 } |
| 370 updateDownloadProgress(item, status); | 371 updateDownloadProgress(item, status); |
| 371 scheduleUpdateIfNeeded(); | 372 scheduleUpdateIfNeeded(); |
| 373 |
| 374 if (!isAutoResumable || sIsNetworkListenerDisabled) return; |
| 375 ConnectivityManager cm = |
| 376 (ConnectivityManager) mContext.getSystemService(Context.CONNECTI
VITY_SERVICE); |
| 377 NetworkInfo info = cm.getActiveNetworkInfo(); |
| 378 if (info == null || !info.isConnected()) return; |
| 379 DownloadProgress progress = mDownloadProgressMap.get(item.getId()); |
| 380 if (progress.mCanDownloadWhileMetered && !isActiveNetworkMetered(mContex
t)) { |
| 381 // Normally the download will automatically resume when network is r
econnected. |
| 382 // However, if there are multiple network connections and the interr
uption is caused |
| 383 // by switching between active networks, onConnectionTypeChanged() w
ill not get called. |
| 384 // As a result, we should resume immediately. |
| 385 // TODO(qinmin): Handle the case if the interruption is caused by sw
itching between |
| 386 // 2 metered networks or 2 non-metered networks on device with multi
ple antennas. |
| 387 scheduleDownloadResumption(item); |
| 388 } |
| 372 } | 389 } |
| 373 | 390 |
| 374 /** | 391 /** |
| 392 * Helper method to schedule a download for resumption. |
| 393 * @param item DownloadItem to resume. |
| 394 */ |
| 395 private void scheduleDownloadResumption(final DownloadItem item) { |
| 396 removeAutoResumableDownload(item.getId()); |
| 397 // Post a delayed task to avoid an issue that when connectivity status j
ust changed |
| 398 // to CONNECTED, immediately establishing a connection will sometimes fa
il. |
| 399 mHandler.postDelayed(new Runnable() { |
| 400 @Override |
| 401 public void run() { |
| 402 resumeDownload(LegacyHelpers.buildLegacyContentId(false, item.ge
tId()), |
| 403 item, false); |
| 404 } |
| 405 }, mUpdateDelayInMillis); |
| 406 } |
| 407 |
| 408 /** |
| 375 * Called when browser activity is launched. For background resumption and c
ancellation, this | 409 * Called when browser activity is launched. For background resumption and c
ancellation, this |
| 376 * will not be called. | 410 * will not be called. |
| 377 */ | 411 */ |
| 378 public void onActivityLaunched() { | 412 public void onActivityLaunched() { |
| 379 DownloadNotificationService.clearResumptionAttemptLeft(); | 413 DownloadNotificationService.clearResumptionAttemptLeft(); |
| 380 } | 414 } |
| 381 | 415 |
| 382 /** | 416 /** |
| 383 * Clear any pending OMA downloads by reading them from shared prefs. | 417 * Clear any pending OMA downloads by reading them from shared prefs. |
| 384 * TODO(qinmin): move this to a separate class. | 418 * TODO(qinmin): move this to a separate class. |
| (...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 private void removeDownloadProgress(String guid) { | 1538 private void removeDownloadProgress(String guid) { |
| 1505 mDownloadProgressMap.remove(guid); | 1539 mDownloadProgressMap.remove(guid); |
| 1506 removeAutoResumableDownload(guid); | 1540 removeAutoResumableDownload(guid); |
| 1507 } | 1541 } |
| 1508 | 1542 |
| 1509 @Override | 1543 @Override |
| 1510 public void onConnectionTypeChanged(int connectionType) { | 1544 public void onConnectionTypeChanged(int connectionType) { |
| 1511 if (mAutoResumableDownloadIds.isEmpty()) return; | 1545 if (mAutoResumableDownloadIds.isEmpty()) return; |
| 1512 if (connectionType == ConnectionType.CONNECTION_NONE) return; | 1546 if (connectionType == ConnectionType.CONNECTION_NONE) return; |
| 1513 boolean isMetered = isActiveNetworkMetered(mContext); | 1547 boolean isMetered = isActiveNetworkMetered(mContext); |
| 1514 Iterator<String> iterator = mAutoResumableDownloadIds.iterator(); | 1548 // Make a copy of |mAutoResumableDownloadIds| as scheduleDownloadResumpt
ion() may delete |
| 1549 // elements inside the array. |
| 1550 List<String> copies = new ArrayList<String>(mAutoResumableDownloadIds); |
| 1551 Iterator<String> iterator = copies.iterator(); |
| 1515 while (iterator.hasNext()) { | 1552 while (iterator.hasNext()) { |
| 1516 final String id = iterator.next(); | 1553 final String id = iterator.next(); |
| 1517 final DownloadProgress progress = mDownloadProgressMap.get(id); | 1554 final DownloadProgress progress = mDownloadProgressMap.get(id); |
| 1518 // Introduce some delay in each resumption so we don't start all of
them immediately. | 1555 // Introduce some delay in each resumption so we don't start all of
them immediately. |
| 1519 if (progress != null && (progress.mCanDownloadWhileMetered || !isMet
ered)) { | 1556 if (progress != null && (progress.mCanDownloadWhileMetered || !isMet
ered)) { |
| 1520 // Remove the pending resumable item so that the task won't be p
osted again on the | 1557 scheduleDownloadResumption(progress.mDownloadItem); |
| 1521 // next connectivity change. | |
| 1522 iterator.remove(); | |
| 1523 // Post a delayed task to avoid an issue that when connectivity
status just changed | |
| 1524 // to CONNECTED, immediately establishing a connection will some
times fail. | |
| 1525 mHandler.postDelayed(new Runnable() { | |
| 1526 @Override | |
| 1527 public void run() { | |
| 1528 resumeDownload(LegacyHelpers.buildLegacyContentId(false,
id), | |
| 1529 progress.mDownloadItem, false); | |
| 1530 } | |
| 1531 }, mUpdateDelayInMillis); | |
| 1532 } | 1558 } |
| 1533 } | 1559 } |
| 1534 stopListenToConnectionChangeIfNotNeeded(); | 1560 stopListenToConnectionChangeIfNotNeeded(); |
| 1535 } | 1561 } |
| 1536 | 1562 |
| 1537 /** | 1563 /** |
| 1538 * Helper method to stop listening to the connection type change | 1564 * Helper method to stop listening to the connection type change |
| 1539 * if it is no longer needed. | 1565 * if it is no longer needed. |
| 1540 */ | 1566 */ |
| 1541 private void stopListenToConnectionChangeIfNotNeeded() { | 1567 private void stopListenToConnectionChangeIfNotNeeded() { |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1896 boolean isOffTheRecord); | 1922 boolean isOffTheRecord); |
| 1897 private native void nativeRemoveDownload(long nativeDownloadManagerService,
String downloadGuid, | 1923 private native void nativeRemoveDownload(long nativeDownloadManagerService,
String downloadGuid, |
| 1898 boolean isOffTheRecord); | 1924 boolean isOffTheRecord); |
| 1899 private native void nativeGetAllDownloads( | 1925 private native void nativeGetAllDownloads( |
| 1900 long nativeDownloadManagerService, boolean isOffTheRecord); | 1926 long nativeDownloadManagerService, boolean isOffTheRecord); |
| 1901 private native void nativeCheckForExternallyRemovedDownloads( | 1927 private native void nativeCheckForExternallyRemovedDownloads( |
| 1902 long nativeDownloadManagerService, boolean isOffTheRecord); | 1928 long nativeDownloadManagerService, boolean isOffTheRecord); |
| 1903 private native void nativeUpdateLastAccessTime( | 1929 private native void nativeUpdateLastAccessTime( |
| 1904 long nativeDownloadManagerService, String downloadGuid, boolean isOf
fTheRecord); | 1930 long nativeDownloadManagerService, String downloadGuid, boolean isOf
fTheRecord); |
| 1905 } | 1931 } |
| OLD | NEW |