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 |