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[];