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