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 17package com.android.providers.downloads; 18 19import android.content.ContentValues; 20import android.database.Cursor; 21import android.net.ConnectivityManager; 22import android.net.Uri; 23import android.os.Environment; 24import android.provider.Downloads; 25import android.test.suitebuilder.annotation.LargeTest; 26import android.util.Log; 27 28import tests.http.MockWebServer; 29import tests.http.RecordedRequest; 30 31import java.io.InputStream; 32import java.net.MalformedURLException; 33 34/** 35 * This test exercises the entire download manager working together -- it requests downloads through 36 * the {@link DownloadProvider}, just like a normal client would, and runs the 37 * {@link DownloadService} with start intents. It sets up a {@link MockWebServer} running on the 38 * device to serve downloads. 39 */ 40@LargeTest 41public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFunctionalTest { 42 private static final String TAG = "DownloadManagerFunctionalTest"; 43 44 public DownloadManagerFunctionalTest() { 45 super(new FakeSystemFacade()); 46 } 47 48 public void testDownloadTextFile() throws Exception { 49 enqueueResponse(HTTP_OK, FILE_CONTENT); 50 51 String path = "/download_manager_test_path"; 52 Uri downloadUri = requestDownload(path); 53 assertEquals(Downloads.Impl.STATUS_PENDING, getDownloadStatus(downloadUri)); 54 assertTrue(mTestContext.mHasServiceBeenStarted); 55 56 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 57 RecordedRequest request = takeRequest(); 58 assertEquals("GET", request.getMethod()); 59 assertEquals(path, request.getPath()); 60 assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); 61 assertStartsWith(Environment.getExternalStorageDirectory().getPath(), 62 getDownloadFilename(downloadUri)); 63 } 64 65 public void testDownloadToCache() throws Exception { 66 enqueueResponse(HTTP_OK, FILE_CONTENT); 67 Uri downloadUri = requestDownload("/path"); 68 updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION, 69 Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION)); 70 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 71 assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); 72 assertStartsWith(getContext().getCacheDir().getAbsolutePath(), 73 getDownloadFilename(downloadUri)); 74 } 75 76 public void testRoaming() throws Exception { 77 mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE; 78 mSystemFacade.mIsRoaming = true; 79 80 // for a normal download, roaming is fine 81 enqueueResponse(HTTP_OK, FILE_CONTENT); 82 Uri downloadUri = requestDownload("/path"); 83 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 84 85 // when roaming is disallowed, the download should pause... 86 downloadUri = requestDownload("/path"); 87 updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION, 88 Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING)); 89 runUntilStatus(downloadUri, Downloads.Impl.STATUS_WAITING_FOR_NETWORK); 90 91 // ...and pick up when we're off roaming 92 enqueueResponse(HTTP_OK, FILE_CONTENT); 93 mSystemFacade.mIsRoaming = false; 94 runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS); 95 } 96 97 /** 98 * Read a downloaded file from disk. 99 */ 100 private String getDownloadContents(Uri downloadUri) throws Exception { 101 InputStream inputStream = mResolver.openInputStream(downloadUri); 102 try { 103 return readStream(inputStream); 104 } finally { 105 inputStream.close(); 106 } 107 } 108 109 private void runUntilStatus(Uri downloadUri, int status) throws Exception { 110 runService(); 111 boolean done = false; 112 while (!done) { 113 int rslt = getDownloadStatus(downloadUri); 114 if (rslt == Downloads.Impl.STATUS_RUNNING || rslt == Downloads.Impl.STATUS_PENDING) { 115 Log.i(TAG, "status is: " + rslt + ", for: " + downloadUri); 116 DownloadHandler.getInstance().WaitUntilDownloadsTerminate(); 117 Thread.sleep(100); 118 } else { 119 done = true; 120 } 121 } 122 assertEquals(status, getDownloadStatus(downloadUri)); 123 } 124 125 protected int getDownloadStatus(Uri downloadUri) { 126 return Integer.valueOf(getDownloadField(downloadUri, Downloads.Impl.COLUMN_STATUS)); 127 } 128 129 private String getDownloadFilename(Uri downloadUri) { 130 return getDownloadField(downloadUri, Downloads.Impl._DATA); 131 } 132 133 private String getDownloadField(Uri downloadUri, String column) { 134 final String[] columns = new String[] {column}; 135 Cursor cursor = mResolver.query(downloadUri, columns, null, null, null); 136 try { 137 assertEquals(1, cursor.getCount()); 138 cursor.moveToFirst(); 139 return cursor.getString(0); 140 } finally { 141 cursor.close(); 142 } 143 } 144 145 /** 146 * Request a download from the Download Manager. 147 */ 148 private Uri requestDownload(String path) throws MalformedURLException { 149 ContentValues values = new ContentValues(); 150 values.put(Downloads.Impl.COLUMN_URI, getServerUri(path)); 151 values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL); 152 return mResolver.insert(Downloads.Impl.CONTENT_URI, values); 153 } 154 155 /** 156 * Update one field of a download in the provider. 157 */ 158 private void updateDownload(Uri downloadUri, String column, String value) { 159 ContentValues values = new ContentValues(); 160 values.put(column, value); 161 int numChanged = mResolver.update(downloadUri, values, null, null); 162 assertEquals(1, numChanged); 163 } 164} 165