| Index: chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
|
| index b01b1b5e23f7431167091943c8b22018b292c39c..8749f8a07632184a603071e5ab73ab2de3bfc629 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
|
| @@ -5,12 +5,19 @@
|
| package org.chromium.chrome.browser.download;
|
|
|
| import android.app.Activity;
|
| +import android.app.PendingIntent;
|
| +import android.content.ActivityNotFoundException;
|
| import android.content.Context;
|
| import android.content.Intent;
|
| import android.content.SharedPreferences;
|
| +import android.graphics.Bitmap;
|
| +import android.graphics.BitmapFactory;
|
| +import android.graphics.Color;
|
| import android.net.Uri;
|
| import android.os.StrictMode;
|
| +import android.provider.Browser;
|
| import android.support.annotation.Nullable;
|
| +import android.support.customtabs.CustomTabsIntent;
|
| import android.text.TextUtils;
|
|
|
| import org.chromium.base.ApplicationStatus;
|
| @@ -24,11 +31,12 @@ import org.chromium.chrome.browser.ChromeActivity;
|
| import org.chromium.chrome.browser.ChromeFeatureList;
|
| import org.chromium.chrome.browser.IntentHandler;
|
| import org.chromium.chrome.browser.UrlConstants;
|
| +import org.chromium.chrome.browser.customtabs.CustomTabActivity;
|
| +import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
|
| import org.chromium.chrome.browser.download.ui.BackendProvider;
|
| import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate;
|
| import org.chromium.chrome.browser.download.ui.DownloadFilter;
|
| import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper;
|
| -import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.DownloadItemWrapper;
|
| import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge;
|
| import org.chromium.chrome.browser.tab.Tab;
|
| import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
|
| @@ -38,6 +46,7 @@ import org.chromium.content_public.browser.LoadUrlParams;
|
| import org.chromium.ui.base.DeviceFormFactor;
|
| import org.chromium.ui.widget.Toast;
|
|
|
| +import java.io.File;
|
| import java.util.ArrayList;
|
| import java.util.List;
|
|
|
| @@ -204,17 +213,17 @@ public class DownloadUtils {
|
|
|
| /**
|
| * Creates an Intent to open the file in another app by firing an Intent to Android.
|
| - * @param item Item to open.
|
| - * @return Intent that can be used to start an Activity for the DownloadItem.
|
| + * @param fileUri Uri pointing to the file.
|
| + * @param mimeType MIME type for the file.
|
| + * @return Intent that can be used to start an Activity for the file.
|
| */
|
| - public static Intent createViewIntentForDownloadItem(DownloadItemWrapper item) {
|
| - String mimeType = Intent.normalizeMimeType(item.getMimeType());
|
| - Uri fileUri = Uri.fromFile(item.getFile());
|
| + public static Intent createViewIntentForDownloadItem(Uri fileUri, String mimeType) {
|
| Intent fileIntent = new Intent(Intent.ACTION_VIEW);
|
| - if (TextUtils.isEmpty(mimeType)) {
|
| + String normalizedMimeType = Intent.normalizeMimeType(mimeType);
|
| + if (TextUtils.isEmpty(normalizedMimeType)) {
|
| fileIntent.setData(fileUri);
|
| } else {
|
| - fileIntent.setDataAndType(fileUri, mimeType);
|
| + fileIntent.setDataAndType(fileUri, normalizedMimeType);
|
| }
|
| fileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
| fileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| @@ -249,7 +258,7 @@ public class DownloadUtils {
|
| }
|
| offlinePagesString.append(wrappedItem.getUrl());
|
| } else {
|
| - itemUris.add(getUriForItem(wrappedItem));
|
| + itemUris.add(getUriForItem(wrappedItem.getFile()));
|
| }
|
|
|
| if (selectedItemsFilterType != wrappedItem.getFilterType()) {
|
| @@ -301,7 +310,8 @@ public class DownloadUtils {
|
| }
|
|
|
| if (itemUris.size() == 1 && offlinePagesString.length() == 0) {
|
| - shareIntent.putExtra(Intent.EXTRA_STREAM, getUriForItem(items.get(0)));
|
| + // Sharing a DownloadItem.
|
| + shareIntent.putExtra(Intent.EXTRA_STREAM, getUriForItem(items.get(0).getFile()));
|
| } else {
|
| shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, itemUris);
|
| }
|
| @@ -319,7 +329,74 @@ public class DownloadUtils {
|
| return shareIntent;
|
| }
|
|
|
| - private static Uri getUriForItem(DownloadHistoryItemWrapper itemWrapper) {
|
| + private static Intent createShareIntent(Uri fileUri, String mimeType) {
|
| + if (TextUtils.isEmpty(mimeType)) mimeType = DEFAULT_MIME_TYPE;
|
| +
|
| + Intent intent = new Intent(Intent.ACTION_SEND);
|
| + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
| + intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
| + intent.setType(mimeType);
|
| + return intent;
|
| + }
|
| +
|
| + /**
|
| + * Creates an Intent that allows viewing the given file in an internal media viewer.
|
| + * @param fileUri URI pointing at the file, ideally in file:// form.
|
| + * @param shareUri URI pointing at the file, ideally in content:// form.
|
| + * @param mimeType MIME type of the file.
|
| + * @return Intent that can be fired to open the file.
|
| + */
|
| + public static Intent getMediaViewerIntentForDownloadItem(
|
| + Uri fileUri, Uri shareUri, String mimeType) {
|
| + Context context = ContextUtils.getApplicationContext();
|
| + Intent viewIntent = createViewIntentForDownloadItem(fileUri, mimeType);
|
| +
|
| + Bitmap closeIcon = BitmapFactory.decodeResource(
|
| + context.getResources(), R.drawable.ic_arrow_back_white_24dp);
|
| + Bitmap shareIcon = BitmapFactory.decodeResource(
|
| + context.getResources(), R.drawable.ic_share_white_24dp);
|
| +
|
| + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
|
| + builder.setToolbarColor(Color.BLACK);
|
| + builder.setCloseButtonIcon(closeIcon);
|
| + builder.setShowTitle(true);
|
| +
|
| + // Create a PendingIntent that can be used to view the file externally.
|
| + // TODO(dfalcantara): Check if this is problematic in multi-window mode, where two
|
| + // different viewers could be visible at the same time.
|
| + Intent chooserIntent = Intent.createChooser(viewIntent, null);
|
| + chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| + String openWithStr = context.getString(R.string.download_manager_open_with);
|
| + PendingIntent pendingViewIntent = PendingIntent.getActivity(
|
| + context, 0, chooserIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
| + builder.addMenuItem(openWithStr, pendingViewIntent);
|
| +
|
| + // Create a PendingIntent that shares the file with external apps.
|
| + PendingIntent pendingShareIntent = PendingIntent.getActivity(
|
| + context, 0, createShareIntent(shareUri, mimeType), 0);
|
| + builder.setActionButton(
|
| + shareIcon, context.getString(R.string.share), pendingShareIntent, true);
|
| +
|
| + // Build up the Intent further.
|
| + Intent intent = builder.build().intent;
|
| + intent.setPackage(context.getPackageName());
|
| + intent.setData(fileUri);
|
| + intent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_MEDIA_VIEWER, true);
|
| + intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
|
| + IntentHandler.addTrustedIntentExtras(intent, context);
|
| +
|
| + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| + intent.setClass(context, CustomTabActivity.class);
|
| + return intent;
|
| + }
|
| +
|
| + /**
|
| + * Returns a URI that points at the file.
|
| + * @param file File to get a URI for.
|
| + * @return URI that points at that file, either as a content:// URI or a file:// URI.
|
| + */
|
| + public static Uri getUriForItem(File file) {
|
| Uri uri = null;
|
|
|
| // #getContentUriFromFile causes a disk read when it calls into FileProvider#getUriForFile.
|
| @@ -329,16 +406,15 @@ public class DownloadUtils {
|
| // know/preload which URIs we need until the user presses share.
|
| StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
|
| try {
|
| - // Try to obtain a content:// URI, which is preferred to a file:/// URI so that
|
| + // Try to obtain a content:// URI, which is preferred to a file:// URI so that
|
| // receiving apps don't attempt to determine the file's mime type (which often fails).
|
| - uri = ContentUriUtils.getContentUriFromFile(ContextUtils.getApplicationContext(),
|
| - itemWrapper.getFile());
|
| + uri = ContentUriUtils.getContentUriFromFile(ContextUtils.getApplicationContext(), file);
|
| } catch (IllegalArgumentException e) {
|
| Log.e(TAG, "Could not create content uri: " + e);
|
| }
|
| StrictMode.setThreadPolicy(oldPolicy);
|
|
|
| - if (uri == null) uri = Uri.fromFile(itemWrapper.getFile());
|
| + if (uri == null) uri = Uri.fromFile(file);
|
|
|
| return uri;
|
| }
|
| @@ -350,4 +426,28 @@ public class DownloadUtils {
|
| RecordHistogram.recordLinearCountHistogram("Android.DownloadManager.Share.Count",
|
| count, 1, 20, 20);
|
| }
|
| +
|
| + /**
|
| + * Fires an Intent to open a downloaded item.
|
| + * @param context Context to use.
|
| + * @param intent Intent that can be fired.
|
| + * @return Whether an Activity was successfully started for the Intent.
|
| + */
|
| + static boolean fireOpenIntentForDownload(Context context, Intent intent) {
|
| + try {
|
| + if (TextUtils.equals(intent.getPackage(), context.getPackageName())) {
|
| + IntentHandler.startActivityForTrustedIntent(intent, context);
|
| + } else {
|
| + context.startActivity(intent);
|
| + }
|
| + return true;
|
| + } catch (ActivityNotFoundException ex) {
|
| + Log.d(TAG, "Activity not found for " + intent.getType() + " over "
|
| + + intent.getData().getScheme(), ex);
|
| + } catch (SecurityException ex) {
|
| + Log.d(TAG, "cannot open intent: " + intent, ex);
|
| + }
|
| +
|
| + return false;
|
| + }
|
| }
|
|
|