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(
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() {
delegate_->Focus();
}
......@@ -56,4 +66,18 @@ void NavigableContentsImpl::FocusThroughTabTraversal(bool 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
......@@ -20,6 +20,7 @@ namespace content {
class Service;
class NavigableContentsDelegate;
class NavigableContentsView;
// 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
......@@ -37,9 +38,14 @@ class NavigableContentsImpl : public mojom::NavigableContents {
// mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(CreateViewCallback callback) override;
void Focus() 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_;
mojo::Receiver<mojom::NavigableContents> receiver_;
......
......@@ -34,6 +34,8 @@ void NavigableContents::RemoveObserver(NavigableContentsObserver* observer) {
NavigableContentsView* NavigableContents::GetView() {
if (!view_) {
view_ = base::WrapUnique(new NavigableContentsView(this));
contents_->CreateView(base::BindOnce(
&NavigableContents::OnEmbedTokenReceived, base::Unretained(this)));
}
return view_.get();
}
......@@ -99,4 +101,10 @@ void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) {
view_->NotifyAccessibilityTreeChange();
}
void NavigableContents::OnEmbedTokenReceived(
const base::UnguessableToken& token) {
DCHECK(view_);
view_->EmbedUsingToken(token);
}
} // namespace content
......@@ -85,6 +85,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
bool from_user_gesture) override;
void UpdateContentAXTree(const ui::AXTreeID& id) override;
void OnEmbedTokenReceived(const base::UnguessableToken& token);
mojo::Remote<mojom::NavigableContents> contents_;
mojo::Receiver<mojom::NavigableContentsClient> client_receiver_;
std::unique_ptr<NavigableContentsView> view_;
......
......@@ -4,6 +4,8 @@
#include "services/content/public/cpp/navigable_contents_view.h"
#include <map>
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/no_destructor.h"
......@@ -28,6 +30,15 @@ namespace content {
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() {
static base::NoDestructor<base::AtomicFlag> in_service_process;
return *in_service_process;
......@@ -144,4 +155,34 @@ NavigableContentsView::NavigableContentsView(NavigableContents* contents)
#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
......@@ -9,6 +9,7 @@
#include "base/callback.h"
#include "base/component_export.h"
#include "base/unguessable_token.h"
#include "ui/gfx/native_widget_types.h"
#if defined(TOOLKIT_VIEWS) && defined(USE_AURA)
......@@ -66,6 +67,16 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsView {
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_;
#if defined(TOOLKIT_VIEWS) && defined(USE_AURA)
......
......@@ -6,6 +6,7 @@
#include "base/bind.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/test/fake_navigable_contents_factory.h"
......@@ -42,6 +43,13 @@ void FakeNavigableContents::GoBack(
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::FocusThroughTabTraversal(bool reverse) {}
......
......@@ -40,6 +40,7 @@ class FakeNavigableContents : public mojom::NavigableContents {
// mojom::NavigableContents:
void Navigate(const GURL& url, mojom::NavigateParamsPtr params) override;
void GoBack(mojom::NavigableContents::GoBackCallback callback) override;
void CreateView(CreateViewCallback callback) override;
void Focus() override;
void FocusThroughTabTraversal(bool reverse) override;
......
......@@ -8,6 +8,7 @@ import "services/network/public/mojom/network_param.mojom";
import "ui/accessibility/mojom/ax_tree_id.mojom";
import "ui/base/mojo/window_open_disposition.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "url/mojom/url.mojom";
// Parameters used to configure the behavior of |NavigableContents.Navigate|.
......@@ -31,6 +32,12 @@ interface NavigableContents {
// 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
// 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
// have an active visual representation.
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