shell.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 "ash/shell.h" 6 7#include <algorithm> 8#include <string> 9 10#include "ash/accelerators/accelerator_controller.h" 11#include "ash/accelerators/accelerator_filter.h" 12#include "ash/accelerators/focus_manager_factory.h" 13#include "ash/accelerators/nested_dispatcher_controller.h" 14#include "ash/ash_switches.h" 15#include "ash/autoclick/autoclick_controller.h" 16#include "ash/desktop_background/desktop_background_controller.h" 17#include "ash/desktop_background/desktop_background_view.h" 18#include "ash/desktop_background/user_wallpaper_delegate.h" 19#include "ash/display/cursor_window_controller.h" 20#include "ash/display/display_controller.h" 21#include "ash/display/display_manager.h" 22#include "ash/display/event_transformation_handler.h" 23#include "ash/display/mouse_cursor_event_filter.h" 24#include "ash/display/screen_position_controller.h" 25#include "ash/display/virtual_keyboard_window_controller.h" 26#include "ash/drag_drop/drag_drop_controller.h" 27#include "ash/first_run/first_run_helper_impl.h" 28#include "ash/focus_cycler.h" 29#include "ash/frame/custom_frame_view_ash.h" 30#include "ash/gpu_support.h" 31#include "ash/high_contrast/high_contrast_controller.h" 32#include "ash/host/window_tree_host_factory.h" 33#include "ash/keyboard_uma_event_filter.h" 34#include "ash/magnifier/magnification_controller.h" 35#include "ash/magnifier/partial_magnification_controller.h" 36#include "ash/media_delegate.h" 37#include "ash/new_window_delegate.h" 38#include "ash/root_window_controller.h" 39#include "ash/session_state_delegate.h" 40#include "ash/shelf/app_list_shelf_item_delegate.h" 41#include "ash/shelf/shelf_delegate.h" 42#include "ash/shelf/shelf_item_delegate.h" 43#include "ash/shelf/shelf_item_delegate_manager.h" 44#include "ash/shelf/shelf_layout_manager.h" 45#include "ash/shelf/shelf_model.h" 46#include "ash/shelf/shelf_widget.h" 47#include "ash/shelf/shelf_window_watcher.h" 48#include "ash/shell_delegate.h" 49#include "ash/shell_factory.h" 50#include "ash/shell_window_ids.h" 51#include "ash/system/locale/locale_notification_controller.h" 52#include "ash/system/status_area_widget.h" 53#include "ash/system/tray/system_tray_delegate.h" 54#include "ash/system/tray/system_tray_notifier.h" 55#include "ash/wm/app_list_controller.h" 56#include "ash/wm/ash_focus_rules.h" 57#include "ash/wm/ash_native_cursor_manager.h" 58#include "ash/wm/coordinate_conversion.h" 59#include "ash/wm/event_client_impl.h" 60#include "ash/wm/lock_state_controller.h" 61#include "ash/wm/maximize_mode/maximize_mode_window_manager.h" 62#include "ash/wm/mru_window_tracker.h" 63#include "ash/wm/overlay_event_filter.h" 64#include "ash/wm/overview/window_selector_controller.h" 65#include "ash/wm/power_button_controller.h" 66#include "ash/wm/resize_shadow_controller.h" 67#include "ash/wm/root_window_layout_manager.h" 68#include "ash/wm/screen_dimmer.h" 69#include "ash/wm/system_gesture_event_filter.h" 70#include "ash/wm/system_modal_container_event_filter.h" 71#include "ash/wm/system_modal_container_layout_manager.h" 72#include "ash/wm/toplevel_window_event_handler.h" 73#include "ash/wm/user_activity_detector.h" 74#include "ash/wm/video_detector.h" 75#include "ash/wm/window_animations.h" 76#include "ash/wm/window_positioner.h" 77#include "ash/wm/window_properties.h" 78#include "ash/wm/window_util.h" 79#include "ash/wm/workspace_controller.h" 80#include "base/bind.h" 81#include "base/debug/trace_event.h" 82#include "ui/aura/client/aura_constants.h" 83#include "ui/aura/env.h" 84#include "ui/aura/layout_manager.h" 85#include "ui/aura/window.h" 86#include "ui/aura/window_event_dispatcher.h" 87#include "ui/base/ui_base_switches.h" 88#include "ui/compositor/layer.h" 89#include "ui/compositor/layer_animator.h" 90#include "ui/events/event_target_iterator.h" 91#include "ui/gfx/display.h" 92#include "ui/gfx/image/image_skia.h" 93#include "ui/gfx/screen.h" 94#include "ui/gfx/size.h" 95#include "ui/keyboard/keyboard.h" 96#include "ui/keyboard/keyboard_controller.h" 97#include "ui/keyboard/keyboard_switches.h" 98#include "ui/keyboard/keyboard_util.h" 99#include "ui/message_center/message_center.h" 100#include "ui/views/corewm/tooltip_aura.h" 101#include "ui/views/corewm/tooltip_controller.h" 102#include "ui/views/focus/focus_manager_factory.h" 103#include "ui/views/widget/native_widget_aura.h" 104#include "ui/views/widget/widget.h" 105#include "ui/wm/core/compound_event_filter.h" 106#include "ui/wm/core/focus_controller.h" 107#include "ui/wm/core/input_method_event_filter.h" 108#include "ui/wm/core/shadow_controller.h" 109#include "ui/wm/core/visibility_controller.h" 110#include "ui/wm/core/window_modality_controller.h" 111 112#if defined(OS_CHROMEOS) 113#if defined(USE_X11) 114#include "ash/accelerators/magnifier_key_scroller.h" 115#include "ash/accelerators/spoken_feedback_toggler.h" 116#include "base/message_loop/message_pump_x11.h" 117#endif // defined(USE_X11) 118#include "ash/ash_constants.h" 119#include "ash/display/display_change_observer_chromeos.h" 120#include "ash/display/display_error_observer_chromeos.h" 121#include "ash/display/output_configurator_animation.h" 122#include "ash/display/projecting_observer_chromeos.h" 123#include "ash/display/resolution_notification_controller.h" 124#include "ash/sticky_keys/sticky_keys_controller.h" 125#include "ash/system/chromeos/bluetooth/bluetooth_notification_controller.h" 126#include "ash/system/chromeos/brightness/brightness_controller_chromeos.h" 127#include "ash/system/chromeos/power/power_event_observer.h" 128#include "ash/system/chromeos/power/power_status.h" 129#include "ash/system/chromeos/power/user_activity_notifier.h" 130#include "ash/system/chromeos/power/video_activity_notifier.h" 131#include "ash/system/chromeos/session/last_window_closed_logout_reminder.h" 132#include "ash/system/chromeos/session/logout_confirmation_controller.h" 133#include "base/bind_helpers.h" 134#include "base/sys_info.h" 135#include "ui/display/chromeos/output_configurator.h" 136#endif // defined(OS_CHROMEOS) 137 138namespace ash { 139 140namespace { 141 142using aura::Window; 143using views::Widget; 144 145// A Corewm VisibilityController subclass that calls the Ash animation routine 146// so we can pick up our extended animations. See ash/wm/window_animations.h. 147class AshVisibilityController : public ::wm::VisibilityController { 148 public: 149 AshVisibilityController() {} 150 virtual ~AshVisibilityController() {} 151 152 private: 153 // Overridden from ::wm::VisibilityController: 154 virtual bool CallAnimateOnChildWindowVisibilityChanged( 155 aura::Window* window, 156 bool visible) OVERRIDE { 157 return AnimateOnChildWindowVisibilityChanged(window, visible); 158 } 159 160 DISALLOW_COPY_AND_ASSIGN(AshVisibilityController); 161}; 162 163} // namespace 164 165// static 166Shell* Shell::instance_ = NULL; 167// static 168bool Shell::initially_hide_cursor_ = false; 169 170//////////////////////////////////////////////////////////////////////////////// 171// Shell, public: 172 173// static 174Shell* Shell::CreateInstance(ShellDelegate* delegate) { 175 CHECK(!instance_); 176 instance_ = new Shell(delegate); 177 instance_->Init(); 178 return instance_; 179} 180 181// static 182Shell* Shell::GetInstance() { 183 DCHECK(instance_); 184 return instance_; 185} 186 187// static 188bool Shell::HasInstance() { 189 return !!instance_; 190} 191 192// static 193void Shell::DeleteInstance() { 194 delete instance_; 195 instance_ = NULL; 196} 197 198// static 199internal::RootWindowController* Shell::GetPrimaryRootWindowController() { 200 return internal::GetRootWindowController(GetPrimaryRootWindow()); 201} 202 203// static 204Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() { 205 return Shell::GetInstance()->display_controller()-> 206 GetAllRootWindowControllers(); 207} 208 209// static 210aura::Window* Shell::GetPrimaryRootWindow() { 211 return GetInstance()->display_controller()->GetPrimaryRootWindow(); 212} 213 214// static 215aura::Window* Shell::GetTargetRootWindow() { 216 Shell* shell = GetInstance(); 217 if (shell->scoped_target_root_window_) 218 return shell->scoped_target_root_window_; 219 return shell->target_root_window_; 220} 221 222// static 223gfx::Screen* Shell::GetScreen() { 224 return gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE); 225} 226 227// static 228aura::Window::Windows Shell::GetAllRootWindows() { 229 return Shell::GetInstance()->display_controller()-> 230 GetAllRootWindows(); 231} 232 233// static 234aura::Window* Shell::GetContainer(aura::Window* root_window, 235 int container_id) { 236 return root_window->GetChildById(container_id); 237} 238 239// static 240const aura::Window* Shell::GetContainer(const aura::Window* root_window, 241 int container_id) { 242 return root_window->GetChildById(container_id); 243} 244 245// static 246std::vector<aura::Window*> Shell::GetContainersFromAllRootWindows( 247 int container_id, 248 aura::Window* priority_root) { 249 std::vector<aura::Window*> containers; 250 aura::Window::Windows root_windows = GetAllRootWindows(); 251 for (aura::Window::Windows::const_iterator it = root_windows.begin(); 252 it != root_windows.end(); ++it) { 253 aura::Window* container = (*it)->GetChildById(container_id); 254 if (container) { 255 if (priority_root && priority_root->Contains(container)) 256 containers.insert(containers.begin(), container); 257 else 258 containers.push_back(container); 259 } 260 } 261 return containers; 262} 263 264void Shell::ShowContextMenu(const gfx::Point& location_in_screen, 265 ui::MenuSourceType source_type) { 266 // No context menus if there is no session with an active user. 267 if (!session_state_delegate_->NumberOfLoggedInUsers()) 268 return; 269 // No context menus when screen is locked. 270 if (session_state_delegate_->IsScreenLocked()) 271 return; 272 273 aura::Window* root = 274 wm::GetRootWindowMatching(gfx::Rect(location_in_screen, gfx::Size())); 275 internal::GetRootWindowController(root)-> 276 ShowContextMenu(location_in_screen, source_type); 277} 278 279void Shell::ToggleAppList(aura::Window* window) { 280 // If the context window is not given, show it on the target root window. 281 if (!window) 282 window = GetTargetRootWindow(); 283 if (!app_list_controller_) 284 app_list_controller_.reset(new internal::AppListController); 285 app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window); 286} 287 288bool Shell::GetAppListTargetVisibility() const { 289 return app_list_controller_.get() && 290 app_list_controller_->GetTargetVisibility(); 291} 292 293aura::Window* Shell::GetAppListWindow() { 294 return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL; 295} 296 297app_list::AppListView* Shell::GetAppListView() { 298 return app_list_controller_.get() ? app_list_controller_->GetView() : NULL; 299} 300 301bool Shell::IsSystemModalWindowOpen() const { 302 if (simulate_modal_window_open_for_testing_) 303 return true; 304 const std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( 305 internal::kShellWindowId_SystemModalContainer, NULL); 306 for (std::vector<aura::Window*>::const_iterator cit = containers.begin(); 307 cit != containers.end(); ++cit) { 308 for (aura::Window::Windows::const_iterator wit = (*cit)->children().begin(); 309 wit != (*cit)->children().end(); ++wit) { 310 if ((*wit)->GetProperty(aura::client::kModalKey) == 311 ui::MODAL_TYPE_SYSTEM && (*wit)->TargetVisibility()) { 312 return true; 313 } 314 } 315 } 316 return false; 317} 318 319views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( 320 views::Widget* widget) { 321 // Use translucent-style window frames for dialogs. 322 return new CustomFrameViewAsh(widget); 323} 324 325void Shell::RotateFocus(Direction direction) { 326 focus_cycler_->RotateFocus( 327 direction == FORWARD ? internal::FocusCycler::FORWARD : 328 internal::FocusCycler::BACKWARD); 329} 330 331void Shell::SetDisplayWorkAreaInsets(Window* contains, 332 const gfx::Insets& insets) { 333 if (!display_controller_->UpdateWorkAreaOfDisplayNearestWindow( 334 contains, insets)) { 335 return; 336 } 337 FOR_EACH_OBSERVER(ShellObserver, observers_, 338 OnDisplayWorkAreaInsetsChanged()); 339} 340 341void Shell::OnLoginStateChanged(user::LoginStatus status) { 342 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLoginStateChanged(status)); 343} 344 345void Shell::OnLoginUserProfilePrepared() { 346 CreateShelf(); 347 CreateKeyboard(); 348} 349 350void Shell::UpdateAfterLoginStatusChange(user::LoginStatus status) { 351 RootWindowControllerList controllers = GetAllRootWindowControllers(); 352 for (RootWindowControllerList::iterator iter = controllers.begin(); 353 iter != controllers.end(); ++iter) 354 (*iter)->UpdateAfterLoginStatusChange(status); 355} 356 357void Shell::OnAppTerminating() { 358 FOR_EACH_OBSERVER(ShellObserver, observers_, OnAppTerminating()); 359} 360 361void Shell::OnLockStateChanged(bool locked) { 362 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLockStateChanged(locked)); 363#ifndef NDEBUG 364 // Make sure that there is no system modal in Lock layer when unlocked. 365 if (!locked) { 366 std::vector<aura::Window*> containers = GetContainersFromAllRootWindows( 367 internal::kShellWindowId_LockSystemModalContainer, 368 GetPrimaryRootWindow()); 369 for (std::vector<aura::Window*>::const_iterator iter = containers.begin(); 370 iter != containers.end(); ++iter) { 371 DCHECK_EQ(0u, (*iter)->children().size()); 372 } 373 } 374#endif 375} 376 377void Shell::OnCastingSessionStartedOrStopped(bool started) { 378#if defined(OS_CHROMEOS) && defined(USE_X11) 379 if (projecting_observer_) 380 projecting_observer_->OnCastingSessionStartedOrStopped(started); 381#endif 382} 383 384void Shell::OnOverviewModeStarting() { 385 FOR_EACH_OBSERVER(ShellObserver, observers_, OnOverviewModeStarting()); 386} 387 388void Shell::OnOverviewModeEnding() { 389 FOR_EACH_OBSERVER(ShellObserver, observers_, OnOverviewModeEnding()); 390} 391 392void Shell::OnMaximizeModeStarted() { 393 FOR_EACH_OBSERVER(ShellObserver, observers_, OnMaximizeModeStarted()); 394} 395 396void Shell::OnMaximizeModeEnded() { 397 FOR_EACH_OBSERVER(ShellObserver, observers_, OnMaximizeModeEnded()); 398} 399 400void Shell::CreateShelf() { 401 RootWindowControllerList controllers = GetAllRootWindowControllers(); 402 for (RootWindowControllerList::iterator iter = controllers.begin(); 403 iter != controllers.end(); ++iter) 404 (*iter)->shelf()->CreateShelf(); 405} 406 407void Shell::CreateKeyboard() { 408 // TODO(bshe): Primary root window controller may not be the controller to 409 // attach virtual keyboard. See http://crbug.com/303429 410 InitKeyboard(); 411 if (keyboard::IsKeyboardUsabilityExperimentEnabled()) { 412 display_controller()->virtual_keyboard_window_controller()-> 413 ActivateKeyboard(keyboard_controller_.get()); 414 } else { 415 GetPrimaryRootWindowController()-> 416 ActivateKeyboard(keyboard_controller_.get()); 417 } 418} 419 420void Shell::DeactivateKeyboard() { 421 if (keyboard_controller_.get()) { 422 RootWindowControllerList controllers = GetAllRootWindowControllers(); 423 for (RootWindowControllerList::iterator iter = controllers.begin(); 424 iter != controllers.end(); ++iter) { 425 (*iter)->DeactivateKeyboard(keyboard_controller_.get()); 426 } 427 } 428 keyboard_controller_.reset(); 429} 430 431void Shell::ShowShelf() { 432 RootWindowControllerList controllers = GetAllRootWindowControllers(); 433 for (RootWindowControllerList::iterator iter = controllers.begin(); 434 iter != controllers.end(); ++iter) 435 (*iter)->ShowShelf(); 436} 437 438void Shell::AddShellObserver(ShellObserver* observer) { 439 observers_.AddObserver(observer); 440} 441 442void Shell::RemoveShellObserver(ShellObserver* observer) { 443 observers_.RemoveObserver(observer); 444} 445 446void Shell::EnableMaximizeModeWindowManager(bool enable) { 447 if (enable && !maximize_mode_window_manager_.get()) { 448 maximize_mode_window_manager_.reset( 449 new internal::MaximizeModeWindowManager()); 450 } else if (!enable && maximize_mode_window_manager_.get()) { 451 maximize_mode_window_manager_.reset(); 452 } 453} 454 455bool Shell::IsMaximizeModeWindowManagerEnabled() { 456 return maximize_mode_window_manager_.get() != NULL; 457} 458 459void Shell::UpdateShelfVisibility() { 460 RootWindowControllerList controllers = GetAllRootWindowControllers(); 461 for (RootWindowControllerList::iterator iter = controllers.begin(); 462 iter != controllers.end(); ++iter) 463 if ((*iter)->shelf()) 464 (*iter)->UpdateShelfVisibility(); 465} 466 467void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior, 468 aura::Window* root_window) { 469 ash::internal::ShelfLayoutManager::ForShelf(root_window)-> 470 SetAutoHideBehavior(behavior); 471} 472 473ShelfAutoHideBehavior Shell::GetShelfAutoHideBehavior( 474 aura::Window* root_window) const { 475 return ash::internal::ShelfLayoutManager::ForShelf(root_window)-> 476 auto_hide_behavior(); 477} 478 479void Shell::SetShelfAlignment(ShelfAlignment alignment, 480 aura::Window* root_window) { 481 if (ash::internal::ShelfLayoutManager::ForShelf(root_window)-> 482 SetAlignment(alignment)) { 483 FOR_EACH_OBSERVER( 484 ShellObserver, observers_, OnShelfAlignmentChanged(root_window)); 485 } 486} 487 488ShelfAlignment Shell::GetShelfAlignment(aura::Window* root_window) { 489 return internal::GetRootWindowController(root_window)-> 490 GetShelfLayoutManager()->GetAlignment(); 491} 492 493void Shell::SetDimming(bool should_dim) { 494 RootWindowControllerList controllers = GetAllRootWindowControllers(); 495 for (RootWindowControllerList::iterator iter = controllers.begin(); 496 iter != controllers.end(); ++iter) 497 (*iter)->screen_dimmer()->SetDimming(should_dim); 498} 499 500void Shell::NotifyFullscreenStateChange(bool is_fullscreen, 501 aura::Window* root_window) { 502 FOR_EACH_OBSERVER(ShellObserver, observers_, OnFullscreenStateChanged( 503 is_fullscreen, root_window)); 504} 505 506void Shell::CreateModalBackground(aura::Window* window) { 507 if (!modality_filter_) { 508 modality_filter_.reset(new internal::SystemModalContainerEventFilter(this)); 509 AddPreTargetHandler(modality_filter_.get()); 510 } 511 RootWindowControllerList controllers = GetAllRootWindowControllers(); 512 for (RootWindowControllerList::iterator iter = controllers.begin(); 513 iter != controllers.end(); ++iter) 514 (*iter)->GetSystemModalLayoutManager(window)->CreateModalBackground(); 515} 516 517void Shell::OnModalWindowRemoved(aura::Window* removed) { 518 RootWindowControllerList controllers = GetAllRootWindowControllers(); 519 bool activated = false; 520 for (RootWindowControllerList::iterator iter = controllers.begin(); 521 iter != controllers.end() && !activated; ++iter) { 522 activated = (*iter)->GetSystemModalLayoutManager(removed)-> 523 ActivateNextModalWindow(); 524 } 525 if (!activated) { 526 RemovePreTargetHandler(modality_filter_.get()); 527 modality_filter_.reset(); 528 for (RootWindowControllerList::iterator iter = controllers.begin(); 529 iter != controllers.end(); ++iter) 530 (*iter)->GetSystemModalLayoutManager(removed)->DestroyModalBackground(); 531 } 532} 533 534WebNotificationTray* Shell::GetWebNotificationTray() { 535 return GetPrimaryRootWindowController()->shelf()-> 536 status_area_widget()->web_notification_tray(); 537} 538 539bool Shell::HasPrimaryStatusArea() { 540 ShelfWidget* shelf = GetPrimaryRootWindowController()->shelf(); 541 return shelf && shelf->status_area_widget(); 542} 543 544SystemTray* Shell::GetPrimarySystemTray() { 545 return GetPrimaryRootWindowController()->GetSystemTray(); 546} 547 548ShelfDelegate* Shell::GetShelfDelegate() { 549 if (!shelf_delegate_) { 550 shelf_model_.reset(new ShelfModel); 551 // Creates ShelfItemDelegateManager before ShelfDelegate. 552 shelf_item_delegate_manager_.reset( 553 new ShelfItemDelegateManager(shelf_model_.get())); 554 555 shelf_delegate_.reset(delegate_->CreateShelfDelegate(shelf_model_.get())); 556 scoped_ptr<ShelfItemDelegate> controller( 557 new internal::AppListShelfItemDelegate); 558 559 // Finding the shelf model's location of the app list and setting its 560 // ShelfItemDelegate. 561 int app_list_index = shelf_model_->GetItemIndexForType(TYPE_APP_LIST); 562 DCHECK_GE(app_list_index, 0); 563 ShelfID app_list_id = shelf_model_->items()[app_list_index].id; 564 DCHECK(app_list_id); 565 shelf_item_delegate_manager_->SetShelfItemDelegate(app_list_id, 566 controller.Pass()); 567 shelf_window_watcher_.reset(new internal::ShelfWindowWatcher( 568 shelf_model_.get(), 569 shelf_item_delegate_manager_.get())); 570 } 571 return shelf_delegate_.get(); 572} 573 574void Shell::SetTouchHudProjectionEnabled(bool enabled) { 575 if (is_touch_hud_projection_enabled_ == enabled) 576 return; 577 578 is_touch_hud_projection_enabled_ = enabled; 579 FOR_EACH_OBSERVER(ShellObserver, observers_, 580 OnTouchHudProjectionToggled(enabled)); 581} 582 583#if defined(OS_CHROMEOS) 584ash::FirstRunHelper* Shell::CreateFirstRunHelper() { 585 return new ash::FirstRunHelperImpl; 586} 587 588void Shell::SetCursorCompositingEnabled(bool enabled) { 589 display_controller_->cursor_window_controller()->SetCursorCompositingEnabled( 590 enabled); 591 native_cursor_manager_->SetNativeCursorEnabled(!enabled); 592} 593#endif // defined(OS_CHROMEOS) 594 595void Shell::DoInitialWorkspaceAnimation() { 596 return GetPrimaryRootWindowController()->workspace_controller()-> 597 DoInitialAnimation(); 598} 599 600//////////////////////////////////////////////////////////////////////////////// 601// Shell, private: 602 603Shell::Shell(ShellDelegate* delegate) 604 : target_root_window_(NULL), 605 scoped_target_root_window_(NULL), 606 delegate_(delegate), 607 window_positioner_(new WindowPositioner), 608 activation_client_(NULL), 609#if defined(OS_CHROMEOS) 610 output_configurator_(new ui::OutputConfigurator()), 611#endif // defined(OS_CHROMEOS) 612 native_cursor_manager_(new AshNativeCursorManager), 613 cursor_manager_( 614 scoped_ptr< ::wm::NativeCursorManager>(native_cursor_manager_)), 615 simulate_modal_window_open_for_testing_(false), 616 is_touch_hud_projection_enabled_(false) { 617 DCHECK(delegate_.get()); 618 gpu_support_.reset(delegate_->CreateGPUSupport()); 619 display_manager_.reset(new internal::DisplayManager); 620 display_controller_.reset(new DisplayController); 621#if defined(OS_CHROMEOS) && defined(USE_X11) 622 user_metrics_recorder_.reset(new UserMetricsRecorder); 623#endif // defined(OS_CHROMEOS) 624 625#if defined(OS_CHROMEOS) 626 internal::PowerStatus::Initialize(); 627#endif 628} 629 630Shell::~Shell() { 631 TRACE_EVENT0("shutdown", "ash::Shell::Destructor"); 632 633 delegate_->PreShutdown(); 634 635 views::FocusManagerFactory::Install(NULL); 636 637 // Remove the focus from any window. This will prevent overhead and side 638 // effects (e.g. crashes) from changing focus during shutdown. 639 // See bug crbug.com/134502. 640 aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(NULL); 641 642 // Please keep in same order as in Init() because it's easy to miss one. 643 if (window_modality_controller_) 644 window_modality_controller_.reset(); 645#if defined(OS_CHROMEOS) && defined(USE_X11) 646 RemovePreTargetHandler(magnifier_key_scroll_handler_.get()); 647 magnifier_key_scroll_handler_.reset(); 648 649 RemovePreTargetHandler(speech_feedback_handler_.get()); 650 speech_feedback_handler_.reset(); 651#endif 652 RemovePreTargetHandler(user_activity_detector_.get()); 653 RemovePreTargetHandler(overlay_filter_.get()); 654 RemovePreTargetHandler(input_method_filter_.get()); 655 RemovePreTargetHandler(accelerator_filter_.get()); 656 RemovePreTargetHandler(event_transformation_handler_.get()); 657 RemovePreTargetHandler(toplevel_window_event_handler_.get()); 658 RemovePostTargetHandler(toplevel_window_event_handler_.get()); 659 RemovePreTargetHandler(system_gesture_filter_.get()); 660 RemovePreTargetHandler(keyboard_metrics_filter_.get()); 661 if (mouse_cursor_filter_) 662 RemovePreTargetHandler(mouse_cursor_filter_.get()); 663 664 // TooltipController is deleted with the Shell so removing its references. 665 RemovePreTargetHandler(tooltip_controller_.get()); 666 667 // Destroy maximize window manager early on since it has some observers which 668 // need to be removed. 669 maximize_mode_window_manager_.reset(); 670 671 // AppList needs to be released before shelf layout manager, which is 672 // destroyed with shelf container in the loop below. However, app list 673 // container is now on top of shelf container and released after it. 674 // TODO(xiyuan): Move it back when app list container is no longer needed. 675 app_list_controller_.reset(); 676 677#if defined(OS_CHROMEOS) 678 // Destroy the LastWindowClosedLogoutReminder before the 679 // LogoutConfirmationController. 680 last_window_closed_logout_reminder_.reset(); 681 682 // Destroy the LogoutConfirmationController before the SystemTrayDelegate. 683 logout_confirmation_controller_.reset(); 684#endif 685 686 // Destroy SystemTrayDelegate before destroying the status area(s). 687 system_tray_delegate_->Shutdown(); 688 system_tray_delegate_.reset(); 689 690 locale_notification_controller_.reset(); 691 692 // Drag-and-drop must be canceled prior to close all windows. 693 drag_drop_controller_.reset(); 694 695 // Controllers who have WindowObserver added must be deleted 696 // before |display_controller_| is deleted. 697 698#if defined(OS_CHROMEOS) 699 // VideoActivityNotifier must be deleted before |video_detector_| is 700 // deleted because it's observing video activity through 701 // VideoDetectorObserver interface. 702 video_activity_notifier_.reset(); 703#endif // defined(OS_CHROMEOS) 704 video_detector_.reset(); 705 706 shadow_controller_.reset(); 707 resize_shadow_controller_.reset(); 708 709 window_selector_controller_.reset(); 710 mru_window_tracker_.reset(); 711 712 // |shelf_window_watcher_| has a weak pointer to |shelf_Model_| 713 // and has window observers. 714 shelf_window_watcher_.reset(); 715 716 // Destroy all child windows including widgets. 717 display_controller_->CloseChildWindows(); 718 display_controller_->CloseNonDesktopDisplay(); 719 720 // Chrome implementation of shelf delegate depends on FocusClient, 721 // so must be deleted before |focus_client_|. 722 shelf_delegate_.reset(); 723 focus_client_.reset(); 724 725 // Destroy SystemTrayNotifier after destroying SystemTray as TrayItems 726 // needs to remove observers from it. 727 system_tray_notifier_.reset(); 728 729 // These need a valid Shell instance to clean up properly, so explicitly 730 // delete them before invalidating the instance. 731 // Alphabetical. TODO(oshima): sort. 732 magnification_controller_.reset(); 733 partial_magnification_controller_.reset(); 734 tooltip_controller_.reset(); 735 event_client_.reset(); 736 nested_dispatcher_controller_.reset(); 737 toplevel_window_event_handler_.reset(); 738 visibility_controller_.reset(); 739 // |shelf_item_delegate_manager_| observes |shelf_model_|. It must be 740 // destroyed before |shelf_model_| is destroyed. 741 shelf_item_delegate_manager_.reset(); 742 shelf_model_.reset(); 743 744 power_button_controller_.reset(); 745 lock_state_controller_.reset(); 746 747#if defined(OS_CHROMEOS) 748 resolution_notification_controller_.reset(); 749#endif 750 desktop_background_controller_.reset(); 751 752 // This also deletes all RootWindows. Note that we invoke Shutdown() on 753 // DisplayController before resetting |display_controller_|, since destruction 754 // of its owned RootWindowControllers relies on the value. 755 display_manager_->CreateScreenForShutdown(); 756 display_controller_->Shutdown(); 757 display_controller_.reset(); 758 screen_position_controller_.reset(); 759 760 keyboard_controller_.reset(); 761 accessibility_delegate_.reset(); 762 new_window_delegate_.reset(); 763 media_delegate_.reset(); 764 765#if defined(OS_CHROMEOS) 766 if (display_change_observer_) 767 output_configurator_->RemoveObserver(display_change_observer_.get()); 768 if (output_configurator_animation_) 769 output_configurator_->RemoveObserver(output_configurator_animation_.get()); 770 if (display_error_observer_) 771 output_configurator_->RemoveObserver(display_error_observer_.get()); 772 if (projecting_observer_) 773 output_configurator_->RemoveObserver(projecting_observer_.get()); 774 display_change_observer_.reset(); 775#endif // defined(OS_CHROMEOS) 776 777#if defined(OS_CHROMEOS) 778 internal::PowerStatus::Shutdown(); 779#endif 780 781 DCHECK(instance_ == this); 782 instance_ = NULL; 783} 784 785void Shell::Init() { 786 delegate_->PreInit(); 787 if (keyboard::IsKeyboardUsabilityExperimentEnabled()) { 788 display_manager_->SetSecondDisplayMode( 789 internal::DisplayManager::VIRTUAL_KEYBOARD); 790 } 791 bool display_initialized = display_manager_->InitFromCommandLine(); 792#if defined(OS_CHROMEOS) 793 output_configurator_->Init(!gpu_support_->IsPanelFittingDisabled()); 794 output_configurator_animation_.reset( 795 new internal::OutputConfiguratorAnimation()); 796 output_configurator_->AddObserver(output_configurator_animation_.get()); 797 798 projecting_observer_.reset(new internal::ProjectingObserver()); 799 output_configurator_->AddObserver(projecting_observer_.get()); 800 801 if (!display_initialized && base::SysInfo::IsRunningOnChromeOS()) { 802 display_change_observer_.reset(new internal::DisplayChangeObserver); 803 // Register |display_change_observer_| first so that the rest of 804 // observer gets invoked after the root windows are configured. 805 output_configurator_->AddObserver(display_change_observer_.get()); 806 display_error_observer_.reset(new internal::DisplayErrorObserver()); 807 output_configurator_->AddObserver(display_error_observer_.get()); 808 output_configurator_->set_state_controller(display_change_observer_.get()); 809 output_configurator_->set_mirroring_controller(display_manager_.get()); 810 output_configurator_->ForceInitialConfigure( 811 delegate_->IsFirstRunAfterBoot() ? kChromeOsBootColor : 0); 812 display_initialized = true; 813 } 814#endif // defined(OS_CHROMEOS) 815 if (!display_initialized) 816 display_manager_->InitDefaultDisplay(); 817 818 // Install the custom factory first so that views::FocusManagers for Tray, 819 // Shelf, and WallPaper could be created by the factory. 820 views::FocusManagerFactory::Install(new AshFocusManagerFactory); 821 822 // Env creates the compositor. Historically it seems to have been implicitly 823 // initialized first by the ActivationController, but now that FocusController 824 // no longer does this we need to do it explicitly. 825 aura::Env::CreateInstance(); 826 827 // The WindowModalityController needs to be at the front of the input event 828 // pretarget handler list to ensure that it processes input events when modal 829 // windows are active. 830 window_modality_controller_.reset( 831 new ::wm::WindowModalityController(this)); 832 833 AddPreTargetHandler(this); 834 835 env_filter_.reset(new ::wm::CompoundEventFilter); 836 AddPreTargetHandler(env_filter_.get()); 837 838 ::wm::FocusController* focus_controller = 839 new ::wm::FocusController(new wm::AshFocusRules); 840 focus_client_.reset(focus_controller); 841 activation_client_ = focus_controller; 842 activation_client_->AddObserver(this); 843 focus_cycler_.reset(new internal::FocusCycler()); 844 845 screen_position_controller_.reset(new internal::ScreenPositionController); 846 window_tree_host_factory_.reset(delegate_->CreateWindowTreeHostFactory()); 847 848 display_controller_->Start(); 849 display_controller_->InitPrimaryDisplay(); 850 aura::Window* root_window = display_controller_->GetPrimaryRootWindow(); 851 target_root_window_ = root_window; 852 853#if defined(OS_CHROMEOS) 854 resolution_notification_controller_.reset( 855 new internal::ResolutionNotificationController); 856#endif 857 858 cursor_manager_.SetDisplay(GetScreen()->GetPrimaryDisplay()); 859 860 nested_dispatcher_controller_.reset(new NestedDispatcherController); 861 accelerator_controller_.reset(new AcceleratorController); 862 863#if defined(OS_CHROMEOS) && defined(USE_X11) 864 magnifier_key_scroll_handler_ = MagnifierKeyScroller::CreateHandler().Pass(); 865 AddPreTargetHandler(magnifier_key_scroll_handler_.get()); 866 speech_feedback_handler_ = SpokenFeedbackToggler::CreateHandler().Pass(); 867 AddPreTargetHandler(speech_feedback_handler_.get()); 868#endif 869 870 // The order in which event filters are added is significant. 871 872#if defined(OS_CHROMEOS) 873 // The StickyKeysController also rewrites events and must be added 874 // before observers, but after the EventRewriterEventFilter. 875 sticky_keys_controller_.reset(new StickyKeysController); 876 AddPreTargetHandler(sticky_keys_controller_.get()); 877#endif 878 879 // UserActivityDetector passes events to observers, so let them get 880 // rewritten first. 881 user_activity_detector_.reset(new UserActivityDetector); 882 AddPreTargetHandler(user_activity_detector_.get()); 883 884 overlay_filter_.reset(new internal::OverlayEventFilter); 885 AddPreTargetHandler(overlay_filter_.get()); 886 AddShellObserver(overlay_filter_.get()); 887 888 input_method_filter_.reset(new ::wm::InputMethodEventFilter( 889 root_window->GetHost()->GetAcceleratedWidget())); 890 AddPreTargetHandler(input_method_filter_.get()); 891 892 accelerator_filter_.reset(new internal::AcceleratorFilter); 893 AddPreTargetHandler(accelerator_filter_.get()); 894 895 event_transformation_handler_.reset(new internal::EventTransformationHandler); 896 AddPreTargetHandler(event_transformation_handler_.get()); 897 898 toplevel_window_event_handler_.reset(new ToplevelWindowEventHandler); 899 900 system_gesture_filter_.reset(new internal::SystemGestureEventFilter); 901 AddPreTargetHandler(system_gesture_filter_.get()); 902 903 keyboard_metrics_filter_.reset(new internal::KeyboardUMAEventFilter); 904 AddPreTargetHandler(keyboard_metrics_filter_.get()); 905 906 // The keyboard system must be initialized before the RootWindowController is 907 // created. 908#if defined(OS_CHROMEOS) 909 keyboard::InitializeKeyboard(); 910#endif 911 912 lock_state_controller_.reset(new LockStateController); 913 power_button_controller_.reset(new PowerButtonController( 914 lock_state_controller_.get())); 915#if defined(OS_CHROMEOS) 916 // Pass the initial display state to PowerButtonController. 917 power_button_controller_->OnDisplayModeChanged( 918 output_configurator_->cached_outputs()); 919#endif 920 AddShellObserver(lock_state_controller_.get()); 921 922 drag_drop_controller_.reset(new internal::DragDropController); 923 mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter()); 924 PrependPreTargetHandler(mouse_cursor_filter_.get()); 925 926 // Create Controllers that may need root window. 927 // TODO(oshima): Move as many controllers before creating 928 // RootWindowController as possible. 929 visibility_controller_.reset(new AshVisibilityController); 930 931 magnification_controller_.reset( 932 MagnificationController::CreateInstance()); 933 mru_window_tracker_.reset(new MruWindowTracker(activation_client_)); 934 935 partial_magnification_controller_.reset( 936 new PartialMagnificationController()); 937 938 autoclick_controller_.reset(AutoclickController::CreateInstance()); 939 940 high_contrast_controller_.reset(new HighContrastController); 941 video_detector_.reset(new VideoDetector); 942 window_selector_controller_.reset(new WindowSelectorController()); 943 944 tooltip_controller_.reset( 945 new views::corewm::TooltipController( 946 scoped_ptr<views::corewm::Tooltip>( 947 new views::corewm::TooltipAura(gfx::SCREEN_TYPE_ALTERNATE)))); 948 AddPreTargetHandler(tooltip_controller_.get()); 949 950 event_client_.reset(new internal::EventClientImpl); 951 952 // This controller needs to be set before SetupManagedWindowMode. 953 desktop_background_controller_.reset(new DesktopBackgroundController()); 954 user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate()); 955 956 session_state_delegate_.reset(delegate_->CreateSessionStateDelegate()); 957 accessibility_delegate_.reset(delegate_->CreateAccessibilityDelegate()); 958 new_window_delegate_.reset(delegate_->CreateNewWindowDelegate()); 959 media_delegate_.reset(delegate_->CreateMediaDelegate()); 960 961 resize_shadow_controller_.reset(new internal::ResizeShadowController()); 962 shadow_controller_.reset( 963 new ::wm::ShadowController(activation_client_)); 964 965 // Create system_tray_notifier_ before the delegate. 966 system_tray_notifier_.reset(new ash::SystemTrayNotifier()); 967 968 // Initialize system_tray_delegate_ before initializing StatusAreaWidget. 969 system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate()); 970 DCHECK(system_tray_delegate_.get()); 971 972 locale_notification_controller_.reset( 973 new internal::LocaleNotificationController); 974 975 // Initialize system_tray_delegate_ after StatusAreaWidget is created. 976 system_tray_delegate_->Initialize(); 977 978#if defined(OS_CHROMEOS) 979 // Create the LogoutConfirmationController after the SystemTrayDelegate. 980 logout_confirmation_controller_.reset( 981 new internal::LogoutConfirmationController( 982 base::Bind(&SystemTrayDelegate::SignOut, 983 base::Unretained(system_tray_delegate_.get())))); 984#endif 985 986 // TODO(oshima): Initialize all RootWindowControllers once, and 987 // initialize controller/delegates above when initializing the 988 // primary root window controller. 989 internal::RootWindowController::CreateForPrimaryDisplay( 990 root_window->GetHost()); 991 992 display_controller_->InitSecondaryDisplays(); 993 994 // It needs to be created after RootWindowController has been created 995 // (which calls OnWindowResized has been called, otherwise the 996 // widget will not paint when restoring after a browser crash. Also it needs 997 // to be created after InitSecondaryDisplays() to initialize the wallpapers in 998 // the correct size. 999 user_wallpaper_delegate_->InitializeWallpaper(); 1000 1001 if (initially_hide_cursor_) 1002 cursor_manager_.HideCursor(); 1003 cursor_manager_.SetCursor(ui::kCursorPointer); 1004 1005#if defined(OS_CHROMEOS) 1006 // Set accelerator controller delegates. 1007 accelerator_controller_->SetBrightnessControlDelegate( 1008 scoped_ptr<ash::BrightnessControlDelegate>( 1009 new ash::system::BrightnessControllerChromeos).Pass()); 1010 1011 power_event_observer_.reset(new internal::PowerEventObserver()); 1012 user_activity_notifier_.reset( 1013 new internal::UserActivityNotifier(user_activity_detector_.get())); 1014 video_activity_notifier_.reset( 1015 new internal::VideoActivityNotifier(video_detector_.get())); 1016 bluetooth_notification_controller_.reset( 1017 new internal::BluetoothNotificationController); 1018 last_window_closed_logout_reminder_.reset( 1019 new internal::LastWindowClosedLogoutReminder); 1020#endif 1021 1022 weak_display_manager_factory_.reset( 1023 new base::WeakPtrFactory<internal::DisplayManager>( 1024 display_manager_.get())); 1025 // The compositor thread and main message loop have to be running in 1026 // order to create mirror window. Run it after the main message loop 1027 // is started. 1028 base::MessageLoopForUI::current()->PostTask( 1029 FROM_HERE, 1030 base::Bind(&internal::DisplayManager::CreateMirrorWindowIfAny, 1031 weak_display_manager_factory_->GetWeakPtr())); 1032} 1033 1034void Shell::InitKeyboard() { 1035 if (keyboard::IsKeyboardEnabled()) { 1036 if (keyboard_controller_.get()) { 1037 RootWindowControllerList controllers = GetAllRootWindowControllers(); 1038 for (RootWindowControllerList::iterator iter = controllers.begin(); 1039 iter != controllers.end(); ++iter) { 1040 (*iter)->DeactivateKeyboard(keyboard_controller_.get()); 1041 } 1042 } 1043 keyboard::KeyboardControllerProxy* proxy = 1044 delegate_->CreateKeyboardControllerProxy(); 1045 keyboard_controller_.reset( 1046 new keyboard::KeyboardController(proxy)); 1047 } 1048} 1049 1050void Shell::InitRootWindow(aura::Window* root_window) { 1051 DCHECK(activation_client_); 1052 DCHECK(visibility_controller_.get()); 1053 DCHECK(drag_drop_controller_.get()); 1054 1055 aura::client::SetFocusClient(root_window, focus_client_.get()); 1056 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window); 1057 aura::client::SetActivationClient(root_window, activation_client_); 1058 ::wm::FocusController* focus_controller = 1059 static_cast< ::wm::FocusController*>(activation_client_); 1060 root_window->AddPreTargetHandler(focus_controller); 1061 aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); 1062 aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); 1063 aura::client::SetScreenPositionClient(root_window, 1064 screen_position_controller_.get()); 1065 aura::client::SetCursorClient(root_window, &cursor_manager_); 1066 aura::client::SetTooltipClient(root_window, tooltip_controller_.get()); 1067 aura::client::SetEventClient(root_window, event_client_.get()); 1068 1069 aura::client::SetWindowMoveClient(root_window, 1070 toplevel_window_event_handler_.get()); 1071 root_window->AddPreTargetHandler(toplevel_window_event_handler_.get()); 1072 root_window->AddPostTargetHandler(toplevel_window_event_handler_.get()); 1073 1074 if (nested_dispatcher_controller_) { 1075 aura::client::SetDispatcherClient(root_window, 1076 nested_dispatcher_controller_.get()); 1077 } 1078} 1079 1080bool Shell::CanWindowReceiveEvents(aura::Window* window) { 1081 RootWindowControllerList controllers = GetAllRootWindowControllers(); 1082 for (RootWindowControllerList::iterator iter = controllers.begin(); 1083 iter != controllers.end(); ++iter) { 1084 internal::SystemModalContainerLayoutManager* layout_manager = 1085 (*iter)->GetSystemModalLayoutManager(window); 1086 if (layout_manager && layout_manager->CanWindowReceiveEvents(window)) 1087 return true; 1088 } 1089 return false; 1090} 1091 1092//////////////////////////////////////////////////////////////////////////////// 1093// Shell, ui::EventTarget overrides: 1094 1095bool Shell::CanAcceptEvent(const ui::Event& event) { 1096 return true; 1097} 1098 1099ui::EventTarget* Shell::GetParentTarget() { 1100 return aura::Env::GetInstance(); 1101} 1102 1103scoped_ptr<ui::EventTargetIterator> Shell::GetChildIterator() const { 1104 return scoped_ptr<ui::EventTargetIterator>(); 1105} 1106 1107ui::EventTargeter* Shell::GetEventTargeter() { 1108 NOTREACHED(); 1109 return NULL; 1110} 1111 1112void Shell::OnEvent(ui::Event* event) { 1113} 1114 1115//////////////////////////////////////////////////////////////////////////////// 1116// Shell, aura::client::ActivationChangeObserver implementation: 1117 1118void Shell::OnWindowActivated(aura::Window* gained_active, 1119 aura::Window* lost_active) { 1120 if (gained_active) 1121 target_root_window_ = gained_active->GetRootWindow(); 1122} 1123 1124} // namespace ash 1125