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.text.format.DateUtils.SECOND_IN_MILLIS; 20 21 import static java.net.HttpURLConnection.HTTP_OK; 22 23 import android.content.ContentUris; 24 import android.content.ContentValues; 25 import android.database.Cursor; 26 import android.net.ConnectivityManager; 27 import android.net.Uri; 28 import android.os.Environment; 29 import android.os.SystemClock; 30 import android.provider.Downloads; 31 import android.test.suitebuilder.annotation.LargeTest; 32 33 import com.google.mockwebserver.MockWebServer; 34 import com.google.mockwebserver.RecordedRequest; 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 * This test exercises the entire download manager working together -- it requests downloads through 43 * the {@link DownloadProvider}, just like a normal client would, and runs the 44 * {@link DownloadService} with start intents. It sets up a {@link MockWebServer} running on the 45 * device to serve downloads. 46 */ 47 @LargeTest 48 public class DownloadProviderFunctionalTest extends AbstractDownloadProviderFunctionalTest { 49 private static final String TAG = "DownloadManagerFunctionalTest"; 50 DownloadProviderFunctionalTest()51 public DownloadProviderFunctionalTest() { 52 super(new FakeSystemFacade()); 53 } 54 testDownloadTextFile()55 public void testDownloadTextFile() throws Exception { 56 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 57 58 String path = "/download_manager_test_path"; 59 Uri downloadUri = requestDownload(path); 60 assertEquals(Downloads.Impl.STATUS_PENDING, getDownloadStatus(downloadUri)); 61 62 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 63 RecordedRequest request = takeRequest(); 64 assertEquals("GET", request.getMethod()); 65 assertEquals(path, request.getPath()); 66 assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); 67 assertStartsWith(Environment.getExternalStorageDirectory().getPath(), 68 getDownloadFilename(downloadUri)); 69 } 70 testDownloadToCache()71 public void testDownloadToCache() throws Exception { 72 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 73 74 Uri downloadUri = requestDownload("/path"); 75 updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION, 76 Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION)); 77 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 78 assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); 79 assertStartsWith(getContext().getCacheDir().getAbsolutePath(), 80 getDownloadFilename(downloadUri)); 81 } 82 testRoaming()83 public void testRoaming() throws Exception { 84 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 85 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 86 87 mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE; 88 mSystemFacade.mIsRoaming = true; 89 90 // for a normal download, roaming is fine 91 Uri downloadUri = requestDownload("/path"); 92 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 93 94 // when roaming is disallowed, the download should pause... 95 downloadUri = requestDownload("/path"); 96 updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION, 97 Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING)); 98 runUntilStatus(downloadUri, Downloads.Impl.STATUS_WAITING_FOR_NETWORK); 99 100 // ...and pick up when we're off roaming 101 mSystemFacade.mIsRoaming = false; 102 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 103 } 104 testCleartextTrafficPermittedFlagHonored()105 public void testCleartextTrafficPermittedFlagHonored() throws Exception { 106 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 107 enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT)); 108 109 // Assert that HTTP request succeeds when cleartext traffic is permitted 110 mSystemFacade.mCleartextTrafficPermitted = true; 111 Uri downloadUri = requestDownload("/path"); 112 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 113 114 // Assert that HTTP request fails when cleartext traffic is not permitted 115 mSystemFacade.mCleartextTrafficPermitted = false; 116 downloadUri = requestDownload("/path"); 117 runUntilStatus(downloadUri, Downloads.Impl.STATUS_BAD_REQUEST); 118 } 119 120 /** 121 * Read a downloaded file from disk. 122 */ getDownloadContents(Uri downloadUri)123 private String getDownloadContents(Uri downloadUri) throws Exception { 124 InputStream inputStream = mResolver.openInputStream(downloadUri); 125 try { 126 return readStream(inputStream); 127 } finally { 128 inputStream.close(); 129 } 130 } 131 runUntilStatus(Uri downloadUri, int expected)132 private void runUntilStatus(Uri downloadUri, int expected) throws Exception { 133 startDownload(ContentUris.parseId(downloadUri)); 134 135 int actual = -1; 136 137 final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS); 138 while (SystemClock.elapsedRealtime() < timeout) { 139 actual = getDownloadStatus(downloadUri); 140 if (expected == actual) { 141 return; 142 } 143 144 SystemClock.sleep(100); 145 } 146 147 throw new TimeoutException("Expected status " + expected + "; only reached " + actual); 148 } 149 getDownloadStatus(Uri downloadUri)150 protected int getDownloadStatus(Uri downloadUri) { 151 return Integer.parseInt(getDownloadField(downloadUri, Downloads.Impl.COLUMN_STATUS)); 152 } 153 getDownloadFilename(Uri downloadUri)154 private String getDownloadFilename(Uri downloadUri) { 155 return getDownloadField(downloadUri, Downloads.Impl._DATA); 156 } 157 getDownloadField(Uri downloadUri, String column)158 private String getDownloadField(Uri downloadUri, String column) { 159 final String[] columns = new String[] {column}; 160 Cursor cursor = mResolver.query(downloadUri, columns, null, null, null); 161 try { 162 assertEquals(1, cursor.getCount()); 163 cursor.moveToFirst(); 164 return cursor.getString(0); 165 } finally { 166 cursor.close(); 167 } 168 } 169 170 /** 171 * Request a download from the Download Manager. 172 */ requestDownload(String path)173 private Uri requestDownload(String path) throws MalformedURLException, UnknownHostException { 174 ContentValues values = new ContentValues(); 175 values.put(Downloads.Impl.COLUMN_URI, getServerUri(path)); 176 values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL); 177 return mResolver.insert(Downloads.Impl.CONTENT_URI, values); 178 } 179 180 /** 181 * Update one field of a download in the provider. 182 */ updateDownload(Uri downloadUri, String column, String value)183 private void updateDownload(Uri downloadUri, String column, String value) { 184 ContentValues values = new ContentValues(); 185 values.put(column, value); 186 int numChanged = mResolver.update(downloadUri, values, null, null); 187 assertEquals(1, numChanged); 188 } 189 } 190