Commit db1404ea authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

WebLayer: allow client to handle downloads.

As with WebView, the client is responsible for handling download
requests. The Android shell client simply uses Android's
DownloadManager.

Bug: none
Change-Id: I0204a2101f675c35682f0c75cbe34a506c7b5e2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1862121
Commit-Queue: Evan Stade <estade@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707177}
parent d47ac152
...@@ -60,6 +60,7 @@ jumbo_static_library("weblayer_lib") { ...@@ -60,6 +60,7 @@ jumbo_static_library("weblayer_lib") {
"common/content_client_impl.h", "common/content_client_impl.h",
"public/browser_controller.h", "public/browser_controller.h",
"public/browser_observer.h", "public/browser_observer.h",
"public/download_delegate.h",
"public/fullscreen_delegate.h", "public/fullscreen_delegate.h",
"public/main.h", "public/main.h",
"public/navigation.h", "public/navigation.h",
...@@ -154,6 +155,8 @@ jumbo_static_library("weblayer_lib") { ...@@ -154,6 +155,8 @@ jumbo_static_library("weblayer_lib") {
"browser/browser_observer_proxy.h", "browser/browser_observer_proxy.h",
"browser/content_view_render_view.cc", "browser/content_view_render_view.cc",
"browser/content_view_render_view.h", "browser/content_view_render_view.h",
"browser/download_delegate_proxy.cc",
"browser/download_delegate_proxy.h",
"browser/fullscreen_delegate_proxy.cc", "browser/fullscreen_delegate_proxy.cc",
"browser/fullscreen_delegate_proxy.h", "browser/fullscreen_delegate_proxy.h",
"browser/top_controls_container_view.cc", "browser/top_controls_container_view.cc",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "weblayer/browser/navigation_controller_impl.h" #include "weblayer/browser/navigation_controller_impl.h"
#include "weblayer/browser/profile_impl.h" #include "weblayer/browser/profile_impl.h"
#include "weblayer/public/browser_observer.h" #include "weblayer/public/browser_observer.h"
#include "weblayer/public/download_delegate.h"
#include "weblayer/public/fullscreen_delegate.h" #include "weblayer/public/fullscreen_delegate.h"
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
...@@ -75,6 +76,10 @@ BrowserControllerImpl* BrowserControllerImpl::FromWebContents( ...@@ -75,6 +76,10 @@ BrowserControllerImpl* BrowserControllerImpl::FromWebContents(
->controller; ->controller;
} }
void BrowserControllerImpl::SetDownloadDelegate(DownloadDelegate* delegate) {
download_delegate_ = delegate;
}
void BrowserControllerImpl::SetFullscreenDelegate( void BrowserControllerImpl::SetFullscreenDelegate(
FullscreenDelegate* delegate) { FullscreenDelegate* delegate) {
if (delegate == fullscreen_delegate_) if (delegate == fullscreen_delegate_)
......
...@@ -56,10 +56,12 @@ class BrowserControllerImpl : public BrowserController, ...@@ -56,10 +56,12 @@ class BrowserControllerImpl : public BrowserController,
jlong native_top_controls_container_view); jlong native_top_controls_container_view);
#endif #endif
DownloadDelegate* download_delegate() { return download_delegate_; }
FullscreenDelegate* fullscreen_delegate() { return fullscreen_delegate_; } FullscreenDelegate* fullscreen_delegate() { return fullscreen_delegate_; }
private: private:
// BrowserController implementation: // BrowserController:
void SetDownloadDelegate(DownloadDelegate* delegate) override;
void SetFullscreenDelegate(FullscreenDelegate* delegate) override; void SetFullscreenDelegate(FullscreenDelegate* delegate) override;
void AddObserver(BrowserObserver* observer) override; void AddObserver(BrowserObserver* observer) override;
void RemoveObserver(BrowserObserver* observer) override; void RemoveObserver(BrowserObserver* observer) override;
...@@ -68,7 +70,7 @@ class BrowserControllerImpl : public BrowserController, ...@@ -68,7 +70,7 @@ class BrowserControllerImpl : public BrowserController,
void AttachToView(views::WebView* web_view) override; void AttachToView(views::WebView* web_view) override;
#endif #endif
// content::WebContentsDelegate implementation: // content::WebContentsDelegate:
void LoadingStateChanged(content::WebContents* source, void LoadingStateChanged(content::WebContents* source,
bool to_different_document) override; bool to_different_document) override;
void LoadProgressChanged(content::WebContents* source, void LoadProgressChanged(content::WebContents* source,
...@@ -89,7 +91,7 @@ class BrowserControllerImpl : public BrowserController, ...@@ -89,7 +91,7 @@ class BrowserControllerImpl : public BrowserController,
blink::mojom::DisplayMode GetDisplayMode( blink::mojom::DisplayMode GetDisplayMode(
const content::WebContents* web_contents) override; const content::WebContents* web_contents) override;
// content::WebContentsObserver implementation: // content::WebContentsObserver:
void DidFirstVisuallyNonEmptyPaint() override; void DidFirstVisuallyNonEmptyPaint() override;
void DidFinishNavigation( void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override; content::NavigationHandle* navigation_handle) override;
...@@ -97,6 +99,7 @@ class BrowserControllerImpl : public BrowserController, ...@@ -97,6 +99,7 @@ class BrowserControllerImpl : public BrowserController,
// Called from closure supplied to delegate to exit fullscreen. // Called from closure supplied to delegate to exit fullscreen.
void OnExitFullscreen(); void OnExitFullscreen();
DownloadDelegate* download_delegate_ = nullptr;
FullscreenDelegate* fullscreen_delegate_ = nullptr; FullscreenDelegate* fullscreen_delegate_ = nullptr;
ProfileImpl* profile_; ProfileImpl* profile_;
std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<content::WebContents> web_contents_;
......
// Copyright 2019 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.
#include "weblayer/browser/download_delegate_proxy.h"
#include "base/android/jni_string.h"
#include "url/gurl.h"
#include "weblayer/browser/browser_controller_impl.h"
#include "weblayer/browser/java/jni/DownloadDelegateProxy_jni.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaLocalRef;
namespace weblayer {
DownloadDelegateProxy::DownloadDelegateProxy(
JNIEnv* env,
jobject obj,
BrowserController* browser_controller)
: browser_controller_(browser_controller), java_delegate_(env, obj) {
browser_controller_->SetDownloadDelegate(this);
}
DownloadDelegateProxy::~DownloadDelegateProxy() {
browser_controller_->SetDownloadDelegate(nullptr);
}
void DownloadDelegateProxy::DownloadRequested(
const GURL& url,
const std::string& user_agent,
const std::string& content_disposition,
const std::string& mime_type,
int64_t content_length) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> jstring_url(
ConvertUTF8ToJavaString(env, url.spec()));
ScopedJavaLocalRef<jstring> jstring_user_agent(
ConvertUTF8ToJavaString(env, user_agent));
ScopedJavaLocalRef<jstring> jstring_content_disposition(
ConvertUTF8ToJavaString(env, content_disposition));
ScopedJavaLocalRef<jstring> jstring_mime_type(
ConvertUTF8ToJavaString(env, mime_type));
Java_DownloadDelegateProxy_downloadRequested(
env, java_delegate_, jstring_url, jstring_user_agent,
jstring_content_disposition, jstring_mime_type, content_length);
}
static jlong JNI_DownloadDelegateProxy_CreateDownloadDelegateProxy(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& proxy,
jlong browser_controller) {
return reinterpret_cast<jlong>(new DownloadDelegateProxy(
env, proxy,
reinterpret_cast<BrowserControllerImpl*>(browser_controller)));
}
static void JNI_DownloadDelegateProxy_DeleteDownloadDelegateProxy(JNIEnv* env,
jlong proxy) {
delete reinterpret_cast<DownloadDelegateProxy*>(proxy);
}
} // namespace weblayer
// Copyright 2019 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.
#ifndef WEBLAYER_BROWSER_DOWNLOAD_DELEGATE_PROXY_H_
#define WEBLAYER_BROWSER_DOWNLOAD_DELEGATE_PROXY_H_
#include <jni.h>
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/macros.h"
#include "weblayer/public/download_delegate.h"
namespace weblayer {
class BrowserController;
// Forwards DownloadDelegate calls to the java-side DownloadDelegateProxy.
class DownloadDelegateProxy : public DownloadDelegate {
public:
DownloadDelegateProxy(JNIEnv* env,
jobject obj,
BrowserController* browser_controller);
~DownloadDelegateProxy() override;
// DownloadDelegate:
void DownloadRequested(const GURL& url,
const std::string& user_agent,
const std::string& content_disposition,
const std::string& mime_type,
int64_t content_length) override;
private:
BrowserController* browser_controller_;
base::android::ScopedJavaGlobalRef<jobject> java_delegate_;
DISALLOW_COPY_AND_ASSIGN(DownloadDelegateProxy);
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_DOWNLOAD_DELEGATE_PROXY_H_
...@@ -23,6 +23,7 @@ android_library("java") { ...@@ -23,6 +23,7 @@ android_library("java") {
"org/chromium/weblayer_private/BrowserObserverProxy.java", "org/chromium/weblayer_private/BrowserObserverProxy.java",
"org/chromium/weblayer_private/ContentView.java", "org/chromium/weblayer_private/ContentView.java",
"org/chromium/weblayer_private/ContentViewRenderView.java", "org/chromium/weblayer_private/ContentViewRenderView.java",
"org/chromium/weblayer_private/DownloadDelegateProxy.java",
"org/chromium/weblayer_private/FullscreenDelegateProxy.java", "org/chromium/weblayer_private/FullscreenDelegateProxy.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java", "org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java", "org/chromium/weblayer_private/NavigationImpl.java",
...@@ -52,6 +53,7 @@ generate_jni("jni") { ...@@ -52,6 +53,7 @@ generate_jni("jni") {
"org/chromium/weblayer_private/BrowserControllerImpl.java", "org/chromium/weblayer_private/BrowserControllerImpl.java",
"org/chromium/weblayer_private/BrowserObserverProxy.java", "org/chromium/weblayer_private/BrowserObserverProxy.java",
"org/chromium/weblayer_private/ContentViewRenderView.java", "org/chromium/weblayer_private/ContentViewRenderView.java",
"org/chromium/weblayer_private/DownloadDelegateProxy.java",
"org/chromium/weblayer_private/FullscreenDelegateProxy.java", "org/chromium/weblayer_private/FullscreenDelegateProxy.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java", "org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java", "org/chromium/weblayer_private/NavigationImpl.java",
...@@ -80,6 +82,7 @@ android_aidl("aidl") { ...@@ -80,6 +82,7 @@ android_aidl("aidl") {
"org/chromium/weblayer_private/aidl/IBrowserFragmentController.aidl", "org/chromium/weblayer_private/aidl/IBrowserFragmentController.aidl",
"org/chromium/weblayer_private/aidl/IChildProcessService.aidl", "org/chromium/weblayer_private/aidl/IChildProcessService.aidl",
"org/chromium/weblayer_private/aidl/IClientNavigation.aidl", "org/chromium/weblayer_private/aidl/IClientNavigation.aidl",
"org/chromium/weblayer_private/aidl/IDownloadDelegateClient.aidl",
"org/chromium/weblayer_private/aidl/IFullscreenDelegateClient.aidl", "org/chromium/weblayer_private/aidl/IFullscreenDelegateClient.aidl",
"org/chromium/weblayer_private/aidl/INavigation.aidl", "org/chromium/weblayer_private/aidl/INavigation.aidl",
"org/chromium/weblayer_private/aidl/INavigationController.aidl", "org/chromium/weblayer_private/aidl/INavigationController.aidl",
......
...@@ -21,6 +21,7 @@ import org.chromium.ui.base.ActivityWindowAndroid; ...@@ -21,6 +21,7 @@ import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.weblayer_private.aidl.IBrowserController; import org.chromium.weblayer_private.aidl.IBrowserController;
import org.chromium.weblayer_private.aidl.IBrowserControllerClient; import org.chromium.weblayer_private.aidl.IBrowserControllerClient;
import org.chromium.weblayer_private.aidl.IDownloadDelegateClient;
import org.chromium.weblayer_private.aidl.IFullscreenDelegateClient; import org.chromium.weblayer_private.aidl.IFullscreenDelegateClient;
import org.chromium.weblayer_private.aidl.INavigationControllerClient; import org.chromium.weblayer_private.aidl.INavigationControllerClient;
import org.chromium.weblayer_private.aidl.IObjectWrapper; import org.chromium.weblayer_private.aidl.IObjectWrapper;
...@@ -43,6 +44,7 @@ public final class BrowserControllerImpl extends IBrowserController.Stub { ...@@ -43,6 +44,7 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
private WebContents mWebContents; private WebContents mWebContents;
private BrowserObserverProxy mBrowserObserverProxy; private BrowserObserverProxy mBrowserObserverProxy;
private NavigationControllerImpl mNavigationController; private NavigationControllerImpl mNavigationController;
private DownloadDelegateProxy mDownloadDelegateProxy;
private FullscreenDelegateProxy mFullscreenDelegateProxy; private FullscreenDelegateProxy mFullscreenDelegateProxy;
private static class InternalAccessDelegateImpl private static class InternalAccessDelegateImpl
...@@ -129,6 +131,21 @@ public final class BrowserControllerImpl extends IBrowserController.Stub { ...@@ -129,6 +131,21 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
mBrowserObserverProxy = new BrowserObserverProxy(mNativeBrowserController, client); mBrowserObserverProxy = new BrowserObserverProxy(mNativeBrowserController, client);
} }
@Override
public void setDownloadDelegateClient(IDownloadDelegateClient client) {
if (client != null) {
if (mDownloadDelegateProxy == null) {
mDownloadDelegateProxy =
new DownloadDelegateProxy(mNativeBrowserController, client);
} else {
mDownloadDelegateProxy.setClient(client);
}
} else if (mDownloadDelegateProxy != null) {
mDownloadDelegateProxy.destroy();
mDownloadDelegateProxy = null;
}
}
@Override @Override
public void setFullscreenDelegateClient(IFullscreenDelegateClient client) { public void setFullscreenDelegateClient(IFullscreenDelegateClient client) {
if (client != null) { if (client != null) {
...@@ -153,6 +170,10 @@ public final class BrowserControllerImpl extends IBrowserController.Stub { ...@@ -153,6 +170,10 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
mBrowserObserverProxy.destroy(); mBrowserObserverProxy.destroy();
mBrowserObserverProxy = null; mBrowserObserverProxy = null;
} }
if (mDownloadDelegateProxy != null) {
mDownloadDelegateProxy.destroy();
mDownloadDelegateProxy = null;
}
if (mFullscreenDelegateProxy != null) { if (mFullscreenDelegateProxy != null) {
mFullscreenDelegateProxy.destroy(); mFullscreenDelegateProxy.destroy();
mFullscreenDelegateProxy = null; mFullscreenDelegateProxy = null;
......
// Copyright 2019 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.weblayer_private;
import android.os.RemoteException;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.weblayer_private.aidl.APICallException;
import org.chromium.weblayer_private.aidl.IDownloadDelegateClient;
/**
* Owns the c++ DownloadDelegateProxy class, which is responsible for forwarding all
* DownloadDelegate delegate calls to this class, which in turn forwards to the
* DownloadDelegateClient.
*/
@JNINamespace("weblayer")
public final class DownloadDelegateProxy {
private long mNativeDownloadDelegateProxy;
private IDownloadDelegateClient mClient;
DownloadDelegateProxy(long browserController, IDownloadDelegateClient client) {
assert client != null;
mClient = client;
mNativeDownloadDelegateProxy =
DownloadDelegateProxyJni.get().createDownloadDelegateProxy(this, browserController);
}
public void setClient(IDownloadDelegateClient client) {
assert client != null;
mClient = client;
}
public void destroy() {
DownloadDelegateProxyJni.get().deleteDownloadDelegateProxy(mNativeDownloadDelegateProxy);
mNativeDownloadDelegateProxy = 0;
}
@CalledByNative
private void downloadRequested(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength) {
try {
mClient.downloadRequested(url, userAgent, contentDisposition, mimetype, contentLength);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
@NativeMethods
interface Natives {
long createDownloadDelegateProxy(DownloadDelegateProxy proxy, long browserController);
void deleteDownloadDelegateProxy(long proxy);
}
}
...@@ -14,5 +14,7 @@ interface IBrowserController { ...@@ -14,5 +14,7 @@ interface IBrowserController {
INavigationController createNavigationController(in INavigationControllerClient client) = 1; INavigationController createNavigationController(in INavigationControllerClient client) = 1;
void setFullscreenDelegateClient(in IFullscreenDelegateClient client) = 2; void setDownloadDelegateClient(IDownloadDelegateClient client) = 2;
void setFullscreenDelegateClient(in IFullscreenDelegateClient client) = 3;
} }
// Copyright 2019 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.weblayer_private.aidl;
/**
* Used to forward download requests to the client.
*/
interface IDownloadDelegateClient {
void downloadRequested(in String url, in String userAgent, in String contentDisposition, in String mimetype, long contentLength) = 0;
}
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/resource_context.h" #include "content/public/browser/resource_context.h"
#include "weblayer/browser/browser_controller_impl.h"
#include "weblayer/public/download_delegate.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
...@@ -26,6 +29,38 @@ class ResourceContextImpl : public content::ResourceContext { ...@@ -26,6 +29,38 @@ class ResourceContextImpl : public content::ResourceContext {
DISALLOW_COPY_AND_ASSIGN(ResourceContextImpl); DISALLOW_COPY_AND_ASSIGN(ResourceContextImpl);
}; };
class DownloadManagerDelegateImpl : public content::DownloadManagerDelegate {
public:
DownloadManagerDelegateImpl() = default;
~DownloadManagerDelegateImpl() override = default;
bool InterceptDownloadIfApplicable(
const GURL& url,
const std::string& user_agent,
const std::string& content_disposition,
const std::string& mime_type,
const std::string& request_origin,
int64_t content_length,
bool is_transient,
content::WebContents* web_contents) override {
// If there's no DownloadDelegate, the download is simply dropped.
auto* browser = BrowserControllerImpl::FromWebContents(web_contents);
if (!browser)
return true;
DownloadDelegate* delegate = browser->download_delegate();
if (!delegate)
return true;
delegate->DownloadRequested(url, user_agent, content_disposition, mime_type,
content_length);
return true;
}
private:
DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateImpl);
};
} // namespace } // namespace
class ProfileImpl::BrowserContextImpl : public content::BrowserContext { class ProfileImpl::BrowserContextImpl : public content::BrowserContext {
...@@ -50,7 +85,7 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext { ...@@ -50,7 +85,7 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext {
bool IsOffTheRecord() override { return path_.empty(); } bool IsOffTheRecord() override { return path_.empty(); }
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override { content::DownloadManagerDelegate* GetDownloadManagerDelegate() override {
return nullptr; return &download_delegate_;
} }
content::ResourceContext* GetResourceContext() override { content::ResourceContext* GetResourceContext() override {
...@@ -108,6 +143,7 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext { ...@@ -108,6 +143,7 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext {
private: private:
base::FilePath path_; base::FilePath path_;
std::unique_ptr<ResourceContextImpl> resource_context_; std::unique_ptr<ResourceContextImpl> resource_context_;
DownloadManagerDelegateImpl download_delegate_;
DISALLOW_COPY_AND_ASSIGN(BrowserContextImpl); DISALLOW_COPY_AND_ASSIGN(BrowserContextImpl);
}; };
......
...@@ -17,6 +17,7 @@ class WebView; ...@@ -17,6 +17,7 @@ class WebView;
namespace weblayer { namespace weblayer {
class BrowserObserver; class BrowserObserver;
class DownloadDelegate;
class FullscreenDelegate; class FullscreenDelegate;
class Profile; class Profile;
class NavigationController; class NavigationController;
...@@ -32,6 +33,9 @@ class BrowserController { ...@@ -32,6 +33,9 @@ class BrowserController {
virtual ~BrowserController() {} virtual ~BrowserController() {}
// Sets the DownloadDelegate. If none is set, downloads will be dropped.
virtual void SetDownloadDelegate(DownloadDelegate* delegate) = 0;
// Sets the FullscreenDelegate. Setting a non-null value implicitly enables // Sets the FullscreenDelegate. Setting a non-null value implicitly enables
// fullscreen. // fullscreen.
virtual void SetFullscreenDelegate(FullscreenDelegate* delegate) = 0; virtual void SetFullscreenDelegate(FullscreenDelegate* delegate) = 0;
......
// Copyright 2019 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.
#ifndef WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_
#define WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_
#include <string>
class GURL;
namespace weblayer {
// An interface that allows clients to handle download requests originating in
// the browser.
class DownloadDelegate {
public:
// A download of |url| has been requested with the specified details. If
// ignored, the download will be dropped.
virtual void DownloadRequested(const GURL& url,
const std::string& user_agent,
const std::string& content_disposition,
const std::string& mime_type,
int64_t content_length) = 0;
protected:
virtual ~DownloadDelegate() {}
};
} // namespace weblayer
#endif // WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_
...@@ -27,6 +27,7 @@ template("weblayer_java") { ...@@ -27,6 +27,7 @@ template("weblayer_java") {
"org/chromium/weblayer/BrowserFragmentController.java", "org/chromium/weblayer/BrowserFragmentController.java",
"org/chromium/weblayer/BrowserObserver.java", "org/chromium/weblayer/BrowserObserver.java",
"org/chromium/weblayer/Callback.java", "org/chromium/weblayer/Callback.java",
"org/chromium/weblayer/DownloadDelegate.java",
"org/chromium/weblayer/FullscreenDelegate.java", "org/chromium/weblayer/FullscreenDelegate.java",
"org/chromium/weblayer/ListenableFuture.java", "org/chromium/weblayer/ListenableFuture.java",
"org/chromium/weblayer/ListenableResult.java", "org/chromium/weblayer/ListenableResult.java",
......
...@@ -11,6 +11,7 @@ import android.webkit.ValueCallback; ...@@ -11,6 +11,7 @@ import android.webkit.ValueCallback;
import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.APICallException;
import org.chromium.weblayer_private.aidl.IBrowserController; import org.chromium.weblayer_private.aidl.IBrowserController;
import org.chromium.weblayer_private.aidl.IBrowserControllerClient; import org.chromium.weblayer_private.aidl.IBrowserControllerClient;
import org.chromium.weblayer_private.aidl.IDownloadDelegateClient;
import org.chromium.weblayer_private.aidl.IFullscreenDelegateClient; import org.chromium.weblayer_private.aidl.IFullscreenDelegateClient;
import org.chromium.weblayer_private.aidl.IObjectWrapper; import org.chromium.weblayer_private.aidl.IObjectWrapper;
import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper;
...@@ -20,6 +21,7 @@ public final class BrowserController { ...@@ -20,6 +21,7 @@ public final class BrowserController {
private FullscreenDelegateClientImpl mFullscreenDelegateClient; private FullscreenDelegateClientImpl mFullscreenDelegateClient;
private final NavigationController mNavigationController; private final NavigationController mNavigationController;
private final ObserverList<BrowserObserver> mObservers; private final ObserverList<BrowserObserver> mObservers;
private DownloadDelegateClientImpl mDownloadDelegateClient;
BrowserController(IBrowserController impl) { BrowserController(IBrowserController impl) {
mImpl = impl; mImpl = impl;
...@@ -33,6 +35,20 @@ public final class BrowserController { ...@@ -33,6 +35,20 @@ public final class BrowserController {
mNavigationController = NavigationController.create(mImpl); mNavigationController = NavigationController.create(mImpl);
} }
public void setDownloadDelegate(DownloadDelegate delegate) {
try {
if (delegate != null) {
mDownloadDelegateClient = new DownloadDelegateClientImpl(delegate);
mImpl.setDownloadDelegateClient(mDownloadDelegateClient);
} else {
mDownloadDelegateClient = null;
mImpl.setDownloadDelegateClient(null);
}
} catch (RemoteException e) {
throw new APICallException(e);
}
}
public void setFullscreenDelegate(FullscreenDelegate delegate) { public void setFullscreenDelegate(FullscreenDelegate delegate) {
try { try {
if (delegate != null) { if (delegate != null) {
...@@ -46,6 +62,10 @@ public final class BrowserController { ...@@ -46,6 +62,10 @@ public final class BrowserController {
} }
} }
public DownloadDelegate getDownloadDelegate() {
return mDownloadDelegateClient != null ? mDownloadDelegateClient.getDelegate() : null;
}
public FullscreenDelegate getFullscreenDelegate() { public FullscreenDelegate getFullscreenDelegate() {
return mFullscreenDelegateClient != null ? mFullscreenDelegateClient.getDelegate() : null; return mFullscreenDelegateClient != null ? mFullscreenDelegateClient.getDelegate() : null;
} }
...@@ -95,6 +115,25 @@ public final class BrowserController { ...@@ -95,6 +115,25 @@ public final class BrowserController {
} }
} }
private final class DownloadDelegateClientImpl extends IDownloadDelegateClient.Stub {
private final DownloadDelegate mDelegate;
DownloadDelegateClientImpl(DownloadDelegate delegate) {
mDelegate = delegate;
}
public DownloadDelegate getDelegate() {
return mDelegate;
}
@Override
public void downloadRequested(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength) {
mDelegate.downloadRequested(
url, userAgent, contentDisposition, mimetype, contentLength);
}
}
private final class FullscreenDelegateClientImpl extends IFullscreenDelegateClient.Stub { private final class FullscreenDelegateClientImpl extends IFullscreenDelegateClient.Stub {
private FullscreenDelegate mDelegate; private FullscreenDelegate mDelegate;
......
// Copyright 2019 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.weblayer;
/**
* An interface that allows clients to handle download requests originating in the browser.
*/
public abstract class DownloadDelegate {
/**
* A download of has been requested with the specified details.
*
* @param url the target that should be downloaded
* @param userAgent the user agent to be used for the download
* @param contentDisposition content-disposition http header, if present
* @param mimetype the mimetype of the content reported by the server
* @param contentLength the file size reported by the server
*/
public abstract void downloadRequested(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength);
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.weblayer.shell; package org.chromium.weblayer.shell;
import android.app.DownloadManager;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
...@@ -30,6 +31,7 @@ import org.chromium.weblayer.BrowserController; ...@@ -30,6 +31,7 @@ import org.chromium.weblayer.BrowserController;
import org.chromium.weblayer.BrowserFragment; import org.chromium.weblayer.BrowserFragment;
import org.chromium.weblayer.BrowserFragmentController; import org.chromium.weblayer.BrowserFragmentController;
import org.chromium.weblayer.BrowserObserver; import org.chromium.weblayer.BrowserObserver;
import org.chromium.weblayer.DownloadDelegate;
import org.chromium.weblayer.FullscreenDelegate; import org.chromium.weblayer.FullscreenDelegate;
import org.chromium.weblayer.NavigationController; import org.chromium.weblayer.NavigationController;
import org.chromium.weblayer.Profile; import org.chromium.weblayer.Profile;
...@@ -196,6 +198,16 @@ public class WebLayerShellActivity extends FragmentActivity { ...@@ -196,6 +198,16 @@ public class WebLayerShellActivity extends FragmentActivity {
mLoadProgressBar.setProgress((int) Math.round(100 * progress)); mLoadProgressBar.setProgress((int) Math.round(100 * progress));
} }
}); });
mBrowserController.setDownloadDelegate(new DownloadDelegate() {
@Override
public void downloadRequested(String url, String userAgent, String contentDisposition,
String mimetype, long contentLength) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
getSystemService(DownloadManager.class).enqueue(request);
}
});
} }
private BrowserFragment getOrCreateBrowserFragment(Bundle savedInstanceState) { private BrowserFragment getOrCreateBrowserFragment(Bundle savedInstanceState) {
......
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