diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index cd5f5169488f97..aa6e258ec2d98b 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -350,6 +350,7 @@ + diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc index 62ca6334d3fb94..d1de8428026d62 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc @@ -115,16 +115,12 @@ class KioskProfileLoader::CryptohomedChecker //////////////////////////////////////////////////////////////////////////////// // KioskProfileLoader -KioskProfileLoader::KioskProfileLoader(KioskAppManager* kiosk_app_manager, - const std::string& app_id, +KioskProfileLoader::KioskProfileLoader(const std::string& app_user_id, + bool force_ephemeral, Delegate* delegate) - : kiosk_app_manager_(kiosk_app_manager), - app_id_(app_id), - delegate_(delegate) { - KioskAppManager::App app; - CHECK(kiosk_app_manager_->GetApp(app_id_, &app)); - user_id_ = app.user_id; -} + : user_id_(app_user_id), + force_ephemeral_(force_ephemeral), + delegate_(delegate) {} KioskProfileLoader::~KioskProfileLoader() {} @@ -137,7 +133,7 @@ void KioskProfileLoader::Start() { void KioskProfileLoader::LoginAsKioskAccount() { login_performer_.reset(new LoginPerformer(this)); - login_performer_->LoginAsKioskAccount(user_id_); + login_performer_->LoginAsKioskAccount(user_id_, force_ephemeral_); } void KioskProfileLoader::ReportLaunchResult(KioskAppLaunchError::Error error) { diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h index 9f28103f5e1d95..06b90291f004bf 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h +++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h @@ -35,8 +35,8 @@ class KioskProfileLoader : public LoginPerformer::Delegate, virtual ~Delegate() {} }; - KioskProfileLoader(KioskAppManager* kiosk_app_manager, - const std::string& app_id, + KioskProfileLoader(const std::string& app_user_id, + bool force_ephemeral, Delegate* delegate); virtual ~KioskProfileLoader(); @@ -61,9 +61,8 @@ class KioskProfileLoader : public LoginPerformer::Delegate, // LoginUtils::Delegate implementation: virtual void OnProfilePrepared(Profile* profile) OVERRIDE; - KioskAppManager* kiosk_app_manager_; - const std::string app_id_; std::string user_id_; + bool force_ephemeral_; Delegate* delegate_; scoped_ptr cryptohomed_checker_; scoped_ptr login_performer_; diff --git a/chrome/browser/chromeos/idle_detector.cc b/chrome/browser/chromeos/idle_detector.cc new file mode 100644 index 00000000000000..a4391667ca5e11 --- /dev/null +++ b/chrome/browser/chromeos/idle_detector.cc @@ -0,0 +1,45 @@ +// Copyright 2014 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/idle_detector.h" + +#include "ash/shell.h" +#include "ash/wm/user_activity_detector.h" +#include "base/bind.h" +#include "base/logging.h" + +namespace chromeos { + +IdleDetector::IdleDetector(const base::Closure& on_active_callback, + const base::Closure& on_idle_callback) + : active_callback_(on_active_callback), idle_callback_(on_idle_callback) {} + +IdleDetector::~IdleDetector() { + if (ash::Shell::HasInstance() && + ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) + ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); +} + +void IdleDetector::OnUserActivity(const ui::Event* event) { + if (!active_callback_.is_null()) + active_callback_.Run(); + ResetTimer(); +} + +void IdleDetector::Start(const base::TimeDelta& timeout) { + timeout_ = timeout; + if (!ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) + ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this); + ResetTimer(); +} + +void IdleDetector::ResetTimer() { + if (timer_.IsRunning()) { + timer_.Reset(); + } else { + timer_.Start(FROM_HERE, timeout_, idle_callback_); + } +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/idle_detector.h b/chrome/browser/chromeos/idle_detector.h new file mode 100644 index 00000000000000..e585c405491654 --- /dev/null +++ b/chrome/browser/chromeos/idle_detector.h @@ -0,0 +1,42 @@ +// Copyright 2014 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_IDLE_DETECTOR_H_ +#define CHROME_BROWSER_CHROMEOS_IDLE_DETECTOR_H_ + +#include "ash/wm/user_activity_observer.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/timer/timer.h" + +namespace chromeos { + +class IdleDetector : public ash::UserActivityObserver { + public: + IdleDetector(const base::Closure& on_active_callback, + const base::Closure& on_idle_callback); + virtual ~IdleDetector(); + + void Start(const base::TimeDelta& timeout); + + private: + // UserActivityObserver overrides: + virtual void OnUserActivity(const ui::Event* event) OVERRIDE; + + // Resets |timer_| to fire when we reach our idle timeout. + void ResetTimer(); + + base::OneShotTimer timer_; + + base::Closure active_callback_; + base::Closure idle_callback_; + + base::TimeDelta timeout_; + + DISALLOW_COPY_AND_ASSIGN(IdleDetector); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_IDLE_DETECTOR_H_ diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index ad559da372cfdb..5d45d6555b2343 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc @@ -120,8 +120,11 @@ void AppLaunchController::StartAppLaunch() { app_launch_splash_screen_actor_->SetDelegate(this); app_launch_splash_screen_actor_->Show(app_id_); + KioskAppManager::App app; + CHECK(KioskAppManager::Get() && + KioskAppManager::Get()->GetApp(app_id_, &app)); kiosk_profile_loader_.reset( - new KioskProfileLoader(KioskAppManager::Get(), app_id_, this)); + new KioskProfileLoader(app.user_id, false, this)); kiosk_profile_loader_->Start(); } diff --git a/chrome/browser/chromeos/login/authenticator.h b/chrome/browser/chromeos/login/authenticator.h index f0618036832856..079fb61e09ce76 100644 --- a/chrome/browser/chromeos/login/authenticator.h +++ b/chrome/browser/chromeos/login/authenticator.h @@ -58,7 +58,9 @@ class Authenticator : public base::RefCountedThreadSafe { // Initiates login into kiosk mode account identified by |app_user_id|. // The |app_user_id| is a generated username for the account. - virtual void LoginAsKioskAccount(const std::string& app_user_id) = 0; + // |force_ephemeral| specifies whether to force the session to be ephemeral. + virtual void LoginAsKioskAccount( + const std::string& app_user_id, bool force_ephemeral) = 0; // Completes retail mode login. virtual void OnRetailModeLoginSuccess() = 0; diff --git a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc new file mode 100644 index 00000000000000..6503d9b9708e6e --- /dev/null +++ b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc @@ -0,0 +1,76 @@ +// Copyright 2014 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/demo_mode/demo_app_launcher.h" + +#include "base/command_line.h" +#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h" +#include "chrome/browser/chromeos/login/login_display_host_impl.h" +#include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/extensions/component_loader.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/ui/extensions/application_launch.h" +#include "chrome/common/chrome_switches.h" +#include "extensions/browser/extension_system.h" +#include "grit/browser_resources.h" + +namespace { + +const char kDemoAppUserId[] = "demouser@demo.app.local"; + +} + +namespace chromeos { + +DemoAppLauncher::DemoAppLauncher() : profile_(NULL) {} + +DemoAppLauncher::~DemoAppLauncher() {} + +void DemoAppLauncher::StartDemoAppLaunch() { + DVLOG(1) << "Launching demo app..."; + // user_id = DemoAppUserId, force_emphemeral = true, delegate = this. + kiosk_profile_loader_.reset( + new KioskProfileLoader(kDemoAppUserId, true, this)); + kiosk_profile_loader_->Start(); +} + +// static +bool DemoAppLauncher::IsDemoAppSession(const std::string& user_id) { + return user_id == kDemoAppUserId ? true : false; +} + +void DemoAppLauncher::OnProfileLoaded(Profile* profile) { + DVLOG(1) << "Profile loaded... Starting demo app launch."; + profile_ = profile; + + kiosk_profile_loader_.reset(); + + // Load our demo app, then launch it. + ExtensionService* extension_service = + extensions::ExtensionSystem::Get(profile_)->extension_service(); + std::string extension_id = extension_service->component_loader()->Add( + IDR_DEMO_APP_MANIFEST, + base::FilePath("/usr/share/chromeos-assets/demo_app")); + + const extensions::Extension* extension = + extension_service->GetExtensionById(extension_id, true); + + CommandLine* command_line = CommandLine::ForCurrentProcess(); + command_line->AppendSwitch(switches::kForceAppMode); + command_line->AppendSwitchASCII(switches::kAppId, extension_id); + + OpenApplication(AppLaunchParams( + profile_, extension, extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW)); + InitAppSession(profile_, extension_id); + + UserManager::Get()->SessionStarted(); + + LoginDisplayHostImpl::default_host()->Finalize(); +} + +void DemoAppLauncher::OnProfileLoadFailed(KioskAppLaunchError::Error error) { + LOG(ERROR) << "Loading the Kiosk Profile failed."; +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h new file mode 100644 index 00000000000000..d449e48a65f9f8 --- /dev/null +++ b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h @@ -0,0 +1,38 @@ +// Copyright 2014 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_LOGIN_DEMO_MODE_DEMO_APP_LAUNCHER_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_DEMO_MODE_DEMO_APP_LAUNCHER_H_ + +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/app_mode/kiosk_profile_loader.h" + +class Profile; + +namespace chromeos { + +// Class responsible for launching the demo app under a kiosk session. +class DemoAppLauncher : public KioskProfileLoader::Delegate { + public: + DemoAppLauncher(); + virtual ~DemoAppLauncher(); + + void StartDemoAppLaunch(); + + static bool IsDemoAppSession(const std::string& user_id); + + private: + // KioskProfileLoader::Delegate overrides: + virtual void OnProfileLoaded(Profile* profile) OVERRIDE; + virtual void OnProfileLoadFailed(KioskAppLaunchError::Error error) OVERRIDE; + + Profile* profile_; + scoped_ptr kiosk_profile_loader_; + + DISALLOW_COPY_AND_ASSIGN(DemoAppLauncher); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_DEMO_MODE_DEMO_APP_LAUNCHER_H_ diff --git a/chrome/browser/chromeos/login/login_display_host.h b/chrome/browser/chromeos/login/login_display_host.h index 72f60d72d53fd6..4dc1adba2b34f8 100644 --- a/chrome/browser/chromeos/login/login_display_host.h +++ b/chrome/browser/chromeos/login/login_display_host.h @@ -111,6 +111,9 @@ class LoginDisplayHost { // Starts app launch splash screen. virtual void StartAppLaunch(const std::string& app_id, bool diagnostic_mode) = 0; + + // Starts the demo app launch. + virtual void StartDemoAppLaunch() = 0; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc index 995b0f8867d90d..0953d2f2f805f8 100644 --- a/chrome/browser/chromeos/login/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/login_display_host_impl.cc @@ -654,6 +654,14 @@ void LoginDisplayHostImpl::PrewarmAuthentication() { pointer_factory_.GetWeakPtr())); } +void LoginDisplayHostImpl::StartDemoAppLaunch() { + LOG(WARNING) << "Login WebUI >> starting demo app."; + SetStatusAreaVisible(false); + + demo_app_launcher_.reset(new DemoAppLauncher()); + demo_app_launcher_->StartDemoAppLaunch(); +} + void LoginDisplayHostImpl::StartAppLaunch(const std::string& app_id, bool diagnostic_mode) { LOG(WARNING) << "Login WebUI >> start app launch."; diff --git a/chrome/browser/chromeos/login/login_display_host_impl.h b/chrome/browser/chromeos/login/login_display_host_impl.h index ec78c1c9b1bb9a..f8de85a027b1e0 100644 --- a/chrome/browser/chromeos/login/login_display_host_impl.h +++ b/chrome/browser/chromeos/login/login_display_host_impl.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/login/app_launch_controller.h" #include "chrome/browser/chromeos/login/auth_prewarmer.h" +#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/login_display.h" #include "chrome/browser/chromeos/login/login_display_host.h" @@ -81,6 +82,7 @@ class LoginDisplayHostImpl : public LoginDisplayHost, virtual void PrewarmAuthentication() OVERRIDE; virtual void StartAppLaunch(const std::string& app_id, bool diagnostic_mode) OVERRIDE; + virtual void StartDemoAppLaunch() OVERRIDE; // Creates WizardController instance. WizardController* CreateWizardController(); @@ -203,6 +205,9 @@ class LoginDisplayHostImpl : public LoginDisplayHost, // App launch controller. scoped_ptr app_launch_controller_; + // Demo app launcher. + scoped_ptr demo_app_launcher_; + // Client for enterprise auto-enrollment check. scoped_ptr auto_enrollment_client_; diff --git a/chrome/browser/chromeos/login/login_performer.cc b/chrome/browser/chromeos/login/login_performer.cc index 3d5471136a6e66..99b1cc802def8c 100644 --- a/chrome/browser/chromeos/login/login_performer.cc +++ b/chrome/browser/chromeos/login/login_performer.cc @@ -296,12 +296,13 @@ void LoginPerformer::LoginAsPublicAccount(const std::string& username) { username)); } -void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id) { +void LoginPerformer::LoginAsKioskAccount( + const std::string& app_user_id, bool force_ephemeral) { authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&Authenticator::LoginAsKioskAccount, authenticator_.get(), - app_user_id)); + app_user_id, force_ephemeral)); } void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { diff --git a/chrome/browser/chromeos/login/login_performer.h b/chrome/browser/chromeos/login/login_performer.h index d4ec7d8639abbe..de6b4485efcbac 100644 --- a/chrome/browser/chromeos/login/login_performer.h +++ b/chrome/browser/chromeos/login/login_performer.h @@ -82,7 +82,8 @@ class LoginPerformer : public LoginStatusConsumer, void LoginAsPublicAccount(const std::string& username); // Performs a login into the kiosk mode account with |app_user_id|. - void LoginAsKioskAccount(const std::string& app_user_id); + void LoginAsKioskAccount(const std::string& app_user_id, + bool force_ephemeral); // Migrates cryptohome using |old_password| specified. void RecoverEncryptedData(const std::string& old_password); diff --git a/chrome/browser/chromeos/login/mock_authenticator.cc b/chrome/browser/chromeos/login/mock_authenticator.cc index 696db2c34484e7..4fa4ee4a9bbedf 100644 --- a/chrome/browser/chromeos/login/mock_authenticator.cc +++ b/chrome/browser/chromeos/login/mock_authenticator.cc @@ -62,7 +62,7 @@ void MockAuthenticator::LoginAsPublicAccount(const std::string& username) { } void MockAuthenticator::LoginAsKioskAccount( - const std::string& app_user_id) { + const std::string& app_user_id, bool force_ephemeral) { consumer_->OnLoginSuccess(UserContext(expected_username_, std::string(), std::string(), diff --git a/chrome/browser/chromeos/login/mock_authenticator.h b/chrome/browser/chromeos/login/mock_authenticator.h index 12e22e44a35f19..600cb22870dab5 100644 --- a/chrome/browser/chromeos/login/mock_authenticator.h +++ b/chrome/browser/chromeos/login/mock_authenticator.h @@ -38,7 +38,8 @@ class MockAuthenticator : public Authenticator { const UserContext& user_context) OVERRIDE; virtual void LoginRetailMode() OVERRIDE; virtual void LoginAsPublicAccount(const std::string& username) OVERRIDE; - virtual void LoginAsKioskAccount(const std::string& app_user_id) OVERRIDE; + virtual void LoginAsKioskAccount( + const std::string& app_user_id, bool force_ephemeral) OVERRIDE; virtual void LoginOffTheRecord() OVERRIDE; virtual void OnRetailModeLoginSuccess() OVERRIDE; diff --git a/chrome/browser/chromeos/login/mock_login_display_host.h b/chrome/browser/chromeos/login/mock_login_display_host.h index 7e21c10575eee6..003efb759bd361 100644 --- a/chrome/browser/chromeos/login/mock_login_display_host.h +++ b/chrome/browser/chromeos/login/mock_login_display_host.h @@ -44,6 +44,7 @@ class MockLoginDisplayHost : public LoginDisplayHost { MOCK_METHOD0(OnPreferencesChanged, void(void)); MOCK_METHOD0(PrewarmAuthentication, void(void)); MOCK_METHOD2(StartAppLaunch, void(const std::string&, bool)); + MOCK_METHOD0(StartDemoAppLaunch, void(void)); private: DISALLOW_COPY_AND_ASSIGN(MockLoginDisplayHost); diff --git a/chrome/browser/chromeos/login/parallel_authenticator.cc b/chrome/browser/chromeos/login/parallel_authenticator.cc index 741f44b2237f60..85ae4b9739f53f 100644 --- a/chrome/browser/chromeos/login/parallel_authenticator.cc +++ b/chrome/browser/chromeos/login/parallel_authenticator.cc @@ -346,7 +346,7 @@ void ParallelAuthenticator::LoginAsPublicAccount(const std::string& username) { } void ParallelAuthenticator::LoginAsKioskAccount( - const std::string& app_user_id) { + const std::string& app_user_id, bool force_ephemeral) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); current_state_.reset(new AuthAttemptState( UserContext(app_user_id, @@ -357,9 +357,10 @@ void ParallelAuthenticator::LoginAsKioskAccount( User::USER_TYPE_KIOSK_APP, false)); remove_user_data_on_failure_ = true; + int ephemeral_flag = force_ephemeral ? cryptohome::ENSURE_EPHEMERAL : 0; MountPublic(current_state_.get(), scoped_refptr(this), - cryptohome::CREATE_IF_MISSING); + cryptohome::CREATE_IF_MISSING | ephemeral_flag); } void ParallelAuthenticator::OnRetailModeLoginSuccess() { diff --git a/chrome/browser/chromeos/login/parallel_authenticator.h b/chrome/browser/chromeos/login/parallel_authenticator.h index 05e887e41923bd..8ea765a59372a7 100644 --- a/chrome/browser/chromeos/login/parallel_authenticator.h +++ b/chrome/browser/chromeos/login/parallel_authenticator.h @@ -134,7 +134,8 @@ class ParallelAuthenticator : public Authenticator, // Initiates login into the kiosk mode account identified by |app_user_id|. // Mounts an public but non-ephemeral cryptohome and notifies consumer on the // success/failure. - virtual void LoginAsKioskAccount(const std::string& app_user_id) OVERRIDE; + virtual void LoginAsKioskAccount( + const std::string& app_user_id, bool force_ephemeral) OVERRIDE; // These methods must be called on the UI thread, as they make DBus calls // and also call back to the login UI. diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index e498b55657087e..cd84ca0023e5c9 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -164,6 +164,7 @@ #include "chrome/browser/chromeos/system/automatic_reboot_manager.h" #include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" #include "chrome/browser/ui/webui/chromeos/charger_replacement_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #else #include "chrome/browser/extensions/default_apps.h" @@ -294,6 +295,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) { chromeos::KioskAppManager::RegisterPrefs(registry); chromeos::LoginUtils::RegisterPrefs(registry); chromeos::MultiProfileUserController::RegisterPrefs(registry); + chromeos::NetworkScreenHandler::RegisterPrefs(registry); chromeos::Preferences::RegisterPrefs(registry); chromeos::proxy_config::RegisterPrefs(registry); chromeos::RegisterDisplayLocalStatePrefs(registry); diff --git a/chrome/browser/resources/chromeos/demo_app/manifest.json b/chrome/browser/resources/chromeos/demo_app/manifest.json new file mode 100644 index 00000000000000..b48679ba478fa2 --- /dev/null +++ b/chrome/browser/resources/chromeos/demo_app/manifest.json @@ -0,0 +1,14 @@ +{ + // chrome-extension://klimoghijjogocdbaikffefjfcfheiel + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqTqJNPnnhAarSbA5aPvPU/h6BxvHO+PWQLVab5RyJUxl1eVnZFx9sIGoXctUgKG+DXpSflYhsvK7opMd1jPqdeSjeSvIDOlsSNX45G+FhAqPQ7OHDdKboQb86TbE53n4qXYamQcx09VIJhi19mPBdqod6myCrTYjPukKiNwAlIEz6eAQL/++uZnIyRzvkht3aMMSfA2PP1qg0ie9aHE/bTwPec9I1kUIe4dPz4NaI5hKxKoDVk2TC9MNNEUx1YznuZNP6Vr21ZRutaOIiptnz1/QJXVr37EMqKvEwNJ/zGFhk1nNju7hYRTbf55CID94yWY14SevnO1nprEGv8+zAwIDAQAB", + "name": "Demo App", + "version": "1.0", + "manifest_version": 2, + "description": "ChromeOS Demo App", + "permissions": ["power"], + "app": { + "background": { + "scripts": ["js/launch.js"] + } + } +} diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index c5663e12484a50..703e1363f16f78 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc @@ -74,8 +74,10 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/app_mode/app_launch_utils.h" #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" +#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/lifetime/application_lifetime.h" #include "chromeos/chromeos_switches.h" #endif @@ -616,6 +618,15 @@ bool StartupBrowserCreator::ProcessCmdLineImpl( // Skip browser launch since app mode launches its app window. silent_launch = true; } + + // If we are a demo app session and we crashed, there is no safe recovery + // possible. We should instead cleanly exit and go back to the OOBE screen, + // where we will launch again after the timeout has expired. + if (chromeos::DemoAppLauncher::IsDemoAppSession( + command_line.GetSwitchValueASCII(chromeos::switches::kLoginUser))) { + chrome::AttemptUserExit(); + return false; + } #endif #if defined(TOOLKIT_VIEWS) && defined(USE_X11) diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc index e5132152220a84..25378b5329687c 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc @@ -6,19 +6,28 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/memory/weak_ptr.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/base/locale_util.h" +#include "chrome/browser/chromeos/idle_detector.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/login/input_events_blocker.h" +#include "chrome/browser/chromeos/login/login_display_host_impl.h" #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/chromeos/system/timezone_util.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" +#include "chrome/common/pref_names.h" +#include "chromeos/chromeos_switches.h" #include "chromeos/ime/input_method_manager.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -39,6 +48,9 @@ const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; const char kUSlayout[] = "xkb:us::eng"; +const int64 kDerelectDetectionTimeoutSeconds = 8 * 60 * 60; // 8 hours. +const int64 kDerelectIdleTimeoutSeconds = 5 * 60; // 5 minutes. + } // namespace namespace chromeos { @@ -50,9 +62,11 @@ NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) screen_(NULL), core_oobe_actor_(core_oobe_actor), is_continue_enabled_(false), + is_derelict_(false), show_on_init_(false), weak_ptr_factory_(this) { DCHECK(core_oobe_actor_); + SetupTimeouts(); } NetworkScreenHandler::~NetworkScreenHandler() { @@ -76,6 +90,7 @@ void NetworkScreenHandler::Show() { } ShowScreen(OobeUI::kScreenOobeNetwork, NULL); + StartIdleDetection(); } void NetworkScreenHandler::Hide() { @@ -159,9 +174,16 @@ void NetworkScreenHandler::RegisterMessages() { &NetworkScreenHandler::HandleOnTimezoneChanged); } + +// static +void NetworkScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kDerelictMachine, false); +} + // NetworkScreenHandler, private: ---------------------------------------------- void NetworkScreenHandler::HandleOnExit() { + detector_.reset(); ClearErrors(); if (screen_) screen_->OnContinuePressed(); @@ -237,6 +259,58 @@ void NetworkScreenHandler::OnSystemTimezoneChanged() { CallJS("setTimezone", current_timezone_id); } +void NetworkScreenHandler::StartIdleDetection() { + if (!detector_.get()) { + detector_.reset( + new IdleDetector(base::Closure(), + base::Bind(&NetworkScreenHandler::OnIdle, + weak_ptr_factory_.GetWeakPtr()))); + } + + detector_->Start( + is_derelict_ ? derelict_idle_timeout_ : derelict_detection_timeout_); +} + +void NetworkScreenHandler::OnIdle() { + if (is_derelict_) { + LoginDisplayHost* host = LoginDisplayHostImpl::default_host(); + host->StartDemoAppLaunch(); + } else { + is_derelict_ = true; + PrefService* prefs = g_browser_process->local_state(); + prefs->SetBoolean(prefs::kDerelictMachine, true); + + StartIdleDetection(); + } +} + +void NetworkScreenHandler::SetupTimeouts() { + CommandLine* cmdline = CommandLine::ForCurrentProcess(); + DCHECK(cmdline); + + PrefService* prefs = g_browser_process->local_state(); + is_derelict_ = prefs->GetBoolean(prefs::kDerelictMachine); + + int64 derelict_detection_timeout; + if (!cmdline->HasSwitch(switches::kDerelictDetectionTimeout) || + !base::StringToInt64( + cmdline->GetSwitchValueASCII(switches::kDerelictDetectionTimeout), + &derelict_detection_timeout)) { + derelict_detection_timeout = kDerelectDetectionTimeoutSeconds; + } + derelict_detection_timeout_ = + base::TimeDelta::FromSeconds(derelict_detection_timeout); + + int64 derelict_idle_timeout; + if (!cmdline->HasSwitch(switches::kDerelictIdleTimeout) || + !base::StringToInt64( + cmdline->GetSwitchValueASCII(switches::kDerelictIdleTimeout), + &derelict_idle_timeout)) { + derelict_idle_timeout = kDerelectIdleTimeoutSeconds; + } + derelict_idle_timeout_ = base::TimeDelta::FromSeconds(derelict_idle_timeout); +} + // static base::ListValue* NetworkScreenHandler::GetLanguageList() { const std::string app_locale = g_browser_process->GetApplicationLocale(); diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h index 56cb8a2ba37164..8d8fb7e0ff2d99 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h @@ -8,14 +8,18 @@ #include #include "base/compiler_specific.h" +#include "base/time/time.h" #include "chrome/browser/chromeos/login/screens/network_screen_actor.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "ui/gfx/point.h" +class PrefRegistrySimple; + namespace chromeos { class CoreOobeActor; +class IdleDetector; struct NetworkScreenHandlerOnLanguageChangedCallbackData; @@ -46,6 +50,9 @@ class NetworkScreenHandler : public NetworkScreenActor, // WebUIMessageHandler implementation: virtual void RegisterMessages() OVERRIDE; + // Registers the preference for derelict state. + static void RegisterPrefs(PrefRegistrySimple* registry); + private: // Handles moving off the screen. void HandleOnExit(); @@ -69,6 +76,11 @@ class NetworkScreenHandler : public NetworkScreenActor, // Callback when the system timezone settings is changed. void OnSystemTimezoneChanged(); + // Idle detection related methods. + void StartIdleDetection(); + void OnIdle(); + void SetupTimeouts(); + // Returns available languages. Caller gets the ownership. Note, it does // depend on the current locale. static base::ListValue* GetLanguageList(); @@ -85,6 +97,9 @@ class NetworkScreenHandler : public NetworkScreenActor, bool is_continue_enabled_; + // Flag set if we believe this is an abandoned machine. + bool is_derelict_; + // Keeps whether screen should be shown right after initialization. bool show_on_init_; @@ -93,6 +108,13 @@ class NetworkScreenHandler : public NetworkScreenActor, scoped_ptr timezone_subscription_; + scoped_ptr detector_; + + // Timeout to detect if the machine is in a derelict state. + base::TimeDelta derelict_detection_timeout_; + // Timeout before showing our demo up if the machine is in a derelict state. + base::TimeDelta derelict_idle_timeout_; + base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(NetworkScreenHandler); diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index bea3f82e87fcb9..ad90a0e90816e1 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -391,6 +391,8 @@ 'browser/chromeos/first_run/steps/tray_step.cc', 'browser/chromeos/first_run/steps/tray_step.h', 'browser/chromeos/genius_app/app_id.h', + 'browser/chromeos/idle_detector.cc', + 'browser/chromeos/idle_detector.h', 'browser/chromeos/imageburner/burn_controller.cc', 'browser/chromeos/imageburner/burn_controller.h', 'browser/chromeos/imageburner/burn_device_handler.cc', @@ -462,6 +464,8 @@ 'browser/chromeos/login/default_pinned_apps_field_trial.h', 'browser/chromeos/login/default_user_images.cc', 'browser/chromeos/login/default_user_images.h', + 'browser/chromeos/login/demo_mode/demo_app_launcher.cc', + 'browser/chromeos/login/demo_mode/demo_app_launcher.h', 'browser/chromeos/login/enrollment/enrollment_screen.cc', 'browser/chromeos/login/enrollment/enrollment_screen.h', 'browser/chromeos/login/enrollment/enrollment_screen_actor.h', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index af9398cc678c75..0de61a1c1d7776 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -892,6 +892,10 @@ const char kSAMLOfflineSigninTimeLimit[] = "saml.offline_signin_time_limit"; // cleared. The time is expressed as the serialization obtained from // base::Time::ToInternalValue(). const char kSAMLLastGAIASignInTime[] = "saml.last_gaia_sign_in_time"; + +// Setting used to determine if the machine is in a 'derelict' state. This is +// determined by the time a machine spends on OOBE without any activity. +const char kDerelictMachine[] = "settings.is_machine_derelict"; #endif // defined(OS_CHROMEOS) // The disabled messages in IPC logging. diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 06bbaca9583750..4eab84c0aa0498 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -278,6 +278,7 @@ extern const char kMultiProfileUserBehavior[]; extern const char kFirstRunTutorialShown[]; extern const char kSAMLOfflineSigninTimeLimit[]; extern const char kSAMLLastGAIASignInTime[]; +extern const char kDerelictMachine[]; #endif // defined(OS_CHROMEOS) extern const char kIpcDisabledMessages[]; extern const char kShowHomeButton[]; diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 86e237b352551d..0304fb7c9c92c3 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc @@ -24,6 +24,12 @@ const char kDbusStub[] = "dbus-stub"; // All stub networks are idle by default. const char kDefaultStubNetworkStateIdle[] = "default-stub-network-state-idle"; +// Time before a machine at OOBE is considered derelict +const char kDerelictDetectionTimeout[] = "derelict-detection-timeout"; + +// Time before a derelict machines starts demo mode. +const char kDerelictIdleTimeout[] = "derelict-idle-timeout"; + // Disables wallpaper boot animation (except of OOBE case). const char kDisableBootAnimation[] = "disable-boot-animation"; diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 5bdf38c75b7ac5..b6ef1872da62c3 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h @@ -25,6 +25,8 @@ CHROMEOS_EXPORT extern const char kAshWebUIInit[]; CHROMEOS_EXPORT extern const char kAuthExtensionPath[]; CHROMEOS_EXPORT extern const char kDbusStub[]; CHROMEOS_EXPORT extern const char kDefaultStubNetworkStateIdle[]; +CHROMEOS_EXPORT extern const char kDerelictDetectionTimeout[]; +CHROMEOS_EXPORT extern const char kDerelictIdleTimeout[]; CHROMEOS_EXPORT extern const char kDisableBootAnimation[]; CHROMEOS_EXPORT extern const char kDisableDrive[]; CHROMEOS_EXPORT extern const char kDisableEnterpriseUserReporting[];