1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/first_run/first_run_controller.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h"
11 #include "chrome/browser/chromeos/first_run/first_run_view.h"
12 #include "chrome/browser/chromeos/first_run/metrics.h"
13 #include "chrome/browser/chromeos/first_run/steps/app_list_step.h"
14 #include "chrome/browser/chromeos/first_run/steps/help_step.h"
15 #include "chrome/browser/chromeos/first_run/steps/tray_step.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/ui/chrome_pages.h"
18 #include "components/user_manager/user_manager.h"
19 #include "ui/views/widget/widget.h"
23 size_t NONE_STEP_INDEX
= std::numeric_limits
<size_t>::max();
25 // Instance of currently running controller, or NULL if controller is not
27 chromeos::FirstRunController
* g_instance
;
29 void RecordCompletion(chromeos::first_run::TutorialCompletion type
) {
30 UMA_HISTOGRAM_ENUMERATION("CrosFirstRun.TutorialCompletion",
32 chromeos::first_run::TUTORIAL_COMPLETION_SIZE
);
39 FirstRunController::~FirstRunController() {}
42 void FirstRunController::Start() {
44 LOG(WARNING
) << "First-run tutorial is running already.";
47 g_instance
= new FirstRunController();
52 void FirstRunController::Stop() {
54 LOG(WARNING
) << "First-run tutorial is not running.";
57 g_instance
->Finalize();
58 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, g_instance
);
62 FirstRunController
* FirstRunController::GetInstanceForTest() {
66 FirstRunController::FirstRunController()
68 current_step_index_(NONE_STEP_INDEX
),
72 void FirstRunController::Init() {
73 start_time_
= base::Time::Now();
74 user_manager::UserManager
* user_manager
= user_manager::UserManager::Get();
75 user_profile_
= ProfileHelper::Get()->GetProfileByUserUnsafe(
76 user_manager
->GetActiveUser());
78 shell_helper_
.reset(ash::Shell::GetInstance()->CreateFirstRunHelper());
79 shell_helper_
->AddObserver(this);
81 FirstRunView
* view
= new FirstRunView();
82 view
->Init(user_profile_
);
83 shell_helper_
->GetOverlayWidget()->SetContentsView(view
);
84 actor_
= view
->GetActor();
85 actor_
->set_delegate(this);
86 shell_helper_
->GetOverlayWidget()->Show();
88 web_contents_for_tests_
= view
->GetWebContents();
90 if (actor_
->IsInitialized())
94 void FirstRunController::Finalize() {
95 int furthest_step
= current_step_index_
== NONE_STEP_INDEX
97 : current_step_index_
;
98 UMA_HISTOGRAM_ENUMERATION("CrosFirstRun.FurthestStep",
101 UMA_HISTOGRAM_MEDIUM_TIMES("CrosFirstRun.TimeSpent",
102 base::Time::Now() - start_time_
);
103 if (GetCurrentStep())
104 GetCurrentStep()->OnBeforeHide();
107 actor_
->set_delegate(NULL
);
109 shell_helper_
->RemoveObserver(this);
110 shell_helper_
.reset();
113 void FirstRunController::OnActorInitialized() {
118 void FirstRunController::OnNextButtonClicked(const std::string
& step_name
) {
119 DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name
);
120 GetCurrentStep()->OnBeforeHide();
121 actor_
->HideCurrentStep();
124 void FirstRunController::OnHelpButtonClicked() {
125 RecordCompletion(first_run::TUTORIAL_COMPLETED_WITH_KEEP_EXPLORING
);
126 on_actor_finalized_
= base::Bind(chrome::ShowHelpForProfile
,
128 chrome::HOST_DESKTOP_TYPE_ASH
,
129 chrome::HELP_SOURCE_MENU
);
133 void FirstRunController::OnStepHidden(const std::string
& step_name
) {
134 DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name
);
135 GetCurrentStep()->OnAfterHide();
136 if (!actor_
->IsFinalizing())
140 void FirstRunController::OnStepShown(const std::string
& step_name
) {
141 DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name
);
144 void FirstRunController::OnActorFinalized() {
145 if (!on_actor_finalized_
.is_null())
146 on_actor_finalized_
.Run();
150 void FirstRunController::OnActorDestroyed() {
151 // Normally this shouldn't happen because we are implicitly controlling
154 "FirstRunActor destroyed before FirstRunController::Finalize.";
157 void FirstRunController::OnCancelled() {
158 RecordCompletion(first_run::TUTORIAL_NOT_FINISHED
);
162 void FirstRunController::RegisterSteps() {
163 steps_
.push_back(make_linked_ptr(
164 new first_run::AppListStep(shell_helper_
.get(), actor_
)));
165 steps_
.push_back(make_linked_ptr(
166 new first_run::TrayStep(shell_helper_
.get(), actor_
)));
167 steps_
.push_back(make_linked_ptr(
168 new first_run::HelpStep(shell_helper_
.get(), actor_
)));
171 void FirstRunController::ShowNextStep() {
173 if (!GetCurrentStep()) {
175 RecordCompletion(first_run::TUTORIAL_COMPLETED_WITH_GOT_IT
);
178 GetCurrentStep()->Show();
181 void FirstRunController::AdvanceStep() {
182 if (current_step_index_
== NONE_STEP_INDEX
)
183 current_step_index_
= 0;
185 ++current_step_index_
;
186 if (current_step_index_
>= steps_
.size())
187 current_step_index_
= NONE_STEP_INDEX
;
190 first_run::Step
* FirstRunController::GetCurrentStep() const {
191 return current_step_index_
!= NONE_STEP_INDEX
?
192 steps_
[current_step_index_
].get() : NULL
;
195 } // namespace chromeos