OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
24 #include "content/browser/user_metrics.h" | 24 #include "content/browser/user_metrics.h" |
25 #include "content/common/notification_service.h" | 25 #include "content/common/notification_service.h" |
26 #include "content/common/notification_type.h" | 26 #include "content/common/notification_type.h" |
27 #include "grit/chromium_strings.h" | 27 #include "grit/chromium_strings.h" |
28 #include "grit/generated_resources.h" | 28 #include "grit/generated_resources.h" |
29 #include "grit/theme_resources.h" | 29 #include "grit/theme_resources.h" |
30 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
31 #include "ui/base/resource/resource_bundle.h" | 31 #include "ui/base/resource/resource_bundle.h" |
32 | 32 |
33 void BackgroundModeManager::OnApplicationDataChanged( | 33 BackgroundModeManager::BackgroundModeData::BackgroundModeData() |
34 const Extension* extension) { | 34 : applications_(NULL), |
35 UpdateContextMenuEntryIcon(extension); | 35 status_icon_(NULL), |
36 context_menu_(NULL), | |
37 context_menu_application_offset_(0) { | |
36 } | 38 } |
37 | 39 |
38 void BackgroundModeManager::OnApplicationListChanged() { | 40 BackgroundModeManager::BackgroundModeData::~BackgroundModeData() { |
39 UpdateStatusTrayIconContextMenu(); | |
40 } | 41 } |
41 | 42 |
42 BackgroundModeManager::BackgroundModeManager(Profile* profile, | 43 void BackgroundModeManager::OnApplicationDataChanged( |
43 CommandLine* command_line) | 44 const Extension* extension, Profile* profile) { |
44 : profile_(profile), | 45 UpdateContextMenuEntryIcon(extension, profile); |
45 applications_(profile), | 46 } |
46 background_app_count_(0), | 47 |
47 context_menu_(NULL), | 48 void BackgroundModeManager::OnApplicationListChanged(Profile* profile) { |
48 context_menu_application_offset_(0), | 49 UpdateStatusTrayIconContextMenu(profile); |
50 } | |
51 | |
52 // static | |
53 BackgroundModeManager* BackgroundModeManager::GetInstance() { | |
54 return Singleton<BackgroundModeManager>::get(); | |
55 } | |
56 | |
57 BackgroundModeManager::BackgroundModeManager() | |
58 : background_app_count_(0), | |
49 in_background_mode_(false), | 59 in_background_mode_(false), |
50 keep_alive_for_startup_(false), | 60 keep_alive_for_startup_(false) { |
51 status_tray_(NULL), | 61 |
52 status_icon_(NULL) { | 62 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
53 // If background mode is currently disabled, just exit - don't listen for any | 63 // If background mode is currently disabled, just exit - don't listen for any |
54 // notifications. | 64 // notifications. |
55 if (IsBackgroundModePermanentlyDisabled(command_line)) | 65 if (IsBackgroundModePermanentlyDisabled(command_line)) |
56 return; | 66 return; |
57 | 67 |
58 // Listen for the background mode preference changing. | 68 // Listen for the background mode preference changing. |
59 if (g_browser_process->local_state()) { // Skip for unit tests | 69 if (g_browser_process->local_state()) { // Skip for unit tests |
60 pref_registrar_.Init(g_browser_process->local_state()); | 70 pref_registrar_.Init(g_browser_process->local_state()); |
61 pref_registrar_.Add(prefs::kBackgroundModeEnabled, this); | 71 pref_registrar_.Add(prefs::kBackgroundModeEnabled, this); |
62 } | 72 } |
63 | 73 |
64 // Keep the browser alive until extensions are done loading - this is needed | 74 // Keep the browser alive until extensions are done loading - this is needed |
65 // by the --no-startup-window flag. We want to stay alive until we load | 75 // by the --no-startup-window flag. We want to stay alive until we load |
66 // extensions, at which point we should either run in background mode (if | 76 // extensions, at which point we should either run in background mode (if |
67 // there are background apps) or exit if there are none. | 77 // there are background apps) or exit if there are none. |
68 if (command_line->HasSwitch(switches::kNoStartupWindow)) { | 78 if (command_line->HasSwitch(switches::kNoStartupWindow)) { |
69 keep_alive_for_startup_ = true; | 79 keep_alive_for_startup_ = true; |
70 BrowserList::StartKeepAlive(); | 80 BrowserList::StartKeepAlive(); |
71 } | 81 } |
72 | 82 |
73 // If the -keep-alive-for-test flag is passed, then always keep chrome running | 83 // If the -keep-alive-for-test flag is passed, then always keep chrome running |
74 // in the background until the user explicitly terminates it, by acting as if | 84 // in the background until the user explicitly terminates it, by acting as if |
75 // we loaded a background app. | 85 // we loaded a background app. |
76 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKeepAliveForTest)) | 86 if (command_line->HasSwitch(switches::kKeepAliveForTest)) |
77 OnBackgroundAppLoaded(); | 87 OnBackgroundAppLoaded(); |
88 } | |
89 | |
90 void BackgroundModeManager::RegisterProfile(Profile* profile) { | |
91 | |
92 // If the profile data already exists, this will overwrite it. | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
Is it valuable to add a DCHECK(background_mode_dat
rpetterson
2011/05/20 05:53:17
Done.
| |
93 background_mode_data_[profile].applications_ = | |
94 new BackgroundApplicationListModel(profile); | |
78 | 95 |
79 // Listen for when extensions are loaded/unloaded so we can track the | 96 // Listen for when extensions are loaded/unloaded so we can track the |
80 // number of background apps and modify our keep-alive and launch-on-startup | 97 // number of background apps and modify our keep-alive and launch-on-startup |
81 // state appropriately. | 98 // state appropriately. |
82 registrar_.Add(this, NotificationType::EXTENSION_LOADED, | 99 registrar_.Add(this, NotificationType::EXTENSION_LOADED, |
83 Source<Profile>(profile)); | 100 Source<Profile>(profile)); |
84 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, | 101 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, |
85 Source<Profile>(profile)); | 102 Source<Profile>(profile)); |
86 | 103 |
87 // Check for the presence of background apps after all extensions have been | 104 // Check for the presence of background apps after all extensions have been |
88 // loaded, to handle the case where an extension has been manually removed | 105 // loaded, to handle the case where an extension has been manually removed |
89 // while Chrome was not running. | 106 // while Chrome was not running. |
90 registrar_.Add(this, NotificationType::EXTENSIONS_READY, | 107 registrar_.Add(this, NotificationType::EXTENSIONS_READY, |
91 Source<Profile>(profile)); | 108 Source<Profile>(profile)); |
92 | 109 |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
nit: remove extra blank line
rpetterson
2011/05/20 05:53:17
Done.
| |
110 | |
111 background_mode_data_[profile].applications_->AddObserver(this); | |
112 | |
93 // Listen for the application shutting down so we can decrement our KeepAlive | 113 // Listen for the application shutting down so we can decrement our KeepAlive |
94 // count. | 114 // count. |
95 registrar_.Add(this, NotificationType::APP_TERMINATING, | 115 registrar_.Add(this, NotificationType::APP_TERMINATING, |
96 NotificationService::AllSources()); | 116 NotificationService::AllSources()); |
97 | |
98 applications_.AddObserver(this); | |
99 } | 117 } |
100 | 118 |
101 BackgroundModeManager::~BackgroundModeManager() { | 119 BackgroundModeManager::~BackgroundModeManager() { |
102 applications_.RemoveObserver(this); | 120 for (std::map<Profile*, BackgroundModeData>::iterator it = |
121 background_mode_data_.begin(); | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
nit: should indent these lines correctly (line up
rpetterson
2011/05/20 05:53:17
I thought the 4 characters was from the start of t
Andrew T Wilson (Slow)
2011/05/20 16:52:45
Typically wrapped for statement elements are inden
Miranda Callahan
2011/05/20 16:56:45
I think that in this case you can choose either --
rpetterson
2011/05/23 03:23:19
:)
| |
122 it != background_mode_data_.end(); | |
123 ++it) { | |
124 it->second.applications_->RemoveObserver(this); | |
125 delete it->second.applications_; | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
See previous note about having applications_ be a
rpetterson
2011/05/20 05:53:17
Done.
| |
126 } | |
103 | 127 |
104 // We're going away, so exit background mode (does nothing if we aren't in | 128 // We're going away, so exit background mode (does nothing if we aren't in |
105 // background mode currently). This is primarily needed for unit tests, | 129 // background mode currently). This is primarily needed for unit tests, |
106 // because in an actual running system we'd get an APP_TERMINATING | 130 // because in an actual running system we'd get an APP_TERMINATING |
107 // notification before being destroyed. | 131 // notification before being destroyed. |
108 EndBackgroundMode(); | 132 EndBackgroundMode(); |
109 } | 133 } |
110 | 134 |
111 void BackgroundModeManager::Observe(NotificationType type, | 135 void BackgroundModeManager::Observe(NotificationType type, |
112 const NotificationSource& source, | 136 const NotificationSource& source, |
(...skipping 20 matching lines...) Expand all Loading... | |
133 // launch on startup even after the user removes the LoginItem manually. | 157 // launch on startup even after the user removes the LoginItem manually. |
134 #if !defined(OS_MACOSX) | 158 #if !defined(OS_MACOSX) |
135 EnableLaunchOnStartup(background_app_count_ > 0); | 159 EnableLaunchOnStartup(background_app_count_ > 0); |
136 #endif | 160 #endif |
137 break; | 161 break; |
138 case NotificationType::EXTENSION_LOADED: { | 162 case NotificationType::EXTENSION_LOADED: { |
139 Extension* extension = Details<Extension>(details).ptr(); | 163 Extension* extension = Details<Extension>(details).ptr(); |
140 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) { | 164 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) { |
141 // Extensions loaded after the ExtensionsService is ready should be | 165 // Extensions loaded after the ExtensionsService is ready should be |
142 // treated as new installs. | 166 // treated as new installs. |
143 if (profile_->GetExtensionService()->is_ready()) | 167 |
144 OnBackgroundAppInstalled(extension); | 168 Profile* profile = Source<Profile>(source).ptr(); |
169 if (profile->GetExtensionService()->is_ready()) | |
170 OnBackgroundAppInstalled(extension, profile); | |
145 OnBackgroundAppLoaded(); | 171 OnBackgroundAppLoaded(); |
146 } | 172 } |
147 } | 173 } |
148 break; | 174 break; |
149 case NotificationType::EXTENSION_UNLOADED: | 175 case NotificationType::EXTENSION_UNLOADED: |
150 if (BackgroundApplicationListModel::IsBackgroundApp( | 176 if (BackgroundApplicationListModel::IsBackgroundApp( |
151 *Details<UnloadedExtensionInfo>(details)->extension)) { | 177 *Details<UnloadedExtensionInfo>(details)->extension)) { |
152 Details<UnloadedExtensionInfo> info = | 178 Details<UnloadedExtensionInfo> info = |
153 Details<UnloadedExtensionInfo>(details); | 179 Details<UnloadedExtensionInfo>(details); |
154 // If we already got an unload notification when it was disabled, ignore | 180 // If we already got an unload notification when it was disabled, ignore |
(...skipping 30 matching lines...) Expand all Loading... | |
185 // keep-alive (which can shutdown Chrome) before the message loop has | 211 // keep-alive (which can shutdown Chrome) before the message loop has |
186 // started. | 212 // started. |
187 MessageLoop::current()->PostTask( | 213 MessageLoop::current()->PostTask( |
188 FROM_HERE, NewRunnableFunction(BrowserList::EndKeepAlive)); | 214 FROM_HERE, NewRunnableFunction(BrowserList::EndKeepAlive)); |
189 } | 215 } |
190 } | 216 } |
191 | 217 |
192 void BackgroundModeManager::OnBackgroundAppLoaded() { | 218 void BackgroundModeManager::OnBackgroundAppLoaded() { |
193 // When a background app loads, increment our count and also enable | 219 // When a background app loads, increment our count and also enable |
194 // KeepAlive mode if the preference is set. | 220 // KeepAlive mode if the preference is set. |
221 // The count here is across all profiles since we must have brackground | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
nit: brackground->background
rpetterson
2011/05/20 05:53:17
Done.
| |
222 // mode if there is even one. | |
195 background_app_count_++; | 223 background_app_count_++; |
196 if (background_app_count_ == 1) | 224 if (background_app_count_ == 1) |
197 StartBackgroundMode(); | 225 StartBackgroundMode(); |
198 } | 226 } |
199 | 227 |
200 void BackgroundModeManager::StartBackgroundMode() { | 228 void BackgroundModeManager::StartBackgroundMode() { |
201 // Don't bother putting ourselves in background mode if we're already there | 229 // Don't bother putting ourselves in background mode if we're already there |
202 // or if background mode is disabled. | 230 // or if background mode is disabled. |
203 if (in_background_mode_ || !IsBackgroundModePrefEnabled()) | 231 if (in_background_mode_ || !IsBackgroundModePrefEnabled()) |
204 return; | 232 return; |
205 | 233 |
206 // Mark ourselves as running in background mode. | 234 // Mark ourselves as running in background mode. |
207 in_background_mode_ = true; | 235 in_background_mode_ = true; |
208 | 236 |
209 // Put ourselves in KeepAlive mode and create a status tray icon. | 237 // Put ourselves in KeepAlive mode and create a status tray icon. |
210 BrowserList::StartKeepAlive(); | 238 BrowserList::StartKeepAlive(); |
211 | 239 |
212 // Display a status icon to exit Chrome. | 240 // Display a status icon to exit Chrome. |
213 CreateStatusTrayIcon(); | 241 // TODO(rlp): Determine if we actually want to do this here. |
242 // I suspect that we might want to create one for all current profiles | |
243 // loaded. | |
244 for (std::map<Profile*, BackgroundModeData>::iterator it = | |
245 background_mode_data_.begin(); | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
nit: indent properly (see above comment)
rpetterson
2011/05/20 05:53:17
Done. See above comment.
| |
246 it != background_mode_data_.end(); | |
247 ++it) { | |
248 CreateStatusTrayIcon(it->first); | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
I think we should only create status tray icons fo
rpetterson
2011/05/20 05:53:17
There's an e-mail thread with Glen about using mul
| |
249 } | |
214 } | 250 } |
215 | 251 |
216 void BackgroundModeManager::OnBackgroundAppUnloaded() { | 252 void BackgroundModeManager::OnBackgroundAppUnloaded() { |
217 // When a background app unloads, decrement our count and also end | 253 // When a background app unloads, decrement our count and also end |
218 // KeepAlive mode if appropriate. | 254 // KeepAlive mode if appropriate. |
219 background_app_count_--; | 255 background_app_count_--; |
220 DCHECK_GE(background_app_count_, 0); | 256 DCHECK_GE(background_app_count_, 0); |
221 if (background_app_count_ == 0) | 257 if (background_app_count_ == 0) |
222 EndBackgroundMode(); | 258 EndBackgroundMode(); |
223 } | 259 } |
224 | 260 |
225 void BackgroundModeManager::EndBackgroundMode() { | 261 void BackgroundModeManager::EndBackgroundMode() { |
226 if (!in_background_mode_) | 262 if (!in_background_mode_) |
227 return; | 263 return; |
228 in_background_mode_ = false; | 264 in_background_mode_ = false; |
229 | 265 |
230 // End KeepAlive mode and blow away our status tray icon. | 266 // End KeepAlive mode and blow away our status tray icon. |
231 BrowserList::EndKeepAlive(); | 267 BrowserList::EndKeepAlive(); |
232 RemoveStatusTrayIcon(); | 268 // There is a status tray icon for each profile. Blow them all away. |
269 for (std::map<Profile*, BackgroundModeData>::iterator it = | |
270 background_mode_data_.begin(); | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
nit: indent properly
rpetterson
2011/05/20 05:53:17
Done. See above comment.
| |
271 it != background_mode_data_.end(); | |
272 ++it) { | |
273 RemoveStatusTrayIcon(it->first); | |
274 } | |
233 } | 275 } |
234 | 276 |
235 void BackgroundModeManager::EnableBackgroundMode() { | 277 void BackgroundModeManager::EnableBackgroundMode() { |
236 DCHECK(IsBackgroundModePrefEnabled()); | 278 DCHECK(IsBackgroundModePrefEnabled()); |
237 // If background mode should be enabled, but isn't, turn it on. | 279 // If background mode should be enabled, but isn't, turn it on. |
238 if (background_app_count_ > 0 && !in_background_mode_) { | 280 if (background_app_count_ > 0 && !in_background_mode_) { |
239 StartBackgroundMode(); | 281 StartBackgroundMode(); |
240 EnableLaunchOnStartup(true); | 282 EnableLaunchOnStartup(true); |
241 } | 283 } |
242 } | 284 } |
243 | 285 |
244 void BackgroundModeManager::DisableBackgroundMode() { | 286 void BackgroundModeManager::DisableBackgroundMode() { |
245 DCHECK(!IsBackgroundModePrefEnabled()); | 287 DCHECK(!IsBackgroundModePrefEnabled()); |
246 // If background mode is currently enabled, turn it off. | 288 // If background mode is currently enabled, turn it off. |
247 if (in_background_mode_) { | 289 if (in_background_mode_) { |
248 EndBackgroundMode(); | 290 EndBackgroundMode(); |
249 EnableLaunchOnStartup(false); | 291 EnableLaunchOnStartup(false); |
250 } | 292 } |
251 } | 293 } |
252 | 294 |
253 void BackgroundModeManager::OnBackgroundAppInstalled( | 295 void BackgroundModeManager::OnBackgroundAppInstalled( |
254 const Extension* extension) { | 296 const Extension* extension, Profile* profile) { |
255 // Background mode is disabled - don't do anything. | 297 // Background mode is disabled - don't do anything. |
256 if (!IsBackgroundModePrefEnabled()) | 298 if (!IsBackgroundModePrefEnabled()) |
257 return; | 299 return; |
258 | 300 |
259 // We're installing a background app. If this is the first background app | 301 // We're installing a background app. If this is the first background app |
260 // being installed, make sure we are set to launch on startup. | 302 // being installed, make sure we are set to launch on startup. |
261 if (background_app_count_ == 0) | 303 if (background_app_count_ == 0) |
262 EnableLaunchOnStartup(true); | 304 EnableLaunchOnStartup(true); |
263 | 305 |
264 // Notify the user that a background app has been installed. | 306 // Notify the user that a background app has been installed. |
265 if (extension) // NULL when called by unit tests. | 307 if (extension) // NULL when called by unit tests. |
266 DisplayAppInstalledNotification(extension); | 308 DisplayAppInstalledNotification(extension, profile); |
267 } | 309 } |
268 | 310 |
269 void BackgroundModeManager::OnBackgroundAppUninstalled() { | 311 void BackgroundModeManager::OnBackgroundAppUninstalled() { |
270 // When uninstalling a background app, disable launch on startup if | 312 // When uninstalling a background app, disable launch on startup if |
271 // we have no more background apps. | 313 // we have no more background apps. |
272 if (background_app_count_ == 0) | 314 if (background_app_count_ == 0) |
273 EnableLaunchOnStartup(false); | 315 EnableLaunchOnStartup(false); |
274 } | 316 } |
275 | 317 |
276 void BackgroundModeManager::CreateStatusTrayIcon() { | 318 void BackgroundModeManager::CreateStatusTrayIcon(Profile* profile) { |
277 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting | 319 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting |
278 // Chrome and Mac can use the dock icon instead. | 320 // Chrome and Mac can use the dock icon instead. |
321 | |
322 // All profiles should point to the same status tray so we can just use the | |
323 // first profile to get the status tray. | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
Not sure how you want this to work now - should St
rpetterson
2011/05/20 05:53:17
So previously, the profile owned the status tray r
| |
279 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) | 324 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) |
280 if (!status_tray_) | 325 if (!status_tray_) |
281 status_tray_ = profile_->GetStatusTray(); | 326 status_tray_ = profile->GetStatusTray(); |
282 #endif | 327 #endif |
283 | 328 |
284 // If the platform doesn't support status icons, or we've already created | 329 // If the platform doesn't support status icons, or we've already created |
285 // our status icon, just return. | 330 // our status icon, just return. |
286 if (!status_tray_ || status_icon_) | 331 BackgroundModeData* bmd = &background_mode_data_[profile]; |
287 return; | 332 DCHECK(bmd->applications_); |
288 status_icon_ = status_tray_->CreateStatusIcon(); | 333 if (!status_tray_ || bmd->status_icon_) |
289 if (!status_icon_) | |
290 return; | 334 return; |
291 | 335 |
292 // Set the image and add ourselves as a click observer on it | 336 bmd->status_icon_ = status_tray_->CreateStatusIcon(); |
337 if (!bmd->status_icon_) | |
338 return; | |
339 | |
340 // Set the image and add ourselves as a click observer on it. | |
341 // TODO(rlp): Status tray icon should have submenus for each profile. | |
293 SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 342 SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
294 IDR_STATUS_TRAY_ICON); | 343 IDR_STATUS_TRAY_ICON); |
295 status_icon_->SetImage(*bitmap); | 344 bmd->status_icon_->SetImage(*bitmap); |
296 status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | 345 bmd->status_icon_->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
297 UpdateStatusTrayIconContextMenu(); | 346 UpdateStatusTrayIconContextMenu(profile); |
298 } | 347 } |
299 | 348 |
300 void BackgroundModeManager::UpdateContextMenuEntryIcon( | 349 void BackgroundModeManager::UpdateContextMenuEntryIcon( |
301 const Extension* extension) { | 350 const Extension* extension, Profile* profile) { |
302 if (!context_menu_) | 351 BackgroundModeData* bmd = &background_mode_data_[profile]; |
352 DCHECK(bmd->applications_); | |
353 | |
354 if (!bmd->context_menu_) | |
303 return; | 355 return; |
304 context_menu_->SetIcon( | 356 bmd->context_menu_->SetIcon( |
305 context_menu_application_offset_ + applications_.GetPosition(extension), | 357 bmd->context_menu_application_offset_ + |
306 *(applications_.GetIcon(extension))); | 358 bmd->applications_->GetPosition(extension), |
307 status_icon_->SetContextMenu(context_menu_); // for Update effect | 359 *(bmd->applications_->GetIcon(extension))); |
360 | |
361 bmd->status_icon_->SetContextMenu(bmd->context_menu_); // for Update effect | |
308 } | 362 } |
309 | 363 |
310 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() { | 364 void BackgroundModeManager::UpdateStatusTrayIconContextMenu(Profile* profile) { |
311 if (!status_icon_) | 365 BackgroundModeData* bmd = &background_mode_data_[profile]; |
366 DCHECK(bmd->applications_); | |
367 if (!bmd->status_icon_) | |
312 return; | 368 return; |
313 | 369 |
370 // TODO(rlp): Add current profile color. | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
Not sure how you'd add a profile color, btw - if w
rpetterson
2011/05/20 05:53:17
Agreed. That's why it's a TODO :)
| |
314 // Create a context menu item for Chrome. | 371 // Create a context menu item for Chrome. |
315 ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(this); | 372 ProfileStatusMenuModel* menu = new ProfileStatusMenuModel(this, profile); |
316 // Add About item | 373 // Add About item |
317 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, | 374 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, |
318 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); | 375 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
319 menu->AddItem(IDC_OPTIONS, GetPreferencesMenuLabel()); | 376 menu->AddItem(IDC_OPTIONS, GetPreferencesMenuLabel()); |
320 menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); | 377 menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); |
321 menu->AddSeparator(); | 378 menu->AddSeparator(); |
322 int position = 0; | 379 int position = 0; |
323 context_menu_application_offset_ = menu->GetItemCount(); | 380 bmd->context_menu_application_offset_ = menu->GetItemCount(); |
324 for (ExtensionList::const_iterator cursor = applications_.begin(); | 381 for (ExtensionList::const_iterator cursor = bmd->applications_->begin(); |
325 cursor != applications_.end(); | 382 cursor != bmd->applications_->end(); |
326 ++cursor, ++position) { | 383 ++cursor, ++position) { |
327 const SkBitmap* icon = applications_.GetIcon(*cursor); | 384 const SkBitmap* icon = bmd->applications_->GetIcon(*cursor); |
328 DCHECK(position == applications_.GetPosition(*cursor)); | 385 DCHECK(position == bmd->applications_->GetPosition(*cursor)); |
329 const std::string& name = (*cursor)->name(); | 386 const std::string& name = (*cursor)->name(); |
330 menu->AddItem(position, UTF8ToUTF16(name)); | 387 menu->AddItem(position, UTF8ToUTF16(name)); |
331 if (icon) | 388 if (icon) |
332 menu->SetIcon(menu->GetItemCount() - 1, *icon); | 389 menu->SetIcon(menu->GetItemCount() - 1, *icon); |
333 } | 390 } |
334 if (applications_.size() > 0) | 391 if (bmd->applications_->size() > 0) |
335 menu->AddSeparator(); | 392 menu->AddSeparator(); |
336 menu->AddCheckItemWithStringId( | 393 menu->AddCheckItemWithStringId( |
337 IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND, | 394 IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND, |
338 IDS_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); | 395 IDS_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); |
339 menu->AddItemWithStringId(IDC_EXIT, IDS_EXIT); | 396 menu->AddItemWithStringId(IDC_EXIT, IDS_EXIT); |
340 context_menu_ = menu; | 397 bmd->context_menu_ = menu; |
341 status_icon_->SetContextMenu(menu); | 398 bmd->status_icon_->SetContextMenu(menu); |
342 } | 399 } |
343 | 400 |
344 bool BackgroundModeManager::IsCommandIdChecked(int command_id) const { | 401 bool BackgroundModeManager::IsCommandIdChecked(int command_id) const { |
345 DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); | 402 DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND); |
346 return true; | 403 return true; |
347 } | 404 } |
348 | 405 |
349 bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const { | 406 bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const { |
350 // For now, we do not support disabled items. | 407 // For now, we do not support disabled items. |
351 return true; | 408 return true; |
352 } | 409 } |
353 | 410 |
354 bool BackgroundModeManager::GetAcceleratorForCommandId( | 411 bool BackgroundModeManager::GetAcceleratorForCommandId( |
355 int command_id, | 412 int command_id, |
356 ui::Accelerator* accelerator) { | 413 ui::Accelerator* accelerator) { |
357 // No accelerators for status icon context menus. | 414 // No accelerators for status icon context menus. |
358 return false; | 415 return false; |
359 } | 416 } |
360 | 417 |
361 void BackgroundModeManager::RemoveStatusTrayIcon() { | 418 void BackgroundModeManager::RemoveStatusTrayIcon(Profile* profile) { |
362 if (status_icon_) | 419 BackgroundModeData* bmd = &background_mode_data_[profile]; |
363 status_tray_->RemoveStatusIcon(status_icon_); | 420 DCHECK(bmd->applications_); |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
You have these two lines in many places - maybe th
rpetterson
2011/05/20 05:53:17
Done.
| |
364 status_icon_ = NULL; | 421 if (bmd->status_icon_) |
365 context_menu_ = NULL; // Do not delete, points within |status_icon_|. | 422 status_tray_->RemoveStatusIcon(bmd->status_icon_); |
423 bmd->status_icon_ = NULL; | |
424 bmd->context_menu_ = NULL; // Do not delete, points within |status_icon_|. | |
366 } | 425 } |
367 | 426 |
368 void BackgroundModeManager::ExecuteApplication(int item) { | 427 // TODO(rlp): FIX. We now have mutliple applications. |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
Is there anything you need to fix here? It seems l
rpetterson
2011/05/20 05:53:17
Done.
| |
369 DCHECK(item >= 0 && item < static_cast<int>(applications_.size())); | 428 void BackgroundModeManager::ExecuteApplication(int item, Profile* profile) { |
370 Browser* browser = BrowserList::GetLastActive(); | 429 BackgroundModeData* bmd = &background_mode_data_[profile]; |
371 if (!browser) { | 430 DCHECK(bmd->applications_); |
372 Browser::OpenEmptyWindow(profile_); | 431 DCHECK(item >= 0 && item < static_cast<int>(bmd->applications_->size())); |
373 browser = BrowserList::GetLastActive(); | 432 |
374 } | 433 Browser* browser = GetBrowserWindow(profile); |
375 const Extension* extension = applications_.GetExtension(item); | 434 const Extension* extension = bmd->applications_->GetExtension(item); |
376 browser->OpenApplicationTab(profile_, extension, NEW_FOREGROUND_TAB); | 435 browser->OpenApplicationTab(profile, extension, NEW_FOREGROUND_TAB); |
377 } | 436 } |
378 | 437 |
379 void BackgroundModeManager::ExecuteCommand(int item) { | 438 void BackgroundModeManager::ExecuteCommand(int item) { |
439 // We only use the version with profile information. | |
Andrew T Wilson (Slow)
2011/05/20 00:22:09
Add NOTREACHED()? Alternatively, can you just not
rpetterson
2011/05/20 05:53:17
I've added NOTREACHED(). In order to subclass of o
| |
440 } | |
441 | |
442 void BackgroundModeManager::ExecuteCommand(int item, Profile* profile) { | |
380 switch (item) { | 443 switch (item) { |
381 case IDC_ABOUT: | 444 case IDC_ABOUT: |
382 GetBrowserWindow()->OpenAboutChromeDialog(); | 445 GetBrowserWindow(profile)->OpenAboutChromeDialog(); |
383 break; | 446 break; |
384 case IDC_EXIT: | 447 case IDC_EXIT: |
385 UserMetrics::RecordAction(UserMetricsAction("Exit")); | 448 UserMetrics::RecordAction(UserMetricsAction("Exit")); |
386 BrowserList::CloseAllBrowsersAndExit(); | 449 BrowserList::CloseAllBrowsersAndExit(); |
387 break; | 450 break; |
388 case IDC_OPTIONS: | 451 case IDC_OPTIONS: |
389 GetBrowserWindow()->OpenOptionsDialog(); | 452 GetBrowserWindow(profile)->OpenOptionsDialog(); |
390 break; | 453 break; |
391 case IDC_TASK_MANAGER: | 454 case IDC_TASK_MANAGER: |
392 GetBrowserWindow()->OpenTaskManager(true); | 455 GetBrowserWindow(profile)->OpenTaskManager(true); |
393 break; | 456 break; |
394 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { | 457 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { |
395 // Background mode must already be enabled (as otherwise this menu would | 458 // Background mode must already be enabled (as otherwise this menu would |
396 // not be visible). | 459 // not be visible). |
397 DCHECK(IsBackgroundModePrefEnabled()); | 460 DCHECK(IsBackgroundModePrefEnabled()); |
398 DCHECK(BrowserList::WillKeepAlive()); | 461 DCHECK(BrowserList::WillKeepAlive()); |
399 if (BrowserList::size() == 0) { | 462 if (BrowserList::size() == 0) { |
400 // There are no windows open - unchecking this will exit Chrome. Warn | 463 // There are no windows open - unchecking this will exit Chrome. Warn |
401 // the user. | 464 // the user. |
402 if (!platform_util::SimpleYesNoBox( | 465 if (!platform_util::SimpleYesNoBox( |
403 NULL, | 466 NULL, |
404 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | 467 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
405 l10n_util::GetStringFUTF16( | 468 l10n_util::GetStringFUTF16( |
406 IDS_CONFIRM_EXIT_BACKGROUND_MODE_BODY, | 469 IDS_CONFIRM_EXIT_BACKGROUND_MODE_BODY, |
407 GetPreferencesMenuLabel()))) { | 470 GetPreferencesMenuLabel()))) { |
408 return; | 471 return; |
409 } | 472 } |
410 } | 473 } |
411 | 474 |
412 // Set the background mode pref to "disabled" - the resulting notification | 475 // Set the background mode pref to "disabled" - the resulting notification |
413 // will result in a call to DisableBackgroundMode(). | 476 // will result in a call to DisableBackgroundMode(). |
414 PrefService* service = g_browser_process->local_state(); | 477 PrefService* service = g_browser_process->local_state(); |
415 DCHECK(service); | 478 DCHECK(service); |
416 service->SetBoolean(prefs::kBackgroundModeEnabled, false); | 479 service->SetBoolean(prefs::kBackgroundModeEnabled, false); |
417 break; | 480 break; |
418 } | 481 } |
419 default: | 482 default: |
420 ExecuteApplication(item); | 483 ExecuteApplication(item, profile); |
421 break; | 484 break; |
422 } | 485 } |
423 } | 486 } |
424 | 487 |
425 Browser* BackgroundModeManager::GetBrowserWindow() { | 488 Browser* BackgroundModeManager::GetBrowserWindow(Profile* profile) { |
426 Browser* browser = BrowserList::GetLastActive(); | 489 Browser* browser = BrowserList::GetLastActive(); |
427 if (!browser) { | 490 if (!browser) { |
428 Browser::OpenEmptyWindow(profile_); | 491 Browser::OpenEmptyWindow(profile); |
429 browser = BrowserList::GetLastActive(); | 492 browser = BrowserList::GetLastActive(); |
430 } | 493 } |
431 return browser; | 494 return browser; |
432 } | 495 } |
433 | 496 |
434 // static | 497 // static |
435 bool BackgroundModeManager::IsBackgroundModePermanentlyDisabled( | 498 bool BackgroundModeManager::IsBackgroundModePermanentlyDisabled( |
436 const CommandLine* command_line) { | 499 const CommandLine* command_line) { |
437 | 500 |
438 // Background mode is disabled if the appropriate flag is passed, or if | 501 // Background mode is disabled if the appropriate flag is passed, or if |
(...skipping 14 matching lines...) Expand all Loading... | |
453 PrefService* service = g_browser_process->local_state(); | 516 PrefService* service = g_browser_process->local_state(); |
454 DCHECK(service); | 517 DCHECK(service); |
455 return service->GetBoolean(prefs::kBackgroundModeEnabled); | 518 return service->GetBoolean(prefs::kBackgroundModeEnabled); |
456 } | 519 } |
457 | 520 |
458 // static | 521 // static |
459 void BackgroundModeManager::RegisterPrefs(PrefService* prefs) { | 522 void BackgroundModeManager::RegisterPrefs(PrefService* prefs) { |
460 prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false); | 523 prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false); |
461 prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true); | 524 prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true); |
462 } | 525 } |
OLD | NEW |