blob: 65ed426262490cad3ad76a610e7dbaf2ea45b2b7 [file] [log] [blame]
// 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/shell.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/chromeos/first_run/steps/app_list_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/login/user_manager.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "ui/views/widget/widget.h"
namespace {
size_t NONE_STEP_INDEX = std::numeric_limits<size_t>::max();
// Instance of currently running controller, or NULL if controller is not
// running now.
chromeos::FirstRunController* g_instance;
} // namespace
namespace chromeos {
FirstRunController::~FirstRunController() {}
// static
void FirstRunController::Start() {
if (g_instance) {
LOG(WARNING) << "First-run tutorial is running already.";
return;
}
g_instance = new FirstRunController();
g_instance->Init();
}
// static
void FirstRunController::Stop() {
if (!g_instance) {
LOG(WARNING) << "First-run tutorial is not running.";
return;
}
g_instance->Finalize();
base::MessageLoop::current()->DeleteSoon(FROM_HERE, g_instance);
g_instance = NULL;
}
FirstRunController* FirstRunController::GetInstanceForTest() {
return g_instance;
}
FirstRunController::FirstRunController()
: actor_(NULL),
current_step_index_(NONE_STEP_INDEX),
user_profile_(NULL) {
}
void FirstRunController::Init() {
UserManager* user_manager = UserManager::Get();
user_profile_ = user_manager->GetProfileByUser(user_manager->GetActiveUser());
shell_helper_.reset(ash::Shell::GetInstance()->CreateFirstRunHelper());
shell_helper_->AddObserver(this);
FirstRunView* view = new FirstRunView();
view->Init(user_profile_);
shell_helper_->GetOverlayWidget()->SetContentsView(view);
actor_ = view->GetActor();
actor_->set_delegate(this);
shell_helper_->GetOverlayWidget()->Show();
view->RequestFocus();
web_contents_for_tests_ = view->GetWebContents();
if (actor_->IsInitialized())
OnActorInitialized();
}
void FirstRunController::Finalize() {
if (GetCurrentStep())
GetCurrentStep()->OnBeforeHide();
steps_.clear();
if (actor_)
actor_->set_delegate(NULL);
actor_ = NULL;
shell_helper_->RemoveObserver(this);
shell_helper_.reset();
}
void FirstRunController::OnActorInitialized() {
RegisterSteps();
ShowNextStep();
}
void FirstRunController::OnNextButtonClicked(const std::string& step_name) {
DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name);
GetCurrentStep()->OnBeforeHide();
actor_->HideCurrentStep();
}
void FirstRunController::OnHelpButtonClicked() {
on_actor_finalized_ = base::Bind(chrome::ShowHelpForProfile,
user_profile_,
chrome::HOST_DESKTOP_TYPE_ASH,
chrome::HELP_SOURCE_MENU);
actor_->Finalize();
}
void FirstRunController::OnStepHidden(const std::string& step_name) {
DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name);
GetCurrentStep()->OnAfterHide();
if (!actor_->IsFinalizing())
ShowNextStep();
}
void FirstRunController::OnStepShown(const std::string& step_name) {
DCHECK(GetCurrentStep() && GetCurrentStep()->name() == step_name);
}
void FirstRunController::OnActorFinalized() {
if (!on_actor_finalized_.is_null())
on_actor_finalized_.Run();
Stop();
}
void FirstRunController::OnActorDestroyed() {
// Normally this shouldn't happen because we are implicitly controlling
// actor's lifetime.
NOTREACHED() <<
"FirstRunActor destroyed before FirstRunController::Finalize.";
}
void FirstRunController::OnCancelled() {
Stop();
}
void FirstRunController::RegisterSteps() {
steps_.push_back(make_linked_ptr(
new first_run::AppListStep(shell_helper_.get(), actor_)));
steps_.push_back(make_linked_ptr(
new first_run::TrayStep(shell_helper_.get(), actor_)));
steps_.push_back(make_linked_ptr(
new first_run::HelpStep(shell_helper_.get(), actor_)));
}
void FirstRunController::ShowNextStep() {
AdvanceStep();
if (GetCurrentStep())
GetCurrentStep()->Show();
else
actor_->Finalize();
}
void FirstRunController::AdvanceStep() {
if (current_step_index_ == NONE_STEP_INDEX)
current_step_index_ = 0;
else
++current_step_index_;
if (current_step_index_ >= steps_.size())
current_step_index_ = NONE_STEP_INDEX;
}
first_run::Step* FirstRunController::GetCurrentStep() const {
return current_step_index_ != NONE_STEP_INDEX ?
steps_[current_step_index_].get() : NULL;
}
} // namespace chromeos