Commit 126093fb authored by James Cook's avatar James Cook Committed by Commit Bot

cros: Move first-run Widget from ash to chrome

This is another step toward out-of-process ash (go/mustash).

* Create the Widget in FirstRunController in chrome
* Move escape key handling into chrome
* Stop using OverlayEventFilter in ash. The old code wasn't actually
  relying on it for blocking event propagation, just for escape key
  handling and detecting screen lock and shutdown. The old code was
  also watching for LoginStatus changes, but that dates back to the
  use of OverlayEventFilter for partial screenshots (no longer used)
  and isn't relevant to first-run.
* Add mojo interfaces to tell ash to start/stop tutorial

Bug: 756057
Test: ash_unittests, browser_tests
Change-Id: Icfd88e3541f1393b6a2309120c74bbe6a69b967f
Reviewed-on: https://chromium-review.googlesource.com/1000395
Commit-Queue: James Cook <jamescook@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551147}
parent 7b7146be
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "ash/first_run/first_run_helper.h" #include "ash/first_run/first_run_helper.h"
#include "ash/first_run/desktop_cleaner.h" #include "ash/first_run/desktop_cleaner.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/session/session_controller.h"
#include "ash/shelf/app_list_button.h" #include "ash/shelf/app_list_button.h"
#include "ash/shelf/shelf.h" #include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_widget.h" #include "ash/shelf/shelf_widget.h"
...@@ -14,29 +14,12 @@ ...@@ -14,29 +14,12 @@
#include "ash/system/tray/system_tray_bubble.h" #include "ash/system/tray/system_tray_bubble.h"
#include "base/logging.h" #include "base/logging.h"
#include "ui/app_list/views/app_list_view.h" #include "ui/app_list/views/app_list_view.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace ash { namespace ash {
namespace { namespace {
views::Widget* CreateFirstRunWindow() {
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
params.show_state = ui::SHOW_STATE_FULLSCREEN;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(),
ash::kShellWindowId_OverlayContainer);
views::Widget* window = new views::Widget;
window->Init(params);
return window;
}
} // namespace } // namespace
FirstRunHelper::FirstRunHelper() = default; FirstRunHelper::FirstRunHelper() = default;
...@@ -47,30 +30,16 @@ void FirstRunHelper::BindRequest(mojom::FirstRunHelperRequest request) { ...@@ -47,30 +30,16 @@ void FirstRunHelper::BindRequest(mojom::FirstRunHelperRequest request) {
bindings_.AddBinding(this, std::move(request)); bindings_.AddBinding(this, std::move(request));
} }
void FirstRunHelper::AddObserver(Observer* observer) { void FirstRunHelper::Start(mojom::FirstRunHelperClientPtr client) {
observers_.AddObserver(observer); client_ = std::move(client);
}
void FirstRunHelper::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
views::Widget* FirstRunHelper::GetOverlayWidget() {
return widget_;
}
void FirstRunHelper::CreateOverlayWidget() {
widget_ = CreateFirstRunWindow();
cleaner_ = std::make_unique<DesktopCleaner>(); cleaner_ = std::make_unique<DesktopCleaner>();
Shell::Get()->overlay_filter()->Activate(this); Shell::Get()->session_controller()->AddObserver(this);
} }
void FirstRunHelper::CloseOverlayWidget() { void FirstRunHelper::Stop() {
Shell::Get()->overlay_filter()->Deactivate(this); Shell::Get()->session_controller()->RemoveObserver(this);
// Ensure the tray is closed. // Ensure the tray is closed.
Shell::Get()->GetPrimarySystemTray()->CloseBubble(); Shell::Get()->GetPrimarySystemTray()->CloseBubble();
widget_->Close();
widget_ = nullptr;
cleaner_.reset(); cleaner_.reset();
} }
...@@ -103,19 +72,21 @@ void FirstRunHelper::GetHelpButtonBounds(GetHelpButtonBoundsCallback cb) { ...@@ -103,19 +72,21 @@ void FirstRunHelper::GetHelpButtonBounds(GetHelpButtonBoundsCallback cb) {
std::move(cb).Run(help_button->GetBoundsInScreen()); std::move(cb).Run(help_button->GetBoundsInScreen());
} }
// OverlayEventFilter::Delegate: void FirstRunHelper::OnLockStateChanged(bool locked) {
Cancel();
}
void FirstRunHelper::Cancel() { void FirstRunHelper::OnChromeTerminating() {
for (auto& observer : observers_) Cancel();
observer.OnCancelled();
} }
bool FirstRunHelper::IsCancelingKeyEvent(ui::KeyEvent* event) { void FirstRunHelper::FlushForTesting() {
return event->key_code() == ui::VKEY_ESCAPE; client_.FlushForTesting();
} }
aura::Window* FirstRunHelper::GetWindow() { void FirstRunHelper::Cancel() {
return widget_->GetNativeWindow(); if (client_)
client_->OnCancelled();
} }
} // namespace ash } // namespace ash
...@@ -7,15 +7,11 @@ ...@@ -7,15 +7,11 @@
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/public/interfaces/first_run_helper.mojom.h" #include "ash/public/interfaces/first_run_helper.mojom.h"
#include "ash/wm/overlay_event_filter.h" #include "ash/session/session_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
namespace views {
class Widget;
}
namespace ash { namespace ash {
class DesktopCleaner; class DesktopCleaner;
...@@ -23,50 +19,36 @@ class DesktopCleaner; ...@@ -23,50 +19,36 @@ class DesktopCleaner;
// Interface used by first-run tutorial to manipulate and retrieve information // Interface used by first-run tutorial to manipulate and retrieve information
// about shell elements. // about shell elements.
class ASH_EXPORT FirstRunHelper : public mojom::FirstRunHelper, class ASH_EXPORT FirstRunHelper : public mojom::FirstRunHelper,
public OverlayEventFilter::Delegate { public SessionObserver {
public:
class Observer {
public:
// Called when first-run UI was cancelled.
virtual void OnCancelled() = 0;
virtual ~Observer() {}
};
public: public:
FirstRunHelper(); FirstRunHelper();
~FirstRunHelper() override; ~FirstRunHelper() override;
void BindRequest(mojom::FirstRunHelperRequest request); void BindRequest(mojom::FirstRunHelperRequest request);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Returns widget to place tutorial UI into it.
// TODO(jamescook): Migrate widget into chrome and remove these methods.
views::Widget* GetOverlayWidget();
void CreateOverlayWidget();
void CloseOverlayWidget();
// mojom::FirstRunHelper: // mojom::FirstRunHelper:
void Start(mojom::FirstRunHelperClientPtr client) override;
void Stop() override;
void GetAppListButtonBounds(GetAppListButtonBoundsCallback cb) override; void GetAppListButtonBounds(GetAppListButtonBoundsCallback cb) override;
void OpenTrayBubble(OpenTrayBubbleCallback cb) override; void OpenTrayBubble(OpenTrayBubbleCallback cb) override;
void CloseTrayBubble() override; void CloseTrayBubble() override;
void GetHelpButtonBounds(GetHelpButtonBoundsCallback cb) override; void GetHelpButtonBounds(GetHelpButtonBoundsCallback cb) override;
// OverlayEventFilter::Delegate: // SessionObserver:
void Cancel() override; void OnLockStateChanged(bool locked) override;
bool IsCancelingKeyEvent(ui::KeyEvent* event) override; void OnChromeTerminating() override;
aura::Window* GetWindow() override;
void FlushForTesting();
private: private:
// Notifies the client to cancel the tutorial.
void Cancel();
// Bindings for clients of the mojo interface. // Bindings for clients of the mojo interface.
mojo::BindingSet<mojom::FirstRunHelper> bindings_; mojo::BindingSet<mojom::FirstRunHelper> bindings_;
// TODO(jamescook): Convert to mojo observer. // Client interface (e.g. chrome).
base::ObserverList<Observer> observers_; mojom::FirstRunHelperClientPtr client_;
// The first run dialog window.
views::Widget* widget_ = nullptr;
std::unique_ptr<DesktopCleaner> cleaner_; std::unique_ptr<DesktopCleaner> cleaner_;
......
...@@ -6,54 +6,14 @@ ...@@ -6,54 +6,14 @@
#include "ash/first_run/desktop_cleaner.h" #include "ash/first_run/desktop_cleaner.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ui/events/event_handler.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
namespace ash { namespace ash {
namespace { class FirstRunHelperTest : public AshTestBase,
public mojom::FirstRunHelperClient {
class TestModalDialogDelegate : public views::DialogDelegateView {
public:
TestModalDialogDelegate() = default;
~TestModalDialogDelegate() override = default;
// Overridden from views::WidgetDelegate:
ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; }
private:
DISALLOW_COPY_AND_ASSIGN(TestModalDialogDelegate);
};
class CountingEventHandler : public ui::EventHandler {
public:
// Handler resets |*mouse_events_registered_| during construction and updates
// it after each registered event.
explicit CountingEventHandler(int* mouse_events_registered)
: mouse_events_registered_(mouse_events_registered) {
*mouse_events_registered = 0;
}
~CountingEventHandler() override = default;
private:
// ui::EventHandler overrides.
void OnMouseEvent(ui::MouseEvent* event) override {
++*mouse_events_registered_;
}
int* mouse_events_registered_;
DISALLOW_COPY_AND_ASSIGN(CountingEventHandler);
};
} // namespace
class FirstRunHelperTest : public AshTestBase, public FirstRunHelper::Observer {
public: public:
FirstRunHelperTest() : cancelled_times_(0) {} FirstRunHelperTest() : cancelled_times_(0) {}
...@@ -62,15 +22,15 @@ class FirstRunHelperTest : public AshTestBase, public FirstRunHelper::Observer { ...@@ -62,15 +22,15 @@ class FirstRunHelperTest : public AshTestBase, public FirstRunHelper::Observer {
void SetUp() override { void SetUp() override {
AshTestBase::SetUp(); AshTestBase::SetUp();
CheckContainersAreVisible(); CheckContainersAreVisible();
helper_ = std::make_unique<FirstRunHelper>(); helper_ = Shell::Get()->first_run_helper();
helper_->AddObserver(this); mojom::FirstRunHelperClientPtr client_ptr;
helper_->CreateOverlayWidget(); binding_.Bind(mojo::MakeRequest(&client_ptr));
helper_->GetOverlayWidget()->Show(); helper_->Start(std::move(client_ptr));
} }
void TearDown() override { void TearDown() override {
helper_->CloseOverlayWidget(); helper_->Stop();
helper_.reset(); helper_ = nullptr;
CheckContainersAreVisible(); CheckContainersAreVisible();
AshTestBase::TearDown(); AshTestBase::TearDown();
} }
...@@ -97,15 +57,16 @@ class FirstRunHelperTest : public AshTestBase, public FirstRunHelper::Observer { ...@@ -97,15 +57,16 @@ class FirstRunHelperTest : public AshTestBase, public FirstRunHelper::Observer {
} }
} }
FirstRunHelper* helper() { return helper_.get(); } FirstRunHelper* helper() { return helper_; }
int cancelled_times() const { return cancelled_times_; } int cancelled_times() const { return cancelled_times_; }
private: private:
// FirstRunHelper::Observer overrides. // mojom::FirstRunHelperClient:
void OnCancelled() override { ++cancelled_times_; } void OnCancelled() override { ++cancelled_times_; }
std::unique_ptr<FirstRunHelper> helper_; FirstRunHelper* helper_;
mojo::Binding<mojom::FirstRunHelperClient> binding_{this};
int cancelled_times_; int cancelled_times_;
DISALLOW_COPY_AND_ASSIGN(FirstRunHelperTest); DISALLOW_COPY_AND_ASSIGN(FirstRunHelperTest);
...@@ -117,28 +78,18 @@ TEST_F(FirstRunHelperTest, ContainersAreHidden) { ...@@ -117,28 +78,18 @@ TEST_F(FirstRunHelperTest, ContainersAreHidden) {
CheckContainersAreHidden(); CheckContainersAreHidden();
} }
// Tests that helper correctly handles Escape key press. // Tests that screen lock cancels the tutorial.
TEST_F(FirstRunHelperTest, Cancel) { TEST_F(FirstRunHelperTest, ScreenLock) {
GetEventGenerator().PressKey(ui::VKEY_ESCAPE, 0); Shell::Get()->session_controller()->LockScreenAndFlushForTest();
helper()->FlushForTesting();
EXPECT_EQ(cancelled_times(), 1); EXPECT_EQ(cancelled_times(), 1);
} }
// Tests that modal window doesn't block events for overlay window. // Tests that shutdown cancels the tutorial.
TEST_F(FirstRunHelperTest, ModalWindowDoesNotBlock) { TEST_F(FirstRunHelperTest, ChromeTerminating) {
views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget( Shell::Get()->session_controller()->NotifyChromeTerminating();
new TestModalDialogDelegate(), CurrentContext(), NULL); helper()->FlushForTesting();
modal_dialog->Show(); EXPECT_EQ(cancelled_times(), 1);
// TODO(dzhioev): modal window should not steal focus from overlay window.
aura::Window* overlay_window = helper()->GetOverlayWidget()->GetNativeView();
overlay_window->Focus();
EXPECT_TRUE(overlay_window->HasFocus());
int mouse_events;
CountingEventHandler handler(&mouse_events);
overlay_window->AddPreTargetHandler(&handler);
GetEventGenerator().PressLeftButton();
GetEventGenerator().ReleaseLeftButton();
EXPECT_EQ(mouse_events, 2);
overlay_window->RemovePreTargetHandler(&handler);
} }
} // namespace ash } // namespace ash
...@@ -12,6 +12,12 @@ import "ui/gfx/geometry/mojo/geometry.mojom"; ...@@ -12,6 +12,12 @@ import "ui/gfx/geometry/mojo/geometry.mojom";
// due to small behavior differences (all methods only affect the primary // due to small behavior differences (all methods only affect the primary
// display, opening the system tray bubble is persistent, etc.). // display, opening the system tray bubble is persistent, etc.).
interface FirstRunHelper { interface FirstRunHelper {
// Cleans up the ash UI on tutorial start.
Start(FirstRunHelperClient client);
// Restores the ash UI on tutorial stop.
Stop();
// Returns the bounds of the app list button on the primary display in screen // Returns the bounds of the app list button on the primary display in screen
// coordinates. // coordinates.
GetAppListButtonBounds() => (gfx.mojom.Rect screen_bounds); GetAppListButtonBounds() => (gfx.mojom.Rect screen_bounds);
...@@ -30,3 +36,9 @@ interface FirstRunHelper { ...@@ -30,3 +36,9 @@ interface FirstRunHelper {
GetHelpButtonBounds() => (gfx.mojom.Rect screen_bounds); GetHelpButtonBounds() => (gfx.mojom.Rect screen_bounds);
}; };
// The client for the FirstRunHelper interface, e.g. chrome.
interface FirstRunHelperClient {
// Informs the client that something happened inside ash that should cancel
// the tutorial (e.g. the device is shutting down).
OnCancelled();
};
...@@ -12,8 +12,46 @@ ...@@ -12,8 +12,46 @@
#include "content/public/common/service_manager_connection.h" #include "content/public/common/service_manager_connection.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "ui/aura/window.h"
#include "ui/events/event_handler.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
namespace chromeos { namespace chromeos {
namespace {
class TestModalDialogDelegate : public views::DialogDelegateView {
public:
TestModalDialogDelegate() = default;
~TestModalDialogDelegate() override = default;
// views::WidgetDelegate:
ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; }
private:
DISALLOW_COPY_AND_ASSIGN(TestModalDialogDelegate);
};
class CountingEventHandler : public ui::EventHandler {
public:
explicit CountingEventHandler(int* mouse_events_registered)
: mouse_events_registered_(mouse_events_registered) {}
~CountingEventHandler() override = default;
private:
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override {
++*mouse_events_registered_;
}
int* mouse_events_registered_;
DISALLOW_COPY_AND_ASSIGN(CountingEventHandler);
};
} // namespace
class FirstRunUIBrowserTest : public InProcessBrowserTest, class FirstRunUIBrowserTest : public InProcessBrowserTest,
public FirstRunActor::Delegate { public FirstRunActor::Delegate {
...@@ -121,6 +159,8 @@ class FirstRunUIBrowserTest : public InProcessBrowserTest, ...@@ -121,6 +159,8 @@ class FirstRunUIBrowserTest : public InProcessBrowserTest,
return is_open; return is_open;
} }
views::Widget* GetOverlayWidget() { return controller()->widget_.get(); }
void FlushForTesting() { void FlushForTesting() {
controller()->first_run_helper_ptr_.FlushForTesting(); controller()->first_run_helper_ptr_.FlushForTesting();
} }
...@@ -160,4 +200,56 @@ IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, FirstRunFlow) { ...@@ -160,4 +200,56 @@ IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, FirstRunFlow) {
EXPECT_FALSE(IsTrayBubbleOpen()); EXPECT_FALSE(IsTrayBubbleOpen());
} }
// Tests that a modal window doesn't block events to the tutorial. A modal
// window might be open if enterprise policy forces a browser tab to open
// on first login and the web page opens a JavaScript alert.
// See https://crrev.com/99673003
IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, ModalWindowDoesNotBlock) {
// Start the tutorial.
LaunchTutorial();
WaitForInitialization();
WaitForStep(first_run::kAppListStep);
FlushForTesting();
// Simulate the browser opening a modal dialog.
views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget(
new TestModalDialogDelegate(), /*context=*/nullptr,
/*parent=*/nullptr);
modal_dialog->Show();
// A mouse click is still received by the overlay widget.
int mouse_events = 0;
CountingEventHandler handler(&mouse_events);
aura::Window* overlay_window = GetOverlayWidget()->GetNativeView();
overlay_window->AddPreTargetHandler(&handler);
ui::test::EventGenerator event_generator(overlay_window);
event_generator.PressLeftButton();
EXPECT_EQ(mouse_events, 1);
overlay_window->RemovePreTargetHandler(&handler);
modal_dialog->Close();
}
// Tests that the escape key cancels the tutorial.
IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, EscapeCancelsTutorial) {
// Run the tutorial for a couple steps, but don't finish it.
LaunchTutorial();
WaitForInitialization();
WaitForStep(first_run::kAppListStep);
AdvanceStep();
WaitForStep(first_run::kTrayStep);
FlushForTesting();
EXPECT_TRUE(IsTrayBubbleOpen());
// Press the escape key.
aura::Window* overlay_window = GetOverlayWidget()->GetNativeView();
ui::test::EventGenerator event_generator(overlay_window);
event_generator.PressKey(ui::VKEY_ESCAPE, ui::EF_NONE);
content::RunAllPendingInMessageLoop();
// The tutorial stopped.
EXPECT_EQ(controller(), nullptr);
EXPECT_FALSE(IsTrayBubbleOpen());
}
} // namespace chromeos } // namespace chromeos
...@@ -4,11 +4,10 @@ ...@@ -4,11 +4,10 @@
#include "chrome/browser/chromeos/first_run/first_run_controller.h" #include "chrome/browser/chromeos/first_run/first_run_controller.h"
#include "ash/first_run/first_run_helper.h"
#include "ash/public/cpp/shelf_prefs.h" #include "ash/public/cpp/shelf_prefs.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/constants.mojom.h"
#include "ash/public/interfaces/first_run_helper.mojom.h" #include "ash/public/interfaces/first_run_helper.mojom.h"
#include "ash/shell.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
...@@ -20,6 +19,7 @@ ...@@ -20,6 +19,7 @@
#include "chrome/browser/chromeos/first_run/steps/help_step.h" #include "chrome/browser/chromeos/first_run/steps/help_step.h"
#include "chrome/browser/chromeos/first_run/steps/tray_step.h" #include "chrome/browser/chromeos/first_run/steps/tray_step.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/chrome_pages.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/common/service_manager_connection.h" #include "content/public/common/service_manager_connection.h"
...@@ -42,6 +42,20 @@ void RecordCompletion(chromeos::first_run::TutorialCompletion type) { ...@@ -42,6 +42,20 @@ void RecordCompletion(chromeos::first_run::TutorialCompletion type) {
chromeos::first_run::TUTORIAL_COMPLETION_SIZE); chromeos::first_run::TUTORIAL_COMPLETION_SIZE);
} }
std::unique_ptr<views::Widget> CreateFirstRunWidget() {
auto widget = std::make_unique<views::Widget>();
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
params.show_state = ui::SHOW_STATE_FULLSCREEN;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
ash_util::SetupWidgetInitParamsForContainer(
&params, ash::kShellWindowId_OverlayContainer);
widget->Init(params);
return widget;
}
} // namespace } // namespace
namespace chromeos { namespace chromeos {
...@@ -71,7 +85,7 @@ void FirstRunController::Stop() { ...@@ -71,7 +85,7 @@ void FirstRunController::Stop() {
} }
gfx::Size FirstRunController::GetOverlaySize() const { gfx::Size FirstRunController::GetOverlaySize() const {
return shell_helper_->GetOverlayWidget()->GetWindowBoundsInScreen().size(); return widget_->GetWindowBoundsInScreen().size();
} }
ash::ShelfAlignment FirstRunController::GetShelfAlignment() const { ash::ShelfAlignment FirstRunController::GetShelfAlignment() const {
...@@ -81,6 +95,10 @@ ash::ShelfAlignment FirstRunController::GetShelfAlignment() const { ...@@ -81,6 +95,10 @@ ash::ShelfAlignment FirstRunController::GetShelfAlignment() const {
display::Screen::GetScreen()->GetPrimaryDisplay().id()); display::Screen::GetScreen()->GetPrimaryDisplay().id());
} }
void FirstRunController::Cancel() {
OnCancelled();
}
FirstRunController* FirstRunController::GetInstanceForTest() { FirstRunController* FirstRunController::GetInstanceForTest() {
return g_first_run_controller_instance; return g_first_run_controller_instance;
} }
...@@ -100,16 +118,17 @@ void FirstRunController::Init() { ...@@ -100,16 +118,17 @@ void FirstRunController::Init() {
content::ServiceManagerConnection::GetForProcess() content::ServiceManagerConnection::GetForProcess()
->GetConnector() ->GetConnector()
->BindInterface(ash::mojom::kServiceName, &first_run_helper_ptr_); ->BindInterface(ash::mojom::kServiceName, &first_run_helper_ptr_);
shell_helper_ = ash::Shell::Get()->first_run_helper(); ash::mojom::FirstRunHelperClientPtr client_ptr;
shell_helper_->AddObserver(this); binding_.Bind(mojo::MakeRequest(&client_ptr));
shell_helper_->CreateOverlayWidget(); first_run_helper_ptr_->Start(std::move(client_ptr));
widget_ = CreateFirstRunWidget();
FirstRunView* view = new FirstRunView(); FirstRunView* view = new FirstRunView();
view->Init(user_profile_); view->Init(user_profile_, this);
shell_helper_->GetOverlayWidget()->SetContentsView(view); widget_->SetContentsView(view);
actor_ = view->GetActor(); actor_ = view->GetActor();
actor_->set_delegate(this); actor_->set_delegate(this);
shell_helper_->GetOverlayWidget()->Show(); widget_->Show();
view->RequestFocus(); view->RequestFocus();
web_contents_for_tests_ = view->GetWebContents(); web_contents_for_tests_ = view->GetWebContents();
...@@ -131,9 +150,9 @@ void FirstRunController::Finalize() { ...@@ -131,9 +150,9 @@ void FirstRunController::Finalize() {
if (actor_) if (actor_)
actor_->set_delegate(NULL); actor_->set_delegate(NULL);
actor_ = NULL; actor_ = NULL;
shell_helper_->CloseOverlayWidget(); first_run_helper_ptr_->Stop();
shell_helper_->RemoveObserver(this); // Close the widget.
shell_helper_ = nullptr; widget_.reset();
} }
void FirstRunController::OnActorInitialized() { void FirstRunController::OnActorInitialized() {
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "ash/first_run/first_run_helper.h"
#include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shelf_types.h"
#include "ash/public/interfaces/first_run_helper.mojom.h" #include "ash/public/interfaces/first_run_helper.mojom.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h" #include "chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h"
#include "mojo/public/cpp/bindings/binding.h"
class Profile; class Profile;
...@@ -25,6 +25,10 @@ namespace content { ...@@ -25,6 +25,10 @@ namespace content {
class WebContents; class WebContents;
} }
namespace views {
class Widget;
}
namespace chromeos { namespace chromeos {
class FirstRunUIBrowserTest; class FirstRunUIBrowserTest;
...@@ -37,7 +41,7 @@ class Step; ...@@ -37,7 +41,7 @@ class Step;
// Object manages its lifetime and deletes itself after completion of the // Object manages its lifetime and deletes itself after completion of the
// tutorial. // tutorial.
class FirstRunController : public FirstRunActor::Delegate, class FirstRunController : public FirstRunActor::Delegate,
public ash::FirstRunHelper::Observer { public ash::mojom::FirstRunHelperClient {
public: public:
~FirstRunController() override; ~FirstRunController() override;
...@@ -53,6 +57,9 @@ class FirstRunController : public FirstRunActor::Delegate, ...@@ -53,6 +57,9 @@ class FirstRunController : public FirstRunActor::Delegate,
// Returns the shelf alignment on the primary display. // Returns the shelf alignment on the primary display.
ash::ShelfAlignment GetShelfAlignment() const; ash::ShelfAlignment GetShelfAlignment() const;
// Stops the tutorial and records early cancellation metrics.
void Cancel();
const ash::mojom::FirstRunHelperPtr& first_run_helper_ptr() { const ash::mojom::FirstRunHelperPtr& first_run_helper_ptr() {
return first_run_helper_ptr_; return first_run_helper_ptr_;
} }
...@@ -75,7 +82,7 @@ class FirstRunController : public FirstRunActor::Delegate, ...@@ -75,7 +82,7 @@ class FirstRunController : public FirstRunActor::Delegate,
void OnActorFinalized() override; void OnActorFinalized() override;
void OnActorDestroyed() override; void OnActorDestroyed() override;
// Overriden from ash::FirstRunHelper::Observer. // ash::mojom::FirstRunHelperClient:
void OnCancelled() override; void OnCancelled() override;
void RegisterSteps(); void RegisterSteps();
...@@ -87,13 +94,12 @@ class FirstRunController : public FirstRunActor::Delegate, ...@@ -87,13 +94,12 @@ class FirstRunController : public FirstRunActor::Delegate,
// FirstRunController. // FirstRunController.
FirstRunActor* actor_; FirstRunActor* actor_;
// Helper for manipulating and retreiving information from Shell.
// TODO(jamescook): Remove once all methods are converted to mojo.
ash::FirstRunHelper* shell_helper_ = nullptr;
// Mojo interface for manipulating and retrieving information from ash. // Mojo interface for manipulating and retrieving information from ash.
ash::mojom::FirstRunHelperPtr first_run_helper_ptr_; ash::mojom::FirstRunHelperPtr first_run_helper_ptr_;
// Binding for callbacks from ash.
mojo::Binding<ash::mojom::FirstRunHelperClient> binding_{this};
// List of all tutorial steps. // List of all tutorial steps.
std::vector<std::unique_ptr<first_run::Step>> steps_; std::vector<std::unique_ptr<first_run::Step>> steps_;
...@@ -106,6 +112,9 @@ class FirstRunController : public FirstRunActor::Delegate, ...@@ -106,6 +112,9 @@ class FirstRunController : public FirstRunActor::Delegate,
// The work that should be made after actor has been finalized. // The work that should be made after actor has been finalized.
base::Closure on_actor_finalized_; base::Closure on_actor_finalized_;
// Widget containing the first-run webui.
std::unique_ptr<views::Widget> widget_;
// Web contents of WebUI. // Web contents of WebUI.
content::WebContents* web_contents_for_tests_; content::WebContents* web_contents_for_tests_;
...@@ -118,4 +127,3 @@ class FirstRunController : public FirstRunActor::Delegate, ...@@ -118,4 +127,3 @@ class FirstRunController : public FirstRunActor::Delegate,
} // namespace chromeos } // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_CONTROLLER_H_ #endif // CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_CONTROLLER_H_
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
#include "chrome/browser/chromeos/first_run/first_run_view.h" #include "chrome/browser/chromeos/first_run/first_run_view.h"
#include "chrome/browser/chromeos/first_run/first_run_controller.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h" #include "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
...@@ -22,7 +24,11 @@ FirstRunView::FirstRunView() ...@@ -22,7 +24,11 @@ FirstRunView::FirstRunView()
: web_view_(NULL) { : web_view_(NULL) {
} }
void FirstRunView::Init(content::BrowserContext* context) { void FirstRunView::Init(content::BrowserContext* context,
FirstRunController* controller) {
DCHECK(context);
DCHECK(controller);
controller_ = controller;
web_view_ = new views::WebView(context); web_view_ = new views::WebView(context);
AddChildView(web_view_); AddChildView(web_view_);
web_view_->LoadInitialURL(GURL(chrome::kChromeUIFirstRunURL)); web_view_->LoadInitialURL(GURL(chrome::kChromeUIFirstRunURL));
...@@ -59,6 +65,16 @@ bool FirstRunView::HandleContextMenu( ...@@ -59,6 +65,16 @@ bool FirstRunView::HandleContextMenu(
return true; return true;
} }
content::KeyboardEventProcessingResult FirstRunView::PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (event.windows_key_code == ui::VKEY_ESCAPE) {
controller_->Cancel();
return content::KeyboardEventProcessingResult::HANDLED;
}
return content::KeyboardEventProcessingResult::NOT_HANDLED;
}
bool FirstRunView::PreHandleGestureEvent( bool FirstRunView::PreHandleGestureEvent(
content::WebContents* source, content::WebContents* source,
const blink::WebGestureEvent& event) { const blink::WebGestureEvent& event) {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_ #ifndef CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_
#define CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_ #define CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_
#include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -21,13 +20,14 @@ class WebView; ...@@ -21,13 +20,14 @@ class WebView;
namespace chromeos { namespace chromeos {
class FirstRunActor; class FirstRunActor;
class FirstRunController;
// WebUI view used for first run tutorial. // WebUI view used for first run tutorial.
class FirstRunView : public views::View, class FirstRunView : public views::View,
public content::WebContentsDelegate { public content::WebContentsDelegate {
public: public:
FirstRunView(); FirstRunView();
void Init(content::BrowserContext* context); void Init(content::BrowserContext* context, FirstRunController* controller);
FirstRunActor* GetActor(); FirstRunActor* GetActor();
// Overriden from views::View. // Overriden from views::View.
...@@ -39,10 +39,14 @@ class FirstRunView : public views::View, ...@@ -39,10 +39,14 @@ class FirstRunView : public views::View,
private: private:
// Overriden from content::WebContentsDelegate. // Overriden from content::WebContentsDelegate.
bool HandleContextMenu(const content::ContextMenuParams& params) override; bool HandleContextMenu(const content::ContextMenuParams& params) override;
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
bool PreHandleGestureEvent(content::WebContents* source, bool PreHandleGestureEvent(content::WebContents* source,
const blink::WebGestureEvent& event) override; const blink::WebGestureEvent& event) override;
views::WebView* web_view_; views::WebView* web_view_ = nullptr;
FirstRunController* controller_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FirstRunView); DISALLOW_COPY_AND_ASSIGN(FirstRunView);
}; };
......
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