Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
|
Matt Perry
2013/01/31 00:37:23
We have other systems that only support 1 active e
rkc
2013/01/31 02:15:46
So I spoke with Josh (the PM for this feature) and
Matt Perry
2013/01/31 22:43:51
OK, that seems fair.
| |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/chromeos/screensaver/screensaver_controller.h" | |
| 6 | |
| 7 #include "ash/screensaver/screensaver_view.h" | |
| 8 #include "ash/shell.h" | |
| 9 #include "ash/wm/user_activity_detector.h" | |
| 10 #include "base/bind.h" | |
| 11 #include "base/callback.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "chrome/browser/extensions/extension_service.h" | |
| 14 #include "chrome/browser/extensions/extension_system.h" | |
| 15 #include "chrome/browser/profiles/profile_manager.h" | |
| 16 #include "chrome/common/chrome_notification_types.h" | |
| 17 #include "chrome/common/extensions/extension.h" | |
| 18 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 19 #include "chromeos/dbus/power_manager_client.h" | |
| 20 #include "content/public/browser/notification_service.h" | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 const int kScreensaverTimeoutMs = 120000; | |
|
Matt Perry
2013/01/31 00:37:23
nit: could specify this in minutes, and use TimeDe
rkc
2013/01/31 02:15:46
Done.
| |
| 25 | |
| 26 ExtensionService* GetDefaultExtensionService() { | |
| 27 Profile* default_profile = ProfileManager::GetDefaultProfile(); | |
|
Matt Perry
2013/01/31 00:37:23
This is generally a bad thing to do... But maybe i
rkc
2013/01/31 02:15:46
The default profile on ChromeOS will always be you
| |
| 28 DCHECK(default_profile); | |
| 29 ExtensionService* service = | |
| 30 extensions::ExtensionSystem::Get(default_profile)->extension_service(); | |
| 31 DCHECK(service); | |
| 32 | |
| 33 return service; | |
| 34 } | |
| 35 | |
| 36 // Find the screensaver extension for the given service, excluding | |
| 37 // the one with exclude_id. | |
| 38 std::string FindScreensaverExtension(ExtensionService* service, | |
| 39 const std::string& exclude_id) { | |
| 40 const ExtensionSet* extensions = service->extensions(); | |
| 41 if (!extensions) | |
| 42 return std::string(); | |
| 43 | |
| 44 for (ExtensionSet::const_iterator it = extensions->begin(); | |
| 45 it != extensions->end(); | |
| 46 ++it) { | |
| 47 const extensions::Extension* extension = *it; | |
| 48 if (extension && | |
| 49 extension->id() != exclude_id && | |
| 50 extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) | |
| 51 return extension->id(); | |
| 52 } | |
| 53 | |
| 54 return std::string(); | |
| 55 } | |
| 56 | |
| 57 void UninstallPreviousScreensavers(const extensions::Extension* current) { | |
| 58 Profile* default_profile = ProfileManager::GetDefaultProfile(); | |
| 59 DCHECK(default_profile); | |
| 60 ExtensionService* service = | |
| 61 extensions::ExtensionSystem::Get(default_profile)->extension_service(); | |
| 62 DCHECK(service); | |
| 63 | |
| 64 std::string screensaver_id; | |
| 65 while (!(screensaver_id = FindScreensaverExtension(service, | |
| 66 current->id())).empty()) { | |
|
Matt Perry
2013/01/31 00:37:23
indent
rkc
2013/01/31 02:15:46
Done.
Matt Perry
2013/01/31 22:43:51
(FYI I just meant that curret_id should be 1 space
| |
| 67 string16 error; | |
| 68 if (!service->UninstallExtension(screensaver_id, false, &error)) | |
| 69 LOG(ERROR) << | |
| 70 "Couldn't uninstall previous screensaver extension with id: " << | |
| 71 screensaver_id << " \nError: " << error; | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 } // namespace | |
| 76 | |
| 77 namespace chromeos { | |
| 78 | |
| 79 ScreensaverController::ScreensaverController() | |
| 80 : threshold_(base::TimeDelta::FromMilliseconds(kScreensaverTimeoutMs)), | |
| 81 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 82 // Register for extension changes. | |
| 83 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | |
| 84 content::NotificationService::AllSources()); | |
| 85 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 86 content::NotificationService::AllSources()); | |
| 87 | |
| 88 std::string screensaver_extension_id = | |
| 89 FindScreensaverExtension(GetDefaultExtensionService(), std::string()); | |
| 90 if (!screensaver_extension_id.empty()) | |
| 91 SetupScreensaver(screensaver_extension_id); | |
| 92 } | |
| 93 | |
| 94 ScreensaverController::~ScreensaverController() { | |
| 95 TeardownScreensaver(); | |
| 96 } | |
| 97 | |
| 98 void ScreensaverController::Observe( | |
| 99 int type, | |
| 100 const content::NotificationSource& source, | |
| 101 const content::NotificationDetails& details) { | |
| 102 switch (type) { | |
| 103 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { | |
| 104 const extensions::Extension* extension = | |
| 105 content::Details<const extensions::Extension>(details).ptr(); | |
| 106 | |
| 107 // Uninstall any previously installed screensaver extensions. | |
| 108 UninstallPreviousScreensavers(extension); | |
|
Matt Perry
2013/01/31 00:37:23
I think you mean to do this only if |extension| is
rkc
2013/01/31 02:15:46
Whoops, yes, this will just unload any previous sc
| |
| 109 break; | |
| 110 } | |
| 111 case chrome::NOTIFICATION_EXTENSION_LOADED: { | |
| 112 const extensions::Extension* extension = | |
| 113 content::Details<const extensions::Extension>(details).ptr(); | |
| 114 if (!extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) | |
| 115 return; | |
|
Matt Perry
2013/01/31 00:37:23
indent
rkc
2013/01/31 02:15:46
Done.
| |
| 116 | |
| 117 SetupScreensaver(extension->id()); | |
| 118 break; | |
| 119 } | |
| 120 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | |
| 121 const extensions::Extension* extension = | |
| 122 content::Details<extensions::UnloadedExtensionInfo>( | |
| 123 details)->extension; | |
| 124 if (extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) | |
|
Matt Perry
2013/01/31 00:37:23
might be clearer to just test if the id matches sc
rkc
2013/01/31 02:15:46
Done.
| |
| 125 TeardownScreensaver(); | |
| 126 break; | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 void ScreensaverController::IdleNotify(int64 threshold) { | |
| 132 ExtensionService* service = GetDefaultExtensionService(); | |
| 133 const extensions::Extension* screensaver_extension = | |
| 134 service->GetExtensionById(screensaver_extension_id_, | |
| 135 ExtensionService::INCLUDE_ENABLED); | |
| 136 ash::ShowScreensaver(screensaver_extension->GetFullLaunchURL()); | |
|
Matt Perry
2013/01/31 00:37:23
interesting.. so a screensaver is just an app with
rkc
2013/01/31 02:15:46
Yep, that's how the screensaver is implemented in
| |
| 137 | |
| 138 ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this); | |
| 139 } | |
| 140 | |
| 141 void ScreensaverController::OnUserActivity() { | |
| 142 // We don't want to handle further user notifications; we'll either login | |
| 143 // the user and close out or or at least close the screensaver. | |
| 144 ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); | |
| 145 ash::CloseScreensaver(); | |
| 146 | |
| 147 RequestNextIdleNotification(); | |
| 148 } | |
| 149 | |
| 150 void ScreensaverController::SetupScreensaver( | |
| 151 const std::string& screensaver_extension_id) { | |
| 152 screensaver_extension_id_ = screensaver_extension_id; | |
| 153 | |
| 154 PowerManagerClient* power_manager = | |
| 155 DBusThreadManager::Get()->GetPowerManagerClient(); | |
| 156 if (!power_manager->HasObserver(this)) | |
| 157 power_manager->AddObserver(this); | |
| 158 | |
| 159 RequestNextIdleNotification(); | |
| 160 } | |
| 161 | |
| 162 void ScreensaverController::TeardownScreensaver() { | |
| 163 PowerManagerClient* power_manager = | |
| 164 DBusThreadManager::Get()->GetPowerManagerClient(); | |
| 165 if (power_manager && power_manager->HasObserver(this)) | |
| 166 power_manager->RemoveObserver(this); | |
| 167 | |
| 168 if (ash::Shell::GetInstance() && | |
| 169 ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) | |
| 170 ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this); | |
| 171 | |
| 172 ash::CloseScreensaver(); | |
| 173 screensaver_extension_id_ = ""; | |
| 174 } | |
| 175 | |
| 176 void ScreensaverController::RequestNextIdleNotification() { | |
| 177 DBusThreadManager::Get()->GetPowerManagerClient()-> | |
| 178 RequestIdleNotification(kScreensaverTimeoutMs); | |
| 179 } | |
| 180 | |
| 181 } // namespace chromeos | |
| OLD | NEW |