• 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.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 
Download(long downloadId)49         private Download(long downloadId) {
50             this.mId = downloadId;
51         }
52 
getStatus()53         public int getStatus() {
54             return (int) getLongField(DownloadManager.COLUMN_STATUS);
55         }
56 
getReason()57         public int getReason() {
58             return (int) getLongField(DownloadManager.COLUMN_REASON);
59         }
60 
getStatusIfExists()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 
getStringField(String field)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 
getLongField(String field)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 
getRawContents()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 
getContents()112         String getContents() throws Exception {
113             return new String(getRawContents());
114         }
115 
runUntilStatus(int status)116         void runUntilStatus(int status) throws TimeoutException {
117             final long startMillis = mSystemFacade.currentTimeMillis();
118             startDownload(mId);
119             waitForStatus(status, startMillis);
120         }
121 
runUntilStatus(int status, long timeout)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 
waitForStatus(int expected, long afterMillis)128         void waitForStatus(int expected, long afterMillis) throws TimeoutException {
129             waitForStatus(expected, afterMillis, 15 * SECOND_IN_MILLIS);
130         }
131 
waitForStatus(int expected, long afterMillis, long timeout)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)%
runUntilProgress(int 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 
AbstractPublicApiTest(FakeSystemFacade systemFacade)215     public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
216         super(systemFacade);
217     }
218 
219     @Override
setUp()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 
getRequest()236     protected DownloadManager.Request getRequest()
237             throws MalformedURLException, UnknownHostException {
238         return getRequest(getServerUri(REQUEST_PATH));
239     }
240 
getRequest(String path)241     protected DownloadManager.Request getRequest(String path) {
242         return new DownloadManager.Request(Uri.parse(path));
243     }
244 
enqueueRequest(DownloadManager.Request request)245     protected Download enqueueRequest(DownloadManager.Request request) {
246         return new Download(mManager.enqueue(request));
247     }
248 }
249