diff options
author | rkc@chromium.org <rkc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-24 00:36:23 +0000 |
---|---|---|
committer | rkc@chromium.org <rkc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-24 00:36:23 +0000 |
commit | fee3db9360447ed9ec11be7e66d6fecad98fcad6 (patch) | |
tree | c883015851f863f3644b480d1defdedbc22c4118 /chrome/browser/chromeos/kiosk_mode | |
parent | f1cde9bce71668a0fa47413780ce2d74b4d10f9b (diff) | |
download | chromium_src-fee3db9360447ed9ec11be7e66d6fecad98fcad6.zip chromium_src-fee3db9360447ed9ec11be7e66d6fecad98fcad6.tar.gz chromium_src-fee3db9360447ed9ec11be7e66d6fecad98fcad6.tar.bz2 |
Get the screensaver path from the app pack.
Instead of using our hard coded path, call into the app pack to get the path for the installed screensaver.
BUG=chromium-os:27909
TEST=Tried it on a VM.
Review URL: https://chromiumcodereview.appspot.com/9808003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128619 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/kiosk_mode')
6 files changed, 234 insertions, 53 deletions
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc index ead0d21..38a3d5c 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc @@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h" #include "base/bind.h" +#include "base/callback.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" @@ -12,33 +13,152 @@ #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/ui/screensaver_extension_dialog.h" +#include "chrome/browser/extensions/sandboxed_extension_unpacker.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_file_util.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" namespace chromeos { -KioskModeScreensaver::KioskModeScreensaver() { +typedef base::Callback<void( + scoped_refptr<Extension>, + const FilePath&)> UnpackCallback; + +class ScreensaverUnpackerClient : public SandboxedExtensionUnpackerClient { + public: + explicit ScreensaverUnpackerClient(const UnpackCallback& unpacker_callback) + : unpack_callback_(unpacker_callback) {} + + void OnUnpackSuccess(const FilePath& temp_dir, + const FilePath& extension_root, + const base::DictionaryValue* original_manifest, + const Extension* extension) OVERRIDE; + void OnUnpackFailure(const string16& error) OVERRIDE; + + private: + void LoadScreensaverExtension( + const FilePath& extension_base_path, + const FilePath& screensaver_extension_path); + + UnpackCallback unpack_callback_; + + DISALLOW_COPY_AND_ASSIGN(ScreensaverUnpackerClient); +}; + +void ScreensaverUnpackerClient::OnUnpackSuccess( + const FilePath& temp_dir, + const FilePath& extension_root, + const base::DictionaryValue* original_manifest, + const Extension* extension) { + content::BrowserThread::PostTask( + content::BrowserThread::FILE, + FROM_HERE, + base::Bind(&ScreensaverUnpackerClient::LoadScreensaverExtension, + this, + temp_dir, + extension_root)); +} + +void ScreensaverUnpackerClient::OnUnpackFailure(const string16& error) { + LOG(ERROR) << "Couldn't unpack screensaver extension. Error: " << error; +} + +void ScreensaverUnpackerClient::LoadScreensaverExtension( + const FilePath& extension_base_path, + const FilePath& screensaver_extension_path) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); + + std::string error; + scoped_refptr<Extension> screensaver_extension = + extension_file_util::LoadExtension(screensaver_extension_path, + Extension::COMPONENT, + Extension::NO_FLAGS, + &error); + if (!screensaver_extension) { + LOG(ERROR) << "Could not load screensaver extension from: " + << screensaver_extension_path.value() << " due to: " << error; + return; + } + + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind( + unpack_callback_, + screensaver_extension, + extension_base_path)); +} + +KioskModeScreensaver::KioskModeScreensaver() + : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { chromeos::KioskModeSettings* kiosk_mode_settings = chromeos::KioskModeSettings::Get(); if (kiosk_mode_settings->is_initialized()) { - Setup(); + GetScreensaverCrxPath(); } else { - kiosk_mode_settings->Initialize(base::Bind(&KioskModeScreensaver::Setup, - base::Unretained(this))); + kiosk_mode_settings->Initialize(base::Bind( + &KioskModeScreensaver::GetScreensaverCrxPath, + weak_ptr_factory_.GetWeakPtr())); } } KioskModeScreensaver::~KioskModeScreensaver() { + // If the extension was unpacked. + if (!extension_base_path_.empty()) { + // Delete it. + content::BrowserThread::PostTask( + content::BrowserThread::FILE, + FROM_HERE, + base::Bind( + &extension_file_util::DeleteFile, extension_base_path_, true)); + } chromeos::PowerManagerClient* power_manager = chromeos::DBusThreadManager::Get()->GetPowerManagerClient(); if (power_manager->HasObserver(this)) power_manager->RemoveObserver(this); } -void KioskModeScreensaver::Setup() { - // We should NOT be created if already logged in. - CHECK(!chromeos::UserManager::Get()->IsUserLoggedIn()); +void KioskModeScreensaver::GetScreensaverCrxPath() { + chromeos::KioskModeSettings::Get()->GetScreensaverPath( + base::Bind(&KioskModeScreensaver::ScreensaverPathCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void KioskModeScreensaver::ScreensaverPathCallback( + const FilePath& screensaver_crx) { + if (screensaver_crx.empty()) + return; + + scoped_refptr<SandboxedExtensionUnpacker> screensaver_unpacker( + new SandboxedExtensionUnpacker( + screensaver_crx, + true, + Extension::COMPONENT, + Extension::NO_FLAGS, + new ScreensaverUnpackerClient(base::Bind( + &KioskModeScreensaver::SetupScreensaver, + weak_ptr_factory_.GetWeakPtr())))); + + // Fire off the unpacker on the file thread; don't need it to return. + content::BrowserThread::PostTask( + content::BrowserThread::FILE, + FROM_HERE, + base::Bind( + &SandboxedExtensionUnpacker::Start, screensaver_unpacker.get())); +} + +void KioskModeScreensaver::SetupScreensaver( + scoped_refptr<Extension> extension, + const FilePath& extension_base_path) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + extension_base_path_ = extension_base_path; + + // If the user is already logged in, don't need to display the screensaver. + if (chromeos::UserManager::Get()->IsUserLoggedIn()) + return; registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED, content::NotificationService::AllSources()); @@ -53,7 +173,7 @@ void KioskModeScreensaver::Setup() { chromeos::DBusThreadManager::Get()-> GetPowerManagerClient()->RequestActiveNotification(); - browser::ShowScreensaverDialog(); + browser::ShowScreensaverDialog(extension); } // NotificationObserver overrides: @@ -77,13 +197,14 @@ void KioskModeScreensaver::ActiveNotify() { ExistingUserController* controller = ExistingUserController::current_controller(); - if (controller) + if (controller) { // Logging in will shut us down, removing the screen saver. controller->LoginAsDemoUser(); - else + } else { // Remove the screensaver so the user can at least use the underlying // login screen to be able to log in. browser::CloseScreensaverDialog(); + } } static KioskModeScreensaver* g_kiosk_mode_screensaver = NULL; diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h index fb2c81c..0ba655e 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h @@ -7,10 +7,14 @@ #pragma once #include "base/basictypes.h" +#include "base/file_path.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/dbus/power_manager_client.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +class Extension; + namespace chromeos { class KioskModeScreensaver : public PowerManagerClient::Observer, @@ -19,9 +23,6 @@ class KioskModeScreensaver : public PowerManagerClient::Observer, KioskModeScreensaver(); virtual ~KioskModeScreensaver(); - // Really initialize screensaver when KioskModeHelper is initialized. - void Setup(); - // NotificationObserver overrides: virtual void Observe(int type, const content::NotificationSource& source, @@ -32,7 +33,24 @@ class KioskModeScreensaver : public PowerManagerClient::Observer, private: friend class KioskModeScreensaverTest; + + // Initialization functions, in order + // Get the screensaver path once KioskModeHelper is initialized. + void GetScreensaverCrxPath(); + + // Callback to receive the path to the screensaver extension's crx and call + // the unpacker to unpack and load the crx. + void ScreensaverPathCallback(const FilePath& screensaver_crx); + + // Called back on the UI thread to Setup the screensaver with the now unpacked + // and loaded extension. + void SetupScreensaver(scoped_refptr<Extension> extension, + const FilePath& extension_base_path); + content::NotificationRegistrar registrar_; + base::WeakPtrFactory<KioskModeScreensaver> weak_ptr_factory_; + + FilePath extension_base_path_; DISALLOW_COPY_AND_ASSIGN(KioskModeScreensaver); }; diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver_unittest.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver_unittest.cc index 934a060..94a0c19 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver_unittest.cc +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver_unittest.cc @@ -12,6 +12,7 @@ #include "chrome/browser/chromeos/dbus/mock_power_manager_client.h" #include "chrome/browser/chromeos/login/mock_user_manager.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/extensions/extension.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" @@ -68,6 +69,7 @@ class KioskModeScreensaverTest : public testing::Test { .Times(AnyNumber()); screensaver_ = new KioskModeScreensaver(); + screensaver_->SetupScreensaver(NULL, FilePath()); } virtual void TearDown() OVERRIDE { diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.cc index 54e2c06..7164e66 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.cc +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.cc @@ -19,6 +19,12 @@ namespace chromeos { +const int KioskModeSettings::kMaxIdleLogoutTimeout = 600000; // ms +const int KioskModeSettings::kMinIdleLogoutTimeout = 5000; // ms + +const int KioskModeSettings::kMaxIdleLogoutWarningDuration = 60000; // ms +const int KioskModeSettings::kMinIdleLogoutWarningDuration = 1000; // ms + static base::LazyInstance<KioskModeSettings> g_kiosk_mode_settings = LAZY_INSTANCE_INITIALIZER; @@ -64,13 +70,17 @@ void KioskModeSettings::Initialize(const base::Closure& notify_initialized) { // Restrict idle timeouts to safe values to prevent them from being turned off // or otherwise misused. - idle_logout_timeout = std::min(idle_logout_timeout, kMaxIdleLogoutTimeout); - idle_logout_timeout = std::max(idle_logout_timeout, kMinIdleLogoutTimeout); + idle_logout_timeout = std::min(idle_logout_timeout, + KioskModeSettings::kMaxIdleLogoutTimeout); + idle_logout_timeout = std::max(idle_logout_timeout, + KioskModeSettings::kMinIdleLogoutTimeout); idle_logout_warning_duration = - std::min(idle_logout_warning_duration, kMaxIdleLogoutWarningDuration); + std::min(idle_logout_warning_duration, + KioskModeSettings::kMaxIdleLogoutWarningDuration); idle_logout_warning_duration = - std::max(idle_logout_warning_duration, kMinIdleLogoutWarningDuration); + std::max(idle_logout_warning_duration, + KioskModeSettings::kMinIdleLogoutWarningDuration); screensaver_timeout_ = base::TimeDelta::FromMilliseconds( screensaver_timeout); @@ -87,12 +97,31 @@ bool KioskModeSettings::is_initialized() const { return is_initialized_; } -std::string KioskModeSettings::GetScreensaverPath() const { - if (!is_initialized_) - return std::string(); +void KioskModeSettings::GetScreensaverPath( + policy::AppPackUpdater::ScreenSaverUpdateCallback callback) const { + if (!is_initialized_) { + callback.Run(FilePath()); + return; + } + + // Command line flag overrides policy since it can be used + // for testing and dev workflows. + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kKioskModeScreensaverPath)) { + callback.Run(FilePath( + CommandLine::ForCurrentProcess()-> + GetSwitchValueASCII(switches::kKioskModeScreensaverPath))); + return; + } - return CommandLine::ForCurrentProcess()-> - GetSwitchValueASCII(switches::kKioskModeScreensaverPath); + if (g_browser_process) { + policy::BrowserPolicyConnector* bpc = + g_browser_process->browser_policy_connector(); + if (bpc && bpc->GetAppPackUpdater()) { + bpc->GetAppPackUpdater()->SetScreenSaverUpdateCallback(callback); + return; + } + } } base::TimeDelta KioskModeSettings::GetScreensaverTimeout() const { diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h index c580254..e164975 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h @@ -11,28 +11,19 @@ #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/time.h" +#include "chrome/browser/policy/app_pack_updater.h" namespace base { template <typename T> struct DefaultLazyInstanceTraits; } -namespace { - -const int kMaxIdleLogoutTimeout = 600000; // ms = 600s = 10m. -const int kMinIdleLogoutTimeout = 5000; // ms = 5s. - -const int kMaxIdleLogoutWarningDuration = 60000; // ms = 60s. -const int kMinIdleLogoutWarningDuration = 1000; // ms = 1s. - -} // namespace - namespace chromeos { // This class centralizes all our code to get KioskMode settings; since // KioskMode interferes with normal operations all over Chrome, having all // data about it pulled from a central location would make future // refactorings easier. This class also handles getting trust for the policies -// via it's init method. +// via its init method. // // Note: If Initialize is not called before the various Getters, we'll return // invalid values. @@ -48,8 +39,11 @@ class KioskModeSettings { virtual void Initialize(const base::Closure& notify_initialized); virtual bool is_initialized() const; - // The path to the screensaver extension. - virtual std::string GetScreensaverPath() const; + // The path to the screensaver extension. This callback may get called + // very late, or even never (depending on the state of the app pack). + virtual void GetScreensaverPath( + policy::AppPackUpdater::ScreenSaverUpdateCallback callback) const; + // The timeout before which we'll start showing the screensaver. virtual base::TimeDelta GetScreensaverTimeout() const; @@ -59,9 +53,16 @@ class KioskModeSettings { // user is logged out. // The time to logout the user in on idle. virtual base::TimeDelta GetIdleLogoutTimeout() const; + // The time to show the countdown timer for. virtual base::TimeDelta GetIdleLogoutWarningDuration() const; + static const int kMaxIdleLogoutTimeout; + static const int kMinIdleLogoutTimeout; + + static const int kMaxIdleLogoutWarningDuration; + static const int kMinIdleLogoutWarningDuration; + protected: // Needed here so MockKioskModeSettings can inherit from us. KioskModeSettings(); diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings_unittest.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings_unittest.cc index a26eb37..3931f38 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings_unittest.cc +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings_unittest.cc @@ -93,52 +93,62 @@ TEST_F(KioskModeSettingsTest, CheckLogoutTimeoutBounds) { chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); // Check if we go over max. - cros_settings->SetInteger(kIdleLogoutTimeout, - kMaxIdleLogoutTimeout + kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutTimeout, + KioskModeSettings::kMaxIdleLogoutTimeout + kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutTimeout(), - base::TimeDelta::FromMilliseconds(kMaxIdleLogoutTimeout)); + base::TimeDelta::FromMilliseconds( + KioskModeSettings::kMaxIdleLogoutTimeout)); // Check if we go under min. - cros_settings->SetInteger(kIdleLogoutTimeout, - kMinIdleLogoutTimeout - kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutTimeout, + KioskModeSettings::kMinIdleLogoutTimeout - kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutTimeout(), - base::TimeDelta::FromMilliseconds(kMinIdleLogoutTimeout)); + base::TimeDelta::FromMilliseconds( + KioskModeSettings::kMinIdleLogoutTimeout)); // Check if we are between max and min. - cros_settings->SetInteger(kIdleLogoutTimeout, - kMaxIdleLogoutTimeout - kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutTimeout, + KioskModeSettings::kMaxIdleLogoutTimeout - kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutTimeout(), base::TimeDelta::FromMilliseconds( - kMaxIdleLogoutTimeout - kFudgeInt)); + KioskModeSettings::kMaxIdleLogoutTimeout - kFudgeInt)); } TEST_F(KioskModeSettingsTest, CheckLogoutWarningDurationBounds) { chromeos::CrosSettings* cros_settings = chromeos::CrosSettings::Get(); // Check if we go over max. - cros_settings->SetInteger(kIdleLogoutWarningDuration, - kMaxIdleLogoutWarningDuration + kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutWarningDuration, + KioskModeSettings::kMaxIdleLogoutWarningDuration + kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutWarningDuration(), - base::TimeDelta::FromMilliseconds(kMaxIdleLogoutWarningDuration)); + base::TimeDelta::FromMilliseconds( + KioskModeSettings::kMaxIdleLogoutWarningDuration)); // Check if we go under min. - cros_settings->SetInteger(kIdleLogoutWarningDuration, - kMinIdleLogoutWarningDuration - kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutWarningDuration, + KioskModeSettings::kMinIdleLogoutWarningDuration - kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutWarningDuration(), - base::TimeDelta::FromMilliseconds(kMinIdleLogoutWarningDuration)); + base::TimeDelta::FromMilliseconds( + KioskModeSettings::kMinIdleLogoutWarningDuration)); // Check if we are between max and min. - cros_settings->SetInteger(kIdleLogoutWarningDuration, - kMaxIdleLogoutWarningDuration - kFudgeInt); + cros_settings->SetInteger( + kIdleLogoutWarningDuration, + KioskModeSettings::kMaxIdleLogoutWarningDuration - kFudgeInt); ReInitialize(); EXPECT_EQ(KioskModeSettings::Get()->GetIdleLogoutWarningDuration(), base::TimeDelta::FromMilliseconds( - kMaxIdleLogoutWarningDuration - kFudgeInt)); + KioskModeSettings::kMaxIdleLogoutWarningDuration - kFudgeInt)); } TEST_F(KioskModeSettingsTest, UnitializedValues) { |