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();
......
......@@ -11,10 +11,8 @@
#include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/util/deep_link_util.h"
#include "ash/public/cpp/app_list/answer_card_contents_registry.h"
#include "ash/public/interfaces/web_contents_manager.mojom.h"
#include "base/callback.h"
#include "base/unguessable_token.h"
#include "services/content/public/cpp/navigable_contents_view.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/display/display.h"
......@@ -28,12 +26,12 @@ namespace ash {
namespace {
// ContentViewMaskPainter -------------------------------------------------
// ContentsMaskPainter ---------------------------------------------------------
class ContentViewMaskPainter : public views::Painter {
class ContentsMaskPainter : public views::Painter {
public:
ContentViewMaskPainter() = default;
~ContentViewMaskPainter() override = default;
ContentsMaskPainter() = default;
~ContentsMaskPainter() override = default;
// views::Painter:
gfx::Size GetMinimumSize() const override { return gfx::Size(); }
......@@ -56,7 +54,7 @@ class ContentViewMaskPainter : public views::Painter {
}
private:
DISALLOW_COPY_AND_ASSIGN(ContentViewMaskPainter);
DISALLOW_COPY_AND_ASSIGN(ContentsMaskPainter);
};
} // namespace
......@@ -64,8 +62,7 @@ class ContentViewMaskPainter : public views::Painter {
// AssistantWebView ------------------------------------------------------------
AssistantWebView::AssistantWebView(AssistantController* assistant_controller)
: assistant_controller_(assistant_controller),
web_contents_request_factory_(this) {
: assistant_controller_(assistant_controller), weak_factory_(this) {
InitLayout();
assistant_controller_->AddObserver(this);
......@@ -73,7 +70,8 @@ AssistantWebView::AssistantWebView(AssistantController* assistant_controller)
AssistantWebView::~AssistantWebView() {
assistant_controller_->RemoveObserver(this);
ReleaseWebContents();
RemoveContents();
}
const char* AssistantWebView::GetClassName() const {
......@@ -101,38 +99,19 @@ void AssistantWebView::ChildPreferredSizeChanged(views::View* child) {
SchedulePaint();
}
void AssistantWebView::OnViewIsDeleting(views::View* view) {
DCHECK_EQ(content_view_, view);
// It's possible for |content_view_| to be deleted before AssistantWebView.
// When this happens, we need to perform clean up on |content_view_| before
// it is destroyed and clear references so that we don't try to perform
// clean up on the destroyed instance when destroying AssistantWebView.
content_view_->RemoveObserver(this);
content_view_ = nullptr;
}
void AssistantWebView::OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
DCHECK_EQ(native_content_view_, window);
// The mask layer should always match the bounds of the native content view.
content_view_mask_->layer()->SetBounds(gfx::Rect(new_bounds.size()));
// The mask layer should always match the bounds of the contents' native view.
contents_mask_->layer()->SetBounds(gfx::Rect(new_bounds.size()));
}
void AssistantWebView::OnWindowDestroying(aura::Window* window) {
DCHECK_EQ(native_content_view_, window);
// It's possible for |native_content_view_| to be deleted before
// AssistantWebView. When this happens, we need to perform clean up on
// |native_content_view_| before it is destroyed and clear references so that
// we don't try to perform clean up on the destroyed instance when destroying
// AssistantWebView.
native_content_view_->RemoveObserver(this);
native_content_view_->layer()->SetMaskLayer(nullptr);
native_content_view_ = nullptr;
// It's possible for |window| to be deleted before AssistantWebView. When this
// happens, we need to perform clean up on |window| before it is destroyed.
window->RemoveObserver(this);
window->layer()->SetMaskLayer(nullptr);
}
void AssistantWebView::InitLayout() {
......@@ -145,36 +124,33 @@ void AssistantWebView::InitLayout() {
caption_bar_->SetButtonVisible(CaptionButtonId::kMinimize, false);
AddChildView(caption_bar_);
// Content mask.
// This is used to enforce corner radius on the contents' layer.
content_view_mask_ = views::Painter::CreatePaintedLayer(
std::make_unique<ContentViewMaskPainter>());
content_view_mask_->layer()->SetFillsBoundsOpaquely(false);
// Contents mask.
// This is used to enforce corner radius on the contents' native view layer.
contents_mask_ = views::Painter::CreatePaintedLayer(
std::make_unique<ContentsMaskPainter>());
contents_mask_->layer()->SetFillsBoundsOpaquely(false);
}
bool AssistantWebView::OnCaptionButtonPressed(CaptionButtonId id) {
CaptionBarDelegate* delegate = assistant_controller_->ui_controller();
// We need special handling of the back button. When possible, the back button
// should navigate backwards in the managed WebContents' history stack.
if (id == CaptionButtonId::kBack && web_contents_id_token_.has_value()) {
assistant_controller_->NavigateWebContentsBack(
web_contents_id_token_.value(),
base::BindOnce(
[](CaptionBarDelegate* delegate, bool navigated) {
// If the WebContents' did not navigate it is because we are
// already at the first entry in the history stack and we cannot
// navigate back any further. In this case, we give back control
// to our primary caption button delegate.
if (!navigated)
delegate->OnCaptionButtonPressed(CaptionButtonId::kBack);
},
base::Unretained(delegate)));
// should navigate backwards in the web contents' history stack.
if (id == CaptionButtonId::kBack && contents_) {
contents_->GoBack(base::BindOnce(
[](const base::WeakPtr<AssistantWebView>& assistant_web_view,
bool success) {
// If we can't navigate back in the web contents' history stack we
// defer back to our primary caption button delegate.
if (!success && assistant_web_view) {
assistant_web_view->assistant_controller_->ui_controller()
->OnCaptionButtonPressed(CaptionButtonId::kBack);
}
},
weak_factory_.GetWeakPtr()));
return true;
}
// For all other buttons we defer to our primary caption button delegate.
return delegate->OnCaptionButtonPressed(id);
return assistant_controller_->ui_controller()->OnCaptionButtonPressed(id);
}
void AssistantWebView::OnDeepLinkReceived(
......@@ -183,86 +159,91 @@ void AssistantWebView::OnDeepLinkReceived(
if (!assistant::util::IsWebDeepLinkType(type))
return;
ReleaseWebContents();
RemoveContents();
web_contents_id_token_ = base::UnguessableToken::Create();
assistant_controller_->GetNavigableContentsFactory(
mojo::MakeRequest(&contents_factory_));
gfx::Size preferred_size_dip =
const gfx::Size preferred_size =
gfx::Size(kPreferredWidthDip,
kMaxHeightDip - caption_bar_->GetPreferredSize().height());
ash::mojom::ManagedWebContentsParamsPtr web_contents_params(
ash::mojom::ManagedWebContentsParams::New());
web_contents_params->url = GetWebUrl(type).value();
web_contents_params->min_size_dip = preferred_size_dip;
web_contents_params->max_size_dip = preferred_size_dip;
auto contents_params = content::mojom::NavigableContentsParams::New();
contents_params->enable_view_auto_resize = true;
contents_params->auto_resize_min_size = preferred_size;
contents_params->auto_resize_max_size = preferred_size;
contents_params->suppress_navigations = true;
assistant_controller_->ManageWebContents(
web_contents_id_token_.value(), std::move(web_contents_params),
base::BindOnce(&AssistantWebView::OnWebContentsReady,
web_contents_request_factory_.GetWeakPtr()));
}
contents_ = std::make_unique<content::NavigableContents>(
contents_factory_.get(), std::move(contents_params));
void AssistantWebView::OnWebContentsReady(
const base::Optional<base::UnguessableToken>& embed_token) {
// TODO(dmblack): In the event that rendering fails, we should show a useful
// message to the user (and perhaps close the UI).
if (!embed_token.has_value())
return;
// We observe |contents_| so that we can handle events from the underlying
// web contents.
contents_->AddObserver(this);
// When web contents are rendered in process, the WebView associated with the
// returned |embed_token| is found in the AnswerCardContentsRegistry.
if (app_list::AnswerCardContentsRegistry::Get()) {
content_view_ = app_list::AnswerCardContentsRegistry::Get()->GetView(
embed_token.value());
content_view_->AddObserver(this);
// Cache a reference to the content's native view and observe it so that
// we can monitor changes to bounds and lifecycle.
native_content_view_ =
app_list::AnswerCardContentsRegistry::Get()->GetNativeView(
embed_token.value());
native_content_view_->AddObserver(this);
// Apply a mask layer to enforce corner radius. The mask bounds must always
// match the bounds of |native_content_view_|. We sync bounds prior to
// applying the mask to prevent a DCHECK failure in cc::Layer.
content_view_mask_->layer()->SetBounds(
gfx::Rect(native_content_view_->GetBoundsInScreen().size()));
native_content_view_->layer()->SetMaskLayer(content_view_mask_->layer());
AddChildView(content_view_);
}
// Navigate to the url associated with the received deep link.
contents_->Navigate(assistant::util::GetWebUrl(type).value());
}
// TODO(dmblack): Handle mash case.
void AssistantWebView::DidAutoResizeView(const gfx::Size& new_size) {
contents_->GetView()->view()->SetPreferredSize(new_size);
}
void AssistantWebView::ReleaseWebContents() {
web_contents_request_factory_.InvalidateWeakPtrs();
void AssistantWebView::DidStopLoading() {
AddChildView(contents_->GetView()->view());
gfx::NativeView native_view = contents_->GetView()->native_view();
// We apply a layer mask to the contents' native view to enforce our desired
// corner radius. We need to sync the bounds of mask layer with the bounds
// of the native view prior to application to prevent DCHECK failure.
contents_mask_->layer()->SetBounds(
gfx::Rect(native_view->GetBoundsInScreen().size()));
native_view->layer()->SetMaskLayer(contents_mask_->layer());
// We observe |native_view| to ensure we keep the mask layer bounds in sync
// with the native view layer's bounds across size changes.
native_view->AddObserver(this);
}
if (!web_contents_id_token_.has_value())
void AssistantWebView::DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) {
if (!from_user_gesture)
return;
if (content_view_) {
content_view_->RemoveObserver(this);
RemoveChildView(content_view_);
// We defer to |assistant_controller_| to tell us if we should allow
// navigation to continue or not as we, in some cases, intercept navigation
// to perform special handling for deep links, etc.
assistant_controller_->ShouldOpenUrlFromTab(
url, disposition,
base::BindOnce(
[](const base::WeakPtr<AssistantWebView>& assistant_web_view,
const GURL& url, bool should_navigate) {
// If the navigation attempt hasn't been specially handled we can
// allow the web contents to continue navigating.
if (should_navigate && assistant_web_view)
assistant_web_view->contents_->Navigate(url);
},
weak_factory_.GetWeakPtr(), url));
}
// In Mash, |content_view_| was owned by the view hierarchy prior to its
// removal. Otherwise the view is owned by the WebContentsManager.
if (!content_view_->owned_by_client())
delete content_view_;
void AssistantWebView::RemoveContents() {
if (!contents_)
return;
content_view_ = nullptr;
gfx::NativeView native_view = contents_->GetView()->native_view();
if (native_view) {
native_view->RemoveObserver(this);
native_view->layer()->SetMaskLayer(nullptr);
}
if (native_content_view_) {
native_content_view_->RemoveObserver(this);
native_content_view_->layer()->SetMaskLayer(nullptr);
native_content_view_ = nullptr;
}
views::View* view = contents_->GetView()->view();
if (view)
RemoveChildView(view);
assistant_controller_->ReleaseWebContents(web_contents_id_token_.value());
web_contents_id_token_.reset();
contents_->RemoveObserver(this);
contents_.reset();
}
} // namespace ash
......@@ -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