From 9da9df3d6e84a3c4b04dd22d277e0e6d8f7f1ccb Mon Sep 17 00:00:00 2001 From: Steve Howard Date: Wed, 28 Jul 2010 17:51:02 -0700 Subject: Make all public API downloads visible. This change makes all downloads through the public API visible by default. It removes the API that had allowed applications to control notifications while the download runs. This has been replaced with a hidden API, since such behavior is needed by SystemUpdater and Market (for self-updates). Additionally, the behavior is now protected by a new permission. I'm making this permission signatureOrSystem, and changing the non-purgeable permission to the same (it should've been that, I just didn't know). I'm also adding string descriptions to appease the translation folks. Change-Id: I192e8b19ff9b0e425257cef0db081c3d75996ea5 --- AndroidManifest.xml | 8 +++++- res/values/strings.xml | 29 +++++++++++++++++----- .../providers/downloads/DownloadProvider.java | 11 ++++++-- .../PublicApiAccessTest.java | 25 ++++++++++++------- .../downloads/PublicApiFunctionalTest.java | 9 +++---- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d6c85d34..8431d1ed 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,7 +25,13 @@ + android:protectionLevel="signatureOrSystem"/> + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 0bc5c09c..62ba38f7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -74,13 +74,30 @@ downloads to the SD card, regardless of which application downloaded them. - Download non-purgeable - files to the cache + + Reserve space in the + download cache + Allows the application to - download files to the download cache through the public API which will not - be automatically deleted when the download manager needs more space. - Malicious applications can use this to block other applications from using - the download cache. + download files to the download cache which cannot be automatically deleted + when the download manager needs more space. + + + Use download manager + without notification + + + Allows the application + to download files through the download manager without any notification + being shown to the user. + diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index a116f87d..41b732f1 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -499,8 +499,15 @@ public final class DownloadProvider extends ContentProvider { enforceAllowedValues(values, Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE, Downloads.Impl.DESTINATION_FILE_URI); - enforceAllowedValues(values, Downloads.Impl.COLUMN_VISIBILITY, - null, Downloads.Impl.VISIBILITY_VISIBLE); + + if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_NO_NOTIFICATION) + == PackageManager.PERMISSION_GRANTED) { + enforceAllowedValues(values, Downloads.Impl.COLUMN_VISIBILITY, + Downloads.Impl.VISIBILITY_HIDDEN, Downloads.Impl.VISIBILITY_VISIBLE); + } else { + enforceAllowedValues(values, Downloads.Impl.COLUMN_VISIBILITY, + Downloads.Impl.VISIBILITY_VISIBLE); + } // remove the rest of the columns that are allowed (with any value) values.remove(Downloads.Impl.COLUMN_URI); diff --git a/tests/public_api_access/src/com/android/providers/downloads/public_api_access_tests/PublicApiAccessTest.java b/tests/public_api_access/src/com/android/providers/downloads/public_api_access_tests/PublicApiAccessTest.java index aca5791b..4b2ae092 100644 --- a/tests/public_api_access/src/com/android/providers/downloads/public_api_access_tests/PublicApiAccessTest.java +++ b/tests/public_api_access/src/com/android/providers/downloads/public_api_access_tests/PublicApiAccessTest.java @@ -53,7 +53,7 @@ public class PublicApiAccessTest extends AndroidTestCase { @Override protected void tearDown() throws Exception { if (mContentResolver != null) { - mContentResolver.delete(Downloads.CONTENT_URI, null, null); + mContentResolver.delete(Downloads.CONTENT_URI, null, null); } super.tearDown(); } @@ -61,7 +61,7 @@ public class PublicApiAccessTest extends AndroidTestCase { public void testMinimalValidWrite() { mContentResolver.insert(Downloads.Impl.CONTENT_URI, buildValidValues()); } - + public void testMaximalValidWrite() { ContentValues values = buildValidValues(); values.put(Downloads.Impl.COLUMN_TITLE, "foo"); @@ -76,18 +76,19 @@ public class PublicApiAccessTest extends AndroidTestCase { private ContentValues buildValidValues() { ContentValues values = new ContentValues(); values.put(Downloads.Impl.COLUMN_URI, "foo"); - values.put(Downloads.Impl.COLUMN_DESTINATION, + values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE); + values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE); values.put(Downloads.Impl.COLUMN_IS_PUBLIC_API, true); return values; } - + public void testNoPublicApi() { ContentValues values = buildValidValues(); values.remove(Downloads.Impl.COLUMN_IS_PUBLIC_API); testInvalidValues(values); } - + public void testInvalidDestination() { ContentValues values = buildValidValues(); values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL); @@ -95,14 +96,20 @@ public class PublicApiAccessTest extends AndroidTestCase { values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_CACHE_PARTITION); testInvalidValues(values); } - + public void testInvalidVisibility() { ContentValues values = buildValidValues(); - values.put(Downloads.Impl.COLUMN_VISIBILITY, + values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); testInvalidValues(values); + + values.put(Downloads.Impl.COLUMN_VISIBILITY, Downloads.Impl.VISIBILITY_HIDDEN); + testInvalidValues(values); + + values.remove(Downloads.Impl.COLUMN_VISIBILITY); + testInvalidValues(values); } - + public void testDisallowedColumns() { for (String column : DISALLOWED_COLUMNS) { ContentValues values = buildValidValues(); @@ -110,7 +117,7 @@ public class PublicApiAccessTest extends AndroidTestCase { testInvalidValues(values); } } - + public void testFileUriWithoutExternalPermission() { ContentValues values = buildValidValues(); values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_FILE_URI); diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java index b601846a..840b20ac 100644 --- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java @@ -358,8 +358,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { } public void testNotificationClickedBroadcast() throws Exception { - Download download = enqueueRequest(getRequest().setShowNotification( - DownloadManager.Request.NOTIFICATION_WHEN_RUNNING)); + Download download = enqueueRequest(getRequest()); DownloadReceiver receiver = new DownloadReceiver(); receiver.mSystemFacade = mSystemFacade; @@ -431,15 +430,13 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { public void testNotifications() throws Exception { enqueueEmptyResponse(HTTP_OK); - Download download = enqueueRequest(getRequest()); // no visibility requested + Download download = enqueueRequest(getRequest().setShowRunningNotification(false)); download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL); assertEquals(0, mSystemFacade.mActiveNotifications.size()); assertEquals(0, mSystemFacade.mCanceledNotifications.size()); enqueueEmptyResponse(HTTP_OK); - download = enqueueRequest( - getRequest() - .setShowNotification(DownloadManager.Request.NOTIFICATION_WHEN_RUNNING)); + download = enqueueRequest(getRequest()); // notifications by default download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL); assertEquals(1, mSystemFacade.mActiveNotifications.size()); -- cgit v1.2.3