Commit 1a33370f authored by John Abd-El-Malek's avatar John Abd-El-Malek Committed by Commit Bot

Resume interrupted downloads on restart in WebLayer.

Bug: 1025603
Change-Id: Ie2ef10c03b9ffea77436c0932727d1545fcf895f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132540Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755922}
parent 4964f415
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "content/public/browser/device_service.h" #include "content/public/browser/device_service.h"
#include "content/public/browser/download_request_utils.h" #include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_context.h" #include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
#include "weblayer/browser/permissions/permission_manager_factory.h" #include "weblayer/browser/permissions/permission_manager_factory.h"
#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" #include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h"
#include "weblayer/public/common/switches.h" #include "weblayer/public/common/switches.h"
...@@ -181,7 +182,10 @@ download::InProgressDownloadManager* ...@@ -181,7 +182,10 @@ download::InProgressDownloadManager*
BrowserContextImpl::RetriveInProgressDownloadManager() { BrowserContextImpl::RetriveInProgressDownloadManager() {
// Override this to provide a connection to the wake lock service. // Override this to provide a connection to the wake lock service.
auto* download_manager = new download::InProgressDownloadManager( auto* download_manager = new download::InProgressDownloadManager(
nullptr, base::FilePath(), nullptr, nullptr, path_,
path_.empty()
? nullptr
: GetDefaultStoragePartition(this)->GetProtoDatabaseProvider(),
base::BindRepeating(&IgnoreOriginSecurityCheck), base::BindRepeating(&IgnoreOriginSecurityCheck),
base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe), base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe),
base::BindRepeating(&BindWakeLockProvider)); base::BindRepeating(&BindWakeLockProvider));
......
...@@ -73,8 +73,10 @@ DownloadState DownloadImpl::GetState() { ...@@ -73,8 +73,10 @@ DownloadState DownloadImpl::GetState() {
if (pause_pending_ || (item_->IsPaused() && !resume_pending_)) if (pause_pending_ || (item_->IsPaused() && !resume_pending_))
return DownloadState::kPaused; return DownloadState::kPaused;
if (item_->GetState() == download::DownloadItem::IN_PROGRESS) if (resume_pending_ ||
item_->GetState() == download::DownloadItem::IN_PROGRESS) {
return DownloadState::kInProgress; return DownloadState::kInProgress;
}
return DownloadState::kFailed; return DownloadState::kFailed;
} }
......
...@@ -54,6 +54,12 @@ DownloadManagerDelegateImpl::DownloadManagerDelegateImpl( ...@@ -54,6 +54,12 @@ DownloadManagerDelegateImpl::DownloadManagerDelegateImpl(
content::DownloadManager* download_manager) content::DownloadManager* download_manager)
: download_manager_(download_manager) { : download_manager_(download_manager) {
download_manager_->AddObserver(this); download_manager_->AddObserver(this);
// WebLayer doesn't use a history DB as the in-progress database maintained by
// the download component is enough. However the download code still depends
// this notification. TODO(jam): update download code to handle this.
download_manager_->PostInitialization(
content::DownloadManager::DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB);
} }
DownloadManagerDelegateImpl::~DownloadManagerDelegateImpl() { DownloadManagerDelegateImpl::~DownloadManagerDelegateImpl() {
...@@ -172,6 +178,13 @@ void DownloadManagerDelegateImpl::OnDownloadCreated( ...@@ -172,6 +178,13 @@ void DownloadManagerDelegateImpl::OnDownloadCreated(
local_state->SetInteger(kDownloadNextIDPref, next_id); local_state->SetInteger(kDownloadNextIDPref, next_id);
} }
if (item->GetLastReason() == download::DOWNLOAD_INTERRUPT_REASON_CRASH &&
item->CanResume() &&
// Don't automatically resume downloads which were previously paused.
!item->IsPaused()) {
DownloadImpl::Get(item)->Resume();
}
auto* delegate = GetDelegate(item); auto* delegate = GetDelegate(item);
if (delegate) if (delegate)
delegate->DownloadStarted(DownloadImpl::Get(item)); delegate->DownloadStarted(DownloadImpl::Get(item));
...@@ -183,6 +196,13 @@ void DownloadManagerDelegateImpl::OnDownloadDropped( ...@@ -183,6 +196,13 @@ void DownloadManagerDelegateImpl::OnDownloadDropped(
download_dropped_callback_.Run(); download_dropped_callback_.Run();
} }
void DownloadManagerDelegateImpl::OnManagerInitialized() {
auto* browser_context_impl =
static_cast<BrowserContextImpl*>(download_manager_->GetBrowserContext());
auto* profile = browser_context_impl->profile_impl();
profile->DownloadsInitialized();
}
void DownloadManagerDelegateImpl::OnDownloadUpdated( void DownloadManagerDelegateImpl::OnDownloadUpdated(
download::DownloadItem* item) { download::DownloadItem* item) {
auto* delegate = GetDelegate(item); auto* delegate = GetDelegate(item);
......
...@@ -60,6 +60,7 @@ class DownloadManagerDelegateImpl : public content::DownloadManagerDelegate, ...@@ -60,6 +60,7 @@ class DownloadManagerDelegateImpl : public content::DownloadManagerDelegate,
void OnDownloadCreated(content::DownloadManager* manager, void OnDownloadCreated(content::DownloadManager* manager,
download::DownloadItem* item) override; download::DownloadItem* item) override;
void OnDownloadDropped(content::DownloadManager* manager) override; void OnDownloadDropped(content::DownloadManager* manager) override;
void OnManagerInitialized() override;
// download::DownloadItem::Observer implementation: // download::DownloadItem::Observer implementation:
void OnDownloadUpdated(download::DownloadItem* item) override; void OnDownloadUpdated(download::DownloadItem* item) override;
......
...@@ -21,17 +21,16 @@ import org.chromium.weblayer_private.interfaces.ObjectWrapper; ...@@ -21,17 +21,16 @@ import org.chromium.weblayer_private.interfaces.ObjectWrapper;
@JNINamespace("weblayer") @JNINamespace("weblayer")
public final class DownloadCallbackProxy { public final class DownloadCallbackProxy {
private long mNativeDownloadCallbackProxy; private long mNativeDownloadCallbackProxy;
private String mProfileName;
private IDownloadCallbackClient mClient; private IDownloadCallbackClient mClient;
DownloadCallbackProxy(long profile, IDownloadCallbackClient client) { DownloadCallbackProxy(String profileName, long profile) {
assert client != null; mProfileName = profileName;
mClient = client;
mNativeDownloadCallbackProxy = mNativeDownloadCallbackProxy =
DownloadCallbackProxyJni.get().createDownloadCallbackProxy(this, profile); DownloadCallbackProxyJni.get().createDownloadCallbackProxy(this, profile);
} }
public void setClient(IDownloadCallbackClient client) { public void setClient(IDownloadCallbackClient client) {
assert client != null;
mClient = client; mClient = client;
} }
...@@ -43,6 +42,10 @@ public final class DownloadCallbackProxy { ...@@ -43,6 +42,10 @@ public final class DownloadCallbackProxy {
@CalledByNative @CalledByNative
private boolean interceptDownload(String url, String userAgent, String contentDisposition, private boolean interceptDownload(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength) throws RemoteException { String mimetype, long contentLength) throws RemoteException {
if (mClient == null) {
return true;
}
return mClient.interceptDownload( return mClient.interceptDownload(
url, userAgent, contentDisposition, mimetype, contentLength); url, userAgent, contentDisposition, mimetype, contentLength);
} }
...@@ -55,6 +58,11 @@ public final class DownloadCallbackProxy { ...@@ -55,6 +58,11 @@ public final class DownloadCallbackProxy {
return; return;
} }
if (mClient == null) {
DownloadCallbackProxyJni.get().allowDownload(callbackId, false);
return;
}
ValueCallback<Boolean> callback = new ValueCallback<Boolean>() { ValueCallback<Boolean> callback = new ValueCallback<Boolean>() {
@Override @Override
public void onReceiveValue(Boolean result) { public void onReceiveValue(Boolean result) {
...@@ -70,30 +78,38 @@ public final class DownloadCallbackProxy { ...@@ -70,30 +78,38 @@ public final class DownloadCallbackProxy {
@CalledByNative @CalledByNative
private DownloadImpl createDownload(long nativeDownloadImpl, int id) { private DownloadImpl createDownload(long nativeDownloadImpl, int id) {
return new DownloadImpl(mClient, nativeDownloadImpl, id); return new DownloadImpl(mProfileName, mClient, nativeDownloadImpl, id);
} }
@CalledByNative @CalledByNative
private void downloadStarted(DownloadImpl download) throws RemoteException { private void downloadStarted(DownloadImpl download) throws RemoteException {
mClient.downloadStarted(download.getClientDownload()); if (mClient != null) {
mClient.downloadStarted(download.getClientDownload());
}
download.downloadStarted(); download.downloadStarted();
} }
@CalledByNative @CalledByNative
private void downloadProgressChanged(DownloadImpl download) throws RemoteException { private void downloadProgressChanged(DownloadImpl download) throws RemoteException {
mClient.downloadProgressChanged(download.getClientDownload()); if (mClient != null) {
mClient.downloadProgressChanged(download.getClientDownload());
}
download.downloadProgressChanged(); download.downloadProgressChanged();
} }
@CalledByNative @CalledByNative
private void downloadCompleted(DownloadImpl download) throws RemoteException { private void downloadCompleted(DownloadImpl download) throws RemoteException {
mClient.downloadCompleted(download.getClientDownload()); if (mClient != null) {
mClient.downloadCompleted(download.getClientDownload());
}
download.downloadCompleted(); download.downloadCompleted();
} }
@CalledByNative @CalledByNative
private void downloadFailed(DownloadImpl download) throws RemoteException { private void downloadFailed(DownloadImpl download) throws RemoteException {
mClient.downloadFailed(download.getClientDownload()); if (mClient != null) {
mClient.downloadFailed(download.getClientDownload());
}
download.downloadFailed(); download.downloadFailed();
} }
......
...@@ -51,11 +51,14 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -51,11 +51,14 @@ public final class DownloadImpl extends IDownload.Stub {
"org.chromium.weblayer.downloads.NOTIFICATION_LOCATION"; "org.chromium.weblayer.downloads.NOTIFICATION_LOCATION";
static final String EXTRA_NOTIFICATION_MIME_TYPE = static final String EXTRA_NOTIFICATION_MIME_TYPE =
"org.chromium.weblayer.downloads.NOTIFICATION_MIME_TYPE"; "org.chromium.weblayer.downloads.NOTIFICATION_MIME_TYPE";
static final String EXTRA_NOTIFICATION_PROFILE =
"org.chromium.weblayer.downloads.NOTIFICATION_PROFILE";
static final String PREF_NEXT_NOTIFICATION_ID = static final String PREF_NEXT_NOTIFICATION_ID =
"org.chromium.weblayer.downloads.notification_next_id"; "org.chromium.weblayer.downloads.notification_next_id";
private static final String CHANNEL_ID = "org.chromium.weblayer.downloads.channel"; private static final String CHANNEL_ID = "org.chromium.weblayer.downloads.channel";
private static final String TAG = "DownloadImpl"; private static final String TAG = "DownloadImpl";
private final String mProfileName;
private final IDownloadCallbackClient mClient; private final IDownloadCallbackClient mClient;
private final IClientDownload mClientDownload; private final IClientDownload mClientDownload;
// WARNING: DownloadImpl may outlive the native side, in which case this member is set to 0. // WARNING: DownloadImpl may outlive the native side, in which case this member is set to 0.
...@@ -67,7 +70,8 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -67,7 +70,8 @@ public final class DownloadImpl extends IDownload.Stub {
private static boolean sCreatedChannel = false; private static boolean sCreatedChannel = false;
private static final HashMap<Integer, DownloadImpl> sMap = new HashMap<Integer, DownloadImpl>(); private static final HashMap<Integer, DownloadImpl> sMap = new HashMap<Integer, DownloadImpl>();
public static void forwardIntent(Context context, Intent intent) { public static void forwardIntent(
Context context, Intent intent, ProfileManager profileManager) {
if (intent.getAction().equals(OPEN_INTENT)) { if (intent.getAction().equals(OPEN_INTENT)) {
String location = intent.getStringExtra(EXTRA_NOTIFICATION_LOCATION); String location = intent.getStringExtra(EXTRA_NOTIFICATION_LOCATION);
if (TextUtils.isEmpty(location)) { if (TextUtils.isEmpty(location)) {
...@@ -96,6 +100,17 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -96,6 +100,17 @@ public final class DownloadImpl extends IDownload.Stub {
return; return;
} }
String profileName = intent.getStringExtra(EXTRA_NOTIFICATION_PROFILE);
ProfileImpl profile = profileManager.getProfile(profileName);
if (!profile.areDownloadsInitialized()) {
profile.addDownloadNotificationIntent(intent);
} else {
handleIntent(intent);
}
}
public static void handleIntent(Intent intent) {
int id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); int id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
DownloadImpl download = sMap.get(id); DownloadImpl download = sMap.get(id);
if (download == null) { if (download == null) {
...@@ -131,14 +146,20 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -131,14 +146,20 @@ public final class DownloadImpl extends IDownload.Stub {
return nextId; return nextId;
} }
public DownloadImpl(IDownloadCallbackClient client, long nativeDownloadImpl, int id) { public DownloadImpl(
String profileName, IDownloadCallbackClient client, long nativeDownloadImpl, int id) {
mProfileName = profileName;
mClient = client; mClient = client;
mNativeDownloadImpl = nativeDownloadImpl; mNativeDownloadImpl = nativeDownloadImpl;
mNotificationId = id; mNotificationId = id;
try { if (mClient == null) {
mClientDownload = client.createClientDownload(this); mClientDownload = null;
} catch (RemoteException e) { } else {
throw new APICallException(e); try {
mClientDownload = mClient.createClientDownload(this);
} catch (RemoteException e) {
throw new APICallException(e);
}
} }
DownloadImplJni.get().setJavaDownload(mNativeDownloadImpl, DownloadImpl.this); DownloadImplJni.get().setJavaDownload(mNativeDownloadImpl, DownloadImpl.this);
} }
...@@ -305,6 +326,7 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -305,6 +326,7 @@ public final class DownloadImpl extends IDownload.Stub {
Intent deleteIntent = createIntent(); Intent deleteIntent = createIntent();
deleteIntent.setAction(DELETE_INTENT); deleteIntent.setAction(DELETE_INTENT);
deleteIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); deleteIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId);
deleteIntent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName);
PendingIntent deletePendingIntent = PendingIntent.getBroadcast( PendingIntent deletePendingIntent = PendingIntent.getBroadcast(
ContextUtils.getApplicationContext(), mNotificationId, deleteIntent, 0); ContextUtils.getApplicationContext(), mNotificationId, deleteIntent, 0);
...@@ -383,6 +405,7 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -383,6 +405,7 @@ public final class DownloadImpl extends IDownload.Stub {
Intent openIntent = createIntent(); Intent openIntent = createIntent();
openIntent.setAction(OPEN_INTENT); openIntent.setAction(OPEN_INTENT);
openIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); openIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId);
openIntent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName);
openIntent.putExtra(EXTRA_NOTIFICATION_LOCATION, getLocation()); openIntent.putExtra(EXTRA_NOTIFICATION_LOCATION, getLocation());
openIntent.putExtra(EXTRA_NOTIFICATION_MIME_TYPE, getMimeType()); openIntent.putExtra(EXTRA_NOTIFICATION_MIME_TYPE, getMimeType());
PendingIntent openPendingIntent = PendingIntent.getBroadcast( PendingIntent openPendingIntent = PendingIntent.getBroadcast(
...@@ -402,6 +425,7 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -402,6 +425,7 @@ public final class DownloadImpl extends IDownload.Stub {
Intent pauseIntent = createIntent(); Intent pauseIntent = createIntent();
pauseIntent.setAction(PAUSE_INTENT); pauseIntent.setAction(PAUSE_INTENT);
pauseIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); pauseIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId);
pauseIntent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName);
PendingIntent pausePendingIntent = PendingIntent.getBroadcast( PendingIntent pausePendingIntent = PendingIntent.getBroadcast(
ContextUtils.getApplicationContext(), mNotificationId, pauseIntent, 0); ContextUtils.getApplicationContext(), mNotificationId, pauseIntent, 0);
mBuilder.addAction(0 /* no icon */, "Pause", pausePendingIntent) mBuilder.addAction(0 /* no icon */, "Pause", pausePendingIntent)
...@@ -410,6 +434,7 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -410,6 +434,7 @@ public final class DownloadImpl extends IDownload.Stub {
Intent resumeIntent = createIntent(); Intent resumeIntent = createIntent();
resumeIntent.setAction(RESUME_INTENT); resumeIntent.setAction(RESUME_INTENT);
resumeIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); resumeIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId);
resumeIntent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName);
PendingIntent resumePendingIntent = PendingIntent.getBroadcast( PendingIntent resumePendingIntent = PendingIntent.getBroadcast(
ContextUtils.getApplicationContext(), mNotificationId, resumeIntent, 0); ContextUtils.getApplicationContext(), mNotificationId, resumeIntent, 0);
mBuilder.addAction(0 /* no icon */, "Resume", resumePendingIntent) mBuilder.addAction(0 /* no icon */, "Resume", resumePendingIntent)
...@@ -420,6 +445,7 @@ public final class DownloadImpl extends IDownload.Stub { ...@@ -420,6 +445,7 @@ public final class DownloadImpl extends IDownload.Stub {
Intent cancelIntent = createIntent(); Intent cancelIntent = createIntent();
cancelIntent.setAction(CANCEL_INTENT); cancelIntent.setAction(CANCEL_INTENT);
cancelIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); cancelIntent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId);
cancelIntent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast( PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(
ContextUtils.getApplicationContext(), mNotificationId, cancelIntent, 0); ContextUtils.getApplicationContext(), mNotificationId, cancelIntent, 0);
mBuilder.addAction(0 /* no icon */, "Cancel", cancelPendingIntent); mBuilder.addAction(0 /* no icon */, "Cancel", cancelPendingIntent);
......
...@@ -4,12 +4,14 @@ ...@@ -4,12 +4,14 @@
package org.chromium.weblayer_private; package org.chromium.weblayer_private;
import android.content.Intent;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.CollectionUtil; import org.chromium.base.CollectionUtil;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.weblayer_private.interfaces.BrowsingDataType; import org.chromium.weblayer_private.interfaces.BrowsingDataType;
...@@ -33,7 +35,9 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -33,7 +35,9 @@ public final class ProfileImpl extends IProfile.Stub {
private CookieManagerImpl mCookieManager; private CookieManagerImpl mCookieManager;
private Runnable mOnDestroyCallback; private Runnable mOnDestroyCallback;
private boolean mBeingDeleted; private boolean mBeingDeleted;
private boolean mDownloadsInitialized;
private DownloadCallbackProxy mDownloadCallbackProxy; private DownloadCallbackProxy mDownloadCallbackProxy;
private List<Intent> mDownloadNotificationIntents = new ArrayList<>();
public static void enumerateAllProfileNames(ValueCallback<String[]> callback) { public static void enumerateAllProfileNames(ValueCallback<String[]> callback) {
final Callback<String[]> baseCallback = (String[] names) -> callback.onReceiveValue(names); final Callback<String[]> baseCallback = (String[] names) -> callback.onReceiveValue(names);
...@@ -45,10 +49,11 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -45,10 +49,11 @@ public final class ProfileImpl extends IProfile.Stub {
throw new IllegalArgumentException("Name can only contain words: " + name); throw new IllegalArgumentException("Name can only contain words: " + name);
} }
mName = name; mName = name;
mNativeProfile = ProfileImplJni.get().createProfile(name); mNativeProfile = ProfileImplJni.get().createProfile(name, ProfileImpl.this);
mCookieManager = mCookieManager =
new CookieManagerImpl(ProfileImplJni.get().getCookieManager(mNativeProfile)); new CookieManagerImpl(ProfileImplJni.get().getCookieManager(mNativeProfile));
mOnDestroyCallback = onDestroyCallback; mOnDestroyCallback = onDestroyCallback;
mDownloadCallbackProxy = new DownloadCallbackProxy(mName, mNativeProfile);
} }
@Override @Override
...@@ -108,6 +113,15 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -108,6 +113,15 @@ public final class ProfileImpl extends IProfile.Stub {
return mName.isEmpty(); return mName.isEmpty();
} }
public boolean areDownloadsInitialized() {
return mDownloadsInitialized;
}
public void addDownloadNotificationIntent(Intent intent) {
mDownloadNotificationIntents.add(intent);
ProfileImplJni.get().ensureBrowserContextInitialized(mNativeProfile);
}
@Override @Override
public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes, long fromMillis, public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes, long fromMillis,
long toMillis, @NonNull IObjectWrapper completionCallback) { long toMillis, @NonNull IObjectWrapper completionCallback) {
...@@ -127,17 +141,7 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -127,17 +141,7 @@ public final class ProfileImpl extends IProfile.Stub {
@Override @Override
public void setDownloadCallbackClient(IDownloadCallbackClient client) { public void setDownloadCallbackClient(IDownloadCallbackClient client) {
StrictModeWorkaround.apply(); mDownloadCallbackProxy.setClient(client);
if (client != null) {
if (mDownloadCallbackProxy == null) {
mDownloadCallbackProxy = new DownloadCallbackProxy(mNativeProfile, client);
} else {
mDownloadCallbackProxy.setClient(client);
}
} else if (mDownloadCallbackProxy != null) {
mDownloadCallbackProxy.destroy();
mDownloadCallbackProxy = null;
}
} }
@Override @Override
...@@ -176,15 +180,26 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -176,15 +180,26 @@ public final class ProfileImpl extends IProfile.Stub {
return mNativeProfile; return mNativeProfile;
} }
@CalledByNative
public void downloadsInitialized() {
mDownloadsInitialized = true;
for (Intent intent : mDownloadNotificationIntents) {
DownloadImpl.handleIntent(intent);
}
mDownloadNotificationIntents.clear();
}
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void enumerateAllProfileNames(Callback<String[]> callback); void enumerateAllProfileNames(Callback<String[]> callback);
long createProfile(String name); long createProfile(String name, ProfileImpl caller);
void deleteProfile(long profile); void deleteProfile(long profile);
boolean deleteDataFromDisk(long nativeProfileImpl, Runnable completionCallback); boolean deleteDataFromDisk(long nativeProfileImpl, Runnable completionCallback);
void clearBrowsingData(long nativeProfileImpl, @ImplBrowsingDataType int[] dataTypes, void clearBrowsingData(long nativeProfileImpl, @ImplBrowsingDataType int[] dataTypes,
long fromMillis, long toMillis, Runnable callback); long fromMillis, long toMillis, Runnable callback);
void setDownloadDirectory(long nativeProfileImpl, String directory); void setDownloadDirectory(long nativeProfileImpl, String directory);
long getCookieManager(long nativeProfileImpl); long getCookieManager(long nativeProfileImpl);
void ensureBrowserContextInitialized(long nativeProfileImpl);
} }
} }
...@@ -308,7 +308,7 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -308,7 +308,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
public void onReceivedDownloadNotification(IObjectWrapper appContextWrapper, Intent intent) { public void onReceivedDownloadNotification(IObjectWrapper appContextWrapper, Intent intent) {
StrictModeWorkaround.apply(); StrictModeWorkaround.apply();
Context context = ObjectWrapper.unwrap(appContextWrapper, Context.class); Context context = ObjectWrapper.unwrap(appContextWrapper, Context.class);
DownloadImpl.forwardIntent(context, intent); DownloadImpl.forwardIntent(context, intent, mProfileManager);
} }
@Override @Override
......
...@@ -222,6 +222,13 @@ content::BrowserContext* ProfileImpl::GetBrowserContext() { ...@@ -222,6 +222,13 @@ content::BrowserContext* ProfileImpl::GetBrowserContext() {
return browser_context_.get(); return browser_context_.get();
} }
void ProfileImpl::DownloadsInitialized() {
#if defined(OS_ANDROID)
return Java_ProfileImpl_downloadsInitialized(
base::android::AttachCurrentThread(), java_profile_);
#endif
}
bool ProfileImpl::DeleteDataFromDisk(base::OnceClosure done_callback) { bool ProfileImpl::DeleteDataFromDisk(base::OnceClosure done_callback) {
if (num_browser_impl_ > 0) if (num_browser_impl_ > 0)
return false; return false;
...@@ -309,14 +316,19 @@ std::unique_ptr<Profile> Profile::Create(const std::string& name) { ...@@ -309,14 +316,19 @@ std::unique_ptr<Profile> Profile::Create(const std::string& name) {
} }
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
ProfileImpl::ProfileImpl(JNIEnv* env, ProfileImpl::ProfileImpl(
const base::android::JavaParamRef<jstring>& name) JNIEnv* env,
: ProfileImpl(ConvertJavaStringToUTF8(env, name)) {} const base::android::JavaParamRef<jstring>& name,
const base::android::JavaParamRef<jobject>& java_profile)
: ProfileImpl(ConvertJavaStringToUTF8(env, name)) {
java_profile_ = java_profile;
}
static jlong JNI_ProfileImpl_CreateProfile( static jlong JNI_ProfileImpl_CreateProfile(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jstring>& name) { const base::android::JavaParamRef<jstring>& name,
return reinterpret_cast<jlong>(new ProfileImpl(env, name)); const base::android::JavaParamRef<jobject>& java_profile) {
return reinterpret_cast<jlong>(new ProfileImpl(env, name, java_profile));
} }
static void JNI_ProfileImpl_DeleteProfile(JNIEnv* env, jlong profile) { static void JNI_ProfileImpl_DeleteProfile(JNIEnv* env, jlong profile) {
...@@ -377,6 +389,9 @@ jlong ProfileImpl::GetCookieManager(JNIEnv* env) { ...@@ -377,6 +389,9 @@ jlong ProfileImpl::GetCookieManager(JNIEnv* env) {
return reinterpret_cast<jlong>(GetCookieManager()); return reinterpret_cast<jlong>(GetCookieManager());
} }
void ProfileImpl::EnsureBrowserContextInitialized(JNIEnv* env) {
content::BrowserContext::GetDownloadManager(GetBrowserContext());
}
#endif // OS_ANDROID #endif // OS_ANDROID
void ProfileImpl::IncrementBrowserImplCount() { void ProfileImpl::IncrementBrowserImplCount() {
......
...@@ -43,6 +43,11 @@ class ProfileImpl : public Profile { ...@@ -43,6 +43,11 @@ class ProfileImpl : public Profile {
content::BrowserContext* GetBrowserContext(); content::BrowserContext* GetBrowserContext();
// Called when the download subsystem has finished initializing. By this point
// information about downloads that were interrupted by a previous crash would
// be available.
void DownloadsInitialized();
// Path data is stored at, empty if off-the-record. // Path data is stored at, empty if off-the-record.
const base::FilePath& data_path() const { return data_path_; } const base::FilePath& data_path() const { return data_path_; }
DownloadDelegate* download_delegate() { return download_delegate_; } DownloadDelegate* download_delegate() { return download_delegate_; }
...@@ -58,7 +63,9 @@ class ProfileImpl : public Profile { ...@@ -58,7 +63,9 @@ class ProfileImpl : public Profile {
CookieManager* GetCookieManager() override; CookieManager* GetCookieManager() override;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
ProfileImpl(JNIEnv* env, const base::android::JavaParamRef<jstring>& path); ProfileImpl(JNIEnv* env,
const base::android::JavaParamRef<jstring>& path,
const base::android::JavaParamRef<jobject>& java_profile);
jboolean DeleteDataFromDisk( jboolean DeleteDataFromDisk(
JNIEnv* env, JNIEnv* env,
...@@ -73,6 +80,7 @@ class ProfileImpl : public Profile { ...@@ -73,6 +80,7 @@ class ProfileImpl : public Profile {
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jstring>& directory); const base::android::JavaParamRef<jstring>& directory);
jlong GetCookieManager(JNIEnv* env); jlong GetCookieManager(JNIEnv* env);
void EnsureBrowserContextInitialized(JNIEnv* env);
#endif #endif
void IncrementBrowserImplCount(); void IncrementBrowserImplCount();
...@@ -107,6 +115,10 @@ class ProfileImpl : public Profile { ...@@ -107,6 +115,10 @@ class ProfileImpl : public Profile {
size_t num_browser_impl_ = 0u; size_t num_browser_impl_ = 0u;
#if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> java_profile_;
#endif
DISALLOW_COPY_AND_ASSIGN(ProfileImpl); DISALLOW_COPY_AND_ASSIGN(ProfileImpl);
}; };
......
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