summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml5
-rw-r--r--res/values/strings.xml6
-rw-r--r--src/com/android/providers/downloads/DownloadNotification.java29
-rw-r--r--src/com/android/providers/downloads/DownloadProvider.java41
4 files changed, 52 insertions, 29 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 374b985a..1b111f06 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -21,6 +21,11 @@
android:description="@string/permdesc_downloadCompletedIntent"
android:protectionLevel="signature" />
+ <permission android:name="android.permission.SEE_ALL_EXTERNAL"
+ android:label="@string/permlab_seeAllExternal"
+ android:description="@string/permdesc_seeAllExternal"
+ android:protectionLevel="normal"/>
+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.ACCESS_DRM" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e7fda559..7e40b608 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -67,6 +67,12 @@
can use this to confuse other applications that download
files.</string>
+ <!-- Title for permission to see all downloads to EXTERNAL -->
+ <string name="permlab_seeAllExternal">See all downloads to SD card</string>
+ <!-- Description for the permission to see all downloads to EXTERNAL -->
+ <string name="permdesc_seeAllExternal">Allows the application to see all
+ downloads to the SD card, regardless of which application downloaded
+ them.</string>
<!-- This is the title that is used when displaying the notification
for a download that doesn't have a title associated with it. -->
<string name="download_unknown_title">&lt;Untitled&gt;</string>
diff --git a/src/com/android/providers/downloads/DownloadNotification.java b/src/com/android/providers/downloads/DownloadNotification.java
index abd975bc..e9c0d4e6 100644
--- a/src/com/android/providers/downloads/DownloadNotification.java
+++ b/src/com/android/providers/downloads/DownloadNotification.java
@@ -119,7 +119,7 @@ class DownloadNotification {
Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
Downloads.Impl.COLUMN_CURRENT_BYTES,
Downloads.Impl.COLUMN_TOTAL_BYTES,
- Downloads.Impl.COLUMN_STATUS, Downloads.Impl._DATA
+ Downloads.Impl.COLUMN_STATUS
},
WHERE_RUNNING, null, Downloads.Impl._ID);
@@ -136,7 +136,6 @@ class DownloadNotification {
final int currentBytesColumn = 5;
final int totalBytesColumn = 6;
final int statusColumn = 7;
- final int filenameColumnId = 8;
// Collate the notifications
mNotifications.clear();
@@ -147,14 +146,8 @@ class DownloadNotification {
long id = c.getLong(idColumn);
String title = c.getString(titleColumn);
if (title == null || title.length() == 0) {
- String filename = c.getString(filenameColumnId);
- if (filename == null) {
- title = mContext.getResources().getString(
- R.string.download_unknown_title);
- } else {
- title = Downloads.Impl.createTitleFromFilename(mContext,
- filename, id);
- }
+ title = mContext.getResources().getString(
+ R.string.download_unknown_title);
}
if (mNotifications.containsKey(packageName)) {
mNotifications.get(packageName).addItem(title, progress, max);
@@ -232,7 +225,6 @@ class DownloadNotification {
Downloads.Impl.COLUMN_CURRENT_BYTES,
Downloads.Impl.COLUMN_TOTAL_BYTES,
Downloads.Impl.COLUMN_STATUS,
- Downloads.Impl._DATA,
Downloads.Impl.COLUMN_LAST_MODIFICATION,
Downloads.Impl.COLUMN_DESTINATION
},
@@ -251,9 +243,8 @@ class DownloadNotification {
final int currentBytesColumn = 5;
final int totalBytesColumn = 6;
final int statusColumn = 7;
- final int filenameColumnId = 8;
- final int lastModColumnId = 9;
- final int destinationColumnId = 10;
+ final int lastModColumnId = 8;
+ final int destinationColumnId = 9;
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
// Add the notifications
@@ -263,14 +254,8 @@ class DownloadNotification {
long id = c.getLong(idColumn);
String title = c.getString(titleColumn);
if (title == null || title.length() == 0) {
- String filename = c.getString(filenameColumnId);
- if (filename == null) {
- title = mContext.getResources().getString(
- R.string.download_unknown_title);
- } else {
- title = Downloads.Impl.createTitleFromFilename(mContext,
- filename, id);
- }
+ title = mContext.getResources().getString(
+ R.string.download_unknown_title);
}
Uri contentUri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + id);
String caption;
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index db005542..d7c24f9a 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -413,23 +413,40 @@ public final class DownloadProvider extends ContentProvider {
callingUid != mSystemUid &&
callingUid != mDefContainerUid &&
Process.supportsProcesses()) {
- if (!emptyWhere) {
- qb.appendWhere(" AND ");
- }
- qb.appendWhere("( " + Constants.UID + "=" + Binder.getCallingUid() + " OR "
- + Downloads.Impl.COLUMN_OTHER_UID + "=" + Binder.getCallingUid() + " )");
- emptyWhere = false;
-
+ boolean canSeeAllExternal;
if (projection == null) {
projection = sAppReadableColumnsArray;
+ // sAppReadableColumnsArray includes _DATA, which is not allowed
+ // to be seen except by the initiating application
+ canSeeAllExternal = false;
} else {
+ canSeeAllExternal = getContext().checkCallingPermission(
+ Downloads.Impl.PERMISSION_SEE_ALL_EXTERNAL)
+ == PackageManager.PERMISSION_GRANTED;
for (int i = 0; i < projection.length; ++i) {
if (!sAppReadableColumnsSet.contains(projection[i])) {
throw new IllegalArgumentException(
"column " + projection[i] + " is not allowed in queries");
}
+ canSeeAllExternal = canSeeAllExternal
+ && !projection[i].equals(Downloads.Impl._DATA);
}
}
+ if (!emptyWhere) {
+ qb.appendWhere(" AND ");
+ emptyWhere = false;
+ }
+ String validUid = "( " + Constants.UID + "="
+ + Binder.getCallingUid() + " OR "
+ + Downloads.Impl.COLUMN_OTHER_UID + "="
+ + Binder.getCallingUid() + " )";
+ if (canSeeAllExternal) {
+ qb.appendWhere("( " + validUid + " OR "
+ + Downloads.Impl.DESTINATION_EXTERNAL + " = "
+ + Downloads.Impl.COLUMN_DESTINATION + " )");
+ } else {
+ qb.appendWhere(validUid);
+ }
}
if (Constants.LOGVV) {
@@ -526,6 +543,16 @@ public final class DownloadProvider extends ContentProvider {
copyString(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues);
} else {
filteredValues = values;
+ String filename = values.getAsString(Downloads.Impl._DATA);
+ if (filename != null) {
+ Cursor c = query(uri, new String[]
+ { Downloads.Impl.COLUMN_TITLE }, null, null, null);
+ if (!c.moveToFirst() || c.getString(0) == null) {
+ values.put(Downloads.Impl.COLUMN_TITLE,
+ new File(filename).getName());
+ }
+ c.close();
+ }
}
int match = sURIMatcher.match(uri);
switch (match) {