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 @@
#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/unguessable_token.h"
#include "services/content/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace ash {
......@@ -309,6 +311,28 @@ void AssistantController::OpenUrl(const GURL& url, bool 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() {
for (AssistantControllerObserver& observer : observers_)
observer.OnAssistantControllerConstructed();
......
......@@ -27,6 +27,7 @@
#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
#include "mojo/public/cpp/bindings/binding_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"
namespace base {
......@@ -135,6 +136,11 @@ class ASH_EXPORT AssistantController
// to deep links which may cause deviation from this behavior.
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() {
DCHECK(assistant_cache_controller_);
return assistant_cache_controller_.get();
......
This diff is collapsed.
......@@ -13,13 +13,10 @@
#include "ash/assistant/ui/caption_bar.h"
#include "base/macros.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/views/view.h"
#include "ui/views/view_observer.h"
namespace base {
class UnguessableToken;
} // namespace base
namespace ash {
......@@ -27,13 +24,13 @@ class AssistantController;
// AssistantWebView is a child of AssistantBubbleView which allows Assistant UI
// to render remotely hosted content within its bubble. It provides a CaptionBar
// for window level controls and a WebView/ServerRemoteViewHost for embedding
// web contents.
// for window level controls and embeds web contents with help from the Content
// Service.
class AssistantWebView : public views::View,
public views::ViewObserver,
public aura::WindowObserver,
public AssistantControllerObserver,
public CaptionBarDelegate {
public CaptionBarDelegate,
public content::NavigableContentsObserver {
public:
explicit AssistantWebView(AssistantController* assistant_controller);
~AssistantWebView() override;
......@@ -44,9 +41,6 @@ class AssistantWebView : public views::View,
int GetHeightForWidth(int width) const override;
void ChildPreferredSizeChanged(views::View* child) override;
// views::ViewObserver:
void OnViewIsDeleting(views::View* view) override;
// views::WindowObserver:
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
......@@ -62,32 +56,31 @@ class AssistantWebView : public views::View,
assistant::util::DeepLinkType type,
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:
void InitLayout();
void OnWebContentsReady(
const base::Optional<base::UnguessableToken>& embed_token);
void ReleaseWebContents();
void RemoveContents();
AssistantController* const assistant_controller_; // Owned by Shell.
CaptionBar* caption_bar_; // Owned by view hierarchy.
// In Mash, |content_view_| is owned by the view hierarchy. Otherwise, the
// view is owned by the WebContentsManager.
views::View* content_view_ = nullptr;
gfx::NativeView native_content_view_ = nullptr;
content::mojom::NavigableContentsFactoryPtr contents_factory_;
std::unique_ptr<content::NavigableContents> contents_;
// 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
// the widget. To address this, we apply a separate layer mask to the
// contents' layer enforcing our desired corner radius.
std::unique_ptr<ui::LayerOwner> content_view_mask_;
// Uniquely identifies web contents owned by WebContentsManager.
base::Optional<base::UnguessableToken> web_contents_id_token_;
// contents' native view layer enforcing our desired corner radius.
std::unique_ptr<ui::LayerOwner> contents_mask_;
// Weak pointer factory used for web contents rendering requests.
base::WeakPtrFactory<AssistantWebView> web_contents_request_factory_;
base::WeakPtrFactory<AssistantWebView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AssistantWebView);
};
......
......@@ -69,6 +69,7 @@
"*": [ "accessibility", "app" ],
"ash_pref_connector": [ "pref_connector" ],
"catalog": [ "directory" ],
"content": [ "navigation" ],
"device": [
"device:bluetooth_system",
"device:fingerprint"
......
......@@ -30,7 +30,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
const mojom::NavigableContentsParams& params,
mojom::NavigableContentsClient* 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);
web_contents_ = WebContents::Create(create_params);
WebContentsObserver::Observe(web_contents_.get());
......@@ -63,7 +67,39 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
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:
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,
const OpenURLParams& params) override {
client_->DidSuppressNavigation(params.url, params.disposition,
......@@ -82,7 +118,7 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
RenderViewHost* new_host) override {
if (enable_view_auto_resize_ && web_contents_->GetRenderWidgetHostView()) {
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,
mojom::NavigableContentsClient* const client_;
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);
};
......
......@@ -33,6 +33,12 @@ class NavigableContentsDelegate {
// Navigates the content object to a new URL.
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
......
......@@ -53,6 +53,11 @@ void NavigableContentsImpl::Navigate(const GURL& url,
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,
CreateViewCallback callback) {
DCHECK(native_content_view_);
......
......@@ -38,6 +38,7 @@ class NavigableContentsImpl : public mojom::NavigableContents {
private:
// mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(bool in_service_process,
CreateViewCallback callback) override;
......
......@@ -51,6 +51,11 @@ void NavigableContents::NavigateWithParams(const GURL& url,
contents_->Navigate(url, std::move(params));
}
void NavigableContents::GoBack(
content::mojom::NavigableContents::GoBackCallback callback) {
contents_->GoBack(std::move(callback));
}
void NavigableContents::DidFinishNavigation(
const GURL& url,
bool is_main_frame,
......
......@@ -52,6 +52,11 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
void Navigate(const GURL& url);
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:
// mojom::NavigableContentsClient:
void DidFinishNavigation(
......
......@@ -36,6 +36,11 @@ void FakeNavigableContents::Navigate(const GURL& url,
client_->DidStopLoading();
}
void FakeNavigableContents::GoBack(
mojom::NavigableContents::GoBackCallback callback) {
std::move(callback).Run(false /* success */);
}
void FakeNavigableContents::CreateView(bool in_service_process,
CreateViewCallback callback) {
auto token = base::UnguessableToken::Create();
......
......@@ -36,6 +36,7 @@ class FakeNavigableContents : public mojom::NavigableContents {
private:
// mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(bool in_service_process,
CreateViewCallback callback) override;
......
......@@ -26,6 +26,11 @@ interface NavigableContents {
// Initiates a navigation to |url|.
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
// maintained by the Content Service. Responds with a |embed_token| which can
// be given to Mus in order to authorize embedding of that visual
......
......@@ -5,6 +5,7 @@
module content.mojom;
import "services/content/public/mojom/navigable_contents.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
// Parameters used to configure a newly created NavigableContents.
struct NavigableContentsParams {
......@@ -13,6 +14,14 @@ struct NavigableContentsParams {
// |DidAutoResizeView()| notifications whenever such resizing happens.
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
// handled within the created NavigableContents. Any attempt to navigate the
// NavigableContents by any means other than an explicit call to
......
......@@ -62,6 +62,11 @@ class TestNavigableContentsDelegate : public NavigableContentsDelegate {
navigation_callback_.Run();
}
void GoBack(
content::mojom::NavigableContents::GoBackCallback callback) override {
std::move(callback).Run(false /* success */);
}
gfx::NativeView GetNativeView() override { return nullptr; }
private:
......
......@@ -110,6 +110,11 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT Connector {
BindInterface(target, Interface::Name_, std::move(pipe.handle1));
}
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,
mojo::InterfacePtr<Interface>* 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