AbstractPublicApiTest.java revision 8ac10e0e0667a4fe35191deebb5fa9786bf4226c
1e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard/*
2e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * Copyright (C) 2010 The Android Open Source Project
3e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard *
4e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * Licensed under the Apache License, Version 2.0 (the "License");
5e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * you may not use this file except in compliance with the License.
6e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * You may obtain a copy of the License at
7e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard *
8e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard *      http://www.apache.org/licenses/LICENSE-2.0
9e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard *
10e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * Unless required by applicable law or agreed to in writing, software
11e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * distributed under the License is distributed on an "AS IS" BASIS,
12e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * See the License for the specific language governing permissions and
14e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * limitations under the License.
15e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard */
16e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
17e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardpackage com.android.providers.downloads;
18e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
198ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkeyimport static android.app.DownloadManager.STATUS_FAILED;
208ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkeyimport static android.app.DownloadManager.STATUS_SUCCESSFUL;
218ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
228ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
23a1448628237471a7a2aeb67b560b1502c2bd5ba8Steve Howardimport android.app.DownloadManager;
24e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport android.database.Cursor;
25e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport android.net.Uri;
26e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport android.os.ParcelFileDescriptor;
278ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkeyimport android.os.SystemClock;
285d217003acf21aea852975af0dff3b398cea6768Vasu Noriimport android.util.Log;
29e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
30e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport java.io.FileInputStream;
31e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport java.io.InputStream;
32e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardimport java.net.MalformedURLException;
33ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkeyimport java.net.UnknownHostException;
348ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkeyimport java.util.concurrent.TimeoutException;
35e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
36e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard/**
37e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard * Code common to tests that use the download manager public API.
38e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard */
39ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkeypublic abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
40e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
41e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    class Download {
42e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        final long mId;
43e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
44e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        private Download(long downloadId) {
45e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            this.mId = downloadId;
46e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
47e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
48e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        public int getStatus() {
49e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            return (int) getLongField(DownloadManager.COLUMN_STATUS);
50e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
51e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
525d217003acf21aea852975af0dff3b398cea6768Vasu Nori        public int getStatusIfExists() {
535d217003acf21aea852975af0dff3b398cea6768Vasu Nori            Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
545d217003acf21aea852975af0dff3b398cea6768Vasu Nori            try {
555d217003acf21aea852975af0dff3b398cea6768Vasu Nori                if (cursor.getCount() > 0) {
565d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    cursor.moveToFirst();
575d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    return (int) cursor.getLong(cursor.getColumnIndexOrThrow(
585d217003acf21aea852975af0dff3b398cea6768Vasu Nori                            DownloadManager.COLUMN_STATUS));
595d217003acf21aea852975af0dff3b398cea6768Vasu Nori                } else {
605d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    // the row doesn't exist
615d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    return -1;
625d217003acf21aea852975af0dff3b398cea6768Vasu Nori                }
635d217003acf21aea852975af0dff3b398cea6768Vasu Nori            } finally {
645d217003acf21aea852975af0dff3b398cea6768Vasu Nori                cursor.close();
655d217003acf21aea852975af0dff3b398cea6768Vasu Nori            }
665d217003acf21aea852975af0dff3b398cea6768Vasu Nori        }
675d217003acf21aea852975af0dff3b398cea6768Vasu Nori
68e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        String getStringField(String field) {
69e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
70e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            try {
71e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                assertEquals(1, cursor.getCount());
72e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                cursor.moveToFirst();
73e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                return cursor.getString(cursor.getColumnIndexOrThrow(field));
74e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            } finally {
75e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                cursor.close();
76e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            }
77e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
78e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
79e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        long getLongField(String field) {
80e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
81e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            try {
82e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                assertEquals(1, cursor.getCount());
83e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                cursor.moveToFirst();
84e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                return cursor.getLong(cursor.getColumnIndexOrThrow(field));
85e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            } finally {
86e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                cursor.close();
87e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            }
88e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
89e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
90e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        String getContents() throws Exception {
91e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
92e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            assertTrue("Invalid file descriptor: " + downloadedFile,
93e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                       downloadedFile.getFileDescriptor().valid());
94e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            InputStream stream = new FileInputStream(downloadedFile.getFileDescriptor());
95e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            try {
96e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                return readStream(stream);
97e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            } finally {
98e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard                stream.close();
99e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard            }
100e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
101e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
1028ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        void runUntilStatus(int status) throws TimeoutException {
1038ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            startService(null);
1048ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            waitForStatus(status);
1058ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        }
1068ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
1078ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        void waitForStatus(int expected) throws TimeoutException {
1088ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            int actual = -1;
1098ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
1108ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS);
1118ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            while (SystemClock.elapsedRealtime() < timeout) {
1128ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                actual = getStatus();
1138ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                if (actual == STATUS_SUCCESSFUL || actual == STATUS_FAILED) {
1148ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                    assertEquals(expected, actual);
1158ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                    return;
1168ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                } else if (actual == expected) {
1178ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                    return;
1188ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                }
1198ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
1208ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey                SystemClock.sleep(100);
1218ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            }
1228ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
1238ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
124e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        }
1255d217003acf21aea852975af0dff3b398cea6768Vasu Nori
1265d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // max time to wait before giving up on the current download operation.
1275d217003acf21aea852975af0dff3b398cea6768Vasu Nori        private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5;
1285d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // while waiting for the above time period, sleep this long to yield to the
1295d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // download thread
1305d217003acf21aea852975af0dff3b398cea6768Vasu Nori        private static final int TIME_TO_SLEEP = 1000;
1315d217003acf21aea852975af0dff3b398cea6768Vasu Nori
1325d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // waits until progress_so_far is >= (progress)%
1335d217003acf21aea852975af0dff3b398cea6768Vasu Nori        boolean runUntilProgress(int progress) throws InterruptedException {
1348ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey            startService(null);
1358ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
1365d217003acf21aea852975af0dff3b398cea6768Vasu Nori            int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP;
1375d217003acf21aea852975af0dff3b398cea6768Vasu Nori            int numBytesReceivedSoFar = 0;
1385d217003acf21aea852975af0dff3b398cea6768Vasu Nori            int totalBytes = 0;
1395d217003acf21aea852975af0dff3b398cea6768Vasu Nori            for (int i = 0; i < sleepCounter; i++) {
1405d217003acf21aea852975af0dff3b398cea6768Vasu Nori                Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
1415d217003acf21aea852975af0dff3b398cea6768Vasu Nori                try {
1425d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    assertEquals(1, cursor.getCount());
1435d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    cursor.moveToFirst();
1445d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    numBytesReceivedSoFar = cursor.getInt(
1455d217003acf21aea852975af0dff3b398cea6768Vasu Nori                            cursor.getColumnIndexOrThrow(
1465d217003acf21aea852975af0dff3b398cea6768Vasu Nori                                    DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
1475d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    totalBytes = cursor.getInt(
1485d217003acf21aea852975af0dff3b398cea6768Vasu Nori                            cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
1495d217003acf21aea852975af0dff3b398cea6768Vasu Nori                } finally {
1505d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    cursor.close();
1515d217003acf21aea852975af0dff3b398cea6768Vasu Nori                }
1525d217003acf21aea852975af0dff3b398cea6768Vasu Nori                Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " +
1535d217003acf21aea852975af0dff3b398cea6768Vasu Nori                        numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
1545d217003acf21aea852975af0dff3b398cea6768Vasu Nori                if (totalBytes == 0) {
1555d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    fail("total_bytes should not be zero");
1565d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    return false;
1575d217003acf21aea852975af0dff3b398cea6768Vasu Nori                } else {
1585d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    if (numBytesReceivedSoFar * 100 / totalBytes >= progress) {
1595d217003acf21aea852975af0dff3b398cea6768Vasu Nori                        // progress_so_far is >= progress%. we are done
1605d217003acf21aea852975af0dff3b398cea6768Vasu Nori                        return true;
1615d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    }
1625d217003acf21aea852975af0dff3b398cea6768Vasu Nori                }
1635d217003acf21aea852975af0dff3b398cea6768Vasu Nori                // download not done yet. sleep a while and try again
1645d217003acf21aea852975af0dff3b398cea6768Vasu Nori                Thread.sleep(TIME_TO_SLEEP);
1655d217003acf21aea852975af0dff3b398cea6768Vasu Nori            }
1665d217003acf21aea852975af0dff3b398cea6768Vasu Nori            Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " +
1675d217003acf21aea852975af0dff3b398cea6768Vasu Nori                    numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
1685d217003acf21aea852975af0dff3b398cea6768Vasu Nori            return false; // failed
1695d217003acf21aea852975af0dff3b398cea6768Vasu Nori        }
170e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
171e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
172e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected static final String PACKAGE_NAME = "my.package.name";
173e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected static final String REQUEST_PATH = "/path";
174e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
175e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected DownloadManager mManager;
176e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
177e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
178e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        super(systemFacade);
179e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
180e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
181e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    @Override
182e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected void setUp() throws Exception {
183e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        super.setUp();
184e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        mManager = new DownloadManager(mResolver, PACKAGE_NAME);
185e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
186e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
187ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey    protected DownloadManager.Request getRequest()
188ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey            throws MalformedURLException, UnknownHostException {
189e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        return getRequest(getServerUri(REQUEST_PATH));
190e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
191e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
192e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected DownloadManager.Request getRequest(String path) {
193e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        return new DownloadManager.Request(Uri.parse(path));
194e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
195e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
196e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected Download enqueueRequest(DownloadManager.Request request) {
197e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        return new Download(mManager.enqueue(request));
198e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
199e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard}
200