summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml8
-rw-r--r--res/values/strings.xml29
-rw-r--r--src/com/android/providers/downloads/DownloadProvider.java11
-rw-r--r--tests/public_api_access/src/com/android/providers/downloads/public_api_access_tests/PublicApiAccessTest.java25
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java9
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 @@
<permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE"
android:label="@string/permlab_downloadCacheNonPurgeable"
android:description="@string/permdesc_downloadCacheNonPurgeable"
- android:protectionLevel="dangerous"/>
+ android:protectionLevel="signatureOrSystem"/>
+
+ <!-- Allows to queue downloads without a notification shown while the download runs. -->
+ <permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"
+ android:label="@string/permlab_downloadWithoutNotification"
+ android:description="@string/permdesc_downloadWithoutNotification"
+ android:protectionLevel="signatureOrSystem"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
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.</string>
- <string name="permlab_downloadCacheNonPurgeable">Download non-purgeable
- files to the cache</string>
+ <!-- The label for the permission to download files to the download cache
+ that can't be automatically deleted by the download manager to free up
+ space [CHAR LIMIT=50] -->
+ <string name="permlab_downloadCacheNonPurgeable">Reserve space in the
+ download cache</string>
+ <!-- The full sentence description for the permission to download files to
+ the download cache that can't be automatically deleted by the download
+ manager to free up space [CHAR LIMIT=160] -->
<string name="permdesc_downloadCacheNonPurgeable">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.</string>
+ download files to the download cache which cannot be automatically deleted
+ when the download manager needs more space.</string>
+
+ <!-- The label for the permission to download files through the download
+ manager without any notification being shown to the user [CHAR LIMIT=50] -->
+ <string name="permlab_downloadWithoutNotification">Use download manager
+ without notification</string>
+
+ <!-- The full sentence description for the permission to download files
+ through the download manager without any notification being shown to the
+ user [CHAR LIMIT=160] -->
+ <string name="permdesc_downloadWithoutNotification">Allows the application
+ to download files through the download manager without any notification
+ being shown to the user.</string>
+
<!-- This is the title that is used when displaying the notification
for a download that doesn't have a title associated with it. -->
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());