From c0622bf896c1af62b0e69b18cd84c7de3b67beb3 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 27 Aug 2012 21:53:30 -0700 Subject: Send ORIGINATING_URI and REFERRER to installer. When building PackageInstaller intents, include ORIGINATING_URI and REFERRER extras. Unify view intent building for both notifications and list UI. Bug: 6900672 Change-Id: I18435e0f8aa549880ec594f82b6a250232706135 --- .../providers/downloads/DownloadReceiver.java | 22 +---- .../android/providers/downloads/OpenHelper.java | 105 +++++++++++++++++++++ ui/Android.mk | 5 +- .../providers/downloads/ui/DownloadList.java | 20 +--- 4 files changed, 119 insertions(+), 33 deletions(-) create mode 100644 src/com/android/providers/downloads/OpenHelper.java diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java index 81ff4040..aa165e41 100644 --- a/src/com/android/providers/downloads/DownloadReceiver.java +++ b/src/com/android/providers/downloads/DownloadReceiver.java @@ -28,13 +28,12 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; +import android.provider.BaseColumns; import android.provider.Downloads; import android.util.Log; import com.google.common.annotations.VisibleForTesting; -import java.io.File; - /** * Receives system broadcasts (boot, network connectivity) */ @@ -144,23 +143,12 @@ public class DownloadReceiver extends BroadcastReceiver { * has been clicked. */ private void openDownload(Context context, Cursor cursor) { - String filename = cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl._DATA)); - String mimetype = - cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE)); - Uri path = Uri.parse(filename); - // If there is no scheme, then it must be a file - if (path.getScheme() == null) { - path = Uri.fromFile(new File(filename)); - } - - Intent activityIntent = new Intent(Intent.ACTION_VIEW); - mimetype = DownloadDrmHelper.getOriginalMimeType(context, filename, mimetype); - activityIntent.setDataAndType(path, mimetype); - activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); + final Intent intent = OpenHelper.buildViewIntent(context, id); try { - context.startActivity(activityIntent); + context.startActivity(intent); } catch (ActivityNotFoundException ex) { - Log.d(Constants.TAG, "no activity for " + mimetype, ex); + Log.d(Constants.TAG, "no activity for " + intent, ex); } } diff --git a/src/com/android/providers/downloads/OpenHelper.java b/src/com/android/providers/downloads/OpenHelper.java new file mode 100644 index 00000000..0151c8de --- /dev/null +++ b/src/com/android/providers/downloads/OpenHelper.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2012 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_LOCAL_URI; +import static android.app.DownloadManager.COLUMN_MEDIA_TYPE; +import static android.app.DownloadManager.COLUMN_URI; +import static android.provider.Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI; + +import android.app.DownloadManager; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.provider.Downloads.Impl.RequestHeaders; + +public class OpenHelper { + /** + * Build an {@link Intent} to view the download at current {@link Cursor} + * position, handling subtleties around installing packages. + */ + public static Intent buildViewIntent(Context context, long id) { + final DownloadManager downManager = (DownloadManager) context.getSystemService( + Context.DOWNLOAD_SERVICE); + downManager.setAccessAllDownloads(true); + + final Cursor cursor = downManager.query(new DownloadManager.Query().setFilterById(id)); + try { + if (!cursor.moveToFirst()) { + throw new IllegalArgumentException("Missing download " + id); + } + + final Uri localUri = getCursorUri(cursor, COLUMN_LOCAL_URI); + final String mimeType = getCursorString(cursor, COLUMN_MEDIA_TYPE); + + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION); + + if ("application/vnd.android.package-archive".equals(mimeType)) { + // PackageInstaller doesn't like content URIs, so open file + intent.setDataAndType(localUri, mimeType); + + // Also splice in details about where it came from + final Uri remoteUri = getCursorUri(cursor, COLUMN_URI); + intent.putExtra(Intent.EXTRA_ORIGINATING_URI, remoteUri); + intent.putExtra(Intent.EXTRA_REFERRER, getRefererUri(context, id)); + } else if ("file".equals(localUri.getScheme())) { + intent.setDataAndType( + ContentUris.withAppendedId(ALL_DOWNLOADS_CONTENT_URI, id), mimeType); + } else { + intent.setDataAndType(localUri, mimeType); + } + + return intent; + } finally { + cursor.close(); + } + } + + private static Uri getRefererUri(Context context, long id) { + final Uri headersUri = Uri.withAppendedPath( + ContentUris.withAppendedId(ALL_DOWNLOADS_CONTENT_URI, id), + RequestHeaders.URI_SEGMENT); + final Cursor headers = context.getContentResolver() + .query(headersUri, null, null, null, null); + try { + while (headers.moveToNext()) { + final String header = getCursorString(headers, RequestHeaders.COLUMN_HEADER); + if ("Referer".equalsIgnoreCase(header)) { + return getCursorUri(headers, RequestHeaders.COLUMN_VALUE); + } + } + } finally { + headers.close(); + } + return null; + } + + private static String getCursorString(Cursor cursor, String column) { + return cursor.getString(cursor.getColumnIndexOrThrow(column)); + } + + private static Uri getCursorUri(Cursor cursor, String column) { + return Uri.parse(getCursorString(cursor, column)); + } + + private static long getCursorLong(Cursor cursor, String column) { + return cursor.getLong(cursor.getColumnIndexOrThrow(column)); + } +} diff --git a/ui/Android.mk b/ui/Android.mk index 8c925f64..14211ea2 100644 --- a/ui/Android.mk +++ b/ui/Android.mk @@ -3,7 +3,10 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := $(call all-java-files-under, src) \ + ../src/com/android/providers/downloads/OpenHelper.java \ + ../src/com/android/providers/downloads/Constants.java \ + ../src/com/android/providers/downloads/DownloadDrmHelper.java LOCAL_PACKAGE_NAME := DownloadProviderUi LOCAL_CERTIFICATE := media diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 103d3f83..6ffa0691 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -32,6 +32,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Parcelable; +import android.provider.BaseColumns; import android.provider.Downloads; import android.util.Log; import android.util.SparseBooleanArray; @@ -50,6 +51,8 @@ import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ListView; import android.widget.Toast; +import com.android.providers.downloads.OpenHelper; + import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; @@ -499,7 +502,6 @@ public class DownloadList extends Activity { * Send an Intent to open the download currently pointed to by the given cursor. */ private void openCurrentDownload(Cursor cursor) { - final long id = cursor.getInt(mIdColumnId); final Uri localUri = Uri.parse(cursor.getString(mLocalUriColumnId)); try { getContentResolver().openFileDescriptor(localUri, "r").close(); @@ -512,20 +514,8 @@ public class DownloadList extends Activity { // close() failed, not a problem } - final Uri viewUri; - final String mimeType = cursor.getString(mMediaTypeColumnId); - if ("application/vnd.android.package-archive".equals(mimeType)) { - // PackageInstaller doesn't like content URIs, so open file - viewUri = localUri; - } else if ("file".equals(localUri.getScheme())) { - viewUri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id); - } else { - viewUri = localUri; - } - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(viewUri, mimeType); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION); + final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); + final Intent intent = OpenHelper.buildViewIntent(this, id); try { startActivity(intent); } catch (ActivityNotFoundException ex) { -- cgit v1.2.3