From 798edb2761165db91fef24935c4a1a14119efe86 Mon Sep 17 00:00:00 2001 From: "dzhioev@chromium.org" Date: Mon, 2 Sep 2013 23:50:01 +0000 Subject: [PATCH] Implemented skeleton of new first-run overlay UI. UI can be enabled by 'enable-first-run-ui' flag. Currently only one example step will be shown right after login. BUG=269286 TBR=jochen,nkostylev Review URL: https://chromiumcodereview.appspot.com/23604021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220877 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser_resources.grd | 4 + chrome/browser/chromeos/first_run/OWNERS | 1 + .../first_run/first_run_controller.cc | 106 ++++++++++++++++++ .../chromeos/first_run/first_run_controller.h | 52 +++++++++ .../chromeos/first_run/first_run_view.cc | 54 +++++++++ .../chromeos/first_run/first_run_view.h | 50 +++++++++ .../chromeos/login/login_display_host_impl.cc | 8 ++ .../browser/chromeos/login/webui_login_view.h | 2 +- .../resources/chromeos/first_run/OWNERS | 1 + .../chromeos/first_run/background.svg | 18 +++ .../chromeos/first_run/first_run.css | 31 +++++ .../chromeos/first_run/first_run.html | 19 ++++ .../resources/chromeos/first_run/first_run.js | 105 +++++++++++++++++ .../chromeos/first_run/first_step.html | 21 ++++ .../resources/chromeos/first_run/step.css | 31 +++++ .../resources/chromeos/first_run/step.js | 38 +++++++ .../webui/chrome_web_ui_controller_factory.cc | 3 + .../ui/webui/chromeos/first_run/OWNERS | 1 + .../chromeos/first_run/first_run_actor.cc | 69 ++++++++++++ .../chromeos/first_run/first_run_actor.h | 82 ++++++++++++++ .../chromeos/first_run/first_run_handler.cc | 62 ++++++++++ .../chromeos/first_run/first_run_handler.h | 44 ++++++++ .../webui/chromeos/first_run/first_run_ui.cc | 42 +++++++ .../webui/chromeos/first_run/first_run_ui.h | 33 ++++++ chrome/chrome_browser_chromeos.gypi | 4 + chrome/chrome_browser_ui.gypi | 6 + chrome/common/url_constants.cc | 3 + chrome/common/url_constants.h | 2 + chromeos/chromeos_switches.cc | 3 + chromeos/chromeos_switches.h | 1 + 30 files changed, 895 insertions(+), 1 deletion(-) create mode 100644 chrome/browser/chromeos/first_run/OWNERS create mode 100644 chrome/browser/chromeos/first_run/first_run_controller.cc create mode 100644 chrome/browser/chromeos/first_run/first_run_controller.h create mode 100644 chrome/browser/chromeos/first_run/first_run_view.cc create mode 100644 chrome/browser/chromeos/first_run/first_run_view.h create mode 100644 chrome/browser/resources/chromeos/first_run/OWNERS create mode 100644 chrome/browser/resources/chromeos/first_run/background.svg create mode 100644 chrome/browser/resources/chromeos/first_run/first_run.css create mode 100644 chrome/browser/resources/chromeos/first_run/first_run.html create mode 100644 chrome/browser/resources/chromeos/first_run/first_run.js create mode 100644 chrome/browser/resources/chromeos/first_run/first_step.html create mode 100644 chrome/browser/resources/chromeos/first_run/step.css create mode 100644 chrome/browser/resources/chromeos/first_run/step.js create mode 100644 chrome/browser/ui/webui/chromeos/first_run/OWNERS create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc create mode 100644 chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 21e11cda1cd611..f8ce2e3ea1788d 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -31,6 +31,10 @@ + + + + diff --git a/chrome/browser/chromeos/first_run/OWNERS b/chrome/browser/chromeos/first_run/OWNERS new file mode 100644 index 00000000000000..df660f70946e61 --- /dev/null +++ b/chrome/browser/chromeos/first_run/OWNERS @@ -0,0 +1 @@ +dzhioev@chromium.org diff --git a/chrome/browser/chromeos/first_run/first_run_controller.cc b/chrome/browser/chromeos/first_run/first_run_controller.cc new file mode 100644 index 00000000000000..f5f41ed14dd283 --- /dev/null +++ b/chrome/browser/chromeos/first_run/first_run_controller.cc @@ -0,0 +1,106 @@ +// Copyright 2013 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 "chrome/browser/chromeos/first_run/first_run_controller.h" + +#include "ash/launcher/launcher.h" +#include "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "chrome/browser/chromeos/first_run/first_run_view.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "ui/views/widget/widget.h" + +namespace { + +gfx::Rect GetScreenBounds() { + return ash::Shell::GetScreen()->GetPrimaryDisplay().bounds(); +} + +views::Widget* CreateFirstRunWindow() { + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.bounds = GetScreenBounds(); + params.show_state = ui::SHOW_STATE_FULLSCREEN; + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.parent = + ash::Shell::GetContainer( + ash::Shell::GetPrimaryRootWindow(), + ash::internal::kShellWindowId_OverlayContainer); + views::Widget* window = new views::Widget; + window->Init(params); + return window; +} + +// We can't get launcher size now in normal way. This workaround uses fact that +// AppList button is the rightmost button in Launcher. +gfx::Rect GetLauncherBounds() { + ash::Launcher* launcher = ash::Launcher::ForPrimaryDisplay(); + views::View* app_button = launcher->GetAppListButtonView(); + gfx::Rect bounds = app_button->GetBoundsInScreen(); + return gfx::Rect(0, bounds.y(), bounds.right(), bounds.height()); +} + +} // anonymous namespace + +namespace chromeos { + +FirstRunController::FirstRunController() + : window_(NULL), + actor_(NULL) { +} + +FirstRunController::~FirstRunController() { + if (window_) + Stop(); +} + +void FirstRunController::Start() { + if (window_) + return; + window_ = CreateFirstRunWindow(); + FirstRunView* view = new FirstRunView(); + view->Init(ProfileManager::GetDefaultProfile()); + window_->SetContentsView(view); + actor_ = view->GetActor(); + actor_->set_delegate(this); + if (actor_->IsInitialized()) + OnActorInitialized(); +} + +void FirstRunController::Stop() { + window_->Close(); + window_ = NULL; + if (actor_) + actor_->set_delegate(NULL); + actor_ = NULL; +} + +void FirstRunController::OnActorInitialized() { + window_->Show(); + gfx::Rect launcher_bounds = GetLauncherBounds(); + actor_->AddBackgroundHole(launcher_bounds.x(), + launcher_bounds.y(), + launcher_bounds.width(), + launcher_bounds.height()); + actor_->ShowStep("first-step", + FirstRunActor::StepPosition() + .SetLeft(0) + .SetBottom( + GetScreenBounds().height() - launcher_bounds.y())); +} + +void FirstRunController::OnNextButtonClicked(const std::string& step_name) { + CHECK(step_name == "first-step"); + Stop(); + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); +} + +void FirstRunController::OnActorDestroyed() { + actor_ = NULL; +} + +} // namespace chromeos + diff --git a/chrome/browser/chromeos/first_run/first_run_controller.h b/chrome/browser/chromeos/first_run/first_run_controller.h new file mode 100644 index 00000000000000..651f1e138f5ff1 --- /dev/null +++ b/chrome/browser/chromeos/first_run/first_run_controller.h @@ -0,0 +1,52 @@ +// Copyright 2013 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 CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_CONTROLLER_H_ +#define CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_CONTROLLER_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h" + +namespace views { +class Widget; +} + +namespace chromeos { + +// FirstRunController creates and manages first-run tutorial. +// Object manages its lifetime and deletes itself after completion of the +// tutorial. +class FirstRunController : public FirstRunActor::Delegate { + public: + FirstRunController(); + virtual ~FirstRunController(); + + // Creates first-run UI and starts tutorial. + void Start(); + + // Finalizes first-run tutorial and destroys UI. + void Stop(); + + private: + // Overriden from FirstRunActor::Delegate. + virtual void OnActorInitialized() OVERRIDE; + virtual void OnNextButtonClicked(const std::string& step_name) OVERRIDE; + virtual void OnActorDestroyed() OVERRIDE; + + // Window with UI. FirstRunController closes window after tutorial completes. + views::Widget* window_; + // The object providing interface to UI layer. It's not directly owned by + // FirstRunController. + FirstRunActor* actor_; + + DISALLOW_COPY_AND_ASSIGN(FirstRunController); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_CONTROLLER_H_ + diff --git a/chrome/browser/chromeos/first_run/first_run_view.cc b/chrome/browser/chromeos/first_run/first_run_view.cc new file mode 100644 index 00000000000000..906284b1a987d5 --- /dev/null +++ b/chrome/browser/chromeos/first_run/first_run_view.cc @@ -0,0 +1,54 @@ +// Copyright 2013 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 "chrome/browser/chromeos/first_run/first_run_view.h" + +#include "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h" +#include "chrome/common/url_constants.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/views/controls/webview/webview.h" +#include "url/gurl.h" + +namespace chromeos { + +FirstRunView::FirstRunView() + : web_view_(NULL) { +} + +void FirstRunView::Init(content::BrowserContext* context) { + web_view_ = new views::WebView(context); + AddChildView(web_view_); + web_view_->LoadInitialURL(GURL(chrome::kChromeUIFirstRunURL)); + web_view_->RequestFocus(); + + web_view_->web_contents()->SetDelegate(this); + + SkBitmap background; + background.setConfig(SkBitmap::kA8_Config, 1, 1); + background.allocPixels(); + background.eraseARGB(0, 0, 0, 0); + web_view_->web_contents()->GetRenderViewHost()->GetView()-> + SetBackground(background); +} + +FirstRunActor* FirstRunView::GetActor() { + return static_cast( + web_view_->web_contents()->GetWebUI()->GetController())->get_actor(); +} + +void FirstRunView::Layout() { + web_view_->SetBoundsRect(bounds()); +} + +bool FirstRunView::HandleContextMenu( + const content::ContextMenuParams& params) { + // Discards context menu. + return true; +} + +} // namespace chromeos + diff --git a/chrome/browser/chromeos/first_run/first_run_view.h b/chrome/browser/chromeos/first_run/first_run_view.h new file mode 100644 index 00000000000000..8d0de59c3c0b5b --- /dev/null +++ b/chrome/browser/chromeos/first_run/first_run_view.h @@ -0,0 +1,50 @@ +// Copyright 2013 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 CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/public/browser/web_contents_delegate.h" +#include "ui/views/view.h" + +class Profile; + +namespace content { +class BrowserContext; +} + +namespace views { +class WebView; +} + +namespace chromeos { + +class FirstRunActor; + +// WebUI view used for first run tutorial. +class FirstRunView : public views::View, + public content::WebContentsDelegate { + public: + FirstRunView(); + void Init(content::BrowserContext* context); + FirstRunActor* GetActor(); + private: + // Overriden from views::View. + virtual void Layout() OVERRIDE; + + // Overriden from content::WebContentsDelegate. + virtual bool HandleContextMenu( + const content::ContextMenuParams& params) OVERRIDE; + + views::WebView* web_view_; + + DISALLOW_COPY_AND_ASSIGN(FirstRunView); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_FIRST_RUN_FIRST_RUN_VIEW_H_ + diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc index 800193143d3140..a41c623dd3798d 100644 --- a/chrome/browser/chromeos/login/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/login_display_host_impl.cc @@ -25,6 +25,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/customization_document.h" +#include "chrome/browser/chromeos/first_run/first_run_controller.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" #include "chrome/browser/chromeos/language_preferences.h" @@ -277,6 +278,13 @@ LoginDisplayHostImpl::~LoginDisplayHostImpl() { chrome::EndKeepAlive(); default_host_ = NULL; + // TODO(dzhioev): find better place for starting tutorial. + if (CommandLine::ForCurrentProcess()-> + HasSwitch(switches::kEnableFirstRunUI)) { + // FirstRunController manages its lifetime and destructs after tutorial + // completion. + (new FirstRunController())->Start(); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/chromeos/login/webui_login_view.h b/chrome/browser/chromeos/login/webui_login_view.h index 86c47a50e022db..f159842bfb59bf 100644 --- a/chrome/browser/chromeos/login/webui_login_view.h +++ b/chrome/browser/chromeos/login/webui_login_view.h @@ -51,7 +51,7 @@ class WebUILoginView : public views::View, // Initializes the webui login view. virtual void Init(); - // Overridden from views::Views: + // Overridden from views::View: virtual bool AcceleratorPressed( const ui::Accelerator& accelerator) OVERRIDE; virtual const char* GetClassName() const OVERRIDE; diff --git a/chrome/browser/resources/chromeos/first_run/OWNERS b/chrome/browser/resources/chromeos/first_run/OWNERS new file mode 100644 index 00000000000000..df660f70946e61 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/OWNERS @@ -0,0 +1 @@ +dzhioev@chromium.org diff --git a/chrome/browser/resources/chromeos/first_run/background.svg b/chrome/browser/resources/chromeos/first_run/background.svg new file mode 100644 index 00000000000000..a6127ebd2a92e0 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/background.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/chrome/browser/resources/chromeos/first_run/first_run.css b/chrome/browser/resources/chromeos/first_run/first_run.css new file mode 100644 index 00000000000000..a241b93661651d --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/first_run.css @@ -0,0 +1,31 @@ +/** + * Copyright 2013 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. + */ + +html, +body { + margin: 0; + padding: 0; +} + +body { + background-color: rgba(0, 0, 0, 0); + cursor: default; + height: 100%; + width: 100%; +} + +#background { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + z-index: -1; +} + +#background .fill { + fill: rgba(0, 0, 0, 0.7); +} diff --git a/chrome/browser/resources/chromeos/first_run/first_run.html b/chrome/browser/resources/chromeos/first_run/first_run.html new file mode 100644 index 00000000000000..fcacf68ab3ac47 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/first_run.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/chrome/browser/resources/chromeos/first_run/first_run.js b/chrome/browser/resources/chromeos/first_run/first_run.js new file mode 100644 index 00000000000000..b0a878d6726754 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/first_run.js @@ -0,0 +1,105 @@ +// Copyright 2013 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. + +/** + * @fileoverview First run UI. + */ + + + +cr.define('cr.FirstRun', function() { + return { + // SVG element representing UI background. + background_: null, + + // Mask element describing transparent "holes" in background. + mask_: null, + + // Pattern used for creating new holes. + hole_pattern_: null, + + // Dictionary keeping all available tutorial steps by their names. + steps_: {}, + + // Element representing step currently shown for user. + currentStep_: null, + + /** + * Initializes internal structures and preparing steps. + */ + initialize: function() { + disableTextSelectAndDrag(); + this.background_ = $('background'); + this.mask_ = $('mask'); + this.hole_pattern_ = $('hole-pattern'); + var stepElements = document.getElementsByClassName('step'); + for (var i = 0; i < stepElements.length; ++i) { + var step = stepElements[i]; + cr.FirstRun.Step.decorate(step); + this.steps_[step.getName()] = step; + } + chrome.send('initialized'); + }, + + /** + * Adds transparent hole to background. + * @param {number} x X coordinate of top-left corner of hole. + * @param {number} y Y coordinate of top-left corner of hole. + * @param {number} widht Width of hole. + * @param {number} height Height of hole. + */ + addHole: function(x, y, width, height) { + var hole = this.hole_pattern_.cloneNode(); + hole.removeAttribute('id'); + hole.setAttribute('x', x); + hole.setAttribute('y', y); + hole.setAttribute('width', width); + hole.setAttribute('height', height); + this.mask_.appendChild(hole); + }, + + /** + * Removes all holes previously added by |addHole|. + */ + removeHoles: function() { + var holes = this.mask_.getElementsByClassName('hole'); + // Removing nodes modifies |holes|, that's why we run reverse cycle. + for (var i = holes.length - 1; i >= 0; --i) { + this.mask_.removeChild(holes[i]); + } + }, + + /** + * Shows step with given name in given position. + * @param {string} name Name of step. + * @param {object} position Optional parameter with optional fields |top|, + * |right|, |bottom|, |left| used for step positioning. + */ + showStep: function(name, position) { + if (!this.steps_.hasOwnProperty(name)) + throw Error('Step "' + name + '" not found.'); + if (this.currentStep_) { + this.currentStep_.style.setProperty('display', 'none'); + } + var step = this.steps_[name]; + var stepStyle = step.style; + if (position) { + ['top', 'right', 'bottom', 'left'].forEach(function(property) { + if (position.hasOwnProperty(property)) + stepStyle.setProperty(property, position[property] + 'px'); + }); + } + stepStyle.setProperty('display', 'inline-block'); + this.currentStep_ = step; + } + }; +}); + +/** + * Initializes UI. + */ +window.onload = function() { + cr.FirstRun.initialize(); +}; + diff --git a/chrome/browser/resources/chromeos/first_run/first_step.html b/chrome/browser/resources/chromeos/first_run/first_step.html new file mode 100644 index 00000000000000..bf190e660ca761 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/first_step.html @@ -0,0 +1,21 @@ +
+

+ Quickly open favorite apps from the Shelf. +

+

+ We've pinned some apps we think you'll use often. +

+

+ Browse the web
+ Check your email
+ Edit docs and sheets
+ Make presentations
+ Listen to music
+ ...and more.
+

+
+ +
+
diff --git a/chrome/browser/resources/chromeos/first_run/step.css b/chrome/browser/resources/chromeos/first_run/step.css new file mode 100644 index 00000000000000..2c069879e700b5 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/step.css @@ -0,0 +1,31 @@ +/** + * Copyright 2013 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. + */ + +.step { + color: white; + display: none; + padding: 18px; + position: absolute; +} + +.step button { + background-color: rgb(72, 136, 246); + border: none; + color: white; + cursor: pointer; + font-size: 0.9em; + padding: 0.5em 2.5em; +} + +.step p { + line-height: 1.4; +} + +.step .controls { + -webkit-margin-after: 2em; + -webkit-margin-before: 1.5em; +} + diff --git a/chrome/browser/resources/chromeos/first_run/step.js b/chrome/browser/resources/chromeos/first_run/step.js new file mode 100644 index 00000000000000..1b944f17108955 --- /dev/null +++ b/chrome/browser/resources/chromeos/first_run/step.js @@ -0,0 +1,38 @@ +// Copyright 2013 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. + +/** + * Prototype for first-run tutorial steps. + */ + +cr.define('cr.FirstRun', function() { + var Step = cr.ui.define('div'); + + Step.prototype = { + __proto__: HTMLDivElement.prototype, + + // Name of step. + name_: null, + + // Button leading to next tutorial step. + nextButton_: null, + + decorate: function() { + this.name_ = this.getAttribute('id'); + this.nextButton_ = this.getElementsByClassName('next-button')[0]; + if (!this.nextButton_) + throw Error('Next button not found.'); + this.nextButton_.addEventListener('click', (function(e) { + chrome.send('nextButtonClicked', [this.getName()]); + e.stopPropagation(); + }).bind(this)); + }, + + getName: function() { + return this.name_; + } + }; + + return {Step: Step}; +}); diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index a80d332cd6a05c..a98016f239b314 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc @@ -98,6 +98,7 @@ #include "chrome/browser/ui/webui/chromeos/cryptohome_ui.h" #include "chrome/browser/ui/webui/chromeos/diagnostics/diagnostics_ui.h" #include "chrome/browser/ui/webui/chromeos/drive_internals_ui.h" +#include "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h" #include "chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.h" #include "chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" @@ -361,6 +362,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI; if (url.host() == chrome::kChromeUIDiagnosticsHost) return &NewWebUI; + if (url.host() == chrome::kChromeUIFirstRunHost) + return &NewWebUI; if (url.host() == chrome::kChromeUIImageBurnerHost) return &NewWebUI; if (url.host() == chrome::kChromeUIKeyboardOverlayHost) diff --git a/chrome/browser/ui/webui/chromeos/first_run/OWNERS b/chrome/browser/ui/webui/chromeos/first_run/OWNERS new file mode 100644 index 00000000000000..df660f70946e61 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/OWNERS @@ -0,0 +1 @@ +dzhioev@chromium.org diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc b/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc new file mode 100644 index 00000000000000..77893ffb73108b --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.cc @@ -0,0 +1,69 @@ +// Copyright 2013 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 "chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h" + +#include + +#include "base/values.h" + +namespace { +const int kNoneValue = std::numeric_limits::min(); +} + +namespace chromeos { + +FirstRunActor::StepPosition::StepPosition() + : top_(kNoneValue), + right_(kNoneValue), + bottom_(kNoneValue), + left_(kNoneValue) { +} + +FirstRunActor::StepPosition& FirstRunActor::StepPosition::SetTop(int top) { + top_ = top; + return *this; +} + +FirstRunActor::StepPosition& FirstRunActor::StepPosition::SetRight(int right) { + right_ = right; + return *this; +} + +FirstRunActor::StepPosition& +FirstRunActor::StepPosition::SetBottom(int bottom) { + bottom_ = bottom; + return *this; +} + +FirstRunActor::StepPosition& FirstRunActor::StepPosition::SetLeft(int left) { + left_ = left; + return *this; +} + +scoped_ptr FirstRunActor::StepPosition::AsValue() const { + base::DictionaryValue* result = new base::DictionaryValue(); + if (top_ != kNoneValue) + result->SetInteger("top", top_); + if (right_ != kNoneValue) + result->SetInteger("right", right_); + if (bottom_ != kNoneValue) + result->SetInteger("bottom", bottom_); + if (left_ != kNoneValue) + result->SetInteger("left", left_); + return make_scoped_ptr(result); +} + +FirstRunActor::FirstRunActor() + : delegate_(NULL) { +} + +FirstRunActor::~FirstRunActor() { + if (delegate()) + delegate()->OnActorDestroyed(); + delegate_ = NULL; +} + +} // namespace chromeos + diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h b/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h new file mode 100644 index 00000000000000..7c403d1f35f364 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h @@ -0,0 +1,82 @@ +// Copyright 2013 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_ACTOR_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_ACTOR_H_ + +#include + +#include "base/memory/scoped_ptr.h" + +namespace base { +class DictionaryValue; +} + +namespace chromeos { + +class FirstRunActor { + public: + class Delegate { + public: + virtual ~Delegate() {} + + // Called after actor was initialized. + virtual void OnActorInitialized() = 0; + + // Called when user clicked "Next" button in step with name |step_name|. + virtual void OnNextButtonClicked(const std::string& step_name) = 0; + + // Notifies about about actor destruction. + virtual void OnActorDestroyed() = 0; + }; + + class StepPosition { + public: + // Initializes fields in "non-set" state. + StepPosition(); + + // Setters for properties. Return |*this|. + StepPosition& SetTop(int top); + StepPosition& SetRight(int right); + StepPosition& SetBottom(int bottom); + StepPosition& SetLeft(int left); + + // Returns DictionaryValue containing set properties. + scoped_ptr AsValue() const; + + private: + int top_; + int right_; + int bottom_; + int left_; + }; + + FirstRunActor(); + virtual ~FirstRunActor(); + + // Returns |true| if actor is initialized. Other public methods can be called + // only if |IsInitialized| returns |true|. + virtual bool IsInitialized() = 0; + + // Adds hole to background with given position and dimensions. + virtual void AddBackgroundHole(int x, int y, int width, int height) = 0; + + // Removes all holes from background. + virtual void RemoveBackgroundHoles() = 0; + + // Shows step with given name and position. + virtual void ShowStep(const std::string& name, + const StepPosition& position) = 0; + + void set_delegate(Delegate* delegate) { delegate_ = delegate; } + Delegate* delegate() const { return delegate_; } + + private: + Delegate* delegate_; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_ACTOR_H_ + diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc new file mode 100644 index 00000000000000..a1975b59f3d0b9 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc @@ -0,0 +1,62 @@ +// Copyright 2013 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 "chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h" + +#include "base/bind.h" +#include "base/values.h" +#include "content/public/browser/web_ui.h" + +namespace chromeos { + +FirstRunHandler::FirstRunHandler() + : is_initialized_(false) { +} + +bool FirstRunHandler::IsInitialized() { + return is_initialized_; +} + +void FirstRunHandler::AddBackgroundHole(int x, int y, int width, int height) { + web_ui()->CallJavascriptFunction("cr.FirstRun.addHole", + base::FundamentalValue(x), + base::FundamentalValue(y), + base::FundamentalValue(width), + base::FundamentalValue(height)); +} + +void FirstRunHandler::RemoveBackgroundHoles() { + web_ui()->CallJavascriptFunction("cr.FirstRun.removeHoles"); +} + +void FirstRunHandler::ShowStep(const std::string& name, + const StepPosition& position) { + web_ui()->CallJavascriptFunction("cr.FirstRun.showStep", + base::StringValue(name), + *position.AsValue()); +} + +void FirstRunHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback("initialized", + base::Bind(&FirstRunHandler::HandleInitialized, base::Unretained(this))); + web_ui()->RegisterMessageCallback("nextButtonClicked", + base::Bind(&FirstRunHandler::HandleNextButtonClicked, + base::Unretained(this))); +} + +void FirstRunHandler::HandleInitialized(const base::ListValue* args) { + is_initialized_ = true; + if (delegate()) + delegate()->OnActorInitialized(); +} + +void FirstRunHandler::HandleNextButtonClicked(const base::ListValue* args) { + std::string step_name; + CHECK(args->GetString(0, &step_name)); + if (delegate()) + delegate()->OnNextButtonClicked(step_name); +} + +} // namespace chromeos + diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h new file mode 100644 index 00000000000000..ea3ae1d9fa4f46 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h @@ -0,0 +1,44 @@ +// Copyright 2013 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_HANDLER_H_ + +#include + +#include "base/compiler_specific.h" +#include "chrome/browser/ui/webui/chromeos/first_run/first_run_actor.h" +#include "content/public/browser/web_ui_message_handler.h" + +namespace chromeos { + +class StepPosition; + +class FirstRunHandler : public FirstRunActor, + public content::WebUIMessageHandler { + public: + FirstRunHandler(); + // Overriden from FirstRunActor. + virtual bool IsInitialized() OVERRIDE; + virtual void AddBackgroundHole(int x, int y, int width, int height) OVERRIDE; + virtual void RemoveBackgroundHoles() OVERRIDE; + virtual void ShowStep(const std::string& name, + const StepPosition& position) OVERRIDE; + private: + // Overriden from content::WebUIMessageHandler. + virtual void RegisterMessages() OVERRIDE; + + // Handlers for calls from JS. + void HandleInitialized(const base::ListValue* args); + void HandleNextButtonClicked(const base::ListValue* args); + + bool is_initialized_; + + DISALLOW_COPY_AND_ASSIGN(FirstRunHandler); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_HANDLER_H_ + diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc b/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc new file mode 100644 index 00000000000000..5738c404e0a1d4 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.cc @@ -0,0 +1,42 @@ +// Copyright 2013 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 "chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h" +#include "chrome/common/url_constants.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "grit/browser_resources.h" + +namespace { + +const char kFirstRunJSPath[] = "first_run.js"; + +content::WebUIDataSource* CreateDataSource() { + content::WebUIDataSource* source = + content::WebUIDataSource::Create(chrome::kChromeUIFirstRunHost); + source->SetUseJsonJSFormatV2(); + source->SetJsonPath("strings.js"); + source->SetDefaultResource(IDR_FIRST_RUN_HTML); + source->AddResourcePath(kFirstRunJSPath, IDR_FIRST_RUN_JS); + return source; +} + +} // anonymous namespace + +namespace chromeos { + +FirstRunUI::FirstRunUI(content::WebUI* web_ui) + : WebUIController(web_ui), + actor_(NULL) { + FirstRunHandler* handler = new FirstRunHandler(); + actor_ = handler; + web_ui->AddMessageHandler(handler); + content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), CreateDataSource()); +} + +} // namespace chromeos + diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h b/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h new file mode 100644 index 00000000000000..0b48e7e1c4f091 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_ui.h @@ -0,0 +1,33 @@ +// Copyright 2013 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_UI_H_ + +#include "base/basictypes.h" +#include "content/public/browser/web_ui_controller.h" + +namespace content { +class WebUI; +} + +namespace chromeos { + +class FirstRunActor; + +// WebUI controller for first-run tutorial. +class FirstRunUI : public content::WebUIController { + public: + explicit FirstRunUI(content::WebUI* web_ui); + FirstRunActor* get_actor() { return actor_; } + private: + FirstRunActor* actor_; + + DISALLOW_COPY_AND_ASSIGN(FirstRunUI); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_FIRST_RUN_FIRST_RUN_UI_H_ + diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index d329ed3e7ef7fb..ebcb70b4de3214 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -373,6 +373,10 @@ 'browser/chromeos/fileapi/file_system_backend.cc', 'browser/chromeos/fileapi/file_system_backend.h', 'browser/chromeos/fileapi/file_system_backend_delegate.h', + 'browser/chromeos/first_run/first_run_controller.cc', + 'browser/chromeos/first_run/first_run_controller.h', + 'browser/chromeos/first_run/first_run_view.cc', + 'browser/chromeos/first_run/first_run_view.h', 'browser/chromeos/imageburner/burn_controller.cc', 'browser/chromeos/imageburner/burn_controller.h', 'browser/chromeos/imageburner/burn_device_handler.cc', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index e27b51d1a2bd3b..3ee1d304c1d3c9 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -2007,6 +2007,12 @@ 'browser/ui/webui/chromeos/diagnostics/diagnostics_ui.h', 'browser/ui/webui/chromeos/drive_internals_ui.cc', 'browser/ui/webui/chromeos/drive_internals_ui.h', + 'browser/ui/webui/chromeos/first_run/first_run_actor.cc', + 'browser/ui/webui/chromeos/first_run/first_run_actor.h', + 'browser/ui/webui/chromeos/first_run/first_run_handler.cc', + 'browser/ui/webui/chromeos/first_run/first_run_handler.h', + 'browser/ui/webui/chromeos/first_run/first_run_ui.cc', + 'browser/ui/webui/chromeos/first_run/first_run_ui.h', 'browser/ui/webui/chromeos/imageburner/imageburner_ui.cc', 'browser/ui/webui/chromeos/imageburner/imageburner_ui.h', 'browser/ui/webui/chromeos/keyboard_overlay_ui.cc', diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 711e59286126f7..cadfa339f28797 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc @@ -99,6 +99,7 @@ const char kChromeUIChooseMobileNetworkURL[] = "chrome://choose-mobile-network/"; const char kChromeUIDiagnosticsURL[] = "chrome://diagnostics/"; const char kChromeUIDiscardsURL[] = "chrome://discards/"; +const char kChromeUIFirstRunURL[] = "chrome://first-run/"; const char kChromeUIIdleLogoutDialogURL[] = "chrome://idle-logout/"; const char kChromeUIImageBurnerURL[] = "chrome://imageburner/"; const char kChromeUIKeyboardOverlayURL[] = "chrome://keyboardoverlay/"; @@ -246,6 +247,7 @@ const char kChromeUIChooseMobileNetworkHost[] = "choose-mobile-network"; const char kChromeUICryptohomeHost[] = "cryptohome"; const char kChromeUIDiagnosticsHost[] = "diagnostics"; const char kChromeUIDiscardsHost[] = "discards"; +const char kChromeUIFirstRunHost[] = "first-run"; const char kChromeUIIdleLogoutDialogHost[] = "idle-logout"; const char kChromeUIImageBurnerHost[] = "imageburner"; const char kChromeUIKeyboardOverlayHost[] = "keyboardoverlay"; @@ -562,6 +564,7 @@ const char* const kChromeHostURLs[] = { kChromeUIDiagnosticsHost, kChromeUIDiscardsHost, kChromeUIDriveInternalsHost, + kChromeUIFirstRunHost, kChromeUIImageBurnerHost, kChromeUIKeyboardOverlayHost, kChromeUILoginHost, diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 0809d6c79a4e24..21ef617be592b7 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h @@ -93,6 +93,7 @@ extern const char kChromeUIBluetoothPairingURL[]; extern const char kChromeUIChooseMobileNetworkURL[]; extern const char kChromeUIDiagnosticsURL[]; extern const char kChromeUIDiscardsURL[]; +extern const char kChromeUIFirstRunURL[]; extern const char kChromeUIIdleLogoutDialogURL[]; extern const char kChromeUIImageBurnerURL[]; extern const char kChromeUIKeyboardOverlayURL[]; @@ -238,6 +239,7 @@ extern const char kChromeUIChooseMobileNetworkHost[]; extern const char kChromeUICryptohomeHost[]; extern const char kChromeUIDiagnosticsHost[]; extern const char kChromeUIDiscardsHost[]; +extern const char kChromeUIFirstRunHost[]; extern const char kChromeUIIdleLogoutDialogHost[]; extern const char kChromeUIImageBurnerHost[]; extern const char kChromeUIKeyboardOverlayHost[]; diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index c4bec2a42e2c43..85777203c50b11 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc @@ -198,5 +198,8 @@ const char kUseNewNetworkConfigurationHandlers[] = // Disables user image sync. const char kDisableUserImageSync[] = "disable-user-image-sync"; +// Enables new first-run overlay UI. +const char kEnableFirstRunUI[] = "enable-first-run-ui"; + } // namespace switches } // namespace chromeos diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 1e99663fde347c..2e73535e29058c 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h @@ -73,6 +73,7 @@ CHROMEOS_EXPORT extern const char kSmsTestMessages[]; CHROMEOS_EXPORT extern const char kStubCrosSettings[]; CHROMEOS_EXPORT extern const char kUseNewNetworkConfigurationHandlers[]; CHROMEOS_EXPORT extern const char kDisableUserImageSync[]; +CHROMEOS_EXPORT extern const char kEnableFirstRunUI[]; } // namespace switches } // namespace chromeos