ash: Add CreateArcCustomTabController() to NewWindowClient interface
Add CreateArcCustomTabController() to NewWindowClient interface. Add OpenArcCustomTab() to OpenUrlDelegate interface. Add OnOpenCustomTab() to IntentHelperHost interface. BUG=925769 TEST=manually Change-Id: I7a9bdcb53c176cf1fb0edbf73e393d3cab9c3038 Reviewed-on: https://chromium-review.googlesource.com/c/1469817 Commit-Queue: Ryo Hashimoto <hashimoto@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Jun Mukai <mukai@chromium.org> Reviewed-by: Mitsuru Oshima <oshima@chromium.org> Reviewed-by: Yusuke Sato <yusukes@chromium.org> Cr-Commit-Position: refs/heads/master@{#635382}
This commit is contained in:

committed by
Commit Bot

parent
55c9b10475
commit
bac835aaa0
ash
chrome/browser/ui/ash
components/arc
@ -194,6 +194,10 @@ component("ash") {
|
||||
"cast_config_controller.h",
|
||||
"contained_shell/contained_shell_controller.cc",
|
||||
"contained_shell/contained_shell_controller.h",
|
||||
"custom_tab/arc_custom_tab_controller.cc",
|
||||
"custom_tab/arc_custom_tab_controller.h",
|
||||
"custom_tab/arc_custom_tab_view.cc",
|
||||
"custom_tab/arc_custom_tab_view.h",
|
||||
"dbus/ash_dbus_services.cc",
|
||||
"dbus/ash_dbus_services.h",
|
||||
"dbus/display_service_provider.cc",
|
||||
|
31
ash/custom_tab/arc_custom_tab_controller.cc
Normal file
31
ash/custom_tab/arc_custom_tab_controller.cc
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/custom_tab/arc_custom_tab_controller.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ash/custom_tab/arc_custom_tab_view.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
ArcCustomTabController::ArcCustomTabController() : binding_(this) {}
|
||||
|
||||
ArcCustomTabController::~ArcCustomTabController() = default;
|
||||
|
||||
void ArcCustomTabController::BindRequest(
|
||||
mojom::ArcCustomTabControllerRequest request) {
|
||||
binding_.Close();
|
||||
binding_.Bind(std::move(request));
|
||||
}
|
||||
|
||||
void ArcCustomTabController::CreateView(int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
CreateViewCallback callback) {
|
||||
std::move(callback).Run(
|
||||
ArcCustomTabView::Create(task_id, surface_id, top_margin));
|
||||
}
|
||||
|
||||
} // namespace ash
|
36
ash/custom_tab/arc_custom_tab_controller.h
Normal file
36
ash/custom_tab/arc_custom_tab_controller.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_CONTROLLER_H_
|
||||
#define ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_CONTROLLER_H_
|
||||
|
||||
#include "ash/public/interfaces/arc_custom_tab.mojom.h"
|
||||
#include "base/macros.h"
|
||||
#include "mojo/public/cpp/bindings/binding.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
// Provides the ArcCustomTabController interface to the outside world.
|
||||
class ArcCustomTabController : public mojom::ArcCustomTabController {
|
||||
public:
|
||||
ArcCustomTabController();
|
||||
~ArcCustomTabController() override;
|
||||
|
||||
void BindRequest(mojom::ArcCustomTabControllerRequest request);
|
||||
|
||||
// ArcCustomTabController:
|
||||
void CreateView(int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
CreateViewCallback callback) override;
|
||||
|
||||
private:
|
||||
mojo::Binding<mojom::ArcCustomTabController> binding_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ArcCustomTabController);
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_CONTROLLER_H_
|
146
ash/custom_tab/arc_custom_tab_view.cc
Normal file
146
ash/custom_tab/arc_custom_tab_view.cc
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/custom_tab/arc_custom_tab_view.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "ash/shell.h"
|
||||
#include "ash/ws/window_service_owner.h"
|
||||
#include "components/exo/shell_surface_util.h"
|
||||
#include "components/exo/surface.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/views/layout/fill_layout.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
namespace {
|
||||
|
||||
// Tries to find the specified ARC window recursively.
|
||||
aura::Window* FindArcWindow(const aura::Window::Windows& windows,
|
||||
const std::string& arc_app_id) {
|
||||
for (aura::Window* window : windows) {
|
||||
const std::string* id = exo::GetShellApplicationId(window);
|
||||
if (id && *id == arc_app_id)
|
||||
return window;
|
||||
|
||||
aura::Window* result = FindArcWindow(window->children(), arc_app_id);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Tries to find the specified ARC surface window recursively.
|
||||
aura::Window* FindSurfaceWindow(aura::Window* window, int surface_id) {
|
||||
auto* surface = exo::Surface::AsSurface(window);
|
||||
if (surface && surface->GetClientSurfaceId() == surface_id)
|
||||
return window;
|
||||
|
||||
for (aura::Window* child : window->children()) {
|
||||
aura::Window* result = FindSurfaceWindow(child, surface_id);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
mojom::ArcCustomTabViewPtr ArcCustomTabView::Create(int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin) {
|
||||
const std::string arc_app_id =
|
||||
base::StringPrintf("org.chromium.arc.%d", task_id);
|
||||
aura::Window* arc_app_window =
|
||||
FindArcWindow(ash::Shell::Get()->GetAllRootWindows(), arc_app_id);
|
||||
if (!arc_app_window) {
|
||||
LOG(ERROR) << "No ARC window with the specified task ID " << task_id;
|
||||
return nullptr;
|
||||
}
|
||||
views::Widget* widget =
|
||||
views::Widget::GetWidgetForNativeWindow(arc_app_window);
|
||||
if (!widget) {
|
||||
LOG(ERROR) << "No widget for the ARC app window.";
|
||||
return nullptr;
|
||||
}
|
||||
auto* parent = widget->widget_delegate()->GetContentsView();
|
||||
auto* view = new ArcCustomTabView(surface_id, top_margin);
|
||||
parent->AddChildView(view);
|
||||
parent->SetLayoutManager(std::make_unique<views::FillLayout>());
|
||||
parent->Layout();
|
||||
|
||||
mojom::ArcCustomTabViewPtr ptr;
|
||||
view->Bind(&ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ArcCustomTabView::EmbedUsingToken(const base::UnguessableToken& token) {
|
||||
remote_view_host_->EmbedUsingToken(token, 0, base::BindOnce([](bool success) {
|
||||
LOG_IF(ERROR, !success)
|
||||
<< "Failed to embed.";
|
||||
}));
|
||||
}
|
||||
|
||||
void ArcCustomTabView::Layout() {
|
||||
if (!GetWidget()) {
|
||||
LOG(ERROR) << "No widget";
|
||||
return;
|
||||
}
|
||||
DCHECK(GetWidget()->GetNativeWindow());
|
||||
aura::Window* surface_window =
|
||||
FindSurfaceWindow(GetWidget()->GetNativeWindow(), surface_id_);
|
||||
if (!surface_window) {
|
||||
LOG(ERROR) << "Surface not found " << surface_id_;
|
||||
return;
|
||||
}
|
||||
gfx::Point topleft(0, top_margin_),
|
||||
bottomright(surface_window->bounds().width(),
|
||||
surface_window->bounds().height());
|
||||
ConvertPointFromWindow(surface_window, &topleft);
|
||||
ConvertPointFromWindow(surface_window, &bottomright);
|
||||
gfx::Rect bounds(topleft, gfx::Size(bottomright.x() - topleft.x(),
|
||||
bottomright.y() - topleft.y()));
|
||||
remote_view_host_->SetBoundsRect(bounds);
|
||||
|
||||
// Stack the remote view window at top.
|
||||
aura::Window* window = remote_view_host_->GetNativeViewContainer();
|
||||
window->parent()->StackChildAtTop(window);
|
||||
}
|
||||
|
||||
ArcCustomTabView::ArcCustomTabView(int32_t surface_id, int32_t top_margin)
|
||||
: binding_(this),
|
||||
remote_view_host_(new ws::ServerRemoteViewHost(
|
||||
ash::Shell::Get()->window_service_owner()->window_service())),
|
||||
surface_id_(surface_id),
|
||||
top_margin_(top_margin),
|
||||
weak_ptr_factory_(this) {
|
||||
AddChildView(remote_view_host_.get());
|
||||
}
|
||||
|
||||
ArcCustomTabView::~ArcCustomTabView() = default;
|
||||
|
||||
void ArcCustomTabView::Bind(mojom::ArcCustomTabViewPtr* ptr) {
|
||||
binding_.Bind(mojo::MakeRequest(ptr));
|
||||
binding_.set_connection_error_handler(
|
||||
base::BindOnce(&ArcCustomTabView::Close, weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void ArcCustomTabView::Close() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ArcCustomTabView::ConvertPointFromWindow(aura::Window* window,
|
||||
gfx::Point* point) {
|
||||
aura::Window::ConvertPointToTarget(window, GetWidget()->GetNativeWindow(),
|
||||
point);
|
||||
views::View::ConvertPointFromWidget(parent(), point);
|
||||
}
|
||||
|
||||
} // namespace ash
|
56
ash/custom_tab/arc_custom_tab_view.h
Normal file
56
ash/custom_tab/arc_custom_tab_view.h
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_VIEW_H_
|
||||
#define ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_VIEW_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ash/public/interfaces/arc_custom_tab.mojom.h"
|
||||
#include "base/macros.h"
|
||||
#include "mojo/public/cpp/bindings/binding.h"
|
||||
#include "services/ws/remote_view_host/server_remote_view_host.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
// Implementation of ArcCustomTabView interface.
|
||||
class ArcCustomTabView : public views::View, public mojom::ArcCustomTabView {
|
||||
public:
|
||||
// Creates a new ArcCustomTabView instance. The instance will be deleted when
|
||||
// the pointer is closed. Returns null when the arguments are invalid.
|
||||
static mojom::ArcCustomTabViewPtr Create(int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin);
|
||||
|
||||
// mojom::ArcCustomTabView:
|
||||
void EmbedUsingToken(const base::UnguessableToken& token) override;
|
||||
|
||||
// views::View:
|
||||
void Layout() override;
|
||||
|
||||
private:
|
||||
ArcCustomTabView(int32_t surface_id, int32_t top_margin);
|
||||
~ArcCustomTabView() override;
|
||||
|
||||
// Binds this instance to the pointer.
|
||||
void Bind(mojom::ArcCustomTabViewPtr* ptr);
|
||||
|
||||
// Deletes this object when the mojo connection is closed.
|
||||
void Close();
|
||||
|
||||
// Converts the point from the given window to this view.
|
||||
void ConvertPointFromWindow(aura::Window* window, gfx::Point* point);
|
||||
|
||||
mojo::Binding<mojom::ArcCustomTabView> binding_;
|
||||
std::unique_ptr<ws::ServerRemoteViewHost> remote_view_host_;
|
||||
int32_t surface_id_, top_margin_;
|
||||
base::WeakPtrFactory<ArcCustomTabView> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ArcCustomTabView);
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_CUSTOM_TAB_ARC_CUSTOM_TAB_VIEW_H_
|
@ -17,6 +17,7 @@
|
||||
#include "ash/assistant/assistant_setup_controller.h"
|
||||
#include "ash/cast_config_controller.h"
|
||||
#include "ash/contained_shell/contained_shell_controller.h"
|
||||
#include "ash/custom_tab/arc_custom_tab_controller.h"
|
||||
#include "ash/display/ash_display_controller.h"
|
||||
#include "ash/display/cros_display_config.h"
|
||||
#include "ash/display/display_output_protection.h"
|
||||
@ -82,6 +83,11 @@ void BindAppListControllerRequestOnMainThread(
|
||||
Shell::Get()->app_list_controller()->BindRequest(std::move(request));
|
||||
}
|
||||
|
||||
void BindArcCustomTabControllerRequestOnMainThread(
|
||||
mojom::ArcCustomTabControllerRequest request) {
|
||||
Shell::Get()->arc_custom_tab_controller()->BindRequest(std::move(request));
|
||||
}
|
||||
|
||||
void BindAshDisplayControllerRequestOnMainThread(
|
||||
mojom::AshDisplayControllerRequest request) {
|
||||
Shell::Get()->ash_display_controller()->BindRequest(std::move(request));
|
||||
@ -274,6 +280,9 @@ void RegisterInterfaces(
|
||||
registry->AddInterface(
|
||||
base::BindRepeating(&BindAppListControllerRequestOnMainThread),
|
||||
main_thread_task_runner);
|
||||
registry->AddInterface(
|
||||
base::BindRepeating(&BindArcCustomTabControllerRequestOnMainThread),
|
||||
main_thread_task_runner);
|
||||
if (chromeos::switches::IsAssistantEnabled()) {
|
||||
registry->AddInterface(
|
||||
base::BindRepeating(
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ash/public/interfaces/accessibility_controller.mojom.h"
|
||||
#include "ash/public/interfaces/accessibility_focus_ring_controller.mojom.h"
|
||||
#include "ash/public/interfaces/app_list.mojom.h"
|
||||
#include "ash/public/interfaces/arc_custom_tab.mojom.h"
|
||||
#include "ash/public/interfaces/ash_display_controller.mojom.h"
|
||||
#include "ash/public/interfaces/ash_message_center_controller.mojom.h"
|
||||
#include "ash/public/interfaces/assistant_controller.mojom.h"
|
||||
@ -79,7 +80,8 @@ const service_manager::Manifest& GetManifest() {
|
||||
service_manager::Manifest::InterfaceList<
|
||||
mojom::AcceleratorController, mojom::AccessibilityController,
|
||||
mojom::AccessibilityFocusRingController,
|
||||
mojom::AppListController, mojom::AshMessageCenterController,
|
||||
mojom::AppListController, mojom::ArcCustomTabController,
|
||||
mojom::AshMessageCenterController,
|
||||
mojom::AssistantAlarmTimerController,
|
||||
mojom::AssistantController,
|
||||
mojom::AssistantNotificationController,
|
||||
|
@ -18,6 +18,7 @@ mojom("interfaces_internal") {
|
||||
"accessibility_controller_enums.mojom",
|
||||
"accessibility_focus_ring_controller.mojom",
|
||||
"app_list.mojom",
|
||||
"arc_custom_tab.mojom",
|
||||
"ash_display_controller.mojom",
|
||||
"ash_message_center_controller.mojom",
|
||||
"ash_window_manager.mojom",
|
||||
|
22
ash/public/interfaces/arc_custom_tab.mojom
Normal file
22
ash/public/interfaces/arc_custom_tab.mojom
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
module ash.mojom;
|
||||
|
||||
import "mojo/public/mojom/base/unguessable_token.mojom";
|
||||
|
||||
// An interface that an ash user uses to interact with each ARC custom tab.
|
||||
interface ArcCustomTabView {
|
||||
// Embeds the remote view specified by the token.
|
||||
EmbedUsingToken(mojo_base.mojom.UnguessableToken token);
|
||||
};
|
||||
|
||||
// An exported object in ash which lets an ash consumer set a client interface.
|
||||
interface ArcCustomTabController {
|
||||
// Creates an ArcCustomTabView instance for the ARC window specified by the
|
||||
// task ID and the surface ID.
|
||||
// May return null when the arguments are invalid.
|
||||
CreateView(int32 task_id, int32 surface_id, int32 top_margin)
|
||||
=> (ArcCustomTabView? controller);
|
||||
};
|
@ -25,6 +25,7 @@
|
||||
#include "ash/cast_config_controller.h"
|
||||
#include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"
|
||||
#include "ash/contained_shell/contained_shell_controller.h"
|
||||
#include "ash/custom_tab/arc_custom_tab_controller.h"
|
||||
#include "ash/dbus/ash_dbus_services.h"
|
||||
#include "ash/detachable_base/detachable_base_handler.h"
|
||||
#include "ash/detachable_base/detachable_base_notification_controller.h"
|
||||
@ -632,6 +633,7 @@ Shell::Shell(std::unique_ptr<ShellDelegate> shell_delegate,
|
||||
: nullptr),
|
||||
aura_env_(owned_aura_env_.get() ? owned_aura_env_.get()
|
||||
: aura::Env::GetInstance()),
|
||||
arc_custom_tab_controller_(std::make_unique<ArcCustomTabController>()),
|
||||
ash_display_controller_(std::make_unique<AshDisplayController>()),
|
||||
brightness_control_delegate_(
|
||||
std::make_unique<system::BrightnessControllerChromeos>()),
|
||||
|
@ -94,6 +94,7 @@ class AcceleratorController;
|
||||
class AccessibilityController;
|
||||
class AccessibilityDelegate;
|
||||
class AccessibilityFocusRingController;
|
||||
class ArcCustomTabController;
|
||||
class AshDBusServices;
|
||||
class AshDisplayController;
|
||||
class AppListControllerImpl;
|
||||
@ -343,6 +344,9 @@ class ASH_EXPORT Shell : public SessionObserver,
|
||||
AppListControllerImpl* app_list_controller() {
|
||||
return app_list_controller_.get();
|
||||
}
|
||||
ArcCustomTabController* arc_custom_tab_controller() {
|
||||
return arc_custom_tab_controller_.get();
|
||||
}
|
||||
AshDisplayController* ash_display_controller() {
|
||||
return ash_display_controller_.get();
|
||||
}
|
||||
@ -704,6 +708,7 @@ class ASH_EXPORT Shell : public SessionObserver,
|
||||
std::unique_ptr<AccessibilityFocusRingController>
|
||||
accessibility_focus_ring_controller_;
|
||||
std::unique_ptr<AppListControllerImpl> app_list_controller_;
|
||||
std::unique_ptr<ArcCustomTabController> arc_custom_tab_controller_;
|
||||
std::unique_ptr<AshDBusServices> ash_dbus_services_;
|
||||
std::unique_ptr<AshDisplayController> ash_display_controller_;
|
||||
std::unique_ptr<AssistantController> assistant_controller_;
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "chrome/browser/ui/ash/chrome_new_window_client.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ash/public/cpp/ash_features.h"
|
||||
#include "ash/public/interfaces/constants.mojom.h"
|
||||
#include "base/macros.h"
|
||||
@ -17,6 +19,7 @@
|
||||
#include "chrome/browser/prefs/incognito_mode_prefs.h"
|
||||
#include "chrome/browser/profiles/profile_manager.h"
|
||||
#include "chrome/browser/sessions/tab_restore_service_factory.h"
|
||||
#include "chrome/browser/tab_contents/tab_util.h"
|
||||
#include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
|
||||
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
@ -44,8 +47,10 @@
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "services/service_manager/public/cpp/connector.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/page_transition_types.h"
|
||||
#include "ui/base/window_open_disposition.h"
|
||||
#include "ui/views/mus/remote_view/remote_view_provider.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
namespace {
|
||||
@ -65,6 +70,88 @@ bool IsIncognitoAllowed() {
|
||||
IncognitoModePrefs::DISABLED;
|
||||
}
|
||||
|
||||
// Converts the given ARC URL to an external file URL to read it via ARC content
|
||||
// file system when necessary. Otherwise, returns the given URL unchanged.
|
||||
GURL ConvertArcUrlToExternalFileUrlIfNeeded(const GURL& url) {
|
||||
if (url.SchemeIs(url::kFileScheme) || url.SchemeIs(url::kContentScheme)) {
|
||||
// Chrome cannot open this URL. Read the contents via ARC content file
|
||||
// system with an external file URL.
|
||||
return arc::ArcUrlToExternalFileUrl(url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// Implementation of CustomTabSession interface.
|
||||
class CustomTabSessionImpl : public arc::mojom::CustomTabSession {
|
||||
public:
|
||||
static arc::mojom::CustomTabSessionPtr Create(
|
||||
Profile* profile,
|
||||
const GURL& url,
|
||||
ash::mojom::ArcCustomTabViewPtr view) {
|
||||
// This object will be deleted when the mojo connection is closed.
|
||||
auto* tab = new CustomTabSessionImpl(profile, url, std::move(view));
|
||||
arc::mojom::CustomTabSessionPtr ptr;
|
||||
tab->Bind(&ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
CustomTabSessionImpl(Profile* profile,
|
||||
const GURL& url,
|
||||
ash::mojom::ArcCustomTabViewPtr view)
|
||||
: binding_(this),
|
||||
view_(std::move(view)),
|
||||
web_contents_(CreateWebContents(profile, url)),
|
||||
weak_ptr_factory_(this) {
|
||||
aura::Window* window = web_contents_->GetNativeView();
|
||||
remote_view_provider_ = std::make_unique<views::RemoteViewProvider>(window);
|
||||
remote_view_provider_->GetEmbedToken(base::BindOnce(
|
||||
&CustomTabSessionImpl::OnEmbedToken, weak_ptr_factory_.GetWeakPtr()));
|
||||
window->Show();
|
||||
}
|
||||
|
||||
~CustomTabSessionImpl() override = default;
|
||||
|
||||
void Bind(arc::mojom::CustomTabSessionPtr* ptr) {
|
||||
binding_.Bind(mojo::MakeRequest(ptr));
|
||||
binding_.set_connection_error_handler(base::BindOnce(
|
||||
&CustomTabSessionImpl::Close, weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
// Deletes this object when the mojo connection is closed.
|
||||
void Close() { delete this; }
|
||||
|
||||
std::unique_ptr<content::WebContents> CreateWebContents(Profile* profile,
|
||||
const GURL& url) {
|
||||
scoped_refptr<content::SiteInstance> site_instance =
|
||||
tab_util::GetSiteInstanceForNewTab(profile, url);
|
||||
content::WebContents::CreateParams create_params(profile, site_instance);
|
||||
std::unique_ptr<content::WebContents> web_contents =
|
||||
content::WebContents::Create(create_params);
|
||||
|
||||
content::NavigationController::LoadURLParams load_url_params(url);
|
||||
load_url_params.source_site_instance = site_instance;
|
||||
web_contents->GetController().LoadURLWithParams(load_url_params);
|
||||
|
||||
// Add a flag to remember this tab originated in the ARC context.
|
||||
web_contents->SetUserData(&arc::ArcWebContentsData::kArcTransitionFlag,
|
||||
std::make_unique<arc::ArcWebContentsData>());
|
||||
return web_contents;
|
||||
}
|
||||
|
||||
void OnEmbedToken(const base::UnguessableToken& token) {
|
||||
view_->EmbedUsingToken(token);
|
||||
}
|
||||
|
||||
mojo::Binding<arc::mojom::CustomTabSession> binding_;
|
||||
ash::mojom::ArcCustomTabViewPtr view_;
|
||||
std::unique_ptr<content::WebContents> web_contents_;
|
||||
std::unique_ptr<views::RemoteViewProvider> remote_view_provider_;
|
||||
base::WeakPtrFactory<CustomTabSessionImpl> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomTabSessionImpl);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ChromeNewWindowClient::ChromeNewWindowClient() : binding_(this) {
|
||||
@ -73,6 +160,8 @@ ChromeNewWindowClient::ChromeNewWindowClient() : binding_(this) {
|
||||
service_manager::Connector* connector =
|
||||
content::ServiceManagerConnection::GetForProcess()->GetConnector();
|
||||
connector->BindInterface(ash::mojom::kServiceName, &new_window_controller_);
|
||||
connector->BindInterface(ash::mojom::kServiceName,
|
||||
&arc_custom_tab_controller_);
|
||||
|
||||
// Register this object as the client interface implementation.
|
||||
ash::mojom::NewWindowClientAssociatedPtrInfo ptr_info;
|
||||
@ -255,13 +344,7 @@ void ChromeNewWindowClient::OpenUrlFromArc(const GURL& url) {
|
||||
if (!url.is_valid())
|
||||
return;
|
||||
|
||||
GURL url_to_open = url;
|
||||
if (url.SchemeIs(url::kFileScheme) || url.SchemeIs(url::kContentScheme)) {
|
||||
// Chrome cannot open this URL. Read the contents via ARC content file
|
||||
// system with an external file URL.
|
||||
url_to_open = arc::ArcUrlToExternalFileUrl(url_to_open);
|
||||
}
|
||||
|
||||
GURL url_to_open = ConvertArcUrlToExternalFileUrlIfNeeded(url);
|
||||
content::WebContents* tab =
|
||||
OpenUrlImpl(url_to_open, false /* from_user_interaction */);
|
||||
if (!tab)
|
||||
@ -310,6 +393,30 @@ void ChromeNewWindowClient::OpenWebAppFromArc(const GURL& url) {
|
||||
std::make_unique<arc::ArcWebContentsData>());
|
||||
}
|
||||
|
||||
void ChromeNewWindowClient::OpenArcCustomTab(
|
||||
const GURL& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
arc::mojom::IntentHelperHost::OnOpenCustomTabCallback callback) {
|
||||
GURL url_to_open = ConvertArcUrlToExternalFileUrlIfNeeded(url);
|
||||
Profile* profile = ProfileManager::GetActiveUserProfile();
|
||||
arc_custom_tab_controller_->CreateView(
|
||||
task_id, surface_id, top_margin,
|
||||
base::BindOnce(
|
||||
[](Profile* profile, const GURL& url,
|
||||
arc::mojom::IntentHelperHost::OnOpenCustomTabCallback callback,
|
||||
ash::mojom::ArcCustomTabViewPtr view) {
|
||||
if (!view) {
|
||||
std::move(callback).Run(nullptr);
|
||||
return;
|
||||
}
|
||||
std::move(callback).Run(
|
||||
CustomTabSessionImpl::Create(profile, url, std::move(view)));
|
||||
},
|
||||
profile, url_to_open, std::move(callback)));
|
||||
}
|
||||
|
||||
content::WebContents* ChromeNewWindowClient::OpenUrlImpl(
|
||||
const GURL& url,
|
||||
bool from_user_interaction) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ash/public/interfaces/arc_custom_tab.mojom.h"
|
||||
#include "ash/public/interfaces/new_window.mojom.h"
|
||||
#include "base/macros.h"
|
||||
#include "components/arc/intent_helper/open_url_delegate.h"
|
||||
@ -42,6 +43,12 @@ class ChromeNewWindowClient : public ash::mojom::NewWindowClient,
|
||||
// arc::OpenUrlDelegate:
|
||||
void OpenUrlFromArc(const GURL& url) override;
|
||||
void OpenWebAppFromArc(const GURL& url) override;
|
||||
void OpenArcCustomTab(
|
||||
const GURL& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
arc::mojom::IntentHelperHost::OnOpenCustomTabCallback callback) override;
|
||||
|
||||
private:
|
||||
class TabRestoreHelper;
|
||||
@ -58,6 +65,8 @@ class ChromeNewWindowClient : public ash::mojom::NewWindowClient,
|
||||
|
||||
ash::mojom::NewWindowControllerPtr new_window_controller_;
|
||||
|
||||
ash::mojom::ArcCustomTabControllerPtr arc_custom_tab_controller_;
|
||||
|
||||
// Binds this object to the client interface.
|
||||
mojo::AssociatedBinding<ash::mojom::NewWindowClient> binding_;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Next MinVersion: 25
|
||||
// Next MinVersion: 26
|
||||
|
||||
module arc.mojom;
|
||||
|
||||
@ -163,9 +163,14 @@ struct TextSelectionAction {
|
||||
[MinVersion=23] ArcBitmap? bitmap_icon;
|
||||
};
|
||||
|
||||
// Interface to interact with a custom tab.
|
||||
// Close the interface pointer to close the custom tab.
|
||||
interface CustomTabSession {
|
||||
};
|
||||
|
||||
// Handles intents from ARC in Chrome.
|
||||
// Deprecated method ID: 4
|
||||
// Next method ID: 10
|
||||
// Next method ID: 11
|
||||
interface IntentHelperHost {
|
||||
// Called when icons associated with the package are no longer up to date.
|
||||
[MinVersion=3] OnIconInvalidated@1(string package_name);
|
||||
@ -182,6 +187,17 @@ interface IntentHelperHost {
|
||||
// navigate to as well. No special URLs that allow access to privileged functions are allowed.
|
||||
OnOpenUrl@0(string url);
|
||||
|
||||
// Opens the url with a custom tab.
|
||||
// |task_id| and |surface_id| specify the Android task and the surface on
|
||||
// which the custom tab should be shown.
|
||||
// |top_margin| is the height of the space at the top of the window which
|
||||
// needs to be vacant to display the top bar rendered by Android code.
|
||||
[MinVersion=25] OnOpenCustomTab@10(string url,
|
||||
int32 task_id,
|
||||
int32 surface_id,
|
||||
int32 top_margin)
|
||||
=> (CustomTabSession? session);
|
||||
|
||||
// Opens the wallpaper picker dialog.
|
||||
[MinVersion=6] OpenWallpaperPicker@3();
|
||||
|
||||
|
@ -171,6 +171,23 @@ void ArcIntentHelperBridge::OnOpenUrl(const std::string& url) {
|
||||
g_open_url_delegate->OpenUrlFromArc(gurl);
|
||||
}
|
||||
|
||||
void ArcIntentHelperBridge::OnOpenCustomTab(const std::string& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
OnOpenCustomTabCallback callback) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
// Converts |url| to a fixed-up one and checks validity.
|
||||
const GURL gurl(url_formatter::FixupURL(url, /*desired_tld=*/std::string()));
|
||||
if (!gurl.is_valid() ||
|
||||
allowed_arc_schemes_.find(gurl.scheme()) == allowed_arc_schemes_.end()) {
|
||||
std::move(callback).Run(nullptr);
|
||||
return;
|
||||
}
|
||||
g_open_url_delegate->OpenArcCustomTab(gurl, task_id, surface_id, top_margin,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void ArcIntentHelperBridge::OnOpenChromePage(mojom::ChromePage page) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
auto it = allowed_chrome_pages_map_.find(page);
|
||||
|
@ -65,6 +65,11 @@ class ArcIntentHelperBridge
|
||||
std::vector<IntentFilter> intent_filters) override;
|
||||
void OnOpenDownloads() override;
|
||||
void OnOpenUrl(const std::string& url) override;
|
||||
void OnOpenCustomTab(const std::string& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
OnOpenCustomTabCallback callback) override;
|
||||
void OnOpenChromePage(mojom::ChromePage page) override;
|
||||
void OpenWallpaperPicker() override;
|
||||
void SetWallpaperDeprecated(const std::vector<uint8_t>& jpeg_data) override;
|
||||
|
@ -40,6 +40,14 @@ class ArcIntentHelperTest : public testing::Test {
|
||||
// OpenUrlDelegate:
|
||||
void OpenUrlFromArc(const GURL& url) override { last_opened_url_ = url; }
|
||||
void OpenWebAppFromArc(const GURL& url) override { last_opened_url_ = url; }
|
||||
void OpenArcCustomTab(
|
||||
const GURL& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
mojom::IntentHelperHost::OnOpenCustomTabCallback callback) override {
|
||||
std::move(callback).Run(nullptr);
|
||||
}
|
||||
|
||||
GURL TakeLastOpenedUrl() {
|
||||
GURL result = std::move(last_opened_url_);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef COMPONENTS_ARC_INTENT_HELPER_OPEN_URL_DELEGATE_H_
|
||||
#define COMPONENTS_ARC_INTENT_HELPER_OPEN_URL_DELEGATE_H_
|
||||
|
||||
#include "components/arc/common/intent_helper.mojom.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace arc {
|
||||
@ -19,6 +21,14 @@ class OpenUrlDelegate {
|
||||
// Opens the given URL as a web app in the Chrome browser, falling back to
|
||||
// opening as a tab if no installed web app is found.
|
||||
virtual void OpenWebAppFromArc(const GURL& url) = 0;
|
||||
|
||||
// Opens the given URL in a custom tab.
|
||||
virtual void OpenArcCustomTab(
|
||||
const GURL& url,
|
||||
int32_t task_id,
|
||||
int32_t surface_id,
|
||||
int32_t top_margin,
|
||||
mojom::IntentHelperHost::OnOpenCustomTabCallback callback) = 0;
|
||||
};
|
||||
|
||||
} // namespace arc
|
||||
|
Reference in New Issue
Block a user