merge in jb-mr2-release history after reset to master
The Android Automerger [Wed, 20 Feb 2013 13:56:21 +0000 (05:56 -0800)]
src/com/android/providers/downloads/DownloadInfo.java
src/com/android/providers/downloads/DownloadService.java
src/com/android/providers/downloads/DownloadThread.java
src/com/android/providers/downloads/Helpers.java

index 6524222..e6ed059 100644 (file)
@@ -358,7 +358,6 @@ public class DownloadInfo {
 
     /**
      * Returns whether this download is allowed to use the network.
-     * @return one of the NETWORK_* constants
      */
     public NetworkState checkCanUseNetwork() {
         final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mUid);
index 34b1b49..66d3be9 100644 (file)
@@ -185,6 +185,7 @@ public class DownloadService extends Service {
 
     @Override
     public void onDestroy() {
+        mUpdateThread.quit();
         mScanner.shutdown();
         getContentResolver().unregisterContentObserver(mObserver);
         if (Constants.LOGVV) {
index d19f71b..48eebfc 100644 (file)
@@ -20,7 +20,6 @@ import static android.provider.Downloads.Impl.STATUS_BAD_REQUEST;
 import static android.provider.Downloads.Impl.STATUS_CANNOT_RESUME;
 import static android.provider.Downloads.Impl.STATUS_FILE_ERROR;
 import static android.provider.Downloads.Impl.STATUS_HTTP_DATA_ERROR;
-import static android.provider.Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
 import static android.provider.Downloads.Impl.STATUS_TOO_MANY_REDIRECTS;
 import static android.provider.Downloads.Impl.STATUS_WAITING_FOR_NETWORK;
 import static android.provider.Downloads.Impl.STATUS_WAITING_TO_RETRY;
@@ -39,7 +38,9 @@ import android.content.Context;
 import android.content.Intent;
 import android.drm.DrmManagerClient;
 import android.drm.DrmOutputStream;
+import android.net.ConnectivityManager;
 import android.net.INetworkPolicyListener;
+import android.net.NetworkInfo;
 import android.net.NetworkPolicyManager;
 import android.net.TrafficStats;
 import android.os.FileUtils;
@@ -73,6 +74,9 @@ import libcore.io.IoUtils;
  */
 public class DownloadThread implements Runnable {
 
+    // TODO: bind each download to a specific network interface to avoid state
+    // checking races once we have ConnectivityManager API
+
     private static final int HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
     private static final int HTTP_TEMP_REDIRECT = 307;
 
@@ -121,6 +125,7 @@ public class DownloadThread implements Runnable {
         public boolean mContinuingDownload = false;
         public long mBytesNotified = 0;
         public long mTimeLastNotification = 0;
+        public int mNetworkType = ConnectivityManager.TYPE_NONE;
 
         /** Historical bytes/second speed of this download. */
         public long mSpeed;
@@ -190,6 +195,13 @@ public class DownloadThread implements Runnable {
 
             Log.i(Constants.TAG, "Initiating download " + mInfo.mId);
 
+            // Remember which network this download started on; used to
+            // determine if errors were due to network changes.
+            final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mInfo.mUid);
+            if (info != null) {
+                state.mNetworkType = info.getType();
+            }
+
             // Network traffic on this thread should be counted against the
             // requesting UID, and is tagged with well-known value.
             TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_DOWNLOAD);
@@ -234,7 +246,15 @@ public class DownloadThread implements Runnable {
                 }
 
                 if (numFailed < Constants.MAX_RETRIES) {
-                    finalStatus = getFinalRetryStatus();
+                    final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mInfo.mUid);
+                    if (info != null && info.getType() == state.mNetworkType
+                            && info.isConnected()) {
+                        // Underlying network is still intact, use normal backoff
+                        finalStatus = STATUS_WAITING_TO_RETRY;
+                    } else {
+                        // Network changed, retry on any next available
+                        finalStatus = STATUS_WAITING_FOR_NETWORK;
+                    }
                 }
             }
 
@@ -431,21 +451,6 @@ public class DownloadThread implements Runnable {
     }
 
     /**
-     * Return retry status appropriate for current network conditions.
-     */
-    private int getFinalRetryStatus() {
-        switch (mInfo.checkCanUseNetwork()) {
-            case OK:
-                return STATUS_WAITING_TO_RETRY;
-            case UNUSABLE_DUE_TO_SIZE:
-            case RECOMMENDED_UNUSABLE_DUE_TO_SIZE:
-                return STATUS_QUEUED_FOR_WIFI;
-            default:
-                return STATUS_WAITING_FOR_NETWORK;
-        }
-    }
-
-    /**
      * Transfer as much data as possible from the HTTP response to the
      * destination file.
      */
@@ -535,10 +540,13 @@ public class DownloadThread implements Runnable {
                 state.mSpeed = ((state.mSpeed * 3) + sampleSpeed) / 4;
             }
 
+            // Only notify once we have a full sample window
+            if (state.mSpeedSampleStart != 0) {
+                mNotifier.notifyDownloadSpeed(mInfo.mId, state.mSpeed);
+            }
+
             state.mSpeedSampleStart = now;
             state.mSpeedSampleBytes = state.mCurrentBytes;
-
-            mNotifier.notifyDownloadSpeed(mInfo.mId, state.mSpeed);
         }
 
         if (state.mCurrentBytes - state.mBytesNotified > Constants.MIN_PROGRESS_STEP &&
index 5c34ebe..593e28b 100644 (file)
@@ -329,14 +329,6 @@ public class Helpers {
     }
 
     /**
-     * Returns whether the network is available
-     */
-    public static boolean isNetworkAvailable(SystemFacade system, int uid) {
-        final NetworkInfo info = system.getActiveNetworkInfo(uid);
-        return info != null && info.isConnected();
-    }
-
-    /**
      * Checks whether the filename looks legitimate
      */
     static boolean isFilenameValid(String filename, File downloadsDataDir) {