blob: 89046b14a5777f6818d10c73c262d2f83a13689c [file] [log] [blame]
// Copyright 2017 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/login/arc_kiosk_controller.h"
#include <memory>
#include "base/bind.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
#include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
#include "chrome/browser/chromeos/login/screens/encryption_migration_screen.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chromeos/login/auth/user_context.h"
#include "components/account_id/account_id.h"
#include "components/session_manager/core/session_manager.h"
namespace chromeos {
// ARC Kiosk splash screen minimum show time.
constexpr base::TimeDelta kArcKioskSplashScreenMinTime =
base::TimeDelta::FromSeconds(10);
ArcKioskController::ArcKioskController(LoginDisplayHost* host, OobeUI* oobe_ui)
: host_(host),
arc_kiosk_splash_screen_view_(oobe_ui->GetArcKioskSplashScreenView()),
weak_ptr_factory_(this) {}
ArcKioskController::~ArcKioskController() {
if (arc_kiosk_splash_screen_view_)
arc_kiosk_splash_screen_view_->SetDelegate(nullptr);
}
void ArcKioskController::StartArcKiosk(const AccountId& account_id) {
DVLOG(1) << "Starting ARC Kiosk for account: " << account_id.GetUserEmail();
host_->GetLoginDisplay()->SetUIEnabled(true);
arc_kiosk_splash_screen_view_->SetDelegate(this);
arc_kiosk_splash_screen_view_->Show();
splash_wait_timer_.Start(FROM_HERE, kArcKioskSplashScreenMinTime,
base::Bind(&ArcKioskController::CloseSplashScreen,
weak_ptr_factory_.GetWeakPtr()));
login_performer_ = std::make_unique<ChromeLoginPerformer>(this);
login_performer_->LoginAsArcKioskAccount(account_id);
}
void ArcKioskController::CleanUp() {
splash_wait_timer_.Stop();
// Delegate is registered only when |profile_| is set.
if (profile_)
ArcKioskAppService::Get(profile_)->SetDelegate(nullptr);
}
void ArcKioskController::CloseSplashScreen() {
if (!launched_)
return;
CleanUp();
host_->Finalize(base::OnceClosure());
session_manager::SessionManager::Get()->SessionStarted();
}
void ArcKioskController::OnAuthFailure(const AuthFailure& error) {
LOG(ERROR) << "ARC Kiosk launch failed. Will now shut down, error="
<< error.GetErrorString();
KioskAppLaunchError::Save(KioskAppLaunchError::ARC_AUTH_FAILED);
CleanUp();
chrome::AttemptUserExit();
}
void ArcKioskController::OnAuthSuccess(const UserContext& user_context) {
// LoginPerformer instance will delete itself in case of successful auth.
login_performer_->set_delegate(nullptr);
ignore_result(login_performer_.release());
UserSessionManager::GetInstance()->StartSession(
user_context, UserSessionManager::PRIMARY_USER_SESSION,
false, // has_auth_cookies
false, // Start session for user.
this);
}
void ArcKioskController::WhiteListCheckFailed(const std::string& email) {
NOTREACHED();
}
void ArcKioskController::PolicyLoadFailed() {
LOG(ERROR) << "Policy load failed. Will now shut down";
KioskAppLaunchError::Save(KioskAppLaunchError::POLICY_LOAD_FAILED);
CleanUp();
chrome::AttemptUserExit();
}
void ArcKioskController::SetAuthFlowOffline(bool offline) {
NOTREACHED();
}
void ArcKioskController::OnOldEncryptionDetected(
const UserContext& user_context,
bool has_incomplete_migration) {
host_->StartWizard(OobeScreen::SCREEN_ENCRYPTION_MIGRATION);
EncryptionMigrationScreen* migration_screen =
static_cast<EncryptionMigrationScreen*>(
host_->GetWizardController()->current_screen());
DCHECK(migration_screen);
migration_screen->SetUserContext(user_context);
migration_screen->SetupInitialView();
}
void ArcKioskController::OnProfilePrepared(Profile* profile,
bool browser_launched) {
DVLOG(1) << "Profile loaded... Starting app launch.";
profile_ = profile;
// This object could be deleted any time after successfully reporting
// a profile load, so invalidate the delegate now.
UserSessionManager::GetInstance()->DelegateDeleted(this);
ArcKioskAppService::Get(profile_)->SetDelegate(this);
if (arc_kiosk_splash_screen_view_) {
arc_kiosk_splash_screen_view_->UpdateArcKioskState(
ArcKioskSplashScreenView::ArcKioskState::WAITING_APP_LAUNCH);
}
}
void ArcKioskController::OnAppStarted() {
DVLOG(1) << "ARC Kiosk launch succeeded, wait for app window.";
if (arc_kiosk_splash_screen_view_) {
arc_kiosk_splash_screen_view_->UpdateArcKioskState(
ArcKioskSplashScreenView::ArcKioskState::WAITING_APP_WINDOW);
}
}
void ArcKioskController::OnAppWindowLaunched() {
DVLOG(1) << "App window created, closing splash screen.";
launched_ = true;
// If timer is running, do not remove splash screen for a few
// more seconds to give the user ability to exit ARC kiosk.
if (splash_wait_timer_.IsRunning())
return;
CloseSplashScreen();
}
void ArcKioskController::OnCancelArcKioskLaunch() {
KioskAppLaunchError::Save(KioskAppLaunchError::USER_CANCEL);
CleanUp();
chrome::AttemptUserExit();
}
void ArcKioskController::OnDeletingSplashScreenView() {
arc_kiosk_splash_screen_view_ = nullptr;
}
} // namespace chromeos