From c442fbd95ad5b3de9e58a11e431f419edb4fe978 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 12 Jul 2017 10:59:43 -0600 Subject: Follow removal of NetworkInfo metered flag. The OS now completely relies on NET_CAPABILITY_NOT_METERED to avoid confusion and staleness. Bug: 63391323 Test: builds, boots, Wi-Fi policy is upgraded Exempt-From-Owner-Approval: Bug 63673347 Change-Id: Iea83e0afd8cbd2be10d85b8a35c903047716b5b9 --- tests/src/com/android/providers/downloads/FakeSystemFacade.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java index b6b800a2..de483c7f 100644 --- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java +++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java @@ -1,6 +1,6 @@ package com.android.providers.downloads; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -21,6 +21,7 @@ import java.net.URLConnection; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.List; + import javax.net.ssl.SSLContext; public class FakeSystemFacade implements SystemFacade { @@ -91,11 +92,15 @@ public class FakeSystemFacade implements SystemFacade { final NetworkInfo info = new NetworkInfo(mActiveNetworkType, 0, null, null); info.setDetailedState(DetailedState.CONNECTED, null, null); info.setRoaming(mIsRoaming); - info.setMetered(mIsMetered); return info; } } + @Override + public boolean isNetworkMetered(Network network) { + return mIsMetered; + } + @Override public long getMaxBytesOverMobile() { return mMaxBytesOverMobile; -- cgit v1.2.3 From d635ac295850ba23d528c02b1e5c6eb44b64b22b Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sat, 15 Jul 2017 12:23:05 -0600 Subject: Allocate space using new StorageManager API. Instead of reaching directly into PackageManager, use the new StorageManager API to allocate disk space for downloads. This wraps both clearing cached files and fallocate() into a single method. Remove support for storing downloads on the /cache partition, which doesn't exist on many devices. Bug: 63057877 Test: bit DownloadProviderTests:* Exempt-From-Owner-Approval: Bug 63673347 Change-Id: I5749f7a2f7ded9157fea763dc652bf4da88d86ff --- tests/AndroidManifest.xml | 2 +- .../AbstractDownloadProviderFunctionalTest.java | 35 +-- .../android/providers/downloads/StorageTest.java | 249 --------------------- 3 files changed, 13 insertions(+), 273 deletions(-) delete mode 100644 tests/src/com/android/providers/downloads/StorageTest.java (limited to 'tests') diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml index ec73ca2e..0f4166f5 100644 --- a/tests/AndroidManifest.xml +++ b/tests/AndroidManifest.xml @@ -21,7 +21,7 @@ - + diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java index 813252a8..13d2c36e 100644 --- a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java @@ -171,8 +171,8 @@ public abstract class AbstractDownloadProviderFunctionalTest extends Helpers.setSystemFacade(mSystemFacade); mSystemFacade.setUp(); - assertTrue(isDatabaseEmpty()); // ensure we're not messing with real data - assertTrue(isDatabaseSecureAgainstBadSelection()); + assertDatabaseEmpty(); // ensure we're not messing with real data + assertDatabaseSecureAgainstBadSelection(); mServer = new MockWebServer(); mServer.play(); } @@ -188,34 +188,23 @@ public abstract class AbstractDownloadProviderFunctionalTest extends protected void startDownload(long id) { final JobParameters params = mock(JobParameters.class); when(params.getJobId()).thenReturn((int) id); + getService().onBind(null); getService().onStartJob(params); } - private boolean isDatabaseEmpty() { - Cursor cursor = mResolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, - null, null, null, null); - try { - return cursor.getCount() == 0; - } finally { - cursor.close(); + private void assertDatabaseEmpty() { + try (Cursor cursor = mResolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, + null, null, null, null)) { + assertEquals(0, cursor.getCount()); } } - private boolean isDatabaseSecureAgainstBadSelection() { - Cursor cursor = null; - try { - cursor = mResolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, null, - "('1'='1'))) ORDER BY lastmod DESC--", null, null); + private void assertDatabaseSecureAgainstBadSelection() { + try (Cursor cursor = mResolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, null, + "('1'='1'))) ORDER BY lastmod DESC--", null, null)) { + fail("Database isn't secure!"); + } catch (Exception expected) { } - catch (Exception e) { - return true; - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return false; } /** diff --git a/tests/src/com/android/providers/downloads/StorageTest.java b/tests/src/com/android/providers/downloads/StorageTest.java deleted file mode 100644 index 95bd3676..00000000 --- a/tests/src/com/android/providers/downloads/StorageTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.providers.downloads; - -import static android.app.DownloadManager.COLUMN_REASON; -import static android.app.DownloadManager.ERROR_INSUFFICIENT_SPACE; -import static android.app.DownloadManager.STATUS_FAILED; -import static android.app.DownloadManager.STATUS_SUCCESSFUL; -import static android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION; -import static android.provider.Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION; - -import android.app.DownloadManager; -import android.content.pm.PackageManager; -import android.os.Environment; -import android.os.StatFs; -import android.provider.Downloads.Impl; -import android.system.ErrnoException; -import android.system.Os; -import android.system.StructStatVfs; -import android.test.MoreAsserts; -import android.test.suitebuilder.annotation.MediumTest; -import android.util.Log; - -import com.android.providers.downloads.StorageUtils.ObserverLatch; -import com.google.mockwebserver.MockResponse; -import com.google.mockwebserver.SocketPolicy; - -import libcore.io.ForwardingOs; -import libcore.io.IoUtils; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -@MediumTest -public class StorageTest extends AbstractPublicApiTest { - private static final String TAG = "StorageTest"; - - private static final int DOWNLOAD_SIZE = 512 * 1024; - private static final byte[] DOWNLOAD_BODY; - - static { - DOWNLOAD_BODY = new byte[DOWNLOAD_SIZE]; - for (int i = 0; i < DOWNLOAD_SIZE; i++) { - DOWNLOAD_BODY[i] = (byte) (i % 32); - } - } - - private libcore.io.Os mOriginal; - private long mStealBytes; - - public StorageTest() { - super(new FakeSystemFacade()); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - StorageUtils.sForceFullEviction = true; - mStealBytes = 0; - - mOriginal = libcore.io.Libcore.os; - libcore.io.Libcore.os = new ForwardingOs(mOriginal) { - @Override - public StructStatVfs statvfs(String path) throws ErrnoException { - return stealBytes(os.statvfs(path)); - } - - @Override - public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException { - return stealBytes(os.fstatvfs(fd)); - } - - private StructStatVfs stealBytes(StructStatVfs s) { - final long stealBlocks = (mStealBytes + (s.f_bsize - 1)) / s.f_bsize; - final long f_bavail = s.f_bavail - stealBlocks; - return new StructStatVfs(s.f_bsize, s.f_frsize, s.f_blocks, s.f_bfree, f_bavail, - s.f_files, s.f_ffree, s.f_favail, s.f_fsid, s.f_flag, s.f_namemax); - } - }; - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - StorageUtils.sForceFullEviction = false; - mStealBytes = 0; - - if (mOriginal != null) { - libcore.io.Libcore.os = mOriginal; - } - } - - private enum CacheStatus { CLEAN, DIRTY } - private enum BodyType { COMPLETE, CHUNKED } - - public void testDataDirtyComplete() throws Exception { - prepareAndRunDownload(DESTINATION_CACHE_PARTITION, - CacheStatus.DIRTY, BodyType.COMPLETE, - STATUS_SUCCESSFUL, -1); - } - - public void testDataDirtyChunked() throws Exception { - prepareAndRunDownload(DESTINATION_CACHE_PARTITION, - CacheStatus.DIRTY, BodyType.CHUNKED, - STATUS_SUCCESSFUL, -1); - } - - public void testDataCleanComplete() throws Exception { - prepareAndRunDownload(DESTINATION_CACHE_PARTITION, - CacheStatus.CLEAN, BodyType.COMPLETE, - STATUS_FAILED, ERROR_INSUFFICIENT_SPACE); - } - - public void testDataCleanChunked() throws Exception { - prepareAndRunDownload(DESTINATION_CACHE_PARTITION, - CacheStatus.CLEAN, BodyType.CHUNKED, - STATUS_FAILED, ERROR_INSUFFICIENT_SPACE); - } - - public void testCacheDirtyComplete() throws Exception { - prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION, - CacheStatus.DIRTY, BodyType.COMPLETE, - STATUS_SUCCESSFUL, -1); - } - - public void testCacheDirtyChunked() throws Exception { - prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION, - CacheStatus.DIRTY, BodyType.CHUNKED, - STATUS_SUCCESSFUL, -1); - } - - public void testCacheCleanComplete() throws Exception { - prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION, - CacheStatus.CLEAN, BodyType.COMPLETE, - STATUS_FAILED, ERROR_INSUFFICIENT_SPACE); - } - - public void testCacheCleanChunked() throws Exception { - prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION, - CacheStatus.CLEAN, BodyType.CHUNKED, - STATUS_FAILED, ERROR_INSUFFICIENT_SPACE); - } - - private void prepareAndRunDownload( - int dest, CacheStatus cache, BodyType body, int expectedStatus, int expectedReason) - throws Exception { - - // Ensure that we've purged everything possible for destination - final File dirtyDir; - if (dest == DESTINATION_CACHE_PARTITION) { - final PackageManager pm = getContext().getPackageManager(); - final ObserverLatch observer = new ObserverLatch(); - pm.freeStorageAndNotify(Long.MAX_VALUE, observer); - - try { - if (!observer.latch.await(30, TimeUnit.SECONDS)) { - throw new IOException("Timeout while freeing disk space"); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - dirtyDir = getContext().getCacheDir(); - - } else if (dest == DESTINATION_SYSTEMCACHE_PARTITION) { - IoUtils.deleteContents(Environment.getDownloadCacheDirectory()); - dirtyDir = Environment.getDownloadCacheDirectory(); - - } else { - throw new IllegalArgumentException("Unknown destination"); - } - - // Allocate a cache file, if requested, making it large enough and old - // enough to clear. - final File dirtyFile; - if (cache == CacheStatus.DIRTY) { - dirtyFile = new File(dirtyDir, "cache_file.bin"); - assertTrue(dirtyFile.createNewFile()); - final FileOutputStream os = new FileOutputStream(dirtyFile); - final int dirtySize = (DOWNLOAD_SIZE * 3) / 2; - Os.posix_fallocate(os.getFD(), 0, dirtySize); - IoUtils.closeQuietly(os); - - dirtyFile.setLastModified( - System.currentTimeMillis() - (StorageUtils.MIN_DELETE_AGE * 2)); - } else { - dirtyFile = null; - } - - // At this point, hide all other disk space to make the download fail; - // if we have a dirty cache file it can be cleared to let us proceed. - final long targetFree = StorageUtils.RESERVED_BYTES + (DOWNLOAD_SIZE / 2); - - final StatFs stat = new StatFs(dirtyDir.getAbsolutePath()); - Log.d(TAG, "Available bytes (before steal): " + stat.getAvailableBytes()); - mStealBytes = stat.getAvailableBytes() - targetFree; - - stat.restat(dirtyDir.getAbsolutePath()); - Log.d(TAG, "Available bytes (after steal): " + stat.getAvailableBytes()); - - final MockResponse resp = new MockResponse().setResponseCode(200) - .setHeader("Content-type", "text/plain") - .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END); - if (body == BodyType.CHUNKED) { - resp.setChunkedBody(DOWNLOAD_BODY, 1021); - } else { - resp.setBody(DOWNLOAD_BODY); - } - enqueueResponse(resp); - - final DownloadManager.Request req = getRequest(); - if (dest == Impl.DESTINATION_SYSTEMCACHE_PARTITION) { - req.setDestinationToSystemCache(); - } - final Download download = enqueueRequest(req); - download.runUntilStatus(expectedStatus); - - if (expectedStatus == STATUS_SUCCESSFUL) { - MoreAsserts.assertEquals(DOWNLOAD_BODY, download.getRawContents()); - } - - if (expectedReason != -1) { - assertEquals(expectedReason, download.getLongField(COLUMN_REASON)); - } - - if (dirtyFile != null) { - assertFalse(dirtyFile.exists()); - } - } -} -- cgit v1.2.3