OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" | 5 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" |
6 | 6 |
7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/multi_profile_uma.h" | 8 #include "ash/multi_profile_uma.h" |
9 #include "ash/root_window_controller.h" | 9 #include "ash/root_window_controller.h" |
10 #include "ash/session/session_state_delegate.h" | 10 #include "ash/session/session_state_delegate.h" |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 const std::string& user_id, | 221 const std::string& user_id, |
222 KeyedServiceShutdownNotifier::Subscription* shutdown_notification) | 222 KeyedServiceShutdownNotifier::Subscription* shutdown_notification) |
223 : user_id_(user_id), | 223 : user_id_(user_id), |
224 profile_shutdown_notification_(shutdown_notification) {} | 224 profile_shutdown_notification_(shutdown_notification) {} |
225 ~AppObserver() override {} | 225 ~AppObserver() override {} |
226 | 226 |
227 // AppWindowRegistry::Observer overrides: | 227 // AppWindowRegistry::Observer overrides: |
228 void OnAppWindowAdded(extensions::AppWindow* app_window) override { | 228 void OnAppWindowAdded(extensions::AppWindow* app_window) override { |
229 aura::Window* window = app_window->GetNativeWindow(); | 229 aura::Window* window = app_window->GetNativeWindow(); |
230 DCHECK(window); | 230 DCHECK(window); |
231 MultiUserWindowManagerChromeOS::GetInstance()->SetWindowOwner(window, | 231 MultiUserWindowManagerChromeOS::GetInstance()->SetWindowOwner( |
232 user_id_); | 232 window, AccountId::FromUserEmail(user_id_)); |
233 } | 233 } |
234 | 234 |
235 private: | 235 private: |
236 std::string user_id_; | 236 std::string user_id_; |
237 | 237 |
238 // This notification is triggered when the profile gets destroyed (during | 238 // This notification is triggered when the profile gets destroyed (during |
239 // shutdown process). | 239 // shutdown process). |
240 // The callback (stored in notification) destroyes AppObserver object. | 240 // The callback (stored in notification) destroyes AppObserver object. |
241 scoped_ptr<KeyedServiceShutdownNotifier::Subscription> | 241 scoped_ptr<KeyedServiceShutdownNotifier::Subscription> |
242 profile_shutdown_notification_; | 242 profile_shutdown_notification_; |
243 | 243 |
244 DISALLOW_COPY_AND_ASSIGN(AppObserver); | 244 DISALLOW_COPY_AND_ASSIGN(AppObserver); |
245 }; | 245 }; |
246 | 246 |
247 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( | 247 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( |
248 const std::string& current_user_id) | 248 const AccountId& current_account_id) |
249 : current_user_id_(current_user_id), | 249 : current_account_id_(current_account_id), |
250 notification_blocker_(new MultiUserNotificationBlockerChromeOS( | 250 notification_blocker_(new MultiUserNotificationBlockerChromeOS( |
251 message_center::MessageCenter::Get(), current_user_id)), | 251 message_center::MessageCenter::Get(), |
| 252 current_account_id)), |
252 suppress_visibility_changes_(false), | 253 suppress_visibility_changes_(false), |
253 animation_speed_(ANIMATION_SPEED_NORMAL) { | 254 animation_speed_(ANIMATION_SPEED_NORMAL) {} |
254 } | |
255 | 255 |
256 MultiUserWindowManagerChromeOS::~MultiUserWindowManagerChromeOS() { | 256 MultiUserWindowManagerChromeOS::~MultiUserWindowManagerChromeOS() { |
257 // When the MultiUserWindowManager gets destroyed, ash::Shell is mostly gone. | 257 // When the MultiUserWindowManager gets destroyed, ash::Shell is mostly gone. |
258 // As such we should not try to finalize any outstanding user animations. | 258 // As such we should not try to finalize any outstanding user animations. |
259 // Note that the destruction of the object can be done later. | 259 // Note that the destruction of the object can be done later. |
260 if (animation_.get()) | 260 if (animation_.get()) |
261 animation_->CancelAnimation(); | 261 animation_->CancelAnimation(); |
262 | 262 |
263 // Remove all window observers. | 263 // Remove all window observers. |
264 WindowToEntryMap::iterator window = window_to_entry_.begin(); | 264 WindowToEntryMap::iterator window = window_to_entry_.begin(); |
265 while (window != window_to_entry_.end()) { | 265 while (window != window_to_entry_.end()) { |
266 OnWindowDestroyed(window->first); | 266 OnWindowDestroyed(window->first); |
267 window = window_to_entry_.begin(); | 267 window = window_to_entry_.begin(); |
268 } | 268 } |
269 | 269 |
270 // Remove all app observers. | 270 // Remove all app observers. |
271 UserIDToAppWindowObserver::iterator app_observer_iterator = | 271 AccountIdToAppWindowObserver::iterator app_observer_iterator = |
272 user_id_to_app_observer_.begin(); | 272 account_id_to_app_observer_.begin(); |
273 while (app_observer_iterator != user_id_to_app_observer_.end()) { | 273 while (app_observer_iterator != account_id_to_app_observer_.end()) { |
274 Profile* profile = multi_user_util::GetProfileFromUserID( | 274 Profile* profile = |
275 app_observer_iterator->first); | 275 multi_user_util::GetProfileFromAccountId(app_observer_iterator->first); |
276 CHECK(profile) << "profile not found for:" << app_observer_iterator->first; | 276 CHECK(profile) << "profile not found for:" |
| 277 << app_observer_iterator->first.GetUserEmail(); |
277 RemoveUser(app_observer_iterator->first, profile); | 278 RemoveUser(app_observer_iterator->first, profile); |
278 app_observer_iterator = user_id_to_app_observer_.begin(); | 279 app_observer_iterator = account_id_to_app_observer_.begin(); |
279 } | 280 } |
280 | 281 |
281 if (ash::Shell::HasInstance()) | 282 if (ash::Shell::HasInstance()) |
282 ash::Shell::GetInstance()->session_state_delegate()-> | 283 ash::Shell::GetInstance()->session_state_delegate()-> |
283 RemoveSessionStateObserver(this); | 284 RemoveSessionStateObserver(this); |
284 } | 285 } |
285 | 286 |
286 void MultiUserWindowManagerChromeOS::Init() { | 287 void MultiUserWindowManagerChromeOS::Init() { |
287 // Since we are setting the SessionStateObserver and adding the user, this | 288 // Since we are setting the SessionStateObserver and adding the user, this |
288 // function should get called only once. | 289 // function should get called only once. |
289 DCHECK(user_id_to_app_observer_.find(current_user_id_) == | 290 DCHECK(account_id_to_app_observer_.find(current_account_id_) == |
290 user_id_to_app_observer_.end()); | 291 account_id_to_app_observer_.end()); |
291 | 292 |
292 // Add a session state observer to be able to monitor session changes. | 293 // Add a session state observer to be able to monitor session changes. |
293 if (ash::Shell::HasInstance()) { | 294 if (ash::Shell::HasInstance()) { |
294 ash::Shell::GetInstance()->session_state_delegate()-> | 295 ash::Shell::GetInstance()->session_state_delegate()-> |
295 AddSessionStateObserver(this); | 296 AddSessionStateObserver(this); |
296 } | 297 } |
297 | 298 |
298 // The BrowserListObserver would have been better to use then the old | 299 // The BrowserListObserver would have been better to use then the old |
299 // notification system, but that observer fires before the window got created. | 300 // notification system, but that observer fires before the window got created. |
300 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, | 301 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, |
301 content::NotificationService::AllSources()); | 302 content::NotificationService::AllSources()); |
302 | 303 |
303 // Add an app window observer & all already running apps. | 304 // Add an app window observer & all already running apps. |
304 Profile* profile = multi_user_util::GetProfileFromUserID(current_user_id_); | 305 Profile* profile = |
| 306 multi_user_util::GetProfileFromAccountId(current_account_id_); |
305 if (profile) | 307 if (profile) |
306 AddUser(profile); | 308 AddUser(profile); |
307 } | 309 } |
308 | 310 |
309 void MultiUserWindowManagerChromeOS::SetWindowOwner( | 311 void MultiUserWindowManagerChromeOS::SetWindowOwner( |
310 aura::Window* window, | 312 aura::Window* window, |
311 const std::string& user_id) { | 313 const AccountId& account_id) { |
312 // Make sure the window is valid and there was no owner yet. | 314 // Make sure the window is valid and there was no owner yet. |
313 DCHECK(window); | 315 DCHECK(window); |
314 DCHECK(!user_id.empty()); | 316 DCHECK(account_id.is_valid()); |
315 if (GetWindowOwner(window) == user_id) | 317 if (GetWindowOwner(window) == account_id) |
316 return; | 318 return; |
317 DCHECK(GetWindowOwner(window).empty()); | 319 DCHECK(GetWindowOwner(window).empty()); |
318 window_to_entry_[window] = new WindowEntry(user_id); | 320 window_to_entry_[window] = new WindowEntry(account_id); |
319 | 321 |
320 // Remember the initial visibility of the window. | 322 // Remember the initial visibility of the window. |
321 window_to_entry_[window]->set_show(window->IsVisible()); | 323 window_to_entry_[window]->set_show(window->IsVisible()); |
322 | 324 |
323 // Add observers to track state changes. | 325 // Add observers to track state changes. |
324 window->AddObserver(this); | 326 window->AddObserver(this); |
325 wm::TransientWindowManager::Get(window)->AddObserver(this); | 327 wm::TransientWindowManager::Get(window)->AddObserver(this); |
326 | 328 |
327 // Check if this window was created due to a user interaction. If it was, | 329 // Check if this window was created due to a user interaction. If it was, |
328 // transfer it to the current user. | 330 // transfer it to the current user. |
329 if (IsProcessingUserEvent()) | 331 if (IsProcessingUserEvent()) |
330 window_to_entry_[window]->set_show_for_user(current_user_id_); | 332 window_to_entry_[window]->set_show_for_user(current_account_id_); |
331 | 333 |
332 // Add all transient children to our set of windows. Note that the function | 334 // Add all transient children to our set of windows. Note that the function |
333 // will add the children but not the owner to the transient children map. | 335 // will add the children but not the owner to the transient children map. |
334 AddTransientOwnerRecursive(window, window); | 336 AddTransientOwnerRecursive(window, window); |
335 | 337 |
336 // Notify entry adding. | 338 // Notify entry adding. |
337 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryAdded(window)); | 339 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryAdded(window)); |
338 | 340 |
339 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) | 341 if (!IsWindowOnDesktopOfUser(window, current_account_id_)) |
340 SetWindowVisibility(window, false, 0); | 342 SetWindowVisibility(window, false, 0); |
341 } | 343 } |
342 | 344 |
343 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( | 345 const AccountId& MultiUserWindowManagerChromeOS::GetWindowOwner( |
344 aura::Window* window) const { | 346 aura::Window* window) const { |
345 WindowToEntryMap::const_iterator it = window_to_entry_.find(window); | 347 WindowToEntryMap::const_iterator it = window_to_entry_.find(window); |
346 return it != window_to_entry_.end() ? it->second->owner() | 348 return it != window_to_entry_.end() ? it->second->owner() : EmptyAccountId(); |
347 : base::EmptyString(); | |
348 } | 349 } |
349 | 350 |
350 void MultiUserWindowManagerChromeOS::ShowWindowForUser( | 351 void MultiUserWindowManagerChromeOS::ShowWindowForUser( |
351 aura::Window* window, | 352 aura::Window* window, |
352 const std::string& user_id) { | 353 const AccountId& account_id) { |
353 std::string previous_owner(GetUserPresentingWindow(window)); | 354 const AccountId previous_owner(GetUserPresentingWindow(window)); |
354 if (!ShowWindowForUserIntern(window, user_id)) | 355 if (!ShowWindowForUserIntern(window, account_id)) |
355 return; | 356 return; |
356 // The window switched to a new desktop and we have to switch to that desktop, | 357 // The window switched to a new desktop and we have to switch to that desktop, |
357 // but only when it was on the visible desktop and the the target is not the | 358 // but only when it was on the visible desktop and the the target is not the |
358 // visible desktop. | 359 // visible desktop. |
359 if (user_id == current_user_id_ || previous_owner != current_user_id_) | 360 if (account_id == current_account_id_ || |
| 361 previous_owner != current_account_id_) |
360 return; | 362 return; |
361 | 363 |
362 ash::Shell::GetInstance()->session_state_delegate()->SwitchActiveUser( | 364 ash::Shell::GetInstance()->session_state_delegate()->SwitchActiveUser( |
363 user_id); | 365 account_id); |
364 } | 366 } |
365 | 367 |
366 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { | 368 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { |
367 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); | 369 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); |
368 for (; it != window_to_entry_.end(); ++it) { | 370 for (; it != window_to_entry_.end(); ++it) { |
369 if (it->second->owner() != it->second->show_for_user()) | 371 if (it->second->owner() != it->second->show_for_user()) |
370 return true; | 372 return true; |
371 } | 373 } |
372 return false; | 374 return false; |
373 } | 375 } |
374 | 376 |
375 void MultiUserWindowManagerChromeOS::GetOwnersOfVisibleWindows( | 377 void MultiUserWindowManagerChromeOS::GetOwnersOfVisibleWindows( |
376 std::set<std::string>* user_ids) const { | 378 std::set<AccountId>* account_ids) const { |
377 for (WindowToEntryMap::const_iterator it = window_to_entry_.begin(); | 379 for (WindowToEntryMap::const_iterator it = window_to_entry_.begin(); |
378 it != window_to_entry_.end(); | 380 it != window_to_entry_.end(); |
379 ++it) { | 381 ++it) { |
380 if (it->first->IsVisible()) | 382 if (it->first->IsVisible()) |
381 user_ids->insert(it->second->owner()); | 383 account_ids->insert(it->second->owner()); |
382 } | 384 } |
383 } | 385 } |
384 | 386 |
385 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( | 387 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( |
386 aura::Window* window, | 388 aura::Window* window, |
387 const std::string& user_id) const { | 389 const AccountId& account_id) const { |
388 const std::string& presenting_user = GetUserPresentingWindow(window); | 390 const AccountId& presenting_user = GetUserPresentingWindow(window); |
389 return presenting_user.empty() || presenting_user == user_id; | 391 return (!presenting_user.is_valid()) || presenting_user == account_id; |
390 } | 392 } |
391 | 393 |
392 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( | 394 const AccountId& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( |
393 aura::Window* window) const { | 395 aura::Window* window) const { |
394 WindowToEntryMap::const_iterator it = window_to_entry_.find(window); | 396 WindowToEntryMap::const_iterator it = window_to_entry_.find(window); |
395 // If the window is not owned by anyone it is shown on all desktops and we | 397 // If the window is not owned by anyone it is shown on all desktops and we |
396 // return the empty string. | 398 // return the empty string. |
397 if (it == window_to_entry_.end()) | 399 if (it == window_to_entry_.end()) |
398 return base::EmptyString(); | 400 return EmptyAccountId(); |
399 // Otherwise we ask the object for its desktop. | 401 // Otherwise we ask the object for its desktop. |
400 return it->second->show_for_user(); | 402 return it->second->show_for_user(); |
401 } | 403 } |
402 | 404 |
403 void MultiUserWindowManagerChromeOS::AddUser(content::BrowserContext* context) { | 405 void MultiUserWindowManagerChromeOS::AddUser(content::BrowserContext* context) { |
404 Profile* profile = Profile::FromBrowserContext(context); | 406 Profile* profile = Profile::FromBrowserContext(context); |
405 const std::string& user_id = multi_user_util::GetUserIDFromProfile(profile); | 407 const AccountId& account_id( |
406 if (user_id_to_app_observer_.find(user_id) != user_id_to_app_observer_.end()) | 408 multi_user_util::GetAccountIdFromProfile(profile)); |
| 409 if (account_id_to_app_observer_.find(account_id) != |
| 410 account_id_to_app_observer_.end()) |
407 return; | 411 return; |
408 | 412 |
409 scoped_ptr<KeyedServiceShutdownNotifier::Subscription> notification = | 413 scoped_ptr<KeyedServiceShutdownNotifier::Subscription> notification = |
410 MultiUserWindowManagerCrOSShutdownNotifierFactory::GetInstance() | 414 MultiUserWindowManagerCrOSShutdownNotifierFactory::GetInstance() |
411 ->Get(profile) | 415 ->Get(profile) |
412 ->Subscribe(base::Bind(&MultiUserWindowManagerChromeOS::RemoveUser, | 416 ->Subscribe(base::Bind(&MultiUserWindowManagerChromeOS::RemoveUser, |
413 base::Unretained(this), user_id, | 417 base::Unretained(this), account_id, |
414 base::Unretained(profile))); | 418 base::Unretained(profile))); |
415 | 419 |
416 user_id_to_app_observer_[user_id] = | 420 account_id_to_app_observer_[account_id] = |
417 new AppObserver(user_id, notification.release()); | 421 new AppObserver(account_id.GetUserEmail(), notification.release()); |
418 extensions::AppWindowRegistry::Get(profile) | 422 extensions::AppWindowRegistry::Get(profile) |
419 ->AddObserver(user_id_to_app_observer_[user_id]); | 423 ->AddObserver(account_id_to_app_observer_[account_id]); |
420 | 424 |
421 // Account all existing application windows of this user accordingly. | 425 // Account all existing application windows of this user accordingly. |
422 const extensions::AppWindowRegistry::AppWindowList& app_windows = | 426 const extensions::AppWindowRegistry::AppWindowList& app_windows = |
423 extensions::AppWindowRegistry::Get(profile)->app_windows(); | 427 extensions::AppWindowRegistry::Get(profile)->app_windows(); |
424 extensions::AppWindowRegistry::AppWindowList::const_iterator it = | 428 extensions::AppWindowRegistry::AppWindowList::const_iterator it = |
425 app_windows.begin(); | 429 app_windows.begin(); |
426 for (; it != app_windows.end(); ++it) | 430 for (; it != app_windows.end(); ++it) |
427 user_id_to_app_observer_[user_id]->OnAppWindowAdded(*it); | 431 account_id_to_app_observer_[account_id]->OnAppWindowAdded(*it); |
428 | 432 |
429 // Account all existing browser windows of this user accordingly. | 433 // Account all existing browser windows of this user accordingly. |
430 BrowserList* browser_list = BrowserList::GetInstance(HOST_DESKTOP_TYPE_ASH); | 434 BrowserList* browser_list = BrowserList::GetInstance(HOST_DESKTOP_TYPE_ASH); |
431 BrowserList::const_iterator browser_it = browser_list->begin(); | 435 BrowserList::const_iterator browser_it = browser_list->begin(); |
432 for (; browser_it != browser_list->end(); ++browser_it) { | 436 for (; browser_it != browser_list->end(); ++browser_it) { |
433 if ((*browser_it)->profile()->GetOriginalProfile() == profile) | 437 if ((*browser_it)->profile()->GetOriginalProfile() == profile) |
434 AddBrowserWindow(*browser_it); | 438 AddBrowserWindow(*browser_it); |
435 } | 439 } |
436 // When adding another user to the session, we auto switch users. | 440 // When adding another user to the session, we auto switch users. |
437 if (user_id_to_app_observer_.size() == 1) | 441 if (account_id_to_app_observer_.size() == 1) |
438 return; | 442 return; |
439 | 443 |
440 // Don't do anything special in case of user session restore after crash. | 444 // Don't do anything special in case of user session restore after crash. |
441 // In that case session restore process will automatically switch to the | 445 // In that case session restore process will automatically switch to the |
442 // last active user session after whole process is complete. | 446 // last active user session after whole process is complete. |
443 if (!chromeos::UserSessionManager::GetInstance()-> | 447 if (!chromeos::UserSessionManager::GetInstance()-> |
444 UserSessionsRestoreInProgress()) { | 448 UserSessionsRestoreInProgress()) { |
445 // Immediately hide the windows of the current user. | 449 // Immediately hide the windows of the current user. |
446 base::AutoReset<AnimationSpeed> animation_speed(&animation_speed_, | 450 base::AutoReset<AnimationSpeed> animation_speed(&animation_speed_, |
447 ANIMATION_SPEED_DISABLED); | 451 ANIMATION_SPEED_DISABLED); |
448 ActiveUserChanged(user_id); | 452 ActiveUserChanged(account_id); |
449 } | 453 } |
450 } | 454 } |
451 | 455 |
452 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { | 456 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { |
453 observers_.AddObserver(observer); | 457 observers_.AddObserver(observer); |
454 } | 458 } |
455 | 459 |
456 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { | 460 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { |
457 observers_.RemoveObserver(observer); | 461 observers_.RemoveObserver(observer); |
458 } | 462 } |
459 | 463 |
460 void MultiUserWindowManagerChromeOS::ActiveUserChanged( | 464 void MultiUserWindowManagerChromeOS::ActiveUserChanged( |
461 const std::string& user_id) { | 465 const AccountId& account_id) { |
462 // This needs to be set before the animation starts. | 466 // This needs to be set before the animation starts. |
463 current_user_id_ = user_id; | 467 current_account_id_ = account_id; |
464 | 468 |
465 // Here to avoid a very nasty race condition, we must destruct any previously | 469 // Here to avoid a very nasty race condition, we must destruct any previously |
466 // created animation before creating a new one. Otherwise, the newly | 470 // created animation before creating a new one. Otherwise, the newly |
467 // constructed will hide all windows of the old user in the first step of the | 471 // constructed will hide all windows of the old user in the first step of the |
468 // animation only to be reshown again by the destructor of the old animation. | 472 // animation only to be reshown again by the destructor of the old animation. |
469 animation_.reset(); | 473 animation_.reset(); |
470 animation_.reset( | 474 animation_.reset(new UserSwitchAnimatorChromeOS( |
471 new UserSwitchAnimatorChromeOS( | 475 this, account_id, GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); |
472 this, user_id, GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); | |
473 // Call notifier here instead of observing ActiveUserChanged because | 476 // Call notifier here instead of observing ActiveUserChanged because |
474 // this must happen after MultiUserWindowManagerChromeOS is notified. | 477 // this must happen after MultiUserWindowManagerChromeOS is notified. |
475 ash::Shell::GetInstance() | 478 ash::Shell::GetInstance() |
476 ->system_tray_notifier() | 479 ->system_tray_notifier() |
477 ->NotifyMediaCaptureChanged(); | 480 ->NotifyMediaCaptureChanged(); |
478 } | 481 } |
479 | 482 |
480 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { | 483 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { |
481 if (GetWindowOwner(window).empty()) { | 484 if (GetWindowOwner(window).empty()) { |
482 // This must be a window in the transient chain - remove it and its | 485 // This must be a window in the transient chain - remove it and its |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 it->second = visible; | 519 it->second = visible; |
517 } | 520 } |
518 } | 521 } |
519 | 522 |
520 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanged( | 523 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanged( |
521 aura::Window* window, bool visible) { | 524 aura::Window* window, bool visible) { |
522 if (suppress_visibility_changes_) | 525 if (suppress_visibility_changes_) |
523 return; | 526 return; |
524 | 527 |
525 // Don't allow to make the window visible if it shouldn't be. | 528 // Don't allow to make the window visible if it shouldn't be. |
526 if (visible && !IsWindowOnDesktopOfUser(window, current_user_id_)) { | 529 if (visible && !IsWindowOnDesktopOfUser(window, current_account_id_)) { |
527 SetWindowVisibility(window, false, 0); | 530 SetWindowVisibility(window, false, 0); |
528 return; | 531 return; |
529 } | 532 } |
530 aura::Window* owned_parent = GetOwningWindowInTransientChain(window); | 533 aura::Window* owned_parent = GetOwningWindowInTransientChain(window); |
531 if (owned_parent && owned_parent != window && visible && | 534 if (owned_parent && owned_parent != window && visible && |
532 !IsWindowOnDesktopOfUser(owned_parent, current_user_id_)) | 535 !IsWindowOnDesktopOfUser(owned_parent, current_account_id_)) |
533 SetWindowVisibility(window, false, 0); | 536 SetWindowVisibility(window, false, 0); |
534 } | 537 } |
535 | 538 |
536 void MultiUserWindowManagerChromeOS::OnTransientChildAdded( | 539 void MultiUserWindowManagerChromeOS::OnTransientChildAdded( |
537 aura::Window* window, | 540 aura::Window* window, |
538 aura::Window* transient_window) { | 541 aura::Window* transient_window) { |
539 if (!GetWindowOwner(window).empty()) { | 542 if (!GetWindowOwner(window).empty()) { |
540 AddTransientOwnerRecursive(transient_window, window); | 543 AddTransientOwnerRecursive(transient_window, window); |
541 return; | 544 return; |
542 } | 545 } |
(...skipping 25 matching lines...) Expand all Loading... |
568 | 571 |
569 void MultiUserWindowManagerChromeOS::SetAnimationSpeedForTest( | 572 void MultiUserWindowManagerChromeOS::SetAnimationSpeedForTest( |
570 MultiUserWindowManagerChromeOS::AnimationSpeed speed) { | 573 MultiUserWindowManagerChromeOS::AnimationSpeed speed) { |
571 animation_speed_ = speed; | 574 animation_speed_ = speed; |
572 } | 575 } |
573 | 576 |
574 bool MultiUserWindowManagerChromeOS::IsAnimationRunningForTest() { | 577 bool MultiUserWindowManagerChromeOS::IsAnimationRunningForTest() { |
575 return animation_.get() != NULL && !animation_->IsAnimationFinished(); | 578 return animation_.get() != NULL && !animation_->IsAnimationFinished(); |
576 } | 579 } |
577 | 580 |
578 const std::string& MultiUserWindowManagerChromeOS::GetCurrentUserForTest() | 581 const AccountId& MultiUserWindowManagerChromeOS::GetCurrentUserForTest() const { |
579 const { | 582 return current_account_id_; |
580 return current_user_id_; | |
581 } | 583 } |
582 | 584 |
583 bool MultiUserWindowManagerChromeOS::ShowWindowForUserIntern( | 585 bool MultiUserWindowManagerChromeOS::ShowWindowForUserIntern( |
584 aura::Window* window, | 586 aura::Window* window, |
585 const std::string& user_id) { | 587 const AccountId& account_id) { |
586 // If there is either no owner, or the owner is the current user, no action | 588 // If there is either no owner, or the owner is the current user, no action |
587 // is required. | 589 // is required. |
588 const std::string& owner = GetWindowOwner(window); | 590 const AccountId& owner = GetWindowOwner(window); |
589 if (owner.empty() || | 591 if ((!owner.is_valid()) || |
590 (owner == user_id && IsWindowOnDesktopOfUser(window, user_id))) | 592 (owner == account_id && IsWindowOnDesktopOfUser(window, account_id))) |
591 return false; | 593 return false; |
592 | 594 |
593 bool minimized = ash::wm::GetWindowState(window)->IsMinimized(); | 595 bool minimized = ash::wm::GetWindowState(window)->IsMinimized(); |
594 // Check that we are not trying to transfer ownership of a minimized window. | 596 // Check that we are not trying to transfer ownership of a minimized window. |
595 if (user_id != owner && minimized) | 597 if (account_id != owner && minimized) |
596 return false; | 598 return false; |
597 | 599 |
598 if (minimized) { | 600 if (minimized) { |
599 // If it is minimized it falls back to the original desktop. | 601 // If it is minimized it falls back to the original desktop. |
600 ash::MultiProfileUMA::RecordTeleportAction( | 602 ash::MultiProfileUMA::RecordTeleportAction( |
601 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_MINIMIZE); | 603 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_MINIMIZE); |
602 } else { | 604 } else { |
603 // If the window was transferred without getting minimized, we should record | 605 // If the window was transferred without getting minimized, we should record |
604 // the window type. | 606 // the window type. |
605 RecordUMAForTransferredWindowType(window); | 607 RecordUMAForTransferredWindowType(window); |
606 } | 608 } |
607 | 609 |
608 WindowToEntryMap::iterator it = window_to_entry_.find(window); | 610 WindowToEntryMap::iterator it = window_to_entry_.find(window); |
609 it->second->set_show_for_user(user_id); | 611 it->second->set_show_for_user(account_id); |
610 | 612 |
611 // Show the window if the added user is the current one. | 613 // Show the window if the added user is the current one. |
612 if (user_id == current_user_id_) { | 614 if (account_id == current_account_id_) { |
613 // Only show the window if it should be shown according to its state. | 615 // Only show the window if it should be shown according to its state. |
614 if (it->second->show()) | 616 if (it->second->show()) |
615 SetWindowVisibility(window, true, kTeleportAnimationTimeMS); | 617 SetWindowVisibility(window, true, kTeleportAnimationTimeMS); |
616 } else { | 618 } else { |
617 SetWindowVisibility(window, false, kTeleportAnimationTimeMS); | 619 SetWindowVisibility(window, false, kTeleportAnimationTimeMS); |
618 } | 620 } |
619 | 621 |
620 // Notify entry change. | 622 // Notify entry change. |
621 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window)); | 623 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window)); |
622 return true; | 624 return true; |
623 } | 625 } |
624 | 626 |
625 void MultiUserWindowManagerChromeOS::SetWindowVisibility( | 627 void MultiUserWindowManagerChromeOS::SetWindowVisibility( |
626 aura::Window* window, bool visible, int animation_time_in_ms) { | 628 aura::Window* window, bool visible, int animation_time_in_ms) { |
627 if (window->IsVisible() == visible) | 629 if (window->IsVisible() == visible) |
628 return; | 630 return; |
629 | 631 |
630 // Hiding a system modal dialog should not be allowed. Instead we switch to | 632 // Hiding a system modal dialog should not be allowed. Instead we switch to |
631 // the user which is showing the system modal window. | 633 // the user which is showing the system modal window. |
632 // Note that in some cases (e.g. unit test) windows might not have a root | 634 // Note that in some cases (e.g. unit test) windows might not have a root |
633 // window. | 635 // window. |
634 if (!visible && window->GetRootWindow()) { | 636 if (!visible && window->GetRootWindow()) { |
635 // Get the system modal container for the window's root window. | 637 // Get the system modal container for the window's root window. |
636 aura::Window* system_modal_container = | 638 aura::Window* system_modal_container = |
637 window->GetRootWindow()->GetChildById( | 639 window->GetRootWindow()->GetChildById( |
638 ash::kShellWindowId_SystemModalContainer); | 640 ash::kShellWindowId_SystemModalContainer); |
639 if (window->parent() == system_modal_container) { | 641 if (window->parent() == system_modal_container) { |
640 // The window is system modal and we need to find the parent which owns | 642 // The window is system modal and we need to find the parent which owns |
641 // it so that we can switch to the desktop accordingly. | 643 // it so that we can switch to the desktop accordingly. |
642 std::string user_id = GetUserPresentingWindow(window); | 644 AccountId account_id = GetUserPresentingWindow(window); |
643 if (user_id.empty()) { | 645 if (!account_id.is_valid()) { |
644 aura::Window* owning_window = GetOwningWindowInTransientChain(window); | 646 aura::Window* owning_window = GetOwningWindowInTransientChain(window); |
645 DCHECK(owning_window); | 647 DCHECK(owning_window); |
646 user_id = GetUserPresentingWindow(owning_window); | 648 account_id = GetUserPresentingWindow(owning_window); |
647 DCHECK(!user_id.empty()); | 649 DCHECK(account_id.is_valid()); |
648 } | 650 } |
649 ash::Shell::GetInstance()->session_state_delegate()->SwitchActiveUser( | 651 ash::Shell::GetInstance()->session_state_delegate()->SwitchActiveUser( |
650 user_id); | 652 account_id); |
651 return; | 653 return; |
652 } | 654 } |
653 } | 655 } |
654 | 656 |
655 // To avoid that these commands are recorded as any other commands, we are | 657 // To avoid that these commands are recorded as any other commands, we are |
656 // suppressing any window entry changes while this is going on. | 658 // suppressing any window entry changes while this is going on. |
657 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); | 659 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); |
658 | 660 |
659 if (visible) | 661 if (visible) |
660 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); | 662 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); |
661 else | 663 else |
662 SetWindowVisible(window, false, animation_time_in_ms); | 664 SetWindowVisible(window, false, animation_time_in_ms); |
663 } | 665 } |
664 | 666 |
665 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) { | 667 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) { |
666 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can | 668 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can |
667 // come here with no valid window. | 669 // come here with no valid window. |
668 if (!browser->window() || !browser->window()->GetNativeWindow()) | 670 if (!browser->window() || !browser->window()->GetNativeWindow()) |
669 return; | 671 return; |
670 SetWindowOwner(browser->window()->GetNativeWindow(), | 672 SetWindowOwner(browser->window()->GetNativeWindow(), |
671 multi_user_util::GetUserIDFromProfile(browser->profile())); | 673 multi_user_util::GetAccountIdFromProfile(browser->profile())); |
672 } | 674 } |
673 | 675 |
674 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive( | 676 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive( |
675 aura::Window* window, int animation_time_in_ms) { | 677 aura::Window* window, int animation_time_in_ms) { |
676 aura::Window::Windows::const_iterator it = | 678 aura::Window::Windows::const_iterator it = |
677 wm::GetTransientChildren(window).begin(); | 679 wm::GetTransientChildren(window).begin(); |
678 for (; it != wm::GetTransientChildren(window).end(); ++it) | 680 for (; it != wm::GetTransientChildren(window).end(); ++it) |
679 ShowWithTransientChildrenRecursive(*it, animation_time_in_ms); | 681 ShowWithTransientChildrenRecursive(*it, animation_time_in_ms); |
680 | 682 |
681 // We show all children which were not explicitly hidden. | 683 // We show all children which were not explicitly hidden. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 transient_window_to_visibility_.end()); | 718 transient_window_to_visibility_.end()); |
717 transient_window_to_visibility_[window] = window->IsVisible(); | 719 transient_window_to_visibility_[window] = window->IsVisible(); |
718 | 720 |
719 // Add observers to track state changes. | 721 // Add observers to track state changes. |
720 window->AddObserver(this); | 722 window->AddObserver(this); |
721 wm::TransientWindowManager::Get(window)->AddObserver(this); | 723 wm::TransientWindowManager::Get(window)->AddObserver(this); |
722 | 724 |
723 // Hide the window if it should not be shown. Note that this hide operation | 725 // Hide the window if it should not be shown. Note that this hide operation |
724 // will hide recursively this and all children - but we have already collected | 726 // will hide recursively this and all children - but we have already collected |
725 // their initial view state. | 727 // their initial view state. |
726 if (!IsWindowOnDesktopOfUser(owned_parent, current_user_id_)) | 728 if (!IsWindowOnDesktopOfUser(owned_parent, current_account_id_)) |
727 SetWindowVisibility(window, false, kAnimationTimeMS); | 729 SetWindowVisibility(window, false, kAnimationTimeMS); |
728 } | 730 } |
729 | 731 |
730 void MultiUserWindowManagerChromeOS::RemoveTransientOwnerRecursive( | 732 void MultiUserWindowManagerChromeOS::RemoveTransientOwnerRecursive( |
731 aura::Window* window) { | 733 aura::Window* window) { |
732 // First remove all child windows. | 734 // First remove all child windows. |
733 aura::Window::Windows::const_iterator it = | 735 aura::Window::Windows::const_iterator it = |
734 wm::GetTransientChildren(window).begin(); | 736 wm::GetTransientChildren(window).begin(); |
735 for (; it != wm::GetTransientChildren(window).end(); ++it) | 737 for (; it != wm::GetTransientChildren(window).end(); ++it) |
736 RemoveTransientOwnerRecursive(*it); | 738 RemoveTransientOwnerRecursive(*it); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 // call. | 782 // call. |
781 DCHECK_EQ(visible, window->IsVisible()); | 783 DCHECK_EQ(visible, window->IsVisible()); |
782 } | 784 } |
783 | 785 |
784 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( | 786 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( |
785 int default_time_in_ms) const { | 787 int default_time_in_ms) const { |
786 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : | 788 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : |
787 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); | 789 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); |
788 } | 790 } |
789 | 791 |
790 void MultiUserWindowManagerChromeOS::RemoveUser(const std::string& user_id, | 792 void MultiUserWindowManagerChromeOS::RemoveUser(const AccountId& account_id, |
791 Profile* profile) { | 793 Profile* profile) { |
792 UserIDToAppWindowObserver::iterator app_observer_iterator = | 794 AccountIdToAppWindowObserver::iterator app_observer_iterator = |
793 user_id_to_app_observer_.find(user_id); | 795 account_id_to_app_observer_.find(account_id); |
794 DCHECK(app_observer_iterator != user_id_to_app_observer_.end()) | 796 DCHECK(app_observer_iterator != account_id_to_app_observer_.end()) |
795 << "User id '" << user_id << "', profile=" << profile | 797 << "User id '" << account_id.GetUserEmail() << "', profile=" << profile |
796 << " was not found."; | 798 << " was not found."; |
797 if (app_observer_iterator == user_id_to_app_observer_.end()) | 799 if (app_observer_iterator == account_id_to_app_observer_.end()) |
798 return; | 800 return; |
799 | 801 |
800 extensions::AppWindowRegistry::Get(profile) | 802 extensions::AppWindowRegistry::Get(profile) |
801 ->RemoveObserver(app_observer_iterator->second); | 803 ->RemoveObserver(app_observer_iterator->second); |
802 delete app_observer_iterator->second; | 804 delete app_observer_iterator->second; |
803 user_id_to_app_observer_.erase(app_observer_iterator); | 805 account_id_to_app_observer_.erase(app_observer_iterator); |
804 } | 806 } |
805 | 807 |
806 } // namespace chrome | 808 } // namespace chrome |
OLD | NEW |