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.content.ContentResolver;
     26 import android.content.ContextWrapper;
     27 import android.database.Cursor;
     28 import android.net.Uri;
     29 import android.os.ParcelFileDescriptor;
     30 import android.os.SystemClock;
     31 import android.util.Log;
     32 
     33 import libcore.io.IoUtils;
     34 import libcore.io.Streams;
     35 
     36 import java.io.InputStream;
     37 import java.net.MalformedURLException;
     38 import java.net.UnknownHostException;
     39 import java.util.concurrent.TimeoutException;
     40 
     41 /**
     42  * Code common to tests that use the download manager public API.
     43  */
     44 public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
     45 
     46     class Download {
     47         final long mId;
     48 
     49         private Download(long downloadId) {
     50             this.mId = downloadId;
     51         }
     52 
     53         public int getStatus() {
     54             return (int) getLongField(DownloadManager.COLUMN_STATUS);
     55         }
     56 
     57         public int getReason() {
     58             return (int) getLongField(DownloadManager.COLUMN_REASON);
     59         }
     60 
     61         public int getStatusIfExists() {
     62             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     63             try {
     64                 if (cursor.getCount() > 0) {
     65                     cursor.moveToFirst();
     66                     return (int) cursor.getLong(cursor.getColumnIndexOrThrow(
     67                             DownloadManager.COLUMN_STATUS));
     68                 } else {
     69                     // the row doesn't exist
     70                     return -1;
     71                 }
     72             } finally {
     73                 cursor.close();
     74             }
     75         }
     76 
     77         String getStringField(String field) {
     78             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     79             try {
     80                 assertEquals(1, cursor.getCount());
     81                 cursor.moveToFirst();
     82                 return cursor.getString(cursor.getColumnIndexOrThrow(field));
     83             } finally {
     84                 cursor.close();
     85             }
     86         }
     87 
     88         long getLongField(String field) {
     89             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
     90             try {
     91                 assertEquals(1, cursor.getCount());
     92                 cursor.moveToFirst();
     93                 return cursor.getLong(cursor.getColumnIndexOrThrow(field));
     94             } finally {
     95                 cursor.close();
     96             }
     97         }
     98 
     99         byte[] getRawContents() throws Exception {
    100             ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
    101             assertTrue("Invalid file descriptor: " + downloadedFile,
    102                        downloadedFile.getFileDescriptor().valid());
    103             final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
    104                     downloadedFile);
    105             try {
    106                 return Streams.readFully(is);
    107             } finally {
    108                 IoUtils.closeQuietly(is);
    109             }
    110         }
    111 
    112         String getContents() throws Exception {
    113             return new String(getRawContents());
    114         }
    115 
    116         void runUntilStatus(int status) throws TimeoutException {
    117             final long startMillis = mSystemFacade.currentTimeMillis();
    118             startDownload(mId);
    119             waitForStatus(status, startMillis);
    120         }
    121 
    122         void runUntilStatus(int status, long timeout) throws TimeoutException {
    123             final long startMillis = mSystemFacade.currentTimeMillis();
    124             startDownload(mId);
    125             waitForStatus(status, startMillis, timeout);
    126         }
    127 
    128         void waitForStatus(int expected, long afterMillis) throws TimeoutException {
    129             waitForStatus(expected, afterMillis, 15 * SECOND_IN_MILLIS);
    130         }
    131 
    132         void waitForStatus(int expected, long afterMillis, long timeout) throws TimeoutException {
    133             int actual = -1;
    134 
    135             final long elapsedTimeout = SystemClock.elapsedRealtime() + timeout;
    136             while (SystemClock.elapsedRealtime() < elapsedTimeout) {
    137                 if (getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP) >= afterMillis) {
    138                     actual = getStatus();
    139                     if (actual == STATUS_SUCCESSFUL || actual == STATUS_FAILED) {
    140                         assertEquals(expected, actual);
    141                         return;
    142                     } else if (actual == expected) {
    143                         return;
    144                     }
    145 
    146                     if (timeout > MINUTE_IN_MILLIS) {
    147                         final int percent = (int) (100
    148                                 * getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
    149                                 / getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
    150                         Log.d(LOG_TAG, percent + "% complete");
    151                     }
    152                 }
    153 
    154                 if (timeout > MINUTE_IN_MILLIS) {
    155                     SystemClock.sleep(SECOND_IN_MILLIS * 3);
    156                 } else {
    157                     SystemClock.sleep(100);
    158                 }
    159             }
    160 
    161             throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
    162         }
    163 
    164         // max time to wait before giving up on the current download operation.
    165         private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5;
    166         // while waiting for the above time period, sleep this long to yield to the
    167         // download thread
    168         private static final int TIME_TO_SLEEP = 1000;
    169 
    170         // waits until progress_so_far is >= (progress)%
    171         boolean runUntilProgress(int progress) throws InterruptedException {
    172             startDownload(mId);
    173 
    174             int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP;
    175             int numBytesReceivedSoFar = 0;
    176             int totalBytes = 0;
    177             for (int i = 0; i < sleepCounter; i++) {
    178                 Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
    179                 try {
    180                     assertEquals(1, cursor.getCount());
    181                     cursor.moveToFirst();
    182                     numBytesReceivedSoFar = cursor.getInt(
    183                             cursor.getColumnIndexOrThrow(
    184                                     DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
    185                     totalBytes = cursor.getInt(
    186                             cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
    187                 } finally {
    188                     cursor.close();
    189                 }
    190                 Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " +
    191                         numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
    192                 if (totalBytes == 0) {
    193                     fail("total_bytes should not be zero");
    194                     return false;
    195                 } else {
    196                     if (numBytesReceivedSoFar * 100 / totalBytes >= progress) {
    197                         // progress_so_far is >= progress%. we are done
    198                         return true;
    199                     }
    200                 }
    201                 // download not done yet. sleep a while and try again
    202                 Thread.sleep(TIME_TO_SLEEP);
    203             }
    204             Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " +
    205                     numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
    206             return false; // failed
    207         }
    208     }
    209 
    210     protected static final String PACKAGE_NAME = "my.package.name";
    211     protected static final String REQUEST_PATH = "/path";
    212 
    213     protected DownloadManager mManager;
    214 
    215     public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
    216         super(systemFacade);
    217     }
    218 
    219     @Override
    220     protected void setUp() throws Exception {
    221         super.setUp();
    222         mManager = new DownloadManager(new ContextWrapper(mContext) {
    223             @Override
    224             public ContentResolver getContentResolver() {
    225                 return mResolver;
    226             }
    227 
    228             @Override
    229             public String getPackageName() {
    230                 return PACKAGE_NAME;
    231             }
    232         });
    233         mManager.setAccessFilename(true);
    234     }
    235 
    236     protected DownloadManager.Request getRequest()
    237             throws MalformedURLException, UnknownHostException {
    238         return getRequest(getServerUri(REQUEST_PATH));
    239     }
    240 
    241     protected DownloadManager.Request getRequest(String path) {
    242         return new DownloadManager.Request(Uri.parse(path));
    243     }
    244 
    245     protected Download enqueueRequest(DownloadManager.Request request) {
    246         return new Download(mManager.enqueue(request));
    247     }
    248 }
    249