| 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 "apps/shell_window.h" | 7 #include "apps/shell_window.h" |
| 8 #include "apps/shell_window_registry.h" | 8 #include "apps/shell_window_registry.h" |
| 9 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
| 10 #include "ash/multi_profile_uma.h" | 10 #include "ash/multi_profile_uma.h" |
| 11 #include "ash/session_state_delegate.h" | 11 #include "ash/session_state_delegate.h" |
| 12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
| 13 #include "ash/shell_delegate.h" | 13 #include "ash/shell_delegate.h" |
| 14 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
| 15 #include "ash/wm/mru_window_tracker.h" | 15 #include "ash/wm/mru_window_tracker.h" |
| 16 #include "ash/wm/window_positioner.h" | 16 #include "ash/wm/window_positioner.h" |
| 17 #include "ash/wm/window_state.h" | 17 #include "ash/wm/window_state.h" |
| 18 #include "base/auto_reset.h" | 18 #include "base/auto_reset.h" |
| 19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
| 20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
| 22 #include "chrome/browser/chrome_notification_types.h" | 22 #include "chrome/browser/chrome_notification_types.h" |
| 23 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
| 24 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/profiles/profile_manager.h" | 25 #include "chrome/browser/profiles/profile_manager.h" |
| 26 #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chrom
eos.h" |
| 26 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | 27 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
| 27 #include "chrome/browser/ui/browser.h" | 28 #include "chrome/browser/ui/browser.h" |
| 28 #include "chrome/browser/ui/browser_finder.h" | 29 #include "chrome/browser/ui/browser_finder.h" |
| 29 #include "chrome/browser/ui/browser_list.h" | 30 #include "chrome/browser/ui/browser_list.h" |
| 30 #include "chrome/browser/ui/browser_window.h" | 31 #include "chrome/browser/ui/browser_window.h" |
| 31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 32 #include "google_apis/gaia/gaia_auth_util.h" | 33 #include "google_apis/gaia/gaia_auth_util.h" |
| 33 #include "ui/aura/client/activation_client.h" | 34 #include "ui/aura/client/activation_client.h" |
| 34 #include "ui/aura/client/aura_constants.h" | 35 #include "ui/aura/client/aura_constants.h" |
| 35 #include "ui/aura/root_window.h" | 36 #include "ui/aura/root_window.h" |
| 36 #include "ui/aura/window.h" | 37 #include "ui/aura/window.h" |
| 37 #include "ui/base/ui_base_types.h" | 38 #include "ui/base/ui_base_types.h" |
| 38 #include "ui/events/event.h" | 39 #include "ui/events/event.h" |
| 40 #include "ui/message_center/message_center.h" |
| 39 #include "ui/views/corewm/window_util.h" | 41 #include "ui/views/corewm/window_util.h" |
| 40 | 42 |
| 41 namespace { | 43 namespace { |
| 42 | 44 |
| 43 // Checks if a given event is a user event. | 45 // Checks if a given event is a user event. |
| 44 bool IsUserEvent(ui::Event* e) { | 46 bool IsUserEvent(ui::Event* e) { |
| 45 if (e) { | 47 if (e) { |
| 46 ui::EventType type = e->type(); | 48 ui::EventType type = e->type(); |
| 47 if (type != ui::ET_CANCEL_MODE && | 49 if (type != ui::ET_CANCEL_MODE && |
| 48 type != ui::ET_UMA_DATA && | 50 type != ui::ET_UMA_DATA && |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 172 |
| 171 private: | 173 private: |
| 172 std::string user_id_; | 174 std::string user_id_; |
| 173 | 175 |
| 174 DISALLOW_COPY_AND_ASSIGN(AppObserver); | 176 DISALLOW_COPY_AND_ASSIGN(AppObserver); |
| 175 }; | 177 }; |
| 176 | 178 |
| 177 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( | 179 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( |
| 178 const std::string& current_user_id) | 180 const std::string& current_user_id) |
| 179 : current_user_id_(current_user_id), | 181 : current_user_id_(current_user_id), |
| 182 notification_blocker_(new MultiUserNotificationBlockerChromeOS( |
| 183 message_center::MessageCenter::Get(), this)), |
| 180 suppress_visibility_changes_(false) { | 184 suppress_visibility_changes_(false) { |
| 181 // Add a session state observer to be able to monitor session changes. | 185 // Add a session state observer to be able to monitor session changes. |
| 182 if (ash::Shell::HasInstance()) | 186 if (ash::Shell::HasInstance()) |
| 183 ash::Shell::GetInstance()->session_state_delegate()-> | 187 ash::Shell::GetInstance()->session_state_delegate()-> |
| 184 AddSessionStateObserver(this); | 188 AddSessionStateObserver(this); |
| 185 | 189 |
| 186 // The BrowserListObserver would have been better to use then the old | 190 // The BrowserListObserver would have been better to use then the old |
| 187 // notification system, but that observer fires before the window got created. | 191 // notification system, but that observer fires before the window got created. |
| 188 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, | 192 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, |
| 189 content::NotificationService::AllSources()); | 193 content::NotificationService::AllSources()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 245 |
| 242 // Check if this window was created due to a user interaction. If it was, | 246 // Check if this window was created due to a user interaction. If it was, |
| 243 // transfer it to the current user. | 247 // transfer it to the current user. |
| 244 if (IsProcessingUserEvent()) | 248 if (IsProcessingUserEvent()) |
| 245 window_to_entry_[window]->set_show_for_user(current_user_id_); | 249 window_to_entry_[window]->set_show_for_user(current_user_id_); |
| 246 | 250 |
| 247 // Add all transient children to our set of windows. Note that the function | 251 // Add all transient children to our set of windows. Note that the function |
| 248 // will add the children but not the owner to the transient children map. | 252 // will add the children but not the owner to the transient children map. |
| 249 AddTransientOwnerRecursive(window, window); | 253 AddTransientOwnerRecursive(window, window); |
| 250 | 254 |
| 255 // Right now only |notification_blocker_| needs to know when the list of |
| 256 // owners may change. |
| 257 // TODO(skuhne): replace this by observer when another one needs this event. |
| 258 notification_blocker_->UpdateWindowOwners(); |
| 259 |
| 251 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) | 260 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) |
| 252 SetWindowVisibility(window, false); | 261 SetWindowVisibility(window, false); |
| 253 } | 262 } |
| 254 | 263 |
| 255 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( | 264 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( |
| 256 aura::Window* window) { | 265 aura::Window* window) { |
| 257 WindowToEntryMap::iterator it = window_to_entry_.find(window); | 266 WindowToEntryMap::iterator it = window_to_entry_.find(window); |
| 258 return it != window_to_entry_.end() ? it->second->owner() | 267 return it != window_to_entry_.end() ? it->second->owner() |
| 259 : base::EmptyString(); | 268 : base::EmptyString(); |
| 260 } | 269 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 288 it->second->set_show_for_user(user_id); | 297 it->second->set_show_for_user(user_id); |
| 289 | 298 |
| 290 // Show the window if the added user is the current one. | 299 // Show the window if the added user is the current one. |
| 291 if (user_id == current_user_id_) { | 300 if (user_id == current_user_id_) { |
| 292 // Only show the window if it should be shown according to its state. | 301 // Only show the window if it should be shown according to its state. |
| 293 if (it->second->show()) | 302 if (it->second->show()) |
| 294 SetWindowVisibility(window, true); | 303 SetWindowVisibility(window, true); |
| 295 } else { | 304 } else { |
| 296 SetWindowVisibility(window, false); | 305 SetWindowVisibility(window, false); |
| 297 } | 306 } |
| 307 |
| 308 // TODO(skuhne): replace this by observer when another one needs this event. |
| 309 notification_blocker_->UpdateWindowOwners(); |
| 298 } | 310 } |
| 299 | 311 |
| 300 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() { | 312 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() { |
| 301 WindowToEntryMap::iterator it = window_to_entry_.begin(); | 313 WindowToEntryMap::iterator it = window_to_entry_.begin(); |
| 302 for (; it != window_to_entry_.end(); ++it) { | 314 for (; it != window_to_entry_.end(); ++it) { |
| 303 if (it->second->owner() != it->second->show_for_user()) | 315 if (it->second->owner() != it->second->show_for_user()) |
| 304 return true; | 316 return true; |
| 305 } | 317 } |
| 306 return false; | 318 return false; |
| 307 } | 319 } |
| 308 | 320 |
| 321 void MultiUserWindowManagerChromeOS::GetOwnersOfVisibleWindows( |
| 322 std::set<std::string>* user_ids) { |
| 323 for (WindowToEntryMap::iterator it = window_to_entry_.begin(); |
| 324 it != window_to_entry_.end(); ++it) { |
| 325 if (it->first->IsVisible()) |
| 326 user_ids->insert(it->second->owner()); |
| 327 } |
| 328 } |
| 329 |
| 309 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( | 330 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( |
| 310 aura::Window* window, | 331 aura::Window* window, |
| 311 const std::string& user_id) { | 332 const std::string& user_id) { |
| 312 const std::string& presenting_user = GetUserPresentingWindow(window); | 333 const std::string& presenting_user = GetUserPresentingWindow(window); |
| 313 return presenting_user.empty() || presenting_user == user_id; | 334 return presenting_user.empty() || presenting_user == user_id; |
| 314 } | 335 } |
| 315 | 336 |
| 316 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( | 337 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( |
| 317 aura::Window* window) { | 338 aura::Window* window) { |
| 318 WindowToEntryMap::iterator it = window_to_entry_.find(window); | 339 WindowToEntryMap::iterator it = window_to_entry_.find(window); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | 420 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); |
| 400 if (IsWindowOnDesktopOfUser(window, user_id) && | 421 if (IsWindowOnDesktopOfUser(window, user_id) && |
| 401 !window_state->IsMinimized()) { | 422 !window_state->IsMinimized()) { |
| 402 aura::client::ActivationClient* client = | 423 aura::client::ActivationClient* client = |
| 403 aura::client::GetActivationClient(window->GetRootWindow()); | 424 aura::client::GetActivationClient(window->GetRootWindow()); |
| 404 // Several unit tests come here without an activation client. | 425 // Several unit tests come here without an activation client. |
| 405 if (client) | 426 if (client) |
| 406 client->ActivateWindow(window); | 427 client->ActivateWindow(window); |
| 407 } | 428 } |
| 408 } | 429 } |
| 430 |
| 431 // This is called directly here to make sure notification_blocker will see the |
| 432 // new window status. |
| 433 notification_blocker_->ActiveUserChanged(user_id); |
| 409 } | 434 } |
| 410 | 435 |
| 411 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { | 436 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { |
| 412 if (GetWindowOwner(window).empty()) { | 437 if (GetWindowOwner(window).empty()) { |
| 413 // This must be a window in the transient chain - remove it and its | 438 // This must be a window in the transient chain - remove it and its |
| 414 // children from the owner. | 439 // children from the owner. |
| 415 RemoveTransientOwnerRecursive(window); | 440 RemoveTransientOwnerRecursive(window); |
| 416 return; | 441 return; |
| 417 } | 442 } |
| 418 // Remove the state and the window observer. | 443 // Remove the state and the window observer. |
| 419 ash::wm::GetWindowState(window)->RemoveObserver(this); | 444 ash::wm::GetWindowState(window)->RemoveObserver(this); |
| 420 // Remove the window from the owners list. | 445 // Remove the window from the owners list. |
| 421 delete window_to_entry_[window]; | 446 delete window_to_entry_[window]; |
| 422 window_to_entry_.erase(window); | 447 window_to_entry_.erase(window); |
| 448 // TODO(skuhne): replace this by observer when another one needs this event. |
| 449 notification_blocker_->UpdateWindowOwners(); |
| 423 } | 450 } |
| 424 | 451 |
| 425 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanging( | 452 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanging( |
| 426 aura::Window* window, bool visible) { | 453 aura::Window* window, bool visible) { |
| 427 // This command gets called first and immediately when show or hide gets | 454 // This command gets called first and immediately when show or hide gets |
| 428 // called. We remember here the desired state for restoration IF we were | 455 // called. We remember here the desired state for restoration IF we were |
| 429 // not ourselves issuing the call. | 456 // not ourselves issuing the call. |
| 430 // Note also that using the OnWindowVisibilityChanged callback cannot be | 457 // Note also that using the OnWindowVisibilityChanged callback cannot be |
| 431 // used for this. | 458 // used for this. |
| 432 if (suppress_visibility_changes_) | 459 if (suppress_visibility_changes_) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 // To prevent these commands from being recorded as any other commands, we | 665 // To prevent these commands from being recorded as any other commands, we |
| 639 // are suppressing any window entry changes while this is going on. | 666 // are suppressing any window entry changes while this is going on. |
| 640 // Instead of calling SetWindowVisible, only show gets called here since all | 667 // Instead of calling SetWindowVisible, only show gets called here since all |
| 641 // dependents have been shown previously already. | 668 // dependents have been shown previously already. |
| 642 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); | 669 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); |
| 643 window->Show(); | 670 window->Show(); |
| 644 } | 671 } |
| 645 } | 672 } |
| 646 | 673 |
| 647 } // namespace chrome | 674 } // namespace chrome |
| OLD | NEW |