Commit 992c4454 authored by David Black's avatar David Black Committed by Commit Bot

Make AssistantWebView compatible w/ single- and multi-process mash.

AssistantWebView is the host for embedding the web contents used by
Assistant Settings and Reminders. Previously, AssistantWebView did
not handle either single- or multi-process mash, so the web contents
would not be embedded.

Now, we use Content Service which works in both single- and multi-
process mash in the same pattern established for AppList in:
https://chromium-review.googlesource.com/c/chromium/src/+/1269622

This required adding a few new abilities to NavigableContents that
Assistant has the need for:
- Adding min/max size for auto resizing.
- Adding ability to navigate backwards in history stack.
- Adding handling for target="_blank" links.

Still TODO: Do the same for the Assistant cards that are embedded in
Assistant's UiElementContainerView. Once this is complete, we will be
able to remove WebContentsManager and associated classes/logic :)

Bug: b:78078693
Change-Id: I4dd19a0a4c9506fc6b7f065d54fc1a75132d278f
Reviewed-on: https://chromium-review.googlesource.com/c/1313745
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#606966}
parent 660d336d
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "services/content/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace ash { namespace ash {
...@@ -309,6 +311,28 @@ void AssistantController::OpenUrl(const GURL& url, bool from_server) { ...@@ -309,6 +311,28 @@ void AssistantController::OpenUrl(const GURL& url, bool from_server) {
NotifyUrlOpened(url, from_server); NotifyUrlOpened(url, from_server);
} }
void AssistantController::GetNavigableContentsFactory(
content::mojom::NavigableContentsFactoryRequest request) {
const mojom::UserSession* user_session =
Shell::Get()->session_controller()->GetUserSession(0);
if (!user_session) {
LOG(WARNING) << "Unable to retrieve active user session.";
return;
}
const std::string& service_user_id = user_session->user_info->service_user_id;
if (service_user_id.empty()) {
LOG(ERROR) << "Unable to retrieve service user id.";
return;
}
Shell::Get()->connector()->BindInterface(
service_manager::Identity(content::mojom::kServiceName, service_user_id),
std::move(request));
}
void AssistantController::NotifyConstructed() { void AssistantController::NotifyConstructed() {
for (AssistantControllerObserver& observer : observers_) for (AssistantControllerObserver& observer : observers_)
observer.OnAssistantControllerConstructed(); observer.OnAssistantControllerConstructed();
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/content/public/mojom/navigable_contents_factory.mojom.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
namespace base { namespace base {
...@@ -135,6 +136,11 @@ class ASH_EXPORT AssistantController ...@@ -135,6 +136,11 @@ class ASH_EXPORT AssistantController
// to deep links which may cause deviation from this behavior. // to deep links which may cause deviation from this behavior.
void OpenUrl(const GURL& url, bool from_server = false); void OpenUrl(const GURL& url, bool from_server = false);
// Acquires a NavigableContentsFactory from the Content Service to allow
// Assistant to display embedded web contents.
void GetNavigableContentsFactory(
content::mojom::NavigableContentsFactoryRequest request);
AssistantCacheController* cache_controller() { AssistantCacheController* cache_controller() {
DCHECK(assistant_cache_controller_); DCHECK(assistant_cache_controller_);
return assistant_cache_controller_.get(); return assistant_cache_controller_.get();
......
This diff is collapsed.
...@@ -13,13 +13,10 @@ ...@@ -13,13 +13,10 @@
#include "ash/assistant/ui/caption_bar.h" #include "ash/assistant/ui/caption_bar.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/content/public/cpp/navigable_contents.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/view_observer.h"
namespace base {
class UnguessableToken;
} // namespace base
namespace ash { namespace ash {
...@@ -27,13 +24,13 @@ class AssistantController; ...@@ -27,13 +24,13 @@ class AssistantController;
// AssistantWebView is a child of AssistantBubbleView which allows Assistant UI // AssistantWebView is a child of AssistantBubbleView which allows Assistant UI
// to render remotely hosted content within its bubble. It provides a CaptionBar // to render remotely hosted content within its bubble. It provides a CaptionBar
// for window level controls and a WebView/ServerRemoteViewHost for embedding // for window level controls and embeds web contents with help from the Content
// web contents. // Service.
class AssistantWebView : public views::View, class AssistantWebView : public views::View,
public views::ViewObserver,
public aura::WindowObserver, public aura::WindowObserver,
public AssistantControllerObserver, public AssistantControllerObserver,
public CaptionBarDelegate { public CaptionBarDelegate,
public content::NavigableContentsObserver {
public: public:
explicit AssistantWebView(AssistantController* assistant_controller); explicit AssistantWebView(AssistantController* assistant_controller);
~AssistantWebView() override; ~AssistantWebView() override;
...@@ -44,9 +41,6 @@ class AssistantWebView : public views::View, ...@@ -44,9 +41,6 @@ class AssistantWebView : public views::View,
int GetHeightForWidth(int width) const override; int GetHeightForWidth(int width) const override;
void ChildPreferredSizeChanged(views::View* child) override; void ChildPreferredSizeChanged(views::View* child) override;
// views::ViewObserver:
void OnViewIsDeleting(views::View* view) override;
// views::WindowObserver: // views::WindowObserver:
void OnWindowBoundsChanged(aura::Window* window, void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds, const gfx::Rect& old_bounds,
...@@ -62,32 +56,31 @@ class AssistantWebView : public views::View, ...@@ -62,32 +56,31 @@ class AssistantWebView : public views::View,
assistant::util::DeepLinkType type, assistant::util::DeepLinkType type,
const std::map<std::string, std::string>& params) override; const std::map<std::string, std::string>& params) override;
// content::NavigableContentsObserver:
void DidAutoResizeView(const gfx::Size& new_size) override;
void DidStopLoading() override;
void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) override;
private: private:
void InitLayout(); void InitLayout();
void OnWebContentsReady( void RemoveContents();
const base::Optional<base::UnguessableToken>& embed_token);
void ReleaseWebContents();
AssistantController* const assistant_controller_; // Owned by Shell. AssistantController* const assistant_controller_; // Owned by Shell.
CaptionBar* caption_bar_; // Owned by view hierarchy. CaptionBar* caption_bar_; // Owned by view hierarchy.
// In Mash, |content_view_| is owned by the view hierarchy. Otherwise, the content::mojom::NavigableContentsFactoryPtr contents_factory_;
// view is owned by the WebContentsManager. std::unique_ptr<content::NavigableContents> contents_;
views::View* content_view_ = nullptr;
gfx::NativeView native_content_view_ = nullptr;
// Our contents are drawn to a layer that is not masked by our widget's layer. // Our contents are drawn to a layer that is not masked by our widget's layer.
// This causes our contents to ignore the corner radius that we have set on // This causes our contents to ignore the corner radius that we have set on
// the widget. To address this, we apply a separate layer mask to the // the widget. To address this, we apply a separate layer mask to the
// contents' layer enforcing our desired corner radius. // contents' native view layer enforcing our desired corner radius.
std::unique_ptr<ui::LayerOwner> content_view_mask_; std::unique_ptr<ui::LayerOwner> contents_mask_;
// Uniquely identifies web contents owned by WebContentsManager.
base::Optional<base::UnguessableToken> web_contents_id_token_;
// Weak pointer factory used for web contents rendering requests. base::WeakPtrFactory<AssistantWebView> weak_factory_;
base::WeakPtrFactory<AssistantWebView> web_contents_request_factory_;
DISALLOW_COPY_AND_ASSIGN(AssistantWebView); DISALLOW_COPY_AND_ASSIGN(AssistantWebView);
}; };
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
"*": [ "accessibility", "app" ], "*": [ "accessibility", "app" ],
"ash_pref_connector": [ "pref_connector" ], "ash_pref_connector": [ "pref_connector" ],
"catalog": [ "directory" ], "catalog": [ "directory" ],
"content": [ "navigation" ],
"device": [ "device": [
"device:bluetooth_system", "device:bluetooth_system",
"device:fingerprint" "device:fingerprint"
......
...@@ -30,7 +30,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate, ...@@ -30,7 +30,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
const mojom::NavigableContentsParams& params, const mojom::NavigableContentsParams& params,
mojom::NavigableContentsClient* client) mojom::NavigableContentsClient* client)
: client_(client), : client_(client),
enable_view_auto_resize_(params.enable_view_auto_resize) { enable_view_auto_resize_(params.enable_view_auto_resize),
auto_resize_min_size_(
params.auto_resize_min_size.value_or(gfx::Size(1, 1))),
auto_resize_max_size_(
params.auto_resize_max_size.value_or(gfx::Size(INT_MAX, INT_MAX))) {
WebContents::CreateParams create_params(browser_context); WebContents::CreateParams create_params(browser_context);
web_contents_ = WebContents::Create(create_params); web_contents_ = WebContents::Create(create_params);
WebContentsObserver::Observe(web_contents_.get()); WebContentsObserver::Observe(web_contents_.get());
...@@ -63,7 +67,39 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate, ...@@ -63,7 +67,39 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
web_contents_->GetController().LoadURLWithParams(load_url_params); web_contents_->GetController().LoadURLWithParams(load_url_params);
} }
void GoBack(
content::mojom::NavigableContents::GoBackCallback callback) override {
content::NavigationController& controller = web_contents_->GetController();
if (controller.CanGoBack()) {
std::move(callback).Run(/*success=*/true);
controller.GoBack();
} else {
std::move(callback).Run(/*success=*/false);
}
}
// WebContentsDelegate: // WebContentsDelegate:
bool ShouldCreateWebContents(
content::WebContents* web_contents,
content::RenderFrameHost* opener,
content::SiteInstance* source_site_instance,
int32_t route_id,
int32_t main_frame_route_id,
int32_t main_frame_widget_route_id,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
const std::string& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override {
// This method is invoked when attempting to open links in a new tab, e.g.:
// <a href="https://www.google.com/" target="_blank">Link</a>
client_->DidSuppressNavigation(target_url,
WindowOpenDisposition::NEW_FOREGROUND_TAB,
/*from_user_gesture=*/true);
return false;
}
WebContents* OpenURLFromTab(WebContents* source, WebContents* OpenURLFromTab(WebContents* source,
const OpenURLParams& params) override { const OpenURLParams& params) override {
client_->DidSuppressNavigation(params.url, params.disposition, client_->DidSuppressNavigation(params.url, params.disposition,
...@@ -82,7 +118,7 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate, ...@@ -82,7 +118,7 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
RenderViewHost* new_host) override { RenderViewHost* new_host) override {
if (enable_view_auto_resize_ && web_contents_->GetRenderWidgetHostView()) { if (enable_view_auto_resize_ && web_contents_->GetRenderWidgetHostView()) {
web_contents_->GetRenderWidgetHostView()->EnableAutoResize( web_contents_->GetRenderWidgetHostView()->EnableAutoResize(
gfx::Size(1, 1), gfx::Size(INT_MAX, INT_MAX)); auto_resize_min_size_, auto_resize_max_size_);
} }
} }
...@@ -102,6 +138,8 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate, ...@@ -102,6 +138,8 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
mojom::NavigableContentsClient* const client_; mojom::NavigableContentsClient* const client_;
const bool enable_view_auto_resize_; const bool enable_view_auto_resize_;
const gfx::Size auto_resize_min_size_;
const gfx::Size auto_resize_max_size_;
DISALLOW_COPY_AND_ASSIGN(NavigableContentsDelegateImpl); DISALLOW_COPY_AND_ASSIGN(NavigableContentsDelegateImpl);
}; };
......
...@@ -33,6 +33,12 @@ class NavigableContentsDelegate { ...@@ -33,6 +33,12 @@ class NavigableContentsDelegate {
// Navigates the content object to a new URL. // Navigates the content object to a new URL.
virtual void Navigate(const GURL& url, mojom::NavigateParamsPtr params) = 0; virtual void Navigate(const GURL& url, mojom::NavigateParamsPtr params) = 0;
// Attempts to navigate the web contents back in its history stack. The
// supplied |callback| is run to indicate success/failure of the attempt. The
// navigation attempt will fail if the history stack is empty.
virtual void GoBack(
content::mojom::NavigableContents::GoBackCallback callback) = 0;
}; };
} // namespace content } // namespace content
......
...@@ -53,6 +53,11 @@ void NavigableContentsImpl::Navigate(const GURL& url, ...@@ -53,6 +53,11 @@ void NavigableContentsImpl::Navigate(const GURL& url,
delegate_->Navigate(url, std::move(params)); delegate_->Navigate(url, std::move(params));
} }
void NavigableContentsImpl::GoBack(
mojom::NavigableContents::GoBackCallback callback) {
delegate_->GoBack(std::move(callback));
}
void NavigableContentsImpl::CreateView(bool in_service_process, void NavigableContentsImpl::CreateView(bool in_service_process,
CreateViewCallback callback) { CreateViewCallback callback) {
DCHECK(native_content_view_); DCHECK(native_content_view_);
......
...@@ -38,6 +38,7 @@ class NavigableContentsImpl : public mojom::NavigableContents { ...@@ -38,6 +38,7 @@ class NavigableContentsImpl : public mojom::NavigableContents {
private: private:
// mojom::NavigableContents: // mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override; void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(bool in_service_process, void CreateView(bool in_service_process,
CreateViewCallback callback) override; CreateViewCallback callback) override;
......
...@@ -51,6 +51,11 @@ void NavigableContents::NavigateWithParams(const GURL& url, ...@@ -51,6 +51,11 @@ void NavigableContents::NavigateWithParams(const GURL& url,
contents_->Navigate(url, std::move(params)); contents_->Navigate(url, std::move(params));
} }
void NavigableContents::GoBack(
content::mojom::NavigableContents::GoBackCallback callback) {
contents_->GoBack(std::move(callback));
}
void NavigableContents::DidFinishNavigation( void NavigableContents::DidFinishNavigation(
const GURL& url, const GURL& url,
bool is_main_frame, bool is_main_frame,
......
...@@ -52,6 +52,11 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents ...@@ -52,6 +52,11 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
void Navigate(const GURL& url); void Navigate(const GURL& url);
void NavigateWithParams(const GURL& url, mojom::NavigateParamsPtr params); void NavigateWithParams(const GURL& url, mojom::NavigateParamsPtr params);
// Attempts to navigate back in the web contents' history stack. The supplied
// |callback| is run to indicate success/failure of the navigation attempt.
// The navigation attempt will fail if the history stack is empty.
void GoBack(content::mojom::NavigableContents::GoBackCallback callback);
private: private:
// mojom::NavigableContentsClient: // mojom::NavigableContentsClient:
void DidFinishNavigation( void DidFinishNavigation(
......
...@@ -36,6 +36,11 @@ void FakeNavigableContents::Navigate(const GURL& url, ...@@ -36,6 +36,11 @@ void FakeNavigableContents::Navigate(const GURL& url,
client_->DidStopLoading(); client_->DidStopLoading();
} }
void FakeNavigableContents::GoBack(
mojom::NavigableContents::GoBackCallback callback) {
std::move(callback).Run(false /* success */);
}
void FakeNavigableContents::CreateView(bool in_service_process, void FakeNavigableContents::CreateView(bool in_service_process,
CreateViewCallback callback) { CreateViewCallback callback) {
auto token = base::UnguessableToken::Create(); auto token = base::UnguessableToken::Create();
......
...@@ -36,6 +36,7 @@ class FakeNavigableContents : public mojom::NavigableContents { ...@@ -36,6 +36,7 @@ class FakeNavigableContents : public mojom::NavigableContents {
private: private:
// mojom::NavigableContents: // mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override; void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(bool in_service_process, void CreateView(bool in_service_process,
CreateViewCallback callback) override; CreateViewCallback callback) override;
......
...@@ -26,6 +26,11 @@ interface NavigableContents { ...@@ -26,6 +26,11 @@ interface NavigableContents {
// Initiates a navigation to |url|. // Initiates a navigation to |url|.
Navigate(url.mojom.Url url, NavigateParams params); Navigate(url.mojom.Url url, NavigateParams params);
// Attempts to navigate the web contents back in its history stack. The
// supplied |callback| is run to indicate success/failure of the attempt. The
// navigation attempt will fail if the history stack is empty.
GoBack() => (bool success);
// Creates a visual representation of the navigated contents, which is // Creates a visual representation of the navigated contents, which is
// maintained by the Content Service. Responds with a |embed_token| which can // maintained by the Content Service. Responds with a |embed_token| which can
// be given to Mus in order to authorize embedding of that visual // be given to Mus in order to authorize embedding of that visual
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
module content.mojom; module content.mojom;
import "services/content/public/mojom/navigable_contents.mojom"; import "services/content/public/mojom/navigable_contents.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
// Parameters used to configure a newly created NavigableContents. // Parameters used to configure a newly created NavigableContents.
struct NavigableContentsParams { struct NavigableContentsParams {
...@@ -13,6 +14,14 @@ struct NavigableContentsParams { ...@@ -13,6 +14,14 @@ struct NavigableContentsParams {
// |DidAutoResizeView()| notifications whenever such resizing happens. // |DidAutoResizeView()| notifications whenever such resizing happens.
bool enable_view_auto_resize = false; bool enable_view_auto_resize = false;
// Specifies the minimum size for auto resizing.
// Defaults to (1, 1).
gfx.mojom.Size? auto_resize_min_size;
// Specifies the maximum size for auto resizing.
// Defaults to (INT_MAX, INT_MAX).
gfx.mojom.Size? auto_resize_max_size;
// Indicates that the client wants to control how navigation requests are // Indicates that the client wants to control how navigation requests are
// handled within the created NavigableContents. Any attempt to navigate the // handled within the created NavigableContents. Any attempt to navigate the
// NavigableContents by any means other than an explicit call to // NavigableContents by any means other than an explicit call to
......
...@@ -62,6 +62,11 @@ class TestNavigableContentsDelegate : public NavigableContentsDelegate { ...@@ -62,6 +62,11 @@ class TestNavigableContentsDelegate : public NavigableContentsDelegate {
navigation_callback_.Run(); navigation_callback_.Run();
} }
void GoBack(
content::mojom::NavigableContents::GoBackCallback callback) override {
std::move(callback).Run(false /* success */);
}
gfx::NativeView GetNativeView() override { return nullptr; } gfx::NativeView GetNativeView() override { return nullptr; }
private: private:
......
...@@ -110,6 +110,11 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT Connector { ...@@ -110,6 +110,11 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT Connector {
BindInterface(target, Interface::Name_, std::move(pipe.handle1)); BindInterface(target, Interface::Name_, std::move(pipe.handle1));
} }
template <typename Interface> template <typename Interface>
void BindInterface(const Identity& target,
mojo::InterfaceRequest<Interface> request) {
BindInterface(target, Interface::Name_, request.PassMessagePipe());
}
template <typename Interface>
void BindInterface(const std::string& name, void BindInterface(const std::string& name,
mojo::InterfacePtr<Interface>* ptr) { mojo::InterfacePtr<Interface>* ptr) {
return BindInterface(Identity(name, mojom::kInheritUserID), ptr); return BindInterface(Identity(name, mojom::kInheritUserID), ptr);
......
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