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