Automate more Better Session Restore tests: POST data and cookies.
[chromium-blink-merge.git] / ash / shell.cc
blob97f3c8f1bffe20c086215429e7ee2f555df9f701
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.
5 #include "ash/shell.h"
7 #include <algorithm>
8 #include <string>
10 #include "ash/accelerators/focus_manager_factory.h"
11 #include "ash/ash_switches.h"
12 #include "ash/caps_lock_delegate.h"
13 #include "ash/desktop_background/desktop_background_controller.h"
14 #include "ash/desktop_background/desktop_background_resources.h"
15 #include "ash/desktop_background/desktop_background_view.h"
16 #include "ash/display/display_controller.h"
17 #include "ash/display/mouse_cursor_event_filter.h"
18 #include "ash/display/multi_display_manager.h"
19 #include "ash/display/screen_position_controller.h"
20 #include "ash/drag_drop/drag_drop_controller.h"
21 #include "ash/focus_cycler.h"
22 #include "ash/high_contrast/high_contrast_controller.h"
23 #include "ash/magnifier/magnification_controller.h"
24 #include "ash/root_window_controller.h"
25 #include "ash/screen_ash.h"
26 #include "ash/shell_delegate.h"
27 #include "ash/shell_factory.h"
28 #include "ash/shell_window_ids.h"
29 #include "ash/system/status_area_widget.h"
30 #include "ash/system/tray/system_tray_delegate.h"
31 #include "ash/tooltips/tooltip_controller.h"
32 #include "ash/touch/touch_observer_hud.h"
33 #include "ash/wm/activation_controller.h"
34 #include "ash/wm/always_on_top_controller.h"
35 #include "ash/wm/app_list_controller.h"
36 #include "ash/wm/base_layout_manager.h"
37 #include "ash/wm/capture_controller.h"
38 #include "ash/wm/coordinate_conversion.h"
39 #include "ash/wm/custom_frame_view_ash.h"
40 #include "ash/wm/dialog_frame_view.h"
41 #include "ash/wm/event_client_impl.h"
42 #include "ash/wm/event_rewriter_event_filter.h"
43 #include "ash/wm/overlay_event_filter.h"
44 #include "ash/wm/power_button_controller.h"
45 #include "ash/wm/property_util.h"
46 #include "ash/wm/resize_shadow_controller.h"
47 #include "ash/wm/root_window_layout_manager.h"
48 #include "ash/wm/screen_dimmer.h"
49 #include "ash/wm/session_state_controller.h"
50 #include "ash/wm/session_state_controller_impl.h"
51 #include "ash/wm/session_state_controller_impl2.h"
52 #include "ash/wm/shadow_controller.h"
53 #include "ash/wm/stacking_controller.h"
54 #include "ash/wm/system_gesture_event_filter.h"
55 #include "ash/wm/system_modal_container_event_filter.h"
56 #include "ash/wm/system_modal_container_layout_manager.h"
57 #include "ash/wm/user_activity_detector.h"
58 #include "ash/wm/video_detector.h"
59 #include "ash/wm/visibility_controller.h"
60 #include "ash/wm/window_cycle_controller.h"
61 #include "ash/wm/window_modality_controller.h"
62 #include "ash/wm/window_properties.h"
63 #include "ash/wm/window_util.h"
64 #include "ash/wm/workspace_controller.h"
65 #include "base/bind.h"
66 #include "base/command_line.h"
67 #include "base/debug/leak_annotations.h"
68 #include "ui/aura/client/aura_constants.h"
69 #include "ui/aura/client/user_action_client.h"
70 #include "ui/aura/display_manager.h"
71 #include "ui/aura/env.h"
72 #include "ui/aura/focus_manager.h"
73 #include "ui/aura/layout_manager.h"
74 #include "ui/aura/root_window.h"
75 #include "ui/aura/shared/compound_event_filter.h"
76 #include "ui/aura/shared/input_method_event_filter.h"
77 #include "ui/aura/ui_controls_aura.h"
78 #include "ui/aura/window.h"
79 #include "ui/compositor/layer.h"
80 #include "ui/compositor/layer_animator.h"
81 #include "ui/gfx/display.h"
82 #include "ui/gfx/image/image_skia.h"
83 #include "ui/gfx/screen.h"
84 #include "ui/gfx/size.h"
85 #include "ui/ui_controls/ui_controls.h"
86 #include "ui/views/focus/focus_manager_factory.h"
87 #include "ui/views/widget/native_widget_aura.h"
88 #include "ui/views/widget/widget.h"
90 #if !defined(OS_MACOSX)
91 #include "ash/accelerators/accelerator_controller.h"
92 #include "ash/accelerators/accelerator_filter.h"
93 #include "ash/accelerators/nested_dispatcher_controller.h"
94 #endif
96 #if defined(OS_CHROMEOS)
97 #include "ash/display/output_configurator_animation.h"
98 #include "base/message_pump_aurax11.h"
99 #include "chromeos/display/output_configurator.h"
100 #include "content/public/browser/gpu_data_manager.h"
101 #include "content/public/common/gpu_feature_type.h"
102 #endif // defined(OS_CHROMEOS)
104 namespace ash {
106 namespace {
108 using aura::Window;
109 using views::Widget;
111 // This dummy class is used for shell unit tests. We dont have chrome delegate
112 // in these tests.
113 class DummyUserWallpaperDelegate : public UserWallpaperDelegate {
114 public:
115 DummyUserWallpaperDelegate() {}
117 virtual ~DummyUserWallpaperDelegate() {}
119 virtual ash::WindowVisibilityAnimationType GetAnimationType() OVERRIDE {
120 return WINDOW_VISIBILITY_ANIMATION_TYPE_FADE;
123 virtual void UpdateWallpaper() OVERRIDE {
126 virtual void InitializeWallpaper() OVERRIDE {
127 ash::Shell::GetInstance()->desktop_background_controller()->
128 CreateEmptyWallpaper();
131 virtual void OpenSetWallpaperPage() OVERRIDE {
134 virtual bool CanOpenSetWallpaperPage() OVERRIDE {
135 return false;
138 virtual void OnWallpaperAnimationFinished() OVERRIDE {
141 virtual void OnWallpaperBootAnimationFinished() OVERRIDE {
144 private:
145 DISALLOW_COPY_AND_ASSIGN(DummyUserWallpaperDelegate);
148 } // namespace
150 // static
151 Shell* Shell::instance_ = NULL;
152 // static
153 bool Shell::initially_hide_cursor_ = false;
155 ////////////////////////////////////////////////////////////////////////////////
156 // Shell::TestApi
158 Shell::TestApi::TestApi(Shell* shell) : shell_(shell) {}
160 internal::RootWindowLayoutManager* Shell::TestApi::root_window_layout() {
161 return shell_->GetPrimaryRootWindowController()->root_window_layout();
164 aura::shared::InputMethodEventFilter*
165 Shell::TestApi::input_method_event_filter() {
166 return shell_->input_method_filter_.get();
169 internal::SystemGestureEventFilter*
170 Shell::TestApi::system_gesture_event_filter() {
171 return shell_->system_gesture_filter_.get();
174 internal::WorkspaceController* Shell::TestApi::workspace_controller() {
175 return shell_->GetPrimaryRootWindowController()->workspace_controller();
178 internal::ScreenPositionController*
179 Shell::TestApi::screen_position_controller() {
180 return shell_->screen_position_controller_.get();
183 ////////////////////////////////////////////////////////////////////////////////
184 // Shell, public:
186 Shell::Shell(ShellDelegate* delegate)
187 : screen_(new ScreenAsh),
188 active_root_window_(NULL),
189 delegate_(delegate),
190 #if defined(OS_CHROMEOS)
191 output_configurator_(new chromeos::OutputConfigurator()),
192 output_configurator_animation_(
193 new internal::OutputConfiguratorAnimation()),
194 #endif // defined(OS_CHROMEOS)
195 browser_context_(NULL),
196 simulate_modal_window_open_for_testing_(false) {
197 DCHECK(delegate_.get());
198 ANNOTATE_LEAKING_OBJECT_PTR(screen_); // see crbug.com/156466
199 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_);
200 if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE))
201 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_);
202 ui_controls::InstallUIControlsAura(internal::CreateUIControls());
203 #if defined(OS_CHROMEOS)
204 content::GpuFeatureType blacklisted_features =
205 content::GpuDataManager::GetInstance()->GetBlacklistedFeatures();
206 bool is_panel_fitting_disabled =
207 (blacklisted_features & content::GPU_FEATURE_TYPE_PANEL_FITTING) ||
208 CommandLine::ForCurrentProcess()->HasSwitch(
209 switches::kAshDisablePanelFitting);
210 output_configurator_->Init(!is_panel_fitting_disabled);
212 output_configurator_->AddObserver(output_configurator_animation_.get());
213 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(
214 output_configurator());
215 #endif // defined(OS_CHROMEOS)
218 Shell::~Shell() {
219 views::FocusManagerFactory::Install(NULL);
221 // Remove the focus from any window. This will prevent overhead and side
222 // effects (e.g. crashes) from changing focus during shutdown.
223 // See bug crbug.com/134502.
224 if (active_root_window_)
225 active_root_window_->GetFocusManager()->SetFocusedWindow(NULL, NULL);
227 // Please keep in same order as in Init() because it's easy to miss one.
228 RemoveEnvEventFilter(user_activity_detector_.get());
229 RemoveEnvEventFilter(event_rewriter_filter_.get());
230 RemoveEnvEventFilter(overlay_filter_.get());
231 RemoveEnvEventFilter(input_method_filter_.get());
232 RemoveEnvEventFilter(window_modality_controller_.get());
233 if (mouse_cursor_filter_.get())
234 RemoveEnvEventFilter(mouse_cursor_filter_.get());
235 RemoveEnvEventFilter(system_gesture_filter_.get());
236 #if !defined(OS_MACOSX)
237 RemoveEnvEventFilter(accelerator_filter_.get());
238 #endif
239 if (touch_observer_hud_.get())
240 RemoveEnvEventFilter(touch_observer_hud_.get());
242 // TooltipController is deleted with the Shell so removing its references.
243 RemoveEnvEventFilter(tooltip_controller_.get());
245 // AppList needs to be released before shelf layout manager, which is
246 // destroyed with launcher container in the loop below. However, app list
247 // container is now on top of launcher container and released after it.
248 // TODO(xiyuan): Move it back when app list container is no longer needed.
249 app_list_controller_.reset();
251 // Destroy SystemTrayDelegate before destroying the status area(s).
252 system_tray_delegate_.reset();
254 // Destroy all child windows including widgets.
255 display_controller_->CloseChildWindows();
257 // These need a valid Shell instance to clean up properly, so explicitly
258 // delete them before invalidating the instance.
259 // Alphabetical.
260 drag_drop_controller_.reset();
261 magnification_controller_.reset();
262 power_button_controller_.reset();
263 session_state_controller_.reset();
264 resize_shadow_controller_.reset();
265 shadow_controller_.reset();
266 tooltip_controller_.reset();
267 event_client_.reset();
268 window_cycle_controller_.reset();
269 capture_controller_.reset();
270 nested_dispatcher_controller_.reset();
271 user_action_client_.reset();
272 visibility_controller_.reset();
274 // This also deletes all RootWindows.
275 display_controller_.reset();
276 screen_position_controller_.reset();
278 // Delete the activation controller after other controllers and launcher
279 // because they might have registered ActivationChangeObserver.
280 activation_controller_.reset();
282 DCHECK(instance_ == this);
283 instance_ = NULL;
285 #if defined(OS_CHROMEOS)
286 output_configurator_->RemoveObserver(output_configurator_animation_.get());
287 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(
288 output_configurator());
289 #endif // defined(OS_CHROMEOS)
292 // static
293 Shell* Shell::CreateInstance(ShellDelegate* delegate) {
294 CHECK(!instance_);
295 aura::Env::GetInstance()->SetDisplayManager(
296 new internal::MultiDisplayManager());
297 instance_ = new Shell(delegate);
298 instance_->Init();
299 return instance_;
302 // static
303 Shell* Shell::GetInstance() {
304 DCHECK(instance_);
305 return instance_;
308 // static
309 bool Shell::HasInstance() {
310 return !!instance_;
313 // static
314 void Shell::DeleteInstance() {
315 delete instance_;
316 instance_ = NULL;
319 // static
320 internal::RootWindowController* Shell::GetPrimaryRootWindowController() {
321 return GetRootWindowController(GetPrimaryRootWindow());
324 // static
325 Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() {
326 return Shell::GetInstance()->display_controller()->
327 GetAllRootWindowControllers();
330 // static
331 aura::RootWindow* Shell::GetPrimaryRootWindow() {
332 return GetInstance()->display_controller()->GetPrimaryRootWindow();
335 // static
336 aura::RootWindow* Shell::GetActiveRootWindow() {
337 return GetInstance()->active_root_window_;
340 // static
341 gfx::Screen* Shell::GetScreen() {
342 return gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
345 // static
346 Shell::RootWindowList Shell::GetAllRootWindows() {
347 return Shell::GetInstance()->display_controller()->
348 GetAllRootWindows();
351 // static
352 aura::Window* Shell::GetContainer(aura::RootWindow* root_window,
353 int container_id) {
354 return root_window->GetChildById(container_id);
357 // static
358 const aura::Window* Shell::GetContainer(const aura::RootWindow* root_window,
359 int container_id) {
360 return root_window->GetChildById(container_id);
363 // static
364 std::vector<aura::Window*> Shell::GetAllContainers(int container_id) {
365 std::vector<aura::Window*> containers;
366 RootWindowList root_windows = GetAllRootWindows();
367 for (RootWindowList::const_iterator it = root_windows.begin();
368 it != root_windows.end(); ++it) {
369 aura::Window* container = (*it)->GetChildById(container_id);
370 if (container)
371 containers.push_back(container);
373 return containers;
376 // static
377 bool Shell::IsLauncherPerDisplayEnabled() {
378 CommandLine* command_line = CommandLine::ForCurrentProcess();
379 return command_line->HasSwitch(switches::kAshLauncherPerDisplay);
382 void Shell::Init() {
383 // Install the custom factory first so that views::FocusManagers for Tray,
384 // Launcher, and WallPaper could be created by the factory.
385 views::FocusManagerFactory::Install(new AshFocusManagerFactory);
387 env_filter_.reset(new aura::shared::CompoundEventFilter);
388 AddEnvEventFilter(env_filter_.get());
390 focus_manager_.reset(new aura::FocusManager);
391 activation_controller_.reset(
392 new internal::ActivationController(focus_manager_.get()));
394 focus_cycler_.reset(new internal::FocusCycler());
396 screen_position_controller_.reset(new internal::ScreenPositionController);
397 display_controller_.reset(new DisplayController);
398 display_controller_->InitPrimaryDisplay();
399 aura::RootWindow* root_window = display_controller_->GetPrimaryRootWindow();
400 active_root_window_ = root_window;
402 cursor_manager_.SetDeviceScaleFactor(
403 root_window->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
405 #if !defined(OS_MACOSX)
406 nested_dispatcher_controller_.reset(new NestedDispatcherController);
407 accelerator_controller_.reset(new AcceleratorController);
408 #endif
410 // The order in which event filters are added is significant.
411 user_activity_detector_.reset(new UserActivityDetector);
412 AddEnvEventFilter(user_activity_detector_.get());
414 event_rewriter_filter_.reset(new internal::EventRewriterEventFilter);
415 AddEnvEventFilter(event_rewriter_filter_.get());
417 overlay_filter_.reset(new internal::OverlayEventFilter);
418 AddEnvEventFilter(overlay_filter_.get());
419 AddShellObserver(overlay_filter_.get());
421 input_method_filter_.reset(new aura::shared::InputMethodEventFilter());
422 AddEnvEventFilter(input_method_filter_.get());
424 #if !defined(OS_MACOSX)
425 accelerator_filter_.reset(new internal::AcceleratorFilter);
426 AddEnvEventFilter(accelerator_filter_.get());
427 #endif
429 system_gesture_filter_.reset(new internal::SystemGestureEventFilter);
430 AddEnvEventFilter(system_gesture_filter_.get());
432 capture_controller_.reset(new internal::CaptureController);
434 internal::RootWindowController* root_window_controller =
435 new internal::RootWindowController(root_window);
436 root_window_controller->CreateContainers();
437 root_window_controller->CreateSystemBackground(
438 delegate_->IsFirstRunAfterBoot());
440 CommandLine* command_line = CommandLine::ForCurrentProcess();
442 if (command_line->HasSwitch(switches::kAshTouchHud)) {
443 touch_observer_hud_.reset(new internal::TouchObserverHUD);
444 AddEnvEventFilter(touch_observer_hud_.get());
447 mouse_cursor_filter_.reset(new internal::MouseCursorEventFilter());
448 AddEnvEventFilter(mouse_cursor_filter_.get());
450 // Create Controllers that may need root window.
451 // TODO(oshima): Move as many controllers before creating
452 // RootWindowController as possible.
453 stacking_controller_.reset(new internal::StackingController);
454 visibility_controller_.reset(new internal::VisibilityController);
455 drag_drop_controller_.reset(new internal::DragDropController);
456 user_action_client_.reset(delegate_->CreateUserActionClient());
457 window_modality_controller_.reset(new internal::WindowModalityController);
458 AddEnvEventFilter(window_modality_controller_.get());
460 magnification_controller_.reset(
461 internal::MagnificationController::CreateInstance());
463 high_contrast_controller_.reset(new HighContrastController);
464 video_detector_.reset(new VideoDetector);
465 window_cycle_controller_.reset(
466 new WindowCycleController(activation_controller_.get()));
468 tooltip_controller_.reset(new internal::TooltipController(
469 drag_drop_controller_.get()));
470 AddEnvEventFilter(tooltip_controller_.get());
472 event_client_.reset(new internal::EventClientImpl);
474 InitRootWindowController(root_window_controller);
476 // This controller needs to be set before SetupManagedWindowMode.
477 desktop_background_controller_.reset(new DesktopBackgroundController());
478 user_wallpaper_delegate_.reset(delegate_->CreateUserWallpaperDelegate());
479 if (!user_wallpaper_delegate_.get())
480 user_wallpaper_delegate_.reset(new DummyUserWallpaperDelegate());
482 // StatusAreaWidget uses Shell's CapsLockDelegate.
483 caps_lock_delegate_.reset(delegate_->CreateCapsLockDelegate());
485 if (!command_line->HasSwitch(switches::kAuraNoShadows)) {
486 resize_shadow_controller_.reset(new internal::ResizeShadowController());
487 shadow_controller_.reset(new internal::ShadowController());
490 // Initialize system_tray_delegate_ before initializing StatusAreaWidget.
491 system_tray_delegate_.reset(delegate()->CreateSystemTrayDelegate());
492 if (!system_tray_delegate_.get())
493 system_tray_delegate_.reset(SystemTrayDelegate::CreateDummyDelegate());
495 // Creates StatusAreaWidget.
496 root_window_controller->InitForPrimaryDisplay();
498 // Initialize system_tray_delegate_ after StatusAreaWidget is created.
499 system_tray_delegate_->Initialize();
501 display_controller_->InitSecondaryDisplays();
503 // Force Layout
504 root_window_controller->root_window_layout()->OnWindowResized();
506 // It needs to be created after OnWindowResized has been called, otherwise the
507 // widget will not paint when restoring after a browser crash. Also it needs
508 // to be created after InitSecondaryDisplays() to initialize the wallpapers in
509 // the correct size.
510 user_wallpaper_delegate_->InitializeWallpaper();
512 if (command_line->HasSwitch(ash::switches::kAshNewLockAnimationsEnabled))
513 session_state_controller_.reset(new SessionStateControllerImpl2);
514 else
515 session_state_controller_.reset(new SessionStateControllerImpl);
516 power_button_controller_.reset(new PowerButtonController(
517 session_state_controller_.get()));
518 AddShellObserver(session_state_controller_.get());
520 if (initially_hide_cursor_)
521 cursor_manager_.ShowCursor(false);
523 // Cursor might have been hidden by somethign other than chrome.
524 // Let the first mouse event show the cursor.
525 env_filter_->set_cursor_hidden_by_filter(true);
528 void Shell::AddEnvEventFilter(aura::EventFilter* filter) {
529 AddPreTargetHandler(filter);
532 void Shell::RemoveEnvEventFilter(aura::EventFilter* filter) {
533 RemovePreTargetHandler(filter);
536 void Shell::ShowContextMenu(const gfx::Point& location_in_screen) {
537 // No context menus if user have not logged in.
538 if (!delegate_->IsUserLoggedIn())
539 return;
540 // No context menus when screen is locked.
541 if (IsScreenLocked())
542 return;
544 aura::RootWindow* root =
545 wm::GetRootWindowMatching(gfx::Rect(location_in_screen, gfx::Size()));
546 GetRootWindowController(root)->ShowContextMenu(location_in_screen);
549 void Shell::ToggleAppList() {
550 if (!app_list_controller_.get())
551 app_list_controller_.reset(new internal::AppListController);
552 app_list_controller_->SetVisible(!app_list_controller_->IsVisible());
555 bool Shell::GetAppListTargetVisibility() const {
556 return app_list_controller_.get() &&
557 app_list_controller_->GetTargetVisibility();
560 aura::Window* Shell::GetAppListWindow() {
561 return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL;
564 bool Shell::IsScreenLocked() const {
565 return delegate_->IsScreenLocked();
568 bool Shell::IsModalWindowOpen() const {
569 if (simulate_modal_window_open_for_testing_)
570 return true;
571 const std::vector<aura::Window*> containers = GetAllContainers(
572 internal::kShellWindowId_SystemModalContainer);
573 for (std::vector<aura::Window*>::const_iterator cit = containers.begin();
574 cit != containers.end(); ++cit) {
575 for (aura::Window::Windows::const_iterator wit = (*cit)->children().begin();
576 wit != (*cit)->children().end(); ++wit) {
577 if ((*wit)->GetProperty(aura::client::kModalKey) ==
578 ui::MODAL_TYPE_SYSTEM && (*wit)->TargetVisibility()) {
579 return true;
583 return false;
586 views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView(
587 views::Widget* widget) {
588 if (CommandLine::ForCurrentProcess()->HasSwitch(
589 switches::kAuraGoogleDialogFrames)) {
590 return new internal::DialogFrameView;
592 // Use translucent-style window frames for dialogs.
593 CustomFrameViewAsh* frame_view = new CustomFrameViewAsh;
594 frame_view->Init(widget);
595 return frame_view;
598 void Shell::RotateFocus(Direction direction) {
599 focus_cycler_->RotateFocus(
600 direction == FORWARD ? internal::FocusCycler::FORWARD :
601 internal::FocusCycler::BACKWARD);
604 void Shell::SetDisplayWorkAreaInsets(Window* contains,
605 const gfx::Insets& insets) {
606 internal::MultiDisplayManager* display_manager =
607 static_cast<internal::MultiDisplayManager*>(
608 aura::Env::GetInstance()->display_manager());
609 if (!display_manager->UpdateWorkAreaOfDisplayNearestWindow(contains, insets))
610 return;
611 FOR_EACH_OBSERVER(ShellObserver, observers_,
612 OnDisplayWorkAreaInsetsChanged());
615 void Shell::OnLoginStateChanged(user::LoginStatus status) {
616 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLoginStateChanged(status));
617 RootWindowControllerList controllers = GetAllRootWindowControllers();
618 for (RootWindowControllerList::iterator iter = controllers.begin();
619 iter != controllers.end(); ++iter)
620 (*iter)->OnLoginStateChanged(status);
623 void Shell::UpdateAfterLoginStatusChange(user::LoginStatus status) {
624 RootWindowControllerList controllers = GetAllRootWindowControllers();
625 for (RootWindowControllerList::iterator iter = controllers.begin();
626 iter != controllers.end(); ++iter)
627 (*iter)->UpdateAfterLoginStatusChange(status);
630 void Shell::OnAppTerminating() {
631 FOR_EACH_OBSERVER(ShellObserver, observers_, OnAppTerminating());
634 void Shell::OnLockStateChanged(bool locked) {
635 FOR_EACH_OBSERVER(ShellObserver, observers_, OnLockStateChanged(locked));
638 void Shell::CreateLauncher() {
639 GetPrimaryRootWindowController()->CreateLauncher();
642 void Shell::ShowLauncher() {
643 GetPrimaryRootWindowController()->ShowLauncher();
646 void Shell::AddShellObserver(ShellObserver* observer) {
647 observers_.AddObserver(observer);
650 void Shell::RemoveShellObserver(ShellObserver* observer) {
651 observers_.RemoveObserver(observer);
654 void Shell::UpdateShelfVisibility() {
655 RootWindowControllerList controllers = GetAllRootWindowControllers();
656 for (RootWindowControllerList::iterator iter = controllers.begin();
657 iter != controllers.end(); ++iter)
658 if ((*iter)->shelf())
659 (*iter)->UpdateShelfVisibility();
662 void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior,
663 aura::RootWindow* root_window) {
664 GetRootWindowController(root_window)->SetShelfAutoHideBehavior(behavior);
667 ShelfAutoHideBehavior Shell::GetShelfAutoHideBehavior(
668 aura::RootWindow* root_window) const {
669 return GetRootWindowController(root_window)->GetShelfAutoHideBehavior();
672 bool Shell::IsShelfAutoHideMenuHideChecked(aura::RootWindow* root_window) {
673 return GetRootWindowController(root_window)->GetShelfAutoHideBehavior() ==
674 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
677 ShelfAutoHideBehavior Shell::GetToggledShelfAutoHideBehavior(
678 aura::RootWindow* root_window) {
679 return GetRootWindowController(root_window)->
680 GetToggledShelfAutoHideBehavior();
683 void Shell::SetShelfAlignment(ShelfAlignment alignment,
684 aura::RootWindow* root_window) {
685 if (GetRootWindowController(root_window)->SetShelfAlignment(alignment))
686 FOR_EACH_OBSERVER(ShellObserver, observers_, OnShelfAlignmentChanged());
689 ShelfAlignment Shell::GetShelfAlignment(aura::RootWindow* root_window) {
690 return GetRootWindowController(root_window)->GetShelfAlignment();
693 void Shell::SetDimming(bool should_dim) {
694 RootWindowControllerList controllers = GetAllRootWindowControllers();
695 for (RootWindowControllerList::iterator iter = controllers.begin();
696 iter != controllers.end(); ++iter)
697 (*iter)->screen_dimmer()->SetDimming(should_dim);
700 void Shell::CreateModalBackground(aura::Window* window) {
701 if (!modality_filter_.get()) {
702 modality_filter_.reset(new internal::SystemModalContainerEventFilter(this));
703 AddEnvEventFilter(modality_filter_.get());
705 RootWindowControllerList controllers = GetAllRootWindowControllers();
706 for (RootWindowControllerList::iterator iter = controllers.begin();
707 iter != controllers.end(); ++iter)
708 (*iter)->GetSystemModalLayoutManager(window)->CreateModalBackground();
711 void Shell::OnModalWindowRemoved(aura::Window* removed) {
712 RootWindowControllerList controllers = GetAllRootWindowControllers();
713 bool activated = false;
714 for (RootWindowControllerList::iterator iter = controllers.begin();
715 iter != controllers.end() && !activated; ++iter) {
716 activated = (*iter)->GetSystemModalLayoutManager(removed)->
717 ActivateNextModalWindow();
719 if (!activated) {
720 RemoveEnvEventFilter(modality_filter_.get());
721 modality_filter_.reset();
722 for (RootWindowControllerList::iterator iter = controllers.begin();
723 iter != controllers.end(); ++iter)
724 (*iter)->GetSystemModalLayoutManager(removed)->DestroyModalBackground();
728 WebNotificationTray* Shell::GetWebNotificationTray() {
729 return GetPrimaryRootWindowController()->status_area_widget()->
730 web_notification_tray();
733 internal::StatusAreaWidget* Shell::status_area_widget() {
734 return GetPrimaryRootWindowController()->status_area_widget();
737 SystemTray* Shell::system_tray() {
738 // We assume in throughout the code that this will not return NULL. If code
739 // triggers this for valid reasons, it should test status_area_widget first.
740 internal::StatusAreaWidget* status_area = status_area_widget();
741 CHECK(status_area);
742 return status_area->system_tray();
745 void Shell::InitRootWindowForSecondaryDisplay(aura::RootWindow* root) {
746 root->set_focus_manager(focus_manager_.get());
747 internal::RootWindowController* controller =
748 new internal::RootWindowController(root);
749 controller->CreateContainers();
750 InitRootWindowController(controller);
751 if (IsLauncherPerDisplayEnabled())
752 controller->InitForPrimaryDisplay();
753 controller->root_window_layout()->OnWindowResized();
754 desktop_background_controller_->OnRootWindowAdded(root);
755 high_contrast_controller_->OnRootWindowAdded(root);
756 root->ShowRootWindow();
757 // Activate new root for testing.
758 active_root_window_ = root;
761 void Shell::DoInitialWorkspaceAnimation() {
762 return GetPrimaryRootWindowController()->workspace_controller()->
763 DoInitialAnimation();
766 void Shell::InitRootWindowController(
767 internal::RootWindowController* controller) {
768 aura::RootWindow* root_window = controller->root_window();
769 DCHECK(activation_controller_.get());
770 DCHECK(visibility_controller_.get());
771 DCHECK(drag_drop_controller_.get());
772 DCHECK(capture_controller_.get());
773 DCHECK(window_cycle_controller_.get());
775 root_window->set_focus_manager(focus_manager_.get());
776 input_method_filter_->SetInputMethodPropertyInRootWindow(root_window);
777 aura::client::SetActivationClient(root_window, activation_controller_.get());
778 aura::client::SetVisibilityClient(root_window, visibility_controller_.get());
779 aura::client::SetDragDropClient(root_window, drag_drop_controller_.get());
780 aura::client::SetCaptureClient(root_window, capture_controller_.get());
781 aura::client::SetScreenPositionClient(root_window,
782 screen_position_controller_.get());
783 aura::client::SetCursorClient(root_window, &cursor_manager_);
784 aura::client::SetTooltipClient(root_window, tooltip_controller_.get());
785 aura::client::SetEventClient(root_window, event_client_.get());
787 if (nested_dispatcher_controller_.get()) {
788 aura::client::SetDispatcherClient(root_window,
789 nested_dispatcher_controller_.get());
791 if (user_action_client_.get())
792 aura::client::SetUserActionClient(root_window, user_action_client_.get());
794 root_window->SetCursor(ui::kCursorPointer);
795 controller->InitLayoutManagers();
797 // TODO(oshima): Move the instance to RootWindowController when
798 // the extended desktop is enabled by default.
799 internal::AlwaysOnTopController* always_on_top_controller =
800 new internal::AlwaysOnTopController;
801 always_on_top_controller->SetAlwaysOnTopContainer(
802 root_window->GetChildById(internal::kShellWindowId_AlwaysOnTopContainer));
803 root_window->SetProperty(internal::kAlwaysOnTopControllerKey,
804 always_on_top_controller);
805 if (GetPrimaryRootWindowController()->GetSystemModalLayoutManager(NULL)->
806 has_modal_background()) {
807 controller->GetSystemModalLayoutManager(NULL)->CreateModalBackground();
810 window_cycle_controller_->OnRootWindowAdded(root_window);
813 ////////////////////////////////////////////////////////////////////////////////
814 // Shell, private:
816 bool Shell::CanWindowReceiveEvents(aura::Window* window) {
817 RootWindowControllerList controllers = GetAllRootWindowControllers();
818 for (RootWindowControllerList::iterator iter = controllers.begin();
819 iter != controllers.end(); ++iter) {
820 if ((*iter)->GetSystemModalLayoutManager(window)->
821 CanWindowReceiveEvents(window)) {
822 return true;
825 return false;
828 bool Shell::CanAcceptEvents() {
829 return true;
832 ui::EventTarget* Shell::GetParentTarget() {
833 return NULL;
836 } // namespace ash