Commit f5bf498e authored by Christian Dullweber's avatar Christian Dullweber Committed by Commit Bot

Revert "Upstream internal DownloadCollectionBridge code"

This reverts commit 680e3222.

Reason for revert: Looks like this broke https://ci.chromium.org/p/chrome/builders/ci/android_arm64-builder-perf/160982

Original change's description:
> Upstream internal DownloadCollectionBridge code
> 
> This will allow download in public chromium build to work on Q with MediaStore.
> 
> BUG=1052490
> 
> Change-Id: I31476292b92c7a5882fa4ad80cc60b29f6b14dba
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2057806
> Reviewed-by: Robert Sesek <rsesek@chromium.org>
> Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
> Reviewed-by: David Trainor <dtrainor@chromium.org>
> Commit-Queue: Min Qin <qinmin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#746867}

TBR=yfriedman@chromium.org,dtrainor@chromium.org,qinmin@chromium.org,rsesek@chromium.org,gmariani@google.com

Change-Id: I1547f1132bbddf575eeacfe2498b97ff1d7cc473
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1052490
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2089771Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747233}
parent bdcbb1dd
...@@ -56,6 +56,7 @@ import org.chromium.chrome.browser.webauth.Fido2ApiHandler; ...@@ -56,6 +56,7 @@ import org.chromium.chrome.browser.webauth.Fido2ApiHandler;
import org.chromium.chrome.browser.xsurface.SurfaceDependencyProvider; import org.chromium.chrome.browser.xsurface.SurfaceDependencyProvider;
import org.chromium.chrome.browser.xsurface.SurfaceRenderer; import org.chromium.chrome.browser.xsurface.SurfaceRenderer;
import org.chromium.components.browser_ui.widget.FeatureHighlightProvider; import org.chromium.components.browser_ui.widget.FeatureHighlightProvider;
import org.chromium.components.download.DownloadCollectionBridge;
import org.chromium.components.signin.AccountManagerDelegate; import org.chromium.components.signin.AccountManagerDelegate;
import org.chromium.components.signin.SystemAccountManagerDelegate; import org.chromium.components.signin.SystemAccountManagerDelegate;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
...@@ -328,6 +329,13 @@ public abstract class AppHooks { ...@@ -328,6 +329,13 @@ public abstract class AppHooks {
return new FeatureHighlightProvider(); return new FeatureHighlightProvider();
} }
/**
* @return A new {@link DownloadCollectionBridge} instance.
*/
public DownloadCollectionBridge getDownloadCollectionBridge() {
return DownloadCollectionBridge.getDownloadCollectionBridge();
}
/** /**
* @return A new {@link DigitalWellbeingClient} instance. * @return A new {@link DigitalWellbeingClient} instance.
*/ */
......
...@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.preferences.SharedPreferencesManager; ...@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.profiles.ProfileManager;
import org.chromium.chrome.browser.util.ConversionUtils; import org.chromium.chrome.browser.util.ConversionUtils;
import org.chromium.components.download.DownloadCollectionBridge;
import org.chromium.components.download.DownloadState; import org.chromium.components.download.DownloadState;
import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.EventConstants;
import org.chromium.components.feature_engagement.Tracker; import org.chromium.components.feature_engagement.Tracker;
...@@ -279,7 +278,6 @@ public class DownloadManagerService implements DownloadController.Observer, ...@@ -279,7 +278,6 @@ public class DownloadManagerService implements DownloadController.Observer,
mHandler = handler; mHandler = handler;
mDownloadSnackbarController = new DownloadSnackbarController(); mDownloadSnackbarController = new DownloadSnackbarController();
mOMADownloadHandler = new OMADownloadHandler(applicationContext); mOMADownloadHandler = new OMADownloadHandler(applicationContext);
DownloadCollectionBridge.setDownloadDelegate(new DownloadDelegateImpl());
// Note that this technically leaks the native object, however, DownloadManagerService // Note that this technically leaks the native object, however, DownloadManagerService
// is a singleton that lives forever and there's no clean shutdown of Chrome on Android. // is a singleton that lives forever and there's no clean shutdown of Chrome on Android.
init(); init();
......
...@@ -16,6 +16,7 @@ import android.text.style.StyleSpan; ...@@ -16,6 +16,7 @@ import android.text.style.StyleSpan;
import android.view.View; import android.view.View;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import org.chromium.base.BuildInfo;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
...@@ -83,8 +84,11 @@ public class DuplicateDownloadInfoBar extends ConfirmInfoBar { ...@@ -83,8 +84,11 @@ public class DuplicateDownloadInfoBar extends ConfirmInfoBar {
new AsyncTask<String>() { new AsyncTask<String>() {
@Override @Override
protected String doInBackground() { protected String doInBackground() {
if (DownloadCollectionBridge.shouldPublishDownload(mFilePath)) { if (BuildInfo.isAtLeastQ()
Uri uri = DownloadCollectionBridge.getDownloadUriForFileName(filename); && DownloadCollectionBridge.getDownloadCollectionBridge()
.needToPublishDownload(mFilePath)) {
Uri uri = DownloadCollectionBridge.getDownloadCollectionBridge()
.getDownloadUriForFileName(filename);
return uri == null ? null : uri.toString(); return uri == null ? null : uri.toString();
} else { } else {
if (file.exists()) return mFilePath; if (file.exists()) return mFilePath;
......
...@@ -81,6 +81,7 @@ import org.chromium.chrome.browser.util.ConversionUtils; ...@@ -81,6 +81,7 @@ import org.chromium.chrome.browser.util.ConversionUtils;
import org.chromium.chrome.browser.webapps.WebApkVersionManager; import org.chromium.chrome.browser.webapps.WebApkVersionManager;
import org.chromium.chrome.browser.webapps.WebappRegistry; import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
import org.chromium.components.download.DownloadCollectionBridge;
import org.chromium.components.minidump_uploader.CrashFileManager; import org.chromium.components.minidump_uploader.CrashFileManager;
import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.AccountsChangeObserver; import org.chromium.components.signin.AccountsChangeObserver;
...@@ -184,6 +185,11 @@ public class ProcessInitializationHandler { ...@@ -184,6 +185,11 @@ public class ProcessInitializationHandler {
application, ChromePreferenceKeys.SYNC_SESSIONS_UUID), application, ChromePreferenceKeys.SYNC_SESSIONS_UUID),
false); false);
// Set up the DownloadCollectionBridge early as display names may be immediately retrieved
// after native is loaded.
DownloadCollectionBridge.setDownloadCollectionBridge(
AppHooks.get().getDownloadCollectionBridge());
// De-jelly can also be controlled by a system property. As sandboxed processes can't // De-jelly can also be controlled by a system property. As sandboxed processes can't
// read this property directly, convert it to the equivalent command line flag. // read this property directly, convert it to the equivalent command line flag.
if (DeJellyUtils.externallyEnableDeJelly()) { if (DeJellyUtils.externallyEnableDeJelly()) {
......
...@@ -8,7 +8,6 @@ android_library("java") { ...@@ -8,7 +8,6 @@ android_library("java") {
sources = [ sources = [
"java/src/org/chromium/chrome/browser/download/DirectoryOption.java", "java/src/org/chromium/chrome/browser/download/DirectoryOption.java",
"java/src/org/chromium/chrome/browser/download/DownloadConstants.java", "java/src/org/chromium/chrome/browser/download/DownloadConstants.java",
"java/src/org/chromium/chrome/browser/download/DownloadDelegateImpl.java",
"java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java", "java/src/org/chromium/chrome/browser/download/DownloadDirectoryProvider.java",
"java/src/org/chromium/chrome/browser/download/DownloadFileProvider.java", "java/src/org/chromium/chrome/browser/download/DownloadFileProvider.java",
"java/src/org/chromium/chrome/browser/download/DownloadFilter.java", "java/src/org/chromium/chrome/browser/download/DownloadFilter.java",
...@@ -25,7 +24,6 @@ android_library("java") { ...@@ -25,7 +24,6 @@ android_library("java") {
"//base:base_java", "//base:base_java",
"//base:jni_java", "//base:jni_java",
"//chrome/browser/util:java", "//chrome/browser/util:java",
"//components/download/internal/common:internal_java",
"//components/download/public/common:public_java", "//components/download/public/common:public_java",
"//components/offline_items_collection/core:core_java", "//components/offline_items_collection/core:core_java",
"//content/public/android:content_java", "//content/public/android:content_java",
......
include_rules = [ include_rules = [
"+media/video", "+media/video",
"+content/public/android/java/src/org/chromium/content_public", "+content/public/android/java/src/org/chromium/content_public",
"+components/download/internal/common",
] ]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download;
import android.net.Uri;
import org.chromium.components.download.DownloadDelegate;
/**
* Utility class that implements DownloadDelegate.
*/
public class DownloadDelegateImpl extends DownloadDelegate {
public DownloadDelegateImpl() {}
@Override
public String remapGenericMimeType(String mimeType, String url, String filename) {
return MimeUtils.remapGenericMimeType(mimeType, url, filename);
}
@Override
public Uri parseOriginalUrl(String originalUrl) {
return UriUtils.parseOriginalUrl(originalUrl);
}
@Override
public boolean isDownloadOnSDCard(String filePath) {
return DownloadDirectoryProvider.isDownloadOnSDCard(filePath);
}
}
...@@ -101,15 +101,11 @@ source_set("internal") { ...@@ -101,15 +101,11 @@ source_set("internal") {
if (is_android) { if (is_android) {
android_library("internal_java") { android_library("internal_java") {
sources = [ sources = [ "android/java/src/org/chromium/components/download/DownloadCollectionBridge.java" ]
"android/java/src/org/chromium/components/download/DownloadCollectionBridge.java",
"android/java/src/org/chromium/components/download/DownloadDelegate.java",
]
deps = [ deps = [
"//base:base_java", "//base:base_java",
"//base:jni_java", "//base:jni_java",
"//third_party/android_provider:android_provider_java",
] ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
} }
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.download;
import android.net.Uri;
/**
* Helper class for providering some helper method needed by DownloadCollectionBridge.
*/
public class DownloadDelegate {
public DownloadDelegate() {}
/**
* If the given MIME type is null, or one of the "generic" types (text/plain
* or application/octet-stream) map it to a type that Android can deal with.
* If the given type is not generic, return it unchanged.
*
* @param mimeType MIME type provided by the server.
* @param url URL of the data being loaded.
* @param filename file name obtained from content disposition header
* @return The MIME type that should be used for this data.
*/
public String remapGenericMimeType(String mimeType, String url, String filename) {
return mimeType;
}
/**
* Parses an originating URL string and returns a valid Uri that can be inserted into
* DownloadManager. The returned Uri has to be null or non-empty http(s) scheme.
* @param originalUrl String representation of the originating URL.
* @return A valid Uri that can be accepted by DownloadManager.
*/
public Uri parseOriginalUrl(String originalUrl) {
return Uri.parse(originalUrl);
}
/**
* Returns whether the downloaded file path is on an external SD card.
* @param filePath The download file path.
* @return Whether download is on external sd card.
*/
public boolean isDownloadOnSDCard(String filePath) {
return false;
}
}
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
assert(is_android)
android_library("android_provider_java") {
sources = [
"java/src/org/chromium/third_party/android/provider/MediaStoreUtils.java",
]
deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ]
}
This diff is collapsed.
qinmin@chromium.org
dtrainor@chromium.org
# TEAM: chrome-downloads@chromium.org
# COMPONENT: UI>Browser>Downloads
Name: MediaStoreUtils Android sample.
URL: https://android.googlesource.com/platform/cts/+/master/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
Version: 50f25a19f2a3de940d6ef7eac84b37d1c62f1b5f
License: Apache 2.0
Security Critical: yes
Description:
This contains a modified copy of MediaStoreUtils.java. Please don't modify this.
MediaStoreUtils.java is based on a public Android sample that was
available as part of the Android cts libraries. It is
also available from:
https://android.googlesource.com/platform/cts/+/master/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
Local Modifications:
- Added logs
- Introduced some helper method.
/*
* Copyright (C) 2019 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 org.chromium.third_party.android.provider;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.MediaStore.DownloadColumns;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.util.Objects;
/**
* Utility class to contribute download to the public download collection using
* MediaStore API from Q.
*/
public class MediaStoreUtils {
private static final String TAG = "MediaStoreUtils";
/**
* Creates a new pending media item using the given parameters. Pending items
* are expected to have a short lifetime, and owners should either
* {@link PendingSession#publish()} or {@link PendingSession#abandon()} a
* pending item within a few hours after first creating it.
*
* @param context Application context.
* @param params Parameters used to configure the item.
* @return token which can be passed to {@link #openPending(Context, Uri)}
* to work with this pending item.
*/
public static @NonNull Uri createPending(
@NonNull Context context, @NonNull PendingParams params) {
return context.getContentResolver().insert(params.mInsertUri, params.mInsertValues);
}
/**
* Opens a pending media item to make progress on it. You can open a pending
* item multiple times before finally calling either
* {@link PendingSession#publish()} or {@link PendingSession#abandon()}.
*
* @param uri token which was previously returned from
* {@link #createPending(Context, PendingParams)}.
* @return pending session that was opened.
*/
public static @NonNull PendingSession openPending(@NonNull Context context, @NonNull Uri uri) {
return new PendingSession(context, uri);
}
/**
* Parameters that describe a pending media item.
*/
public static class PendingParams {
final Uri mInsertUri;
final ContentValues mInsertValues;
/**
* Creates parameters that describe a pending media item.
*
* @param insertUri the {@code content://} Uri where this pending item
* should be inserted when finally published. For example, to
* publish an image, use
* {@link MediaStore.Images.Media#getContentUri(String)}.
* @param displayName Display name of the item.
* @param mimeType MIME type of the item.
*/
public PendingParams(
@NonNull Uri insertUri, @NonNull String displayName, @NonNull String mimeType) {
mInsertUri = Objects.requireNonNull(insertUri);
final long now = System.currentTimeMillis() / 1000;
mInsertValues = new ContentValues();
mInsertValues.put(MediaColumns.DISPLAY_NAME, Objects.requireNonNull(displayName));
mInsertValues.put(MediaColumns.MIME_TYPE, Objects.requireNonNull(mimeType));
mInsertValues.put(MediaColumns.DATE_ADDED, now);
mInsertValues.put(MediaColumns.DATE_MODIFIED, now);
try {
setPendingContentValues(this.mInsertValues, true);
} catch (Exception e) {
Log.e(TAG, "Unable to set pending content values.", e);
}
}
/**
* Optionally sets the Uri from where the file has been downloaded. This is used
* for files being added to {@link Downloads} table.
*
* @see DownloadColumns#DOWNLOAD_URI
*/
public void setDownloadUri(@Nullable Uri downloadUri) {
if (downloadUri == null) {
mInsertValues.remove(DownloadColumns.DOWNLOAD_URI);
} else {
mInsertValues.put(DownloadColumns.DOWNLOAD_URI, downloadUri.toString());
}
}
/**
* Optionally set the Uri indicating HTTP referer of the file. This is used for
* files being added to {@link Downloads} table.
*
* @see DownloadColumns#REFERER_URI
*/
public void setRefererUri(@Nullable Uri refererUri) {
if (refererUri == null) {
mInsertValues.remove(DownloadColumns.REFERER_URI);
} else {
mInsertValues.put(DownloadColumns.REFERER_URI, refererUri.toString());
}
}
/**
* Sets the expiration time of the download.
*
* @time Epoch time in seconds.
*/
public void setExpirationTime(long time) {
mInsertValues.put("date_expires", time);
}
}
/**
* Session actively working on a pending media item. Pending items are
* expected to have a short lifetime, and owners should either
* {@link PendingSession#publish()} or {@link PendingSession#abandon()} a
* pending item within a few hours after first creating it.
*/
public static class PendingSession implements AutoCloseable {
private final Context mContext;
private final Uri mUri;
/**
* Create a new pending session item to be published.
* @param context Contexxt of the application.
* @param uri Token which was previously returned from
* {@link #createPending(Context, PendingParams)}.
*/
PendingSession(Context context, Uri uri) {
mContext = Objects.requireNonNull(context);
mUri = Objects.requireNonNull(uri);
}
/**
* Open the underlying file representing this media item. When a media
* item is successfully completed, you should
* {@link ParcelFileDescriptor#close()} and then {@link #publish()} it.
*
* @return ParcelFileDescriptor to be written into.
*/
public @NonNull ParcelFileDescriptor open() throws FileNotFoundException {
return mContext.getContentResolver().openFileDescriptor(mUri, "rw");
}
/**
* Open the underlying file representing this media item. When a media
* item is successfully completed, you should
* {@link OutputStream#close()} and then {@link #publish()} it.
*
* @return OutputStream to be written into.
*/
public @NonNull OutputStream openOutputStream() throws FileNotFoundException {
return mContext.getContentResolver().openOutputStream(mUri);
}
/**
* When this media item is successfully completed, call this method to
* publish and make the final item visible to the user.
*
* @return the final {@code content://} Uri representing the newly
* published media.
*/
public @NonNull Uri publish() {
try {
final ContentValues values = new ContentValues();
setPendingContentValues(values, false);
values.putNull("date_expires");
mContext.getContentResolver().update(mUri, values, null, null);
} catch (Exception e) {
Log.e(TAG, "Unable to publish pending session.", e);
}
return mUri;
}
/**
* When this media item has failed to be completed, call this method to
* destroy the pending item record and any data related to it.
*/
public void abandon() {
mContext.getContentResolver().delete(mUri, null, null);
}
@Override
public void close() {
// No resources to close, but at least we can inform people that no
// progress is being actively made.
}
}
/**
* Helper method to set the ContentValues to pending or non-pending.
* @param values ContentValues to be set.
* @param isPending Whether the item is pending.
*/
private static void setPendingContentValues(ContentValues values, boolean isPending)
throws Exception {
values.put(MediaColumns.IS_PENDING, isPending ? 1 : 0);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment