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