A little tweaking of DL Manager tests and adding better debugging output.

Adding more detail to the output logging to help track down issues, fixing some
download completed notification counter flakiness and making reboot test more
robust, and reducing the number of concurrent downloads in testMultipleDownloads()
to 10. After talking with Vasu, this is probably more appropriate as it is
closer to typical usage scenarios, and as a side effect should trim some
time from the test runs. Large numbers of downloads will be left for stress
testing.

Change-Id: Ie337cfe9b8d27299d70553e39c60e241ff3afe66
diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
index 37fc6c7..340137c 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
@@ -132,14 +132,34 @@
          */
         @Override
         public void onReceive(Context context, Intent intent) {
-            Log.i(LOG_TAG, "Received Notification:");
             if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
                 synchronized(this) {
-                    ++mNumDownloadsCompleted;
-                    Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
-                            intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
-                    Bundle extras = intent.getExtras();
-                    downloadIds.add(new Long(extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID)));
+                    long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
+                    Log.i(LOG_TAG, "Received Notification for download: " + id);
+                    if (!downloadIds.contains(id)) {
+                        ++mNumDownloadsCompleted;
+                        Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
+                                intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
+                        downloadIds.add(id);
+
+                        DownloadManager dm = (DownloadManager)context.getSystemService(
+                                Context.DOWNLOAD_SERVICE);
+
+                        Cursor cursor = dm.query(new Query().setFilterById(id));
+                        try {
+                            if (cursor.moveToFirst()) {
+                                int status = cursor.getInt(cursor.getColumnIndex(
+                                        DownloadManager.COLUMN_STATUS));
+                                Log.i(LOG_TAG, "Download status is: " + status);
+                            } else {
+                                fail("No status found for completed download!");
+                            }
+                        } finally {
+                            cursor.close();
+                        }
+                    } else {
+                        Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
+                    }
                 }
             }
         }
@@ -621,9 +641,11 @@
     /**
      * Helper to wait for a particular download to finish, or else a timeout to occur
      *
+     * Does not wait for a receiver notification of the download.
+     *
      * @param id The download id to query on (wait for)
      */
-    protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
+    protected void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
             InterruptedException {
         waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
     }
@@ -631,6 +653,21 @@
     /**
      * Helper to wait for a particular download to finish, or else a timeout to occur
      *
+     * Also guarantees a notification has been posted for the download.
+     *
+     * @param id The download id to query on (wait for)
+     */
+    protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
+            InterruptedException {
+        waitForDownloadOrTimeout_skipNotification(id);
+        waitForReceiverNotifications(1);
+    }
+
+    /**
+     * Helper to wait for a particular download to finish, or else a timeout to occur
+     *
+     * Also guarantees a notification has been posted for the download.
+     *
      * @param id The download id to query on (wait for)
      * @param poll The amount of time to wait
      * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
@@ -638,11 +675,14 @@
     protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
             throws TimeoutException, InterruptedException {
         doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
+        waitForReceiverNotifications(1);
     }
 
     /**
      * Helper to wait for all downloads to finish, or else a specified timeout to occur
      *
+     * Makes no guaranee that notifications have been posted for all downloads.
+     *
      * @param poll The amount of time to wait
      * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
      */
@@ -654,6 +694,8 @@
     /**
      * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
      *
+     * Also guarantees a notification has been posted for the download.
+     *
      * @param id The id of the download to query against
      * @param poll The amount of time to wait
      * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
@@ -662,6 +704,7 @@
     protected boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
         try {
             doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
+            waitForReceiverNotifications(1);
         } catch (TimeoutException e) {
             return false;
         }
@@ -717,9 +760,8 @@
             Cursor cursor = mDownloadManager.query(query);
 
             try {
-                // @TODO: there may be a little cleaner way to check for success, perhaps
-                // via STATUS_SUCCESSFUL and/or STATUS_FAILED
-                if (cursor.getCount() == 0 && mReceiver.numDownloadsCompleted() > 0) {
+                if (cursor.getCount() == 0) {
+                    Log.i(LOG_TAG, "All downloads should be done...");
                     break;
                 }
                 currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
@@ -779,6 +821,36 @@
     }
 
     /**
+     * Convenience function to wait for just 1 notification of a download.
+     *
+     * @throws Exception if timed out while waiting
+     */
+    protected void waitForReceiverNotification() throws Exception {
+        waitForReceiverNotifications(1);
+    }
+
+    /**
+     * Synchronously waits for our receiver to receive notification for a given number of
+     * downloads.
+     *
+     * @param targetNumber The number of notifications for unique downloads to wait for; pass in
+     *         -1 to not wait for notification.
+     * @throws Exception if timed out while waiting
+     */
+    protected void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
+        int count = mReceiver.numDownloadsCompleted();
+        int currentWaitTime = 0;
+
+        while (count < targetNumber) {
+            Log.i(LOG_TAG, "Waiting for notification of downloads...");
+            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
+                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
+                    + " Received " + count + "notifications.");
+            count = mReceiver.numDownloadsCompleted();
+        }
+    }
+
+    /**
      * Synchronously waits for a file to increase in size (such as to monitor that a download is
      * progressing).
      *
diff --git a/core/tests/coretests/src/android/app/DownloadManagerIntegrationTest.java b/core/tests/coretests/src/android/app/DownloadManagerIntegrationTest.java
index cb7c2d2..4f79108 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerIntegrationTest.java
@@ -197,7 +197,7 @@
     public void testMultipleDownloads() throws Exception {
         // need to be sure all current downloads have stopped first
         removeAllCurrentDownloads();
-        int NUM_FILES = 50;
+        int NUM_FILES = 10;
         int MAX_FILE_SIZE = 500 * 1024; // 500 kb
 
         Random r = new LoggingRng();
@@ -205,15 +205,15 @@
             int size = r.nextInt(MAX_FILE_SIZE);
             byte[] blobData = generateData(size, DataType.TEXT);
 
-            Uri uri = getServerUri(DEFAULT_FILENAME);
+            Uri uri = getServerUri(DEFAULT_FILENAME + i);
             Request request = new Request(uri);
-            request.setTitle(String.format("%s--%d", DEFAULT_FILENAME, i));
+            request.setTitle(String.format("%s--%d", DEFAULT_FILENAME + i, i));
 
             // Prepare the mock server with a standard response
             enqueueResponse(HTTP_OK, blobData);
 
-            Log.i(LOG_TAG, "request: " + i);
-            mDownloadManager.enqueue(request);
+            long requestID = mDownloadManager.enqueue(request);
+            Log.i(LOG_TAG, "request: " + i + " -- requestID: " + requestID);
         }
 
         waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
@@ -236,6 +236,8 @@
 
             assertEquals(NUM_FILES, mReceiver.numDownloadsCompleted());
         } finally {
+            Log.i(LOG_TAG, "All download IDs: " + mReceiver.getDownloadIds().toString());
+            Log.i(LOG_TAG, "Total downloads completed: " + mReceiver.getDownloadIds().size());
             cursor.close();
         }
     }
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
index c0f670b..e1d7b4c 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
@@ -53,6 +53,8 @@
     protected static long DOWNLOAD_500K_FILESIZE = 570927;
     protected static String DOWNLOAD_1MB_FILENAME = "External1mb.apk";
     protected static long DOWNLOAD_1MB_FILESIZE = 1041262;
+    protected static String DOWNLOAD_5MB_FILENAME = "External5mb.apk";
+    protected static long DOWNLOAD_5MB_FILESIZE = 5138700;
     protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
     protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
 
@@ -135,7 +137,7 @@
      * @throws Exception if unsuccessful
      */
     public void initiateDownload() throws Exception {
-        String filename = DOWNLOAD_1MB_FILENAME;
+        String filename = DOWNLOAD_5MB_FILENAME;
         mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
         FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0);
         DataOutputStream outputFile = null;
@@ -171,8 +173,8 @@
      * @throws Exception if unsuccessful
      */
     public void verifyFileDownloadSucceeded() throws Exception {
-        String filename = DOWNLOAD_1MB_FILENAME;
-        long filesize = DOWNLOAD_1MB_FILESIZE;
+        String filename = DOWNLOAD_5MB_FILENAME;
+        long filesize = DOWNLOAD_5MB_FILESIZE;
         long dlRequest = -1;
         boolean rebootMarkerValid = false;
         DataInputStream dataInputFile = null;
@@ -205,7 +207,8 @@
             int status = cursor.getInt(columnIndex);
             int currentWaitTime = 0;
 
-            // Wait until the download finishes
+            // Wait until the download finishes; don't wait for a notification b/c
+            // the download may well have been completed before the last reboot.
             waitForDownloadOrTimeout(dlRequest);
 
             Log.i(LOG_TAG, "Verifying download information...");