Index: chrome/browser/chromeos/screensaver/screensaver_controller.cc |
diff --git a/chrome/browser/chromeos/screensaver/screensaver_controller.cc b/chrome/browser/chromeos/screensaver/screensaver_controller.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..01934981ebd61f00db7f7d5f8dc17aa0afef6502 |
--- /dev/null |
+++ b/chrome/browser/chromeos/screensaver/screensaver_controller.cc |
@@ -0,0 +1,184 @@ |
+// Copyright (c) 2012 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/screensaver/screensaver_controller.h" |
+ |
+#include "ash/screensaver/screensaver_view.h" |
+#include "ash/shell.h" |
+#include "ash/wm/user_activity_detector.h" |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/logging.h" |
+#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/browser/extensions/extension_system.h" |
+#include "chrome/browser/profiles/profile_manager.h" |
+#include "chrome/common/chrome_notification_types.h" |
+#include "chrome/common/extensions/extension.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/power_manager_client.h" |
+#include "content/public/browser/notification_service.h" |
+ |
+namespace { |
+ |
+const int kScreensaverTimeoutMinutes = 2; |
+ |
+ExtensionService* GetDefaultExtensionService() { |
+ Profile* default_profile = ProfileManager::GetDefaultProfile(); |
+ DCHECK(default_profile); |
+ ExtensionService* service = |
+ extensions::ExtensionSystem::Get(default_profile)->extension_service(); |
+ DCHECK(service); |
+ |
+ return service; |
+} |
+ |
+// Find the screensaver extension for the given service, excluding |
+// the one with exclude_id. |
+std::string FindScreensaverExtension(ExtensionService* service, |
+ const std::string& exclude_id) { |
+ const ExtensionSet* extensions = service->extensions(); |
+ if (!extensions) |
+ return std::string(); |
+ |
+ for (ExtensionSet::const_iterator it = extensions->begin(); |
+ it != extensions->end(); |
+ ++it) { |
+ const extensions::Extension* extension = *it; |
+ if (extension && |
+ extension->id() != exclude_id && |
+ extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) |
+ return extension->id(); |
stevenjb
2013/01/31 23:42:18
nit: {}
rkc
2013/02/01 00:35:45
Done.
|
+ } |
+ |
+ return std::string(); |
+} |
+ |
+void UninstallPreviousScreensavers(const extensions::Extension* current) { |
+ Profile* default_profile = ProfileManager::GetDefaultProfile(); |
+ DCHECK(default_profile); |
+ ExtensionService* service = |
+ extensions::ExtensionSystem::Get(default_profile)->extension_service(); |
+ DCHECK(service); |
+ |
+ std::string screensaver_id; |
+ while (!(screensaver_id = |
+ FindScreensaverExtension(service, current->id())).empty()) { |
stevenjb
2013/01/31 23:42:18
Does this compile? I'm not sure what this logic is
rkc
2013/02/01 00:35:45
This is fairly standard C++ syntax. It is equivale
stevenjb
2013/02/01 04:16:27
Ahhh.... I'm familiar with the pattern, but I comp
rkc
2013/02/01 08:37:39
Done.
|
+ string16 error; |
+ if (!service->UninstallExtension(screensaver_id, false, &error)) |
+ LOG(ERROR) << |
+ "Couldn't uninstall previous screensaver extension with id: " << |
+ screensaver_id << " \nError: " << error; |
stevenjb
2013/01/31 23:42:18
{}
nit: << at beginning of line
rkc
2013/02/01 00:35:45
Done.
|
+ } |
+} |
+ |
+} // namespace |
+ |
+namespace chromeos { |
+ |
+ScreensaverController::ScreensaverController() |
+ : threshold_(base::TimeDelta::FromMinutes(kScreensaverTimeoutMinutes)), |
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
+ // Register for extension changes. |
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
+ content::NotificationService::AllSources()); |
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
+ content::NotificationService::AllSources()); |
+ |
+ std::string screensaver_extension_id = |
+ FindScreensaverExtension(GetDefaultExtensionService(), std::string()); |
+ if (!screensaver_extension_id.empty()) |
+ SetupScreensaver(screensaver_extension_id); |
+} |
+ |
+ScreensaverController::~ScreensaverController() { |
+ TeardownScreensaver(); |
+} |
+ |
+void ScreensaverController::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ switch (type) { |
+ case chrome::NOTIFICATION_EXTENSION_INSTALLED: { |
+ const extensions::Extension* extension = |
+ content::Details<const extensions::Extension>(details).ptr(); |
+ // Uninstall any previously installed screensaver extensions if a new |
+ // screensaver extension is installed. |
+ if (extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) |
+ UninstallPreviousScreensavers(extension); |
+ break; |
+ } |
+ case chrome::NOTIFICATION_EXTENSION_LOADED: { |
+ const extensions::Extension* extension = |
+ content::Details<const extensions::Extension>(details).ptr(); |
+ if (!extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) |
+ return; |
stevenjb
2013/01/31 23:42:18
nit: Use either if (HasAPIPermission) {} or if (!H
rkc
2013/02/01 00:35:45
Done.
|
+ |
+ SetupScreensaver(extension->id()); |
+ break; |
+ } |
+ case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
+ const extensions::Extension* extension = |
+ content::Details<extensions::UnloadedExtensionInfo>( |
+ details)->extension; |
+ if (extension->id() == screensaver_extension_id_) |
+ TeardownScreensaver(); |
+ break; |
+ } |
+ } |
+} |
+ |
+void ScreensaverController::IdleNotify(int64 threshold) { |
+ ExtensionService* service = GetDefaultExtensionService(); |
+ const extensions::Extension* screensaver_extension = |
+ service->GetExtensionById(screensaver_extension_id_, |
+ ExtensionService::INCLUDE_ENABLED); |
+ ash::ShowScreensaver(screensaver_extension->GetFullLaunchURL()); |
+ |
+ if (!ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) |
+ ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this); |
+} |
+ |
+void ScreensaverController::OnUserActivity() { |
+ // We don't want to handle further user notifications; we'll either login |
+ // the user and close out or or at least close the screensaver. |
+ if (ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) |
+ ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); |
+ ash::CloseScreensaver(); |
+ |
+ RequestNextIdleNotification(); |
+} |
+ |
+void ScreensaverController::SetupScreensaver( |
+ const std::string& screensaver_extension_id) { |
+ screensaver_extension_id_ = screensaver_extension_id; |
+ |
+ PowerManagerClient* power_manager = |
+ DBusThreadManager::Get()->GetPowerManagerClient(); |
+ if (!power_manager->HasObserver(this)) |
+ power_manager->AddObserver(this); |
+ |
+ RequestNextIdleNotification(); |
+} |
+ |
+void ScreensaverController::TeardownScreensaver() { |
+ PowerManagerClient* power_manager = |
+ DBusThreadManager::Get()->GetPowerManagerClient(); |
+ if (power_manager && power_manager->HasObserver(this)) |
+ power_manager->RemoveObserver(this); |
+ |
+ if (ash::Shell::GetInstance() && |
+ ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) |
+ ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); |
stevenjb
2013/01/31 23:42:18
{}
rkc
2013/02/01 00:35:45
Done.
|
+ |
+ ash::CloseScreensaver(); |
+ screensaver_extension_id_ = ""; |
+} |
+ |
+void ScreensaverController::RequestNextIdleNotification() { |
+ DBusThreadManager::Get()->GetPowerManagerClient()-> |
+ RequestIdleNotification(threshold_.InMilliseconds()); |
+} |
+ |
+} // namespace chromeos |