Commit 5f87dd90 authored by wutao's avatar wutao Committed by Commit Bot

assistant: Handle back event in web container

This patch updates the back button visibility for Assistant web
container.

Bug: b/141268413
Test: manual
Change-Id: I2dfd3209e4954e04295340d48f05516bde37d09a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1873147
Commit-Queue: Tao Wu <wutao@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712852}
parent ed773dfb
......@@ -210,6 +210,8 @@ component("ash") {
"assistant/assistant_view_delegate_impl.h",
"assistant/assistant_web_ui_controller.cc",
"assistant/assistant_web_ui_controller.h",
"assistant/assistant_web_view_delegate_impl.cc",
"assistant/assistant_web_view_delegate_impl.h",
"autoclick/autoclick_controller.cc",
"autoclick/autoclick_controller.h",
"autoclick/autoclick_drag_event_rewriter.cc",
......
......@@ -85,8 +85,9 @@ void AssistantPageView::InitLayout() {
// Do not add web view when Assistant web container is enabled.
if (!chromeos::assistant::features::IsAssistantWebContainerEnabled()) {
assistant_web_view_ = AddChildView(
std::make_unique<AssistantWebView>(assistant_view_delegate_));
assistant_web_view_ = AddChildView(std::make_unique<AssistantWebView>(
assistant_view_delegate_,
/*web_container_view_delegate=*/nullptr));
}
// Update the view state based on the current UI mode.
......
......@@ -399,7 +399,8 @@ void AssistantUiController::OnDeepLinkReceived(
assistant::util::DeepLinkType type,
const std::map<std::string, std::string>& params) {
// This method only handles web deep links, which will be handled separately
// in |AssistantWebUiController| when Assistant web container is enabled.
// in |AssistantWebUiController| when Assistant web container is
// enabled.
if (chromeos::assistant::features::IsAssistantWebContainerEnabled())
return;
......
......@@ -12,14 +12,65 @@
#include "ash/shell.h"
#include "chromeos/services/assistant/public/features.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/events/event_observer.h"
#include "ui/views/event_monitor.h"
namespace ash {
// -----------------------------------------------------------------------------
// AssistantWebContainerEventObserver:
class AssistantWebContainerEventObserver : public ui::EventObserver {
public:
AssistantWebContainerEventObserver(AssistantWebUiController* owner,
views::Widget* widget)
: owner_(owner),
widget_(widget),
event_monitor_(
views::EventMonitor::CreateWindowMonitor(this,
widget->GetNativeWindow(),
{ui::ET_KEY_PRESSED})) {}
~AssistantWebContainerEventObserver() override = default;
// ui::EventObserver:
void OnEvent(const ui::Event& event) override {
DCHECK(event.type() == ui::ET_KEY_PRESSED);
const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
switch (key_event.key_code()) {
case ui::VKEY_BROWSER_BACK:
owner_->OnBackButtonPressed();
break;
case ui::VKEY_W:
if (!key_event.IsControlDown())
break;
event_monitor_.reset();
widget_->Close();
break;
default:
// No action necessary.
break;
}
}
private:
AssistantWebUiController* owner_ = nullptr;
views::Widget* widget_ = nullptr;
std::unique_ptr<views::EventMonitor> event_monitor_;
DISALLOW_COPY_AND_ASSIGN(AssistantWebContainerEventObserver);
};
// -----------------------------------------------------------------------------
// AssistantWebUiController:
AssistantWebUiController::AssistantWebUiController(
AssistantController* assistant_controller)
: assistant_controller_(assistant_controller) {
DCHECK(chromeos::assistant::features::IsAssistantWebContainerEnabled());
assistant_controller_->AddObserver(this);
}
......@@ -56,6 +107,11 @@ void AssistantWebUiController::ShowUi() {
web_container_view_->GetWidget()->Show();
}
void AssistantWebUiController::OnBackButtonPressed() {
DCHECK(web_container_view_);
web_container_view_->OnBackButtonPressed();
}
AssistantWebContainerView* AssistantWebUiController::GetViewForTest() {
return web_container_view_;
}
......@@ -63,9 +119,12 @@ AssistantWebContainerView* AssistantWebUiController::GetViewForTest() {
void AssistantWebUiController::CreateWebContainerView() {
DCHECK(!web_container_view_);
web_container_view_ =
new AssistantWebContainerView(assistant_controller_->view_delegate());
web_container_view_->GetWidget()->AddObserver(this);
web_container_view_ = new AssistantWebContainerView(
assistant_controller_->view_delegate(), &view_delegate_);
auto* widget = web_container_view_->GetWidget();
widget->AddObserver(this);
event_observer_ =
std::make_unique<AssistantWebContainerEventObserver>(this, widget);
// Associate the window for Assistant Web UI with the active user in order to
// not leak across user sessions.
......@@ -78,16 +137,16 @@ void AssistantWebUiController::CreateWebContainerView() {
if (!active_user_session)
return;
web_container_view_->GetWidget()->GetNativeWindow()->SetProperty(
aura::client::kCreatedByUserGesture, true);
window_manager->SetWindowOwner(
web_container_view_->GetWidget()->GetNativeWindow(),
active_user_session->user_info.account_id);
auto* native_window = widget->GetNativeWindow();
native_window->SetProperty(aura::client::kCreatedByUserGesture, true);
window_manager->SetWindowOwner(native_window,
active_user_session->user_info.account_id);
}
void AssistantWebUiController::ResetWebContainerView() {
DCHECK(web_container_view_);
event_observer_.reset();
web_container_view_->GetWidget()->RemoveObserver(this);
web_container_view_ = nullptr;
}
......
......@@ -5,8 +5,11 @@
#ifndef ASH_ASSISTANT_ASSISTANT_WEB_UI_CONTROLLER_H_
#define ASH_ASSISTANT_ASSISTANT_WEB_UI_CONTROLLER_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/assistant/assistant_controller_observer.h"
#include "ash/assistant/assistant_web_view_delegate_impl.h"
#include "base/macros.h"
#include "ui/views/widget/widget_observer.h"
......@@ -14,6 +17,7 @@ namespace ash {
class AssistantController;
class AssistantWebContainerView;
class AssistantWebContainerEventObserver;
// The class to manage Assistant web container view.
class ASH_EXPORT AssistantWebUiController : public views::WidgetObserver,
......@@ -31,6 +35,8 @@ class ASH_EXPORT AssistantWebUiController : public views::WidgetObserver,
assistant::util::DeepLinkType type,
const std::map<std::string, std::string>& params) override;
void OnBackButtonPressed();
AssistantWebContainerView* GetViewForTest();
private:
......@@ -42,9 +48,14 @@ class ASH_EXPORT AssistantWebUiController : public views::WidgetObserver,
AssistantController* const assistant_controller_; // Owned by Shell.
AssistantWebViewDelegateImpl view_delegate_;
// Owned by view hierarchy.
AssistantWebContainerView* web_container_view_ = nullptr;
// Observes key press events on the |web_container_view_|.
std::unique_ptr<AssistantWebContainerEventObserver> event_observer_;
DISALLOW_COPY_AND_ASSIGN(AssistantWebUiController);
};
......
// 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/assistant/assistant_web_view_delegate_impl.h"
#include "ash/frame/non_client_frame_view_ash.h"
#include "ash/public/cpp/caption_buttons/caption_button_model.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/caption_button_types.h"
#include "ui/views/window/non_client_view.h"
namespace ash {
namespace {
class AssistantWebContainerCaptionButtonModel : public CaptionButtonModel {
public:
AssistantWebContainerCaptionButtonModel() = default;
~AssistantWebContainerCaptionButtonModel() override = default;
// CaptionButtonModel:
bool IsVisible(views::CaptionButtonIcon type) const override {
switch (type) {
case views::CAPTION_BUTTON_ICON_CLOSE:
return true;
case views::CAPTION_BUTTON_ICON_BACK:
return back_button_visibility_;
case views::CAPTION_BUTTON_ICON_MINIMIZE:
case views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
case views::CAPTION_BUTTON_ICON_LEFT_SNAPPED:
case views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
case views::CAPTION_BUTTON_ICON_MENU:
case views::CAPTION_BUTTON_ICON_ZOOM:
case views::CAPTION_BUTTON_ICON_LOCATION:
case views::CAPTION_BUTTON_ICON_COUNT:
return false;
}
}
bool IsEnabled(views::CaptionButtonIcon type) const override { return true; }
bool InZoomMode() const override { return false; }
void set_back_button_visibility(bool visibility) {
back_button_visibility_ = visibility;
}
private:
bool back_button_visibility_ = false;
DISALLOW_COPY_AND_ASSIGN(AssistantWebContainerCaptionButtonModel);
};
} // namespace
AssistantWebViewDelegateImpl::AssistantWebViewDelegateImpl() = default;
AssistantWebViewDelegateImpl::~AssistantWebViewDelegateImpl() = default;
void AssistantWebViewDelegateImpl::UpdateBackButtonVisibility(
views::Widget* widget,
bool visibility) {
auto caption_button_model =
std::make_unique<AssistantWebContainerCaptionButtonModel>();
caption_button_model->set_back_button_visibility(visibility);
auto* non_client_view = widget->non_client_view();
DCHECK_EQ(NonClientFrameViewAsh::kViewClassName,
non_client_view->GetClassName());
auto* frame_view_ash =
static_cast<NonClientFrameViewAsh*>(non_client_view->frame_view());
frame_view_ash->SetCaptionButtonModel(std::move(caption_button_model));
}
} // namespace ash
// 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_ASSISTANT_ASSISTANT_WEB_VIEW_DELEGATE_IMPL_H_
#define ASH_ASSISTANT_ASSISTANT_WEB_VIEW_DELEGATE_IMPL_H_
#include "ash/assistant/ui/assistant_web_view_delegate.h"
#include "base/macros.h"
namespace ash {
class AssistantWebViewDelegateImpl : public AssistantWebViewDelegate {
public:
AssistantWebViewDelegateImpl();
~AssistantWebViewDelegateImpl() override;
// AssistantWebViewDelegate:
void UpdateBackButtonVisibility(views::Widget* widget,
bool visibility) override;
private:
DISALLOW_COPY_AND_ASSIGN(AssistantWebViewDelegateImpl);
};
} // namespace ash
#endif // ASH_ASSISTANT_ASSISTANT_WEB_VIEW_DELEGATE_IMPL_H_
......@@ -55,6 +55,7 @@ component("ui") {
"assistant_web_container_view.h",
"assistant_web_view.cc",
"assistant_web_view.h",
"assistant_web_view_delegate.h",
"base/assistant_button.cc",
"base/assistant_button.h",
"base/assistant_scroll_view.cc",
......
......@@ -332,16 +332,17 @@ void AssistantContainerView::Init() {
layer()->SetFillsBoundsOpaquely(false);
// Main view.
assistant_main_view_ = new AssistantMainViewDeprecated(delegate_);
AddChildView(assistant_main_view_);
assistant_main_view_ =
AddChildView(std::make_unique<AssistantMainViewDeprecated>(delegate_));
// Mini view.
assistant_mini_view_ = new AssistantMiniView(delegate_);
AddChildView(assistant_mini_view_);
assistant_mini_view_ =
AddChildView(std::make_unique<AssistantMiniView>(delegate_));
// Web view.
assistant_web_view_ = new AssistantWebView(delegate_);
AddChildView(assistant_web_view_);
assistant_web_view_ = AddChildView(std::make_unique<AssistantWebView>(
delegate_,
/*web_container_view_delegate=*/nullptr));
// Update the view state based on the current UI mode.
OnUiModeChanged(delegate_->GetUiModel()->ui_mode(),
......
......@@ -7,6 +7,7 @@
#include <algorithm>
#include <memory>
#include "ash/assistant/model/assistant_ui_model.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/ui/assistant_web_view.h"
......@@ -31,8 +32,10 @@ constexpr int kPreferredPaddingMinDip = 48;
} // namespace
AssistantWebContainerView::AssistantWebContainerView(
AssistantViewDelegate* delegate)
: delegate_(delegate) {
AssistantViewDelegate* assistant_view_delegate,
AssistantWebViewDelegate* web_container_view_delegate)
: assistant_view_delegate_(assistant_view_delegate),
web_container_view_delegate_(web_container_view_delegate) {
InitLayout();
}
......@@ -60,6 +63,14 @@ gfx::Size AssistantWebContainerView::CalculatePreferredSize() const {
return gfx::Size(width, height - non_client_frame_view_height);
}
void AssistantWebContainerView::OnBackButtonPressed() {
assistant_web_view_->OnCaptionButtonPressed(AssistantButtonId::kBack);
}
views::View* AssistantWebContainerView::GetCaptionBarForTesting() {
return assistant_web_view_->caption_bar_for_testing();
}
void AssistantWebContainerView::InitLayout() {
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_WINDOW;
......@@ -73,7 +84,8 @@ void AssistantWebContainerView::InitLayout() {
SetBackground(views::CreateSolidBackground(SK_ColorWHITE));
// Web view.
AddChildView(std::make_unique<AssistantWebView>(delegate_));
assistant_web_view_ = AddChildView(std::make_unique<AssistantWebView>(
assistant_view_delegate_, web_container_view_delegate_));
}
} // namespace ash
......@@ -12,22 +12,34 @@
namespace ash {
class AssistantViewDelegate;
class AssistantWebViewDelegate;
class AssistantWebView;
// The container of assistant_web_view when Assistant web container is enabled.
class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebContainerView
: public views::WidgetDelegateView {
public:
explicit AssistantWebContainerView(AssistantViewDelegate* delegate);
AssistantWebContainerView(
AssistantViewDelegate* assistant_view_delegate,
AssistantWebViewDelegate* web_container_view_delegate);
~AssistantWebContainerView() override;
// views::WidgetDelegateView:
const char* GetClassName() const override;
gfx::Size CalculatePreferredSize() const override;
void OnBackButtonPressed();
views::View* GetCaptionBarForTesting();
private:
void InitLayout();
AssistantViewDelegate* const delegate_;
AssistantViewDelegate* const assistant_view_delegate_;
AssistantWebViewDelegate* const web_container_view_delegate_;
// Owned by the views hierarchy.
AssistantWebView* assistant_web_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AssistantWebContainerView);
};
......
......@@ -11,8 +11,10 @@
#include "ash/public/cpp/assistant/assistant_settings.h"
#include "ash/shell.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "chromeos/services/assistant/public/features.h"
#include "ui/events/test/event_generator.h"
namespace ash {
......@@ -89,4 +91,28 @@ TEST_F(AssistantWebContainerViewTest, CenterWindow) {
}
}
TEST_F(AssistantWebContainerViewTest, CloseWindowByKeyEvent) {
// Show Assistant Settings UI.
OpenAssistantSettings();
ASSERT_TRUE(view());
// Close Assistant Settings UI by key event.
ui::test::EventGenerator* generator = GetEventGenerator();
generator->PressKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(view());
}
TEST_F(AssistantWebContainerViewTest, NoCaptionBarInAssistantWebView) {
// Show Assistant Settings UI.
OpenAssistantSettings();
AssistantWebContainerView* container_view = view();
ASSERT_TRUE(container_view);
// AssistantWebContainerView's widget should have its own caption buttons in
// the ash frame view. Therefore the AssistantWebView should not have the
// caption bar.
ASSERT_FALSE(container_view->GetCaptionBarForTesting());
}
} // namespace ash
......@@ -9,8 +9,8 @@
#include "ash/assistant/model/assistant_ui_model.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/ui/assistant_view_ids.h"
#include "ash/assistant/ui/assistant_web_view_delegate.h"
#include "ash/assistant/util/deep_link_util.h"
#include "ash/public/cpp/app_list/app_list_features.h"
#include "base/bind.h"
......@@ -29,24 +29,27 @@ namespace ash {
// AssistantWebView ------------------------------------------------------------
AssistantWebView::AssistantWebView(AssistantViewDelegate* delegate)
: delegate_(delegate) {
AssistantWebView::AssistantWebView(
AssistantViewDelegate* assistant_view_delegate,
AssistantWebViewDelegate* web_container_view_delegate)
: assistant_view_delegate_(assistant_view_delegate),
web_container_view_delegate_(web_container_view_delegate) {
SetID(AssistantViewID::kWebView);
InitLayout();
delegate_->AddObserver(this);
assistant_view_delegate_->AddObserver(this);
// |AssistantWebView| has its own separate container when Assistant web
// container is enabled. The container will handle its own lifecycle.
if (!chromeos::assistant::features::IsAssistantWebContainerEnabled())
delegate_->AddUiModelObserver(this);
assistant_view_delegate_->AddUiModelObserver(this);
}
AssistantWebView::~AssistantWebView() {
if (!chromeos::assistant::features::IsAssistantWebContainerEnabled())
delegate_->RemoveUiModelObserver(this);
assistant_view_delegate_->RemoveUiModelObserver(this);
delegate_->RemoveObserver(this);
assistant_view_delegate_->RemoveObserver(this);
}
const char* AssistantWebView::GetClassName() const {
......@@ -68,7 +71,7 @@ int AssistantWebView::GetHeightForWidth(int width) const {
// |height| <= |kMaxHeightDip|.
// |height| should not exceed the height of the usable work area.
const gfx::Rect usable_work_area =
delegate_->GetUiModel()->usable_work_area();
assistant_view_delegate_->GetUiModel()->usable_work_area();
return std::min(kMaxHeightDip, usable_work_area.height());
}
......@@ -95,6 +98,10 @@ void AssistantWebView::InitLayout() {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
// Will use ash caption buttons when Assistant web container is enabled.
if (chromeos::assistant::features::IsAssistantWebContainerEnabled())
return;
// Caption bar.
caption_bar_ = new CaptionBar();
caption_bar_->set_delegate(this);
......@@ -114,7 +121,8 @@ bool AssistantWebView::OnCaptionButtonPressed(AssistantButtonId id) {
// 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->delegate_->GetCaptionBarDelegate()
assistant_web_view->assistant_view_delegate_
->GetCaptionBarDelegate()
->OnCaptionButtonPressed(AssistantButtonId::kBack);
}
},
......@@ -123,7 +131,8 @@ bool AssistantWebView::OnCaptionButtonPressed(AssistantButtonId id) {
}
// For all other buttons we defer to our primary caption button delegate.
return delegate_->GetCaptionBarDelegate()->OnCaptionButtonPressed(id);
return assistant_view_delegate_->GetCaptionBarDelegate()
->OnCaptionButtonPressed(id);
}
void AssistantWebView::OnDeepLinkReceived(
......@@ -135,7 +144,7 @@ void AssistantWebView::OnDeepLinkReceived(
RemoveContents();
if (!contents_factory_.is_bound()) {
delegate_->GetNavigableContentsFactoryForView(
assistant_view_delegate_->GetNavigableContentsFactoryForView(
contents_factory_.BindNewPipeAndPassReceiver());
}
......@@ -184,7 +193,7 @@ void AssistantWebView::DidSuppressNavigation(const GURL& url,
// browser.
if (assistant::util::IsDeepLinkUrl(url) ||
disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB) {
delegate_->OpenUrlFromView(url);
assistant_view_delegate_->OpenUrlFromView(url);
return;
}
......@@ -192,6 +201,15 @@ void AssistantWebView::DidSuppressNavigation(const GURL& url,
contents_->Navigate(url);
}
void AssistantWebView::UpdateCanGoBack(bool can_go_back) {
if (!chromeos::assistant::features::IsAssistantWebContainerEnabled())
return;
DCHECK(web_container_view_delegate_);
web_container_view_delegate_->UpdateBackButtonVisibility(GetWidget(),
can_go_back);
}
void AssistantWebView::OnUiVisibilityChanged(
AssistantVisibility new_visibility,
AssistantVisibility old_visibility,
......@@ -232,6 +250,11 @@ void AssistantWebView::UpdateContentSize() {
if (!contents_ || !contents_view_initialized_)
return;
if (chromeos::assistant::features::IsAssistantWebContainerEnabled()) {
contents_->GetView()->view()->SetPreferredSize(GetPreferredSize());
return;
}
const gfx::Size preferred_size = gfx::Size(
kPreferredWidthDip, GetHeightForWidth(kPreferredWidthDip) -
caption_bar_->GetPreferredSize().height());
......
......@@ -22,7 +22,7 @@
namespace ash {
enum class AssistantButtonId;
class AssistantViewDelegate;
class AssistantWebViewDelegate;
// AssistantWebView is a child of AssistantBubbleView which allows Assistant UI
// to render remotely hosted content within its bubble. It provides a CaptionBar
......@@ -35,7 +35,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView
public content::NavigableContentsObserver,
public AssistantUiModelObserver {
public:
explicit AssistantWebView(AssistantViewDelegate* delegate);
AssistantWebView(AssistantViewDelegate* assistant_view_delegate,
AssistantWebViewDelegate* web_container_view_delegate);
~AssistantWebView() override;
// views::View:
......@@ -59,6 +60,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView
void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) override;
void UpdateCanGoBack(bool can_go_back) override;
// AssistantUiModelObserver:
void OnUiVisibilityChanged(
......@@ -68,6 +70,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView
base::Optional<AssistantExitPoint> exit_point) override;
void OnUsableWorkAreaChanged(const gfx::Rect& usable_work_area) override;
views::View* caption_bar_for_testing() { return caption_bar_; }
private:
void InitLayout();
void RemoveContents();
......@@ -77,9 +81,12 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView
// work area changed.
void UpdateContentSize();
AssistantViewDelegate* const delegate_;
// TODO(b/143177141): Remove AssistantViewDelegate once standalone is
// deprecated.
AssistantViewDelegate* const assistant_view_delegate_;
AssistantWebViewDelegate* const web_container_view_delegate_;
CaptionBar* caption_bar_; // Owned by view hierarchy.
CaptionBar* caption_bar_ = nullptr; // Owned by view hierarchy.
mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_;
std::unique_ptr<content::NavigableContents> contents_;
......
// 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_ASSISTANT_UI_ASSISTANT_WEB_VIEW_DELEGATE_H_
#define ASH_ASSISTANT_UI_ASSISTANT_WEB_VIEW_DELEGATE_H_
#include "base/component_export.h"
namespace views {
class Widget;
} // namespace views
namespace ash {
// A delegate of web container views in assistant/ui.
class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebViewDelegate {
public:
virtual ~AssistantWebViewDelegate() = default;
// Updates the visibility of the back button in Assistant web container.
virtual void UpdateBackButtonVisibility(views::Widget* widget,
bool visibility) = 0;
};
} // namespace ash
#endif // ASH_ASSISTANT_UI_ASSISTANT_WEB_VIEW_DELEGATE_H_
......@@ -131,6 +131,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
client_->DidAutoResizeView(new_size);
}
void NavigationStateChanged(WebContents* source,
InvalidateTypes changed_flags) override {
MaybeNotifyCanGoBack();
}
// WebContentsObserver:
void RenderViewReady() override {
if (background_color_) {
......@@ -175,6 +180,23 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
void DidStopLoading() override { client_->DidStopLoading(); }
void NavigationEntriesDeleted() override { MaybeNotifyCanGoBack(); }
void DidAttachInterstitialPage() override { MaybeNotifyCanGoBack(); }
void DidDetachInterstitialPage() override { MaybeNotifyCanGoBack(); }
// Notifies the client whether the web contents can navigate back in its
// history stack.
void MaybeNotifyCanGoBack() {
const bool can_go_back = web_contents_->GetController().CanGoBack();
if (can_go_back_ == can_go_back)
return;
can_go_back_ = can_go_back;
client_->UpdateCanGoBack(can_go_back);
}
std::unique_ptr<WebContents> web_contents_;
mojom::NavigableContentsClient* const client_;
......@@ -183,6 +205,8 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
const gfx::Size auto_resize_max_size_;
const base::Optional<SkColor> background_color_;
bool can_go_back_ = false;
DISALLOW_COPY_AND_ASSIGN(NavigableContentsDelegateImpl);
};
......
......@@ -95,6 +95,11 @@ void NavigableContents::DidSuppressNavigation(const GURL& url,
observer.DidSuppressNavigation(url, disposition, from_user_gesture);
}
void NavigableContents::UpdateCanGoBack(bool can_go_back) {
for (auto& observer : observers_)
observer.UpdateCanGoBack(can_go_back);
}
void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) {
content_ax_tree_id_ = id;
if (view_)
......
......@@ -83,6 +83,7 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) override;
void UpdateCanGoBack(bool can_go_back) override;
void UpdateContentAXTree(const ui::AXTreeID& id) override;
void OnEmbedTokenReceived(const base::UnguessableToken& token);
......
......@@ -27,6 +27,7 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsObserver
virtual void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) {}
virtual void UpdateCanGoBack(bool can_go_back) {}
};
} // namespace content
......
......@@ -79,6 +79,10 @@ interface NavigableContentsClient {
ui.mojom.WindowOpenDisposition disposition,
bool from_user_gesture);
// Notifies the client whether the web contents can navigate back in its
// history stack.
UpdateCanGoBack(bool can_go_back);
// Informs the client of the ID of the content area's accessibility tree
// whenever it changes.
UpdateContentAXTree(ax.mojom.AXTreeID id);
......
......@@ -43,6 +43,7 @@ class TestNavigableContentsClient : public mojom::NavigableContentsClient {
void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition,
bool from_user_gesture) override {}
void UpdateCanGoBack(bool can_go_back) override {}
void UpdateContentAXTree(const ui::AXTreeID& id) override {}
DISALLOW_COPY_AND_ASSIGN(TestNavigableContentsClient);
......
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