Commit bca2cfd8 authored by David Black's avatar David Black Committed by Commit Bot

Restore in process embedding to NavigableContents.

This code is being restored after having been removed from:
https://chromium-review.googlesource.com/c/chromium/src/+/1603743

Only change to restored code is to remove any |use_window_service|
params/codepaths that were present in the originally removed version.

This fixes a regression in Assistant which prevented Assistant Settings
and cards (implemented using NavigableContents) from rendering to the
user.

Bug: b:132717712
Change-Id: I27f3595f8e25bcf91664ea27beec27bf39855a31
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1613723Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Commit-Queue: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#660684}
parent b8a4076c
...@@ -48,6 +48,16 @@ void NavigableContentsImpl::GoBack( ...@@ -48,6 +48,16 @@ void NavigableContentsImpl::GoBack(
delegate_->GoBack(std::move(callback)); delegate_->GoBack(std::move(callback));
} }
void NavigableContentsImpl::CreateView(CreateViewCallback callback) {
// Create and stash a new callback (indexed by token) which the in-process
// client library can use to establish an "embedding" of the contents' view.
auto token = base::UnguessableToken::Create();
NavigableContentsView::RegisterInProcessEmbedCallback(
token, base::BindOnce(&NavigableContentsImpl::EmbedInProcessClientView,
weak_ptr_factory_.GetWeakPtr()));
std::move(callback).Run(token);
}
void NavigableContentsImpl::Focus() { void NavigableContentsImpl::Focus() {
delegate_->Focus(); delegate_->Focus();
} }
...@@ -56,4 +66,18 @@ void NavigableContentsImpl::FocusThroughTabTraversal(bool reverse) { ...@@ -56,4 +66,18 @@ void NavigableContentsImpl::FocusThroughTabTraversal(bool reverse) {
delegate_->FocusThroughTabTraversal(reverse); delegate_->FocusThroughTabTraversal(reverse);
} }
void NavigableContentsImpl::EmbedInProcessClientView(
NavigableContentsView* view) {
DCHECK(native_content_view_);
#if defined(TOOLKIT_VIEWS) && defined(USE_AURA)
view->native_view()->AddChild(native_content_view_);
native_content_view_->Show();
#else
// TODO(https://crbug.com/855092): Support embedding of other native client
// views without Views + Aura.
NOTREACHED()
<< "NavigableContents views are currently only supported on Views UI.";
#endif
}
} // namespace content } // namespace content
...@@ -20,6 +20,7 @@ namespace content { ...@@ -20,6 +20,7 @@ namespace content {
class Service; class Service;
class NavigableContentsDelegate; class NavigableContentsDelegate;
class NavigableContentsView;
// This is the state which backs an individual NavigableContents owned by some // This is the state which backs an individual NavigableContents owned by some
// client of the Content Service. In terms of the classical Content API, this is // client of the Content Service. In terms of the classical Content API, this is
...@@ -37,9 +38,14 @@ class NavigableContentsImpl : public mojom::NavigableContents { ...@@ -37,9 +38,14 @@ class NavigableContentsImpl : public mojom::NavigableContents {
// 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 GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(CreateViewCallback callback) override;
void Focus() override; void Focus() override;
void FocusThroughTabTraversal(bool reverse) override; void FocusThroughTabTraversal(bool reverse) override;
// Used (indirectly) by the client library when run in the same process as the
// service. See the |CreateView()| implementation for details.
void EmbedInProcessClientView(NavigableContentsView* view);
Service* const service_; Service* const service_;
mojo::Receiver<mojom::NavigableContents> receiver_; mojo::Receiver<mojom::NavigableContents> receiver_;
......
...@@ -34,6 +34,8 @@ void NavigableContents::RemoveObserver(NavigableContentsObserver* observer) { ...@@ -34,6 +34,8 @@ void NavigableContents::RemoveObserver(NavigableContentsObserver* observer) {
NavigableContentsView* NavigableContents::GetView() { NavigableContentsView* NavigableContents::GetView() {
if (!view_) { if (!view_) {
view_ = base::WrapUnique(new NavigableContentsView(this)); view_ = base::WrapUnique(new NavigableContentsView(this));
contents_->CreateView(base::BindOnce(
&NavigableContents::OnEmbedTokenReceived, base::Unretained(this)));
} }
return view_.get(); return view_.get();
} }
...@@ -99,4 +101,10 @@ void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) { ...@@ -99,4 +101,10 @@ void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) {
view_->NotifyAccessibilityTreeChange(); view_->NotifyAccessibilityTreeChange();
} }
void NavigableContents::OnEmbedTokenReceived(
const base::UnguessableToken& token) {
DCHECK(view_);
view_->EmbedUsingToken(token);
}
} // namespace content } // namespace content
...@@ -85,6 +85,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents ...@@ -85,6 +85,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
bool from_user_gesture) override; bool from_user_gesture) override;
void UpdateContentAXTree(const ui::AXTreeID& id) override; void UpdateContentAXTree(const ui::AXTreeID& id) override;
void OnEmbedTokenReceived(const base::UnguessableToken& token);
mojo::Remote<mojom::NavigableContents> contents_; mojo::Remote<mojom::NavigableContents> contents_;
mojo::Receiver<mojom::NavigableContentsClient> client_receiver_; mojo::Receiver<mojom::NavigableContentsClient> client_receiver_;
std::unique_ptr<NavigableContentsView> view_; std::unique_ptr<NavigableContentsView> view_;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "services/content/public/cpp/navigable_contents_view.h" #include "services/content/public/cpp/navigable_contents_view.h"
#include <map>
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
...@@ -28,6 +30,15 @@ namespace content { ...@@ -28,6 +30,15 @@ namespace content {
namespace { namespace {
using InProcessEmbeddingMap =
std::map<base::UnguessableToken,
base::OnceCallback<void(NavigableContentsView*)>>;
InProcessEmbeddingMap& GetInProcessEmbeddingMap() {
static base::NoDestructor<InProcessEmbeddingMap> embedding_map;
return *embedding_map;
}
base::AtomicFlag& GetInServiceProcessFlag() { base::AtomicFlag& GetInServiceProcessFlag() {
static base::NoDestructor<base::AtomicFlag> in_service_process; static base::NoDestructor<base::AtomicFlag> in_service_process;
return *in_service_process; return *in_service_process;
...@@ -144,4 +155,34 @@ NavigableContentsView::NavigableContentsView(NavigableContents* contents) ...@@ -144,4 +155,34 @@ NavigableContentsView::NavigableContentsView(NavigableContents* contents)
#endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA) #endif // defined(TOOLKIT_VIEWS) && defined(USE_AURA)
} }
void NavigableContentsView::EmbedUsingToken(
const base::UnguessableToken& token) {
#if defined(TOOLKIT_VIEWS)
DCHECK(IsClientRunningInServiceProcess());
// |token| should already have an embed callback entry in the in-process
// callback map, injected by the in-process Content Service implementation.
auto& embeddings = GetInProcessEmbeddingMap();
auto it = embeddings.find(token);
if (it == embeddings.end()) {
DLOG(ERROR) << "Unable to embed with unknown token " << token.ToString();
return;
}
// Invoke a callback provided by the Content Service's host environment. This
// should parent a web content view to our own |view()|, as well as set
// |native_view_| to the corresponding web contents' own NativeView.
auto callback = std::move(it->second);
embeddings.erase(it);
std::move(callback).Run(this);
#endif // defined(TOOLKIT_VIEWS)
}
// static
void NavigableContentsView::RegisterInProcessEmbedCallback(
const base::UnguessableToken& token,
base::OnceCallback<void(NavigableContentsView*)> callback) {
GetInProcessEmbeddingMap()[token] = std::move(callback);
}
} // namespace content } // namespace content
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/component_export.h" #include "base/component_export.h"
#include "base/unguessable_token.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) #if defined(TOOLKIT_VIEWS) && defined(USE_AURA)
...@@ -66,6 +67,16 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsView { ...@@ -66,6 +67,16 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsView {
explicit NavigableContentsView(NavigableContents* contents_); explicit NavigableContentsView(NavigableContents* contents_);
// Establishes a hierarchical relationship between this view's native UI
// object and another native UI object within the Content Service.
void EmbedUsingToken(const base::UnguessableToken& token);
// Used by the service directly when running in the same process. Establishes
// a way for an embed token to be used without the UI service.
static void RegisterInProcessEmbedCallback(
const base::UnguessableToken& token,
base::OnceCallback<void(NavigableContentsView*)> callback);
NavigableContents* const contents_; NavigableContents* const contents_;
#if defined(TOOLKIT_VIEWS) && defined(USE_AURA) #if defined(TOOLKIT_VIEWS) && defined(USE_AURA)
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/unguessable_token.h"
#include "services/content/public/cpp/navigable_contents_view.h" #include "services/content/public/cpp/navigable_contents_view.h"
#include "services/content/public/cpp/test/fake_navigable_contents_factory.h" #include "services/content/public/cpp/test/fake_navigable_contents_factory.h"
...@@ -42,6 +43,13 @@ void FakeNavigableContents::GoBack( ...@@ -42,6 +43,13 @@ void FakeNavigableContents::GoBack(
std::move(callback).Run(false /* success */); std::move(callback).Run(false /* success */);
} }
void FakeNavigableContents::CreateView(CreateViewCallback callback) {
auto token = base::UnguessableToken::Create();
NavigableContentsView::RegisterInProcessEmbedCallback(token,
base::DoNothing());
std::move(callback).Run(token);
}
void FakeNavigableContents::Focus() {} void FakeNavigableContents::Focus() {}
void FakeNavigableContents::FocusThroughTabTraversal(bool reverse) {} void FakeNavigableContents::FocusThroughTabTraversal(bool reverse) {}
......
...@@ -40,6 +40,7 @@ class FakeNavigableContents : public mojom::NavigableContents { ...@@ -40,6 +40,7 @@ class FakeNavigableContents : public mojom::NavigableContents {
// 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 GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(CreateViewCallback callback) override;
void Focus() override; void Focus() override;
void FocusThroughTabTraversal(bool reverse) override; void FocusThroughTabTraversal(bool reverse) override;
......
...@@ -8,6 +8,7 @@ import "services/network/public/mojom/network_param.mojom"; ...@@ -8,6 +8,7 @@ import "services/network/public/mojom/network_param.mojom";
import "ui/accessibility/mojom/ax_tree_id.mojom"; import "ui/accessibility/mojom/ax_tree_id.mojom";
import "ui/base/mojo/window_open_disposition.mojom"; import "ui/base/mojo/window_open_disposition.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "url/mojom/url.mojom"; import "url/mojom/url.mojom";
// Parameters used to configure the behavior of |NavigableContents.Navigate|. // Parameters used to configure the behavior of |NavigableContents.Navigate|.
...@@ -31,6 +32,12 @@ interface NavigableContents { ...@@ -31,6 +32,12 @@ interface NavigableContents {
// navigation attempt will fail if the history stack is empty. // navigation attempt will fail if the history stack is empty.
GoBack() => (bool success); 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
// representation within the client application's own window tree.
CreateView() => (mojo_base.mojom.UnguessableToken embed_token);
// Attempts to transfer global input focus to the navigated contents if they // Attempts to transfer global input focus to the navigated contents if they
// have an active visual representation. // have an active visual representation.
Focus(); Focus();
......
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