Home | History | Annotate | Download | only in downloads
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.providers.downloads;
     18 
     19 import static android.app.DownloadManager.STATUS_FAILED;
     20 import static android.app.DownloadManager.STATUS_SUCCESSFUL;
     21 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
     22 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
     23 
     24 import android.app.DownloadManager;
     25 import android.database.Cursor;
     26 import android.net.Uri;
     27 import android.os.ParcelFileDescriptor;
     28 import android.os.SystemClock;
     29 import android.util.Log;
     30 
     31 import java.io.InputStream;
     32 import java.net.MalformedURLException;
     33 import java.net.UnknownHostException;
     34 import java.util.concurrent.TimeoutException;
     35 
     36 /**
     37  * Code common to tests that use the download manager public API.
     38  */
     39 public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
     40 
     41     class Download {
     42         final long mId;
     43 
     44         private Download(long downloadId) {
     45             this.mId = downloadId;
     46         }
     47 
     48         public int getStatus() {
     49             return (int) getLongField(DownloadManager.COLUMN_STATUS);
     50         }
     51 
     52         public int getReason() {
     53             return (int) getLongField(DownloadManager.COLUMN_REASON);
     54         }
     55 
     56         public int getStatusIfExists() {
     57             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     58             try {
     59                 if (cursor.getCount() > 0) {
     60                     cursor.moveToFirst();
     61                     return (int) cursor.getLong(cursor.getColumnIndexOrThrow(
     62                             DownloadManager.COLUMN_STATUS));
     63                 } else {
     64                     // the row doesn't exist
     65                     return -1;
     66                 }
     67             } finally {
     68                 cursor.close();
     69             }
     70         }
     71 
     72         String getStringField(String field) {
     73             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     74             try {
     75                 assertEquals(1, cursor.getCount());
     76                 cursor.moveToFirst();
     77                 return cursor.getString(cursor.getColumnIndexOrThrow(field));
     78             } finally {
     79                 cursor.close();
     80             }
     81         }
     82 
     83         long getLongField(String field) {
     84             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     85             try {
     86                 assertEquals(1, cursor.getCount());
     87                 cursor.moveToFirst();
     88                 return cursor.getLong(cursor.getColumnIndexOrThrow(field));
     89             } finally {
     90                 cursor.close();
     91             }
     92         }
     93 
     94         String getContents() throws Exception {
     95             ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
     96             assertTrue("Invalid file descriptor: " + downloadedFile,
     97                        downloadedFile.getFileDescriptor().valid());
     98             final InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
     99                     downloadedFile);
    100             try {
    101                 return readStream(stream);
    102             } finally {
    103                 stream.close();
    104             }
    105         }
    106 
    107         void runUntilStatus(int status) throws TimeoutException {
    108             final long startMillis = mSystemFacade.currentTimeMillis();
    109             startService(null);
    110             waitForStatus(status, startMillis);
    111         }
    112 
    113         void runUntilStatus(int status, long timeout) throws TimeoutException {
    114             final long startMillis = mSystemFacade.currentTimeMillis();
    115             startService(null);
    116             waitForStatus(status, startMillis, timeout);
    117         }
    118 
    119         void waitForStatus(int expected, long afterMillis) throws TimeoutException {
    120             waitForStatus(expected, afterMillis, 15 * SECOND_IN_MILLIS);
    121         }
    122 
    123         void waitForStatus(int expected, long afterMillis, long timeout) throws TimeoutException {
    124             int actual = -1;
    125 
    126             final long elapsedTimeout = SystemClock.elapsedRealtime() + timeout;
    127             while (SystemClock.elapsedRealtime() < elapsedTimeout) {
    128                 if (getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP) >= afterMillis) {
    129                     actual = getStatus();
    130                     if (actual == STATUS_SUCCESSFUL || actual == STATUS_FAILED) {
    131                         assertEquals(expected, actual);
    132                         return;
    133                     } else if (actual == expected) {
    134                         return;
    135                     }
    136 
    137                     if (timeout > MINUTE_IN_MILLIS) {
    138                         final int percent = (int) (100
    139                                 * getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
    140                                 / getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
    141                         Log.d(LOG_TAG, percent + "% complete");
    142                     }
    143                 }
    144 
    145                 if (timeout > MINUTE_IN_MILLIS) {
    146                     SystemClock.sleep(SECOND_IN_MILLIS * 3);
    147                 } else {
    148                     SystemClock.sleep(100);
    149                 }
    150             }
    151 
    152             throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
    153         }
    154 
    155         // max time to wait before giving up on the current download operation.
    156         private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5;
    157         // while waiting for the above time period, sleep this long to yield to the
    158         // download thread
    159         private static final int TIME_TO_SLEEP = 1000;
    160 
    161         // waits until progress_so_far is >= (progress)%
    162         boolean runUntilProgress(int progress) throws InterruptedException {
    163             startService(null);
    164 
    165             int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP;
    166             int numBytesReceivedSoFar = 0;
    167             int totalBytes = 0;
    168             for (int i = 0; i < sleepCounter; i++) {
    169                 Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
    170                 try {
    171                     assertEquals(1, cursor.getCount());
    172                     cursor.moveToFirst();
    173                     numBytesReceivedSoFar = cursor.getInt(
    174                             cursor.getColumnIndexOrThrow(
    175                                     DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
    176                     totalBytes = cursor.getInt(
    177                             cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
    178                 } finally {
    179                     cursor.close();
    180                 }
    181                 Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " +
    182                         numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
    183                 if (totalBytes == 0) {
    184                     fail("total_bytes should not be zero");
    185                     return false;
    186                 } else {
    187                     if (numBytesReceivedSoFar * 100 / totalBytes >= progress) {
    188                         // progress_so_far is >= progress%. we are done
    189                         return true;
    190                     }
    191                 }
    192                 // download not done yet. sleep a while and try again
    193                 Thread.sleep(TIME_TO_SLEEP);
    194             }
    195             Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " +
    196                     numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
    197             return false; // failed
    198         }
    199     }
    200 
    201     protected static final String PACKAGE_NAME = "my.package.name";
    202     protected static final String REQUEST_PATH = "/path";
    203 
    204     protected DownloadManager mManager;
    205 
    206     public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
    207         super(systemFacade);
    208     }
    209 
    210     @Override
    211     protected void setUp() throws Exception {
    212         super.setUp();
    213         mManager = new DownloadManager(mResolver, PACKAGE_NAME);
    214     }
    215 
    216     protected DownloadManager.Request getRequest()
    217             throws MalformedURLException, UnknownHostException {
    218         return getRequest(getServerUri(REQUEST_PATH));
    219     }
    220 
    221     protected DownloadManager.Request getRequest(String path) {
    222         return new DownloadManager.Request(Uri.parse(path));
    223     }
    224 
    225     protected Download enqueueRequest(DownloadManager.Request request) {
    226         return new Download(mManager.enqueue(request));
    227     }
    228 }
    229