| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/shell.h" |
| |
| #include <algorithm> |
| #include <iterator> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "ash/accelerators/accelerator_controller_impl.h" |
| #include "ash/accelerators/accelerator_prefs.h" |
| #include "ash/accelerators/accelerator_tracker.h" |
| #include "ash/accelerators/ash_accelerator_configuration.h" |
| #include "ash/accelerators/ash_focus_manager_factory.h" |
| #include "ash/accelerators/magnifier_key_scroller.h" |
| #include "ash/accelerators/pre_target_accelerator_handler.h" |
| #include "ash/accelerators/shortcut_input_handler.h" |
| #include "ash/accelerators/spoken_feedback_toggler.h" |
| #include "ash/accelerometer/accelerometer_reader.h" |
| #include "ash/accessibility/accessibility_controller_impl.h" |
| #include "ash/accessibility/accessibility_delegate.h" |
| #include "ash/accessibility/autoclick/autoclick_controller.h" |
| #include "ash/accessibility/chromevox/key_accessibility_enabler.h" |
| #include "ash/accessibility/magnifier/docked_magnifier_controller.h" |
| #include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h" |
| #include "ash/accessibility/magnifier/partial_magnifier_controller.h" |
| #include "ash/accessibility/sticky_keys/sticky_keys_controller.h" |
| #include "ash/accessibility/ui/accessibility_focus_ring_controller_impl.h" |
| #include "ash/ambient/ambient_controller.h" |
| #include "ash/api/tasks/tasks_controller.h" |
| #include "ash/api/tasks/tasks_delegate.h" |
| #include "ash/app_list/app_list_controller_impl.h" |
| #include "ash/app_list/app_list_feature_usage_metrics.h" |
| #include "ash/assistant/assistant_controller_impl.h" |
| #include "ash/booting/booting_animation_controller.h" |
| #include "ash/calendar/calendar_controller.h" |
| #include "ash/capture_mode/capture_mode_controller.h" |
| #include "ash/child_accounts/parent_access_controller_impl.h" |
| #include "ash/clipboard/clipboard_history_controller_delegate.h" |
| #include "ash/clipboard/clipboard_history_controller_impl.h" |
| #include "ash/clipboard/clipboard_history_util.h" |
| #include "ash/clipboard/control_v_histogram_recorder.h" |
| #include "ash/color_enhancement/color_enhancement_controller.h" |
| #include "ash/constants/ash_features.h" |
| #include "ash/constants/ash_switches.h" |
| #include "ash/controls/contextual_tooltip.h" |
| #include "ash/curtain/security_curtain_controller_impl.h" |
| #include "ash/dbus/ash_dbus_services.h" |
| #include "ash/detachable_base/detachable_base_handler.h" |
| #include "ash/detachable_base/detachable_base_notification_controller.h" |
| #include "ash/display/cros_display_config.h" |
| #include "ash/display/cursor_window_controller.h" |
| #include "ash/display/display_alignment_controller.h" |
| #include "ash/display/display_color_manager.h" |
| #include "ash/display/display_configuration_controller.h" |
| #include "ash/display/display_configuration_observer.h" |
| #include "ash/display/display_error_observer.h" |
| #include "ash/display/display_highlight_controller.h" |
| #include "ash/display/display_prefs.h" |
| #include "ash/display/display_shutdown_observer.h" |
| #include "ash/display/event_transformation_handler.h" |
| #include "ash/display/mouse_cursor_event_filter.h" |
| #include "ash/display/privacy_screen_controller.h" |
| #include "ash/display/projecting_observer.h" |
| #include "ash/display/resolution_notification_controller.h" |
| #include "ash/display/screen_ash.h" |
| #include "ash/display/screen_orientation_controller.h" |
| #include "ash/display/screen_position_controller.h" |
| #include "ash/display/window_tree_host_manager.h" |
| #include "ash/drag_drop/drag_drop_controller.h" |
| #include "ash/events/event_rewriter_controller_impl.h" |
| #include "ash/fast_ink/laser/laser_pointer_controller.h" |
| #include "ash/focus_cycler.h" |
| #include "ash/frame/non_client_frame_view_ash.h" |
| #include "ash/frame/snap_controller_impl.h" |
| #include "ash/frame_throttler/frame_throttling_controller.h" |
| #include "ash/game_dashboard/game_dashboard_controller.h" |
| #include "ash/glanceables/glanceables_controller.h" |
| #include "ash/glanceables/post_login_glanceables_metrics_recorder.h" |
| #include "ash/host/ash_window_tree_host_init_params.h" |
| #include "ash/hud_display/hud_display.h" |
| #include "ash/ime/ime_controller_impl.h" |
| #include "ash/in_session_auth/in_session_auth_dialog_controller_impl.h" |
| #include "ash/in_session_auth/webauthn_dialog_controller_impl.h" |
| #include "ash/keyboard/keyboard_controller_impl.h" |
| #include "ash/keyboard/ui/keyboard_ui_factory.h" |
| #include "ash/login/login_screen_controller.h" |
| #include "ash/login/ui/local_authentication_request_controller_impl.h" |
| #include "ash/login_status.h" |
| #include "ash/media/media_controller_impl.h" |
| #include "ash/metrics/feature_discovery_duration_reporter_impl.h" |
| #include "ash/metrics/login_unlock_throughput_recorder.h" |
| #include "ash/metrics/user_metrics_recorder.h" |
| #include "ash/multi_capture/multi_capture_service_client.h" |
| #include "ash/multi_device_setup/multi_device_notification_presenter.h" |
| #include "ash/picker/picker_controller.h" |
| #include "ash/policy/policy_recommendation_restorer.h" |
| #include "ash/projector/projector_controller_impl.h" |
| #include "ash/public/cpp/accelerator_keycode_lookup_cache.h" |
| #include "ash/public/cpp/ash_prefs.h" |
| #include "ash/public/cpp/holding_space/holding_space_controller.h" |
| #include "ash/public/cpp/login/local_authentication_request_controller.h" |
| #include "ash/public/cpp/nearby_share_delegate.h" |
| #include "ash/public/cpp/saved_desk_delegate.h" |
| #include "ash/public/cpp/shelf_config.h" |
| #include "ash/public/cpp/shelf_model.h" |
| #include "ash/public/cpp/shell_window_ids.h" |
| #include "ash/public/cpp/system_sounds_delegate.h" |
| #include "ash/public/cpp/tab_cluster/tab_cluster_ui_controller.h" |
| #include "ash/public/cpp/views_text_services_context_menu_ash.h" |
| #include "ash/quick_pair/keyed_service/quick_pair_mediator.h" |
| #include "ash/rgb_keyboard/rgb_keyboard_manager.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/session/session_controller_impl.h" |
| #include "ash/shelf/shelf_controller.h" |
| #include "ash/shelf/shelf_window_watcher.h" |
| #include "ash/shell_delegate.h" |
| #include "ash/shell_init_params.h" |
| #include "ash/shell_observer.h" |
| #include "ash/shell_tab_handler.h" |
| #include "ash/shutdown_controller_impl.h" |
| #include "ash/style/ash_color_mixer.h" |
| #include "ash/style/ash_color_provider.h" |
| #include "ash/style/color_palette_controller.h" |
| #include "ash/style/dark_light_mode_controller_impl.h" |
| #include "ash/style/style_util.h" |
| #include "ash/system/audio/audio_effects_controller.h" |
| #include "ash/system/audio/display_speaker_controller.h" |
| #include "ash/system/bluetooth/bluetooth_device_status_ui_handler.h" |
| #include "ash/system/bluetooth/bluetooth_notification_controller.h" |
| #include "ash/system/bluetooth/bluetooth_state_cache.h" |
| #include "ash/system/brightness/brightness_controller_chromeos.h" |
| #include "ash/system/brightness_control_delegate.h" |
| #include "ash/system/camera/autozoom_controller_impl.h" |
| #include "ash/system/camera/camera_effects_controller.h" |
| #include "ash/system/caps_lock_notification_controller.h" |
| #include "ash/system/diagnostics/diagnostics_log_controller.h" |
| #include "ash/system/federated/federated_service_controller_impl.h" |
| #include "ash/system/firmware_update/firmware_update_notification_controller.h" |
| #include "ash/system/focus_mode/focus_mode_controller.h" |
| #include "ash/system/geolocation/geolocation_controller.h" |
| #include "ash/system/hotspot/hotspot_icon_animation.h" |
| #include "ash/system/hotspot/hotspot_info_cache.h" |
| #include "ash/system/human_presence/human_presence_orientation_controller.h" |
| #include "ash/system/human_presence/snooping_protection_controller.h" |
| #include "ash/system/input_device_settings/input_device_key_alias_manager.h" |
| #include "ash/system/input_device_settings/input_device_settings_controller_impl.h" |
| #include "ash/system/input_device_settings/input_device_settings_dispatcher.h" |
| #include "ash/system/input_device_settings/input_device_tracker.h" |
| #include "ash/system/input_device_settings/keyboard_modifier_metrics_recorder.h" |
| #include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h" |
| #include "ash/system/keyboard_brightness/keyboard_brightness_controller.h" |
| #include "ash/system/keyboard_brightness_control_delegate.h" |
| #include "ash/system/locale/locale_update_controller_impl.h" |
| #include "ash/system/media/media_notification_provider.h" |
| #include "ash/system/message_center/message_center_ash_impl.h" |
| #include "ash/system/message_center/message_center_controller.h" |
| #include "ash/system/model/system_tray_model.h" |
| #include "ash/system/model/virtual_keyboard_model.h" |
| #include "ash/system/nearby_share/nearby_share_controller_impl.h" |
| #include "ash/system/network/sms_observer.h" |
| #include "ash/system/night_light/night_light_controller_impl.h" |
| #include "ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h" |
| #include "ash/system/power/adaptive_charging_controller.h" |
| #include "ash/system/power/backlights_forced_off_setter.h" |
| #include "ash/system/power/battery_saver_controller.h" |
| #include "ash/system/power/peripheral_battery_notifier.h" |
| #include "ash/system/power/power_button_controller.h" |
| #include "ash/system/power/power_event_observer.h" |
| #include "ash/system/power/power_prefs.h" |
| #include "ash/system/power/power_status.h" |
| #include "ash/system/power/video_activity_notifier.h" |
| #include "ash/system/privacy/screen_switch_check_controller.h" |
| #include "ash/system/privacy_hub/privacy_hub_controller.h" |
| #include "ash/system/screen_layout_observer.h" |
| #include "ash/system/session/logout_confirmation_controller.h" |
| #include "ash/system/status_area_widget.h" |
| #include "ash/system/system_notification_controller.h" |
| #include "ash/system/toast/anchored_nudge_manager_impl.h" |
| #include "ash/system/toast/system_nudge_pause_manager_impl.h" |
| #include "ash/system/toast/toast_manager_impl.h" |
| #include "ash/system/tray/system_tray_notifier.h" |
| #include "ash/system/usb_peripheral/usb_peripheral_notification_controller.h" |
| #include "ash/system/video_conference/fake_video_conference_tray_controller.h" |
| #include "ash/touch/ash_touch_transform_controller.h" |
| #include "ash/touch/touch_devices_controller.h" |
| #include "ash/tray_action/tray_action.h" |
| #include "ash/user_education/user_education_controller.h" |
| #include "ash/user_education/user_education_delegate.h" |
| #include "ash/utility/occlusion_tracker_pauser.h" |
| #include "ash/wallpaper/wallpaper_controller_impl.h" |
| #include "ash/wm/ash_focus_rules.h" |
| #include "ash/wm/bounds_tracker/window_bounds_tracker.h" |
| #include "ash/wm/container_finder.h" |
| #include "ash/wm/coral/coral_controller.h" |
| #include "ash/wm/cursor_manager_chromeos.h" |
| #include "ash/wm/desks/desks_controller.h" |
| #include "ash/wm/desks/templates/saved_desk_controller.h" |
| #include "ash/wm/event_client_impl.h" |
| #include "ash/wm/float/float_controller.h" |
| #include "ash/wm/gestures/back_gesture/back_gesture_event_handler.h" |
| #include "ash/wm/immersive_context_ash.h" |
| #include "ash/wm/lock_state_controller.h" |
| #include "ash/wm/mru_window_tracker.h" |
| #include "ash/wm/multi_display/multi_display_metrics_controller.h" |
| #include "ash/wm/multi_display/persistent_window_controller.h" |
| #include "ash/frame/multitask_menu_nudge_delegate_ash.h" |
| #include "ash/wm/native_cursor_manager_ash.h" |
| #include "ash/wm/overview/overview_controller.h" |
| #include "ash/wm/pip/pip_controller.h" |
| #include "ash/wm/raster_scale/raster_scale_controller.h" |
| #include "ash/wm/resize_shadow_controller.h" |
| #include "ash/wm/screen_pinning_controller.h" |
| #include "ash/wm/snap_group/snap_group_controller.h" |
| #include "ash/wm/system_gesture_event_filter.h" |
| #include "ash/wm/system_modal_container_event_filter.h" |
| #include "ash/wm/system_modal_container_layout_manager.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller.h" |
| #include "ash/wm/tablet_mode/tablet_mode_window_manager.h" |
| #include "ash/wm/toplevel_window_event_handler.h" |
| #include "ash/wm/video_detector.h" |
| #include "ash/wm/window_animations.h" |
| #include "ash/wm/window_cycle/window_cycle_controller.h" |
| #include "ash/wm/window_properties.h" |
| #include "ash/wm/window_restore/window_restore_controller.h" |
| #include "ash/wm/window_util.h" |
| #include "ash/wm/wm_shadow_controller_delegate.h" |
| #include "ash/wm/workspace_controller.h" |
| #include "ash/wm_mode/wm_mode_controller.h" |
| #include "base/check.h" |
| #include "base/command_line.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/notreached.h" |
| #include "base/ranges/algorithm.h" |
| #include "base/system/sys_info.h" |
| #include "base/trace_event/trace_event.h" |
| #include "chromeos/ash/components/dbus/fwupd/fwupd_client.h" |
| #include "chromeos/ash/components/dbus/typecd/typecd_client.h" |
| #include "chromeos/ash/components/dbus/usb/usbguard_client.h" |
| #include "chromeos/ash/components/fwupd/firmware_update_manager.h" |
| #include "chromeos/ash/components/peripheral_notification/peripheral_notification_manager.h" |
| #include "chromeos/ash/services/assistant/public/cpp/features.h" |
| #include "chromeos/dbus/init/initialize_dbus_client.h" |
| #include "chromeos/dbus/power/power_policy_controller.h" |
| #include "chromeos/ui/clipboard_history/clipboard_history_util.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/viz/host/host_frame_sink_manager.h" |
| #include "dbus/bus.h" |
| #include "media/capture/video/chromeos/video_capture_features_chromeos.h" |
| #include "services/video_capture/public/mojom/multi_capture_service.mojom.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/env.h" |
| #include "ui/aura/layout_manager.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_event_dispatcher.h" |
| #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" |
| #include "ui/base/ui_base_features.h" |
| #include "ui/base/user_activity/user_activity_detector.h" |
| #include "ui/chromeos/user_activity_power_manager_notifier.h" |
| #include "ui/color/color_provider_manager.h" |
| #include "ui/compositor/layer.h" |
| #include "ui/compositor/layer_animator.h" |
| #include "ui/display/display.h" |
| #include "ui/display/manager/default_touch_transform_setter.h" |
| #include "ui/display/manager/display_change_observer.h" |
| #include "ui/display/manager/display_configurator.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/manager/display_port_observer.h" |
| #include "ui/display/manager/touch_transform_setter.h" |
| #include "ui/display/screen.h" |
| #include "ui/display/types/native_display_delegate.h" |
| #include "ui/events/ash/keyboard_capability.h" |
| #include "ui/events/event_target_iterator.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/message_center/message_center.h" |
| #include "ui/ozone/public/ozone_platform.h" |
| #include "ui/views/controls/views_text_services_context_menu_chromeos.h" |
| #include "ui/views/corewm/tooltip_aura.h" |
| #include "ui/views/corewm/tooltip_controller.h" |
| #include "ui/views/focus/focus_manager_factory.h" |
| #include "ui/views/widget/native_widget_aura.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/wm/core/accelerator_filter.h" |
| #include "ui/wm/core/capture_controller.h" |
| #include "ui/wm/core/compound_event_filter.h" |
| #include "ui/wm/core/focus_controller.h" |
| #include "ui/wm/core/shadow_controller.h" |
| #include "ui/wm/core/visibility_controller.h" |
| #include "ui/wm/core/window_modality_controller.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| using aura::Window; |
| using views::Widget; |
| |
| // A Corewm VisibilityController subclass that calls the Ash animation routine |
| // so we can pick up our extended animations. See ash/wm/window_animations.h. |
| class AshVisibilityController : public ::wm::VisibilityController { |
| public: |
| AshVisibilityController() = default; |
| |
| AshVisibilityController(const AshVisibilityController&) = delete; |
| AshVisibilityController& operator=(const AshVisibilityController&) = delete; |
| |
| ~AshVisibilityController() override = default; |
| |
| private: |
| // Overridden from ::wm::VisibilityController: |
| bool CallAnimateOnChildWindowVisibilityChanged(aura::Window* window, |
| bool visible) override { |
| return AnimateOnChildWindowVisibilityChanged(window, visible); |
| } |
| }; |
| |
| } // namespace |
| |
| // static |
| Shell* Shell::instance_ = nullptr; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Shell, public: |
| |
| // static |
| Shell* Shell::CreateInstance(ShellInitParams init_params) { |
| CHECK(!instance_); |
| instance_ = new Shell(std::move(init_params.delegate)); |
| instance_->Init(init_params.context_factory, init_params.local_state, |
| std::move(init_params.keyboard_ui_factory), |
| std::move(init_params.quick_pair_mediator_factory), |
| init_params.dbus_bus, |
| std::move(init_params.native_display_delegate)); |
| return instance_; |
| } |
| |
| // static |
| Shell* Shell::Get() { |
| CHECK(instance_); |
| return instance_; |
| } |
| |
| // static |
| bool Shell::HasInstance() { |
| return !!instance_; |
| } |
| |
| // static |
| void Shell::DeleteInstance() { |
| delete instance_; |
| } |
| |
| // static |
| RootWindowController* Shell::GetPrimaryRootWindowController() { |
| CHECK(HasInstance()); |
| return RootWindowController::ForWindow(GetPrimaryRootWindow()); |
| } |
| |
| // static |
| Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() { |
| CHECK(HasInstance()); |
| RootWindowControllerList root_window_controllers; |
| for (aura::Window* root : GetAllRootWindows()) { |
| root_window_controllers.push_back(RootWindowController::ForWindow(root)); |
| } |
| return root_window_controllers; |
| } |
| |
| // static |
| RootWindowController* Shell::GetRootWindowControllerWithDisplayId( |
| int64_t display_id) { |
| CHECK(HasInstance()); |
| aura::Window* root = GetRootWindowForDisplayId(display_id); |
| return root ? RootWindowController::ForWindow(root) : nullptr; |
| } |
| |
| // static |
| aura::Window* Shell::GetRootWindowForDisplayId(int64_t display_id) { |
| CHECK(HasInstance()); |
| return instance_->window_tree_host_manager_->GetRootWindowForDisplayId( |
| display_id); |
| } |
| |
| // static |
| aura::Window* Shell::GetPrimaryRootWindow() { |
| CHECK(HasInstance()); |
| return instance_->window_tree_host_manager_->GetPrimaryRootWindow(); |
| } |
| |
| // static |
| void Shell::SetRootWindowForNewWindows(aura::Window* root) { |
| display::Screen::GetScreen()->SetDisplayForNewWindows( |
| display::Screen::GetScreen()->GetDisplayNearestWindow(root).id()); |
| } |
| |
| // static |
| aura::Window* Shell::GetRootWindowForNewWindows() { |
| return GetRootWindowForDisplayId( |
| display::Screen::GetScreen()->GetDisplayForNewWindows().id()); |
| } |
| |
| // static |
| aura::Window::Windows Shell::GetAllRootWindows() { |
| CHECK(HasInstance()); |
| return instance_->window_tree_host_manager_->GetAllRootWindows(); |
| } |
| |
| // static |
| aura::Window* Shell::GetContainer(aura::Window* root_window, int container_id) { |
| return root_window->GetChildById(container_id); |
| } |
| |
| // static |
| const aura::Window* Shell::GetContainer(const aura::Window* root_window, |
| int container_id) { |
| return root_window->GetChildById(container_id); |
| } |
| |
| // static |
| int Shell::GetOpenSystemModalWindowContainerId() { |
| // The test boolean is not static to avoid leaking state between tests. |
| if (Get()->simulate_modal_window_open_for_test_) { |
| return kShellWindowId_SystemModalContainer; |
| } |
| |
| // Traverse all system modal containers, and find its direct child window |
| // with "SystemModal" setting, and visible. |
| for (aura::Window* root : Shell::GetAllRootWindows()) { |
| for (int modal_window_id : kSystemModalContainerIds) { |
| aura::Window* system_modal = root->GetChildById(modal_window_id); |
| if (!system_modal) { |
| continue; |
| } |
| for (const aura::Window* child : system_modal->children()) { |
| if (child->GetProperty(aura::client::kModalKey) == |
| ui::MODAL_TYPE_SYSTEM && |
| child->layer()->GetTargetVisibility()) { |
| return modal_window_id; |
| } |
| } |
| } |
| } |
| return -1; |
| } |
| |
| // static |
| bool Shell::IsSystemModalWindowOpen() { |
| return GetOpenSystemModalWindowContainerId() >= 0; |
| } |
| |
| display::DisplayConfigurator* Shell::display_configurator() { |
| return display_manager_->configurator(); |
| } |
| |
| void Shell::TrackInputMethodBounds(ArcInputMethodBoundsTracker* tracker) { |
| system_tray_model()->virtual_keyboard()->SetInputMethodBoundsTrackerObserver( |
| tracker); |
| } |
| |
| void Shell::UntrackTrackInputMethodBounds( |
| ArcInputMethodBoundsTracker* tracker) { |
| system_tray_model() |
| ->virtual_keyboard() |
| ->RemoveInputMethodBoundsTrackerObserver(tracker); |
| } |
| |
| std::unique_ptr<views::NonClientFrameView> |
| Shell::CreateDefaultNonClientFrameView(views::Widget* widget) { |
| // Use translucent-style window frames for dialogs. |
| return std::make_unique<NonClientFrameViewAsh>(widget); |
| } |
| |
| void Shell::OnCastingSessionStartedOrStopped(bool started) { |
| for (auto& observer : shell_observers_) { |
| observer.OnCastingSessionStartedOrStopped(started); |
| } |
| } |
| |
| void Shell::OnRootWindowAdded(aura::Window* root_window) { |
| for (auto& observer : shell_observers_) { |
| observer.OnRootWindowAdded(root_window); |
| } |
| } |
| |
| void Shell::OnRootWindowWillShutdown(aura::Window* root_window) { |
| DCHECK(toplevel_window_event_handler_); |
| root_window->RemovePreTargetHandler(toplevel_window_event_handler_.get()); |
| root_window->RemovePostTargetHandler(toplevel_window_event_handler_.get()); |
| |
| for (auto& observer : shell_observers_) { |
| observer.OnRootWindowWillShutdown(root_window); |
| } |
| } |
| |
| void Shell::OnDictationStarted() { |
| for (auto& observer : shell_observers_) { |
| observer.OnDictationStarted(); |
| } |
| } |
| |
| void Shell::OnDictationEnded() { |
| for (auto& observer : shell_observers_) { |
| observer.OnDictationEnded(); |
| } |
| } |
| |
| bool Shell::IsInTabletMode() const { |
| return display::Screen::GetScreen()->InTabletMode(); |
| } |
| |
| bool Shell::ShouldSaveDisplaySettings() { |
| return !( |
| screen_orientation_controller_->ignore_display_configuration_updates() || |
| // Save display settings if we don't need to show the display change |
| // dialog. |
| resolution_notification_controller_->ShouldShowDisplayChangeDialog()); |
| } |
| |
| ::wm::ActivationClient* Shell::activation_client() { |
| return focus_controller_.get(); |
| } |
| |
| bool Shell::HasPrimaryStatusArea() { |
| return !!GetPrimaryRootWindowController()->GetStatusAreaWidget(); |
| } |
| |
| void Shell::SetLargeCursorSizeInDip(int large_cursor_size_in_dip) { |
| window_tree_host_manager_->cursor_window_controller() |
| ->SetLargeCursorSizeInDip(large_cursor_size_in_dip); |
| } |
| |
| void Shell::SetCursorColor(SkColor cursor_color) { |
| window_tree_host_manager_->cursor_window_controller()->SetCursorColor( |
| cursor_color); |
| } |
| |
| void Shell::UpdateCursorCompositingEnabled() { |
| SetCursorCompositingEnabled( |
| window_tree_host_manager_->cursor_window_controller() |
| ->ShouldEnableCursorCompositing()); |
| } |
| |
| void Shell::SetCursorCompositingEnabled(bool enabled) { |
| CursorWindowController* cursor_window_controller = |
| window_tree_host_manager_->cursor_window_controller(); |
| |
| if (cursor_window_controller->is_cursor_compositing_enabled() == enabled) { |
| return; |
| } |
| cursor_window_controller->SetCursorCompositingEnabled(enabled); |
| native_cursor_manager_->SetNativeCursorEnabled(!enabled); |
| } |
| |
| void Shell::DoInitialWorkspaceAnimation() { |
| // Uses the active desk's workspace. |
| auto* workspace = GetActiveWorkspaceController(GetPrimaryRootWindow()); |
| DCHECK(workspace); |
| workspace->DoInitialAnimation(); |
| } |
| |
| void Shell::ShowContextMenu(const gfx::Point& location_in_screen, |
| ui::MenuSourceType source_type) { |
| // Bail with no active user session, in the lock screen, or in app/kiosk mode. |
| if (session_controller_->NumberOfLoggedInUsers() < 1 || |
| session_controller_->IsScreenLocked() || |
| session_controller_->IsRunningInAppMode()) { |
| return; |
| } |
| |
| aura::Window* root = window_util::GetRootWindowAt(location_in_screen); |
| RootWindowController::ForWindow(root)->ShowContextMenu(location_in_screen, |
| source_type); |
| } |
| |
| void Shell::AddShellObserver(ShellObserver* observer) { |
| shell_observers_.AddObserver(observer); |
| } |
| |
| void Shell::RemoveShellObserver(ShellObserver* observer) { |
| shell_observers_.RemoveObserver(observer); |
| } |
| |
| void Shell::ShutdownEventDispatch() { |
| for (aura::Window* root : GetAllRootWindows()) { |
| aura::client::SetDragDropClient(root, nullptr); |
| } |
| |
| // Stop dispatching events (e.g. synthesized mouse exits from window close). |
| // https://crbug.com/874156 |
| for (RootWindowController* rwc : GetAllRootWindowControllers()) { |
| rwc->GetHost()->dispatcher()->Shutdown(); |
| } |
| } |
| |
| void Shell::UpdateAfterLoginStatusChange(LoginStatus status) { |
| for (auto* root_window_controller : GetAllRootWindowControllers()) { |
| root_window_controller->UpdateAfterLoginStatusChange(status); |
| } |
| } |
| |
| void Shell::NotifyFullscreenStateChanged(bool is_fullscreen, |
| aura::Window* container) { |
| for (auto& observer : shell_observers_) { |
| observer.OnFullscreenStateChanged(is_fullscreen, container); |
| } |
| } |
| |
| void Shell::NotifyPinnedStateChanged(aura::Window* pinned_window) { |
| for (auto& observer : shell_observers_) { |
| observer.OnPinnedStateChanged(pinned_window); |
| } |
| } |
| |
| void Shell::NotifyUserWorkAreaInsetsChanged(aura::Window* root_window) { |
| for (auto& observer : shell_observers_) { |
| observer.OnUserWorkAreaInsetsChanged(root_window); |
| } |
| } |
| |
| void Shell::NotifyShelfAlignmentChanged(aura::Window* root_window, |
| ShelfAlignment old_alignment) { |
| for (auto& observer : shell_observers_) { |
| observer.OnShelfAlignmentChanged(root_window, old_alignment); |
| } |
| } |
| |
| void Shell::NotifyDisplayForNewWindowsChanged() { |
| for (auto& observer : shell_observers_) { |
| observer.OnDisplayForNewWindowsChanged(); |
| } |
| } |
| |
| void Shell::AddAccessibilityEventHandler( |
| ui::EventHandler* handler, |
| AccessibilityEventHandlerManager::HandlerType type) { |
| if (!accessibility_event_handler_manager_) { |
| accessibility_event_handler_manager_ = |
| std::make_unique<AccessibilityEventHandlerManager>(); |
| } |
| |
| accessibility_event_handler_manager_->AddAccessibilityEventHandler(handler, |
| type); |
| } |
| void Shell::RemoveAccessibilityEventHandler(ui::EventHandler* handler) { |
| accessibility_event_handler_manager_->RemoveAccessibilityEventHandler( |
| handler); |
| } |
| |
| DeskProfilesDelegate* Shell::GetDeskProfilesDelegate() { |
| return shell_delegate_->GetDeskProfilesDelegate(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Shell, private: |
| |
| Shell::Shell(std::unique_ptr<ShellDelegate> shell_delegate) |
| : brightness_control_delegate_( |
| std::make_unique<system::BrightnessControllerChromeos>()), |
| focus_cycler_(std::make_unique<FocusCycler>()), |
| ime_controller_(std::make_unique<ImeControllerImpl>()), |
| immersive_context_(std::make_unique<ImmersiveContextAsh>()), |
| webauthn_dialog_controller_( |
| std::make_unique<WebAuthNDialogControllerImpl>()), |
| in_session_auth_dialog_controller_( |
| std::make_unique<InSessionAuthDialogControllerImpl>()), |
| keyboard_brightness_control_delegate_( |
| std::make_unique<KeyboardBrightnessController>()), |
| locale_update_controller_(std::make_unique<LocaleUpdateControllerImpl>()), |
| parent_access_controller_(std::make_unique<ParentAccessControllerImpl>()), |
| local_authentication_request_controller_( |
| std::make_unique<LocalAuthenticationRequestControllerImpl>()), |
| session_controller_(std::make_unique<SessionControllerImpl>()), |
| feature_discover_reporter_( |
| std::make_unique<FeatureDiscoveryDurationReporterImpl>( |
| session_controller_.get())), |
| shell_delegate_(std::move(shell_delegate)), |
| shutdown_controller_(std::make_unique<ShutdownControllerImpl>()), |
| system_tray_notifier_(std::make_unique<SystemTrayNotifier>()), |
| native_cursor_manager_(nullptr) { |
| AccelerometerReader::GetInstance()->Initialize(); |
| |
| login_screen_controller_ = |
| std::make_unique<LoginScreenController>(system_tray_notifier_.get()); |
| display_manager_ = ScreenAsh::CreateDisplayManager(); |
| window_tree_host_manager_ = std::make_unique<WindowTreeHostManager>(); |
| user_metrics_recorder_ = std::make_unique<UserMetricsRecorder>(); |
| keyboard_controller_ = |
| std::make_unique<KeyboardControllerImpl>(session_controller_.get()); |
| |
| PowerStatus::Initialize(); |
| |
| session_controller_->AddObserver(this); |
| } |
| |
| Shell::~Shell() { |
| TRACE_EVENT0("shutdown", "ash::Shell::Destructor"); |
| #if DCHECK_IS_ON() |
| // All WindowEventDispatchers should be shutdown before the Shell is |
| // destroyed. |
| for (RootWindowController* rwc : GetAllRootWindowControllers()) { |
| DCHECK(rwc->GetHost()->dispatcher()->in_shutdown()); |
| } |
| #endif |
| booting_animation_controller_.reset(); |
| login_unlock_throughput_recorder_.reset(); |
| |
| hud_display::HUDDisplayView::Destroy(); |
| |
| // Observes `SessionController` and must be destroyed before it. |
| privacy_hub_controller_.reset(); |
| |
| for (auto& observer : shell_observers_) { |
| observer.OnShellDestroying(); |
| } |
| |
| ash_dbus_services_.reset(); |
| |
| saved_desk_controller_.reset(); |
| saved_desk_delegate_.reset(); |
| desks_controller_->Shutdown(); |
| |
| user_metrics_recorder_->OnShellShuttingDown(); |
| |
| cros_display_config_.reset(); |
| display_configuration_observer_.reset(); |
| display_prefs_.reset(); |
| display_alignment_controller_.reset(); |
| |
| // Remove the focus from any window. This will prevent overhead and side |
| // effects (e.g. crashes) from changing focus during shutdown. |
| // See bug crbug.com/134502. |
| aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(nullptr); |
| |
| // Please keep in reverse order as in Init() because it's easy to miss one. |
| if (window_modality_controller_) { |
| window_modality_controller_.reset(); |
| } |
| |
| RemovePreTargetHandler(shell_tab_handler_.get()); |
| shell_tab_handler_.reset(); |
| |
| RemovePreTargetHandler(magnifier_key_scroll_handler_.get()); |
| magnifier_key_scroll_handler_.reset(); |
| |
| RemovePreTargetHandler(speech_feedback_handler_.get()); |
| speech_feedback_handler_.reset(); |
| |
| RemovePreTargetHandler(control_v_histogram_recorder_.get()); |
| RemovePreTargetHandler(accelerator_tracker_.get()); |
| RemovePreTargetHandler(accelerator_filter_.get()); |
| RemovePreTargetHandler(event_transformation_handler_.get()); |
| if (back_gesture_event_handler_) { |
| RemovePreTargetHandler(back_gesture_event_handler_.get()); |
| } |
| RemovePreTargetHandler(system_gesture_filter_.get()); |
| RemoveAccessibilityEventHandler(mouse_cursor_filter_.get()); |
| if (features::IsPeripheralCustomizationEnabled()) { |
| RemovePreTargetHandler(shortcut_input_handler_.get()); |
| } |
| RemovePreTargetHandler(modality_filter_.get()); |
| RemovePreTargetHandler(tooltip_controller_.get()); |
| |
| // Resets the implementation of clipboard history utility functions. |
| chromeos::clipboard_history::SetQueryItemDescriptorsImpl( |
| base::NullCallback()); |
| chromeos::clipboard_history::SetPasteClipboardItemByIdImpl( |
| base::NullCallback()); |
| |
| // Resets the text context menu implementation factory. |
| views::ViewsTextServicesContextMenuChromeos::SetImplFactory( |
| base::NullCallback()); |
| |
| wm_mode_controller_.reset(); |
| |
| // `shortcut_input_handler_` must be cleaned up before |
| // `event_rewriter_controller_`. |
| shortcut_input_handler_.reset(); |
| event_rewriter_controller_.reset(); |
| keyboard_modifier_metrics_recorder_.reset(); |
| input_device_settings_dispatcher_.reset(); |
| input_device_tracker_.reset(); |
| input_device_settings_controller_.reset(); |
| input_device_key_alias_manager_.reset(); |
| |
| screen_orientation_controller_.reset(); |
| screen_layout_observer_.reset(); |
| |
| // Destroy the virtual keyboard controller before the tablet mode controller |
| // since the latters destructor triggers events that the former is listening |
| // to but no longer cares about. |
| keyboard_controller_->DestroyVirtualKeyboard(); |
| |
| // Depends on |tablet_mode_controller_|. |
| window_restore_controller_.reset(); |
| shelf_controller_->Shutdown(); |
| shelf_config_->Shutdown(); |
| |
| // Depends on `app_list_controller_` and `tablet_mode_controller_`. |
| app_list_feature_usage_metrics_.reset(); |
| |
| // Destroy |app_list_controller_| earlier than |tablet_mode_controller_| since |
| // the former may use the latter before destruction. |
| app_list_controller_.reset(); |
| |
| // Accelerometer file reader stops listening to tablet mode controller. |
| AccelerometerReader::GetInstance()->StopListenToTabletModeController(); |
| |
| // Destroy |ambient_controller_| before |assistant_controller_|. |
| ambient_controller_.reset(); |
| |
| // Destroy |assistant_controller_| earlier than |tablet_mode_controller_| so |
| // that the former will destroy the Assistant view hierarchy which has a |
| // dependency on the latter. |
| assistant_controller_.reset(); |
| |
| // Because this function will call |TabletModeController::RemoveObserver|, do |
| // it before destroying |tablet_mode_controller_|. |
| accessibility_controller_->Shutdown(); |
| |
| // Must be destructed before human_presence_orientation_controller_. |
| power_prefs_.reset(); |
| |
| // Must be destructed before the tablet mode and message center controllers, |
| // both of which these rely on. |
| snooping_protection_controller_.reset(); |
| human_presence_orientation_controller_.reset(); |
| |
| snap_group_controller_.reset(); |
| |
| // Shutdown tablet mode controller early on since it has some observers which |
| // need to be removed. It will be destroyed later after all windows are closed |
| // since it might be accessed during this process. |
| tablet_mode_controller_->Shutdown(); |
| |
| // Shutdown the clipboard history controller to clean up the child windows and |
| // widgets that may be animating out. |
| clipboard_history_controller_->Shutdown(); |
| |
| toast_manager_.reset(); |
| anchored_nudge_manager_.reset(); |
| |
| // Accesses root window containers. |
| logout_confirmation_controller_.reset(); |
| |
| adaptive_charging_controller_.reset(); |
| |
| // Drag-and-drop must be canceled prior to close all windows. |
| drag_drop_controller_.reset(); |
| |
| // Controllers who have WindowObserver added must be deleted |
| // before |window_tree_host_manager_| is deleted. |
| persistent_window_controller_.reset(); |
| |
| window_bounds_tracker_.reset(); |
| |
| display_highlight_controller_.reset(); |
| |
| // VideoActivityNotifier must be deleted before |video_detector_| is |
| // deleted because it's observing video activity through |
| // VideoDetector::Observer interface. |
| video_activity_notifier_.reset(); |
| video_detector_.reset(); |
| color_enhancement_controller_.reset(); |
| |
| shadow_controller_.reset(); |
| resize_shadow_controller_.reset(); |
| raster_scale_controller_.reset(); |
| |
| // Has to happen before ~MruWindowTracker. |
| window_cycle_controller_.reset(); |
| |
| // As clients of `capture_mode_controller_`, `projector_controller_` and |
| // `game_dashboard_controller_` need to be destroyed before |
| // `capture_mode_controller_`. |
| projector_controller_.reset(); |
| game_dashboard_controller_.reset(); |
| |
| // This must be called before `capture_mode_controller_` is destroyed. Note |
| // that 'capture' in `CaptureModeController` means 'screenshot capture, while |
| // 'capture' in `wm::CaptureController` means 'input capture'. Some windows |
| // like popup windows close themselves when losing 'input capture' but if |
| // 'screenshot capture' is in progress, they do not close themselves. For this |
| // reason, change of 'input capture' can cause a call to |
| // `CaptureModeController::Get()`. By calling `PrepareForShutdown()` here, it |
| // prevents `CaptureModeController::Get()` from being called after the object |
| // is destroyed. |
| wm::CaptureController::Get()->PrepareForShutdown(); |
| |
| // This must be destroyed before deleting all the windows below in |
| // `CloseAllRootWindowChildWindows()`, since shutting down the session will |
| // need to access those windows and it will be a UAF. |
| // https://crbug.com/1350711. |
| capture_mode_controller_.reset(); |
| |
| // Relies on `overview_controller`. |
| post_login_glanceables_metrics_reporter_.reset(); |
| |
| // Has to happen before `~MruWindowTracker` and after |
| // `~GameDashboardController`. |
| overview_controller_.reset(); |
| |
| // This must be called before deleting all the windows below in |
| // `CloseAllRootWindowChildWindows()` since host_windows(which gets destroyed) |
| // are needed for proper deletion of RoundedDisplayProviders. |
| window_tree_host_manager_->ShutdownRoundedDisplays(); |
| |
| // Close all widgets (including the shelf) and destroy all window containers. |
| CloseAllRootWindowChildWindows(); |
| |
| glanceables_controller_.reset(); |
| |
| tasks_controller_.reset(); |
| |
| multitask_menu_nudge_delegate_.reset(); |
| tablet_mode_controller_.reset(); |
| login_screen_controller_.reset(); |
| |
| // This must be destroyed before `message_center_controller_` in order to |
| // restore the original settings if a focus session was active. Also, this |
| // should be destroyed before `system_notification_controller_`, which could |
| // be indirectly called by `focus_mode_controller_` to update the DND |
| // notification. |
| focus_mode_controller_.reset(); |
| |
| system_notification_controller_.reset(); |
| // Should be destroyed after Shelf and |system_notification_controller_|. |
| system_tray_model_.reset(); |
| system_sounds_delegate_.reset(); |
| |
| // MultiDisplayMetricsController has a dependency on `mru_window_tracker_`. |
| multi_display_metrics_controller_.reset(); |
| |
| // MruWindowTracker must be destroyed after all windows have been deleted to |
| // avoid a possible crash when Shell is destroyed from a non-normal shutdown |
| // path. (crbug.com/485438). |
| mru_window_tracker_.reset(); |
| |
| // These need a valid Shell instance to clean up properly, so explicitly |
| // delete them before invalidating the instance. |
| // Alphabetical. TODO(oshima): sort. |
| autoclick_controller_.reset(); |
| fullscreen_magnifier_controller_.reset(); |
| tooltip_controller_.reset(); |
| event_client_.reset(); |
| toplevel_window_event_handler_.reset(); |
| visibility_controller_.reset(); |
| |
| tray_action_.reset(); |
| |
| power_button_controller_.reset(); |
| lock_state_controller_.reset(); |
| backlights_forced_off_setter_.reset(); |
| |
| float_controller_.reset(); |
| pip_controller_.reset(); |
| screen_pinning_controller_.reset(); |
| |
| multidevice_notification_presenter_.reset(); |
| resolution_notification_controller_.reset(); |
| mouse_cursor_filter_.reset(); |
| modality_filter_.reset(); |
| |
| touch_transformer_controller_.reset(); |
| key_accessibility_enabler_.reset(); |
| |
| display_speaker_controller_.reset(); |
| screen_switch_check_controller_.reset(); |
| |
| ScreenAsh::CreateScreenForShutdown(); |
| display_configuration_controller_.reset(); |
| |
| // Needs to be destructed before `ime_controler_`. |
| keyboard_backlight_color_controller_.reset(); |
| rgb_keyboard_manager_.reset(); |
| |
| ash_color_provider_.reset(); |
| |
| // Depends on `dark_light_mode_controller_` and `wallpaper_controller_` so it |
| // should be destroyed first. |
| color_palette_controller_.reset(); |
| |
| // Depends on `geolocation_controller_` and `wallpaper_controller_`, so it |
| // must be destructed before the geolocation controller and wallpaper |
| // controller. |
| dark_light_mode_controller_.reset(); |
| |
| // These members access Shell in their destructors. |
| wallpaper_controller_.reset(); |
| accessibility_controller_.reset(); |
| accessibility_delegate_.reset(); |
| accessibility_focus_ring_controller_.reset(); |
| policy_recommendation_restorer_.reset(); |
| ime_controller_.reset(); |
| back_gesture_event_handler_.reset(); |
| |
| // Balances the Install() in Initialize(). |
| views::FocusManagerFactory::Install(nullptr); |
| |
| // ShelfWindowWatcher has window observers and a pointer to the shelf model. |
| shelf_window_watcher_.reset(); |
| |
| // Removes itself as an observer of |pref_service_|. |
| shelf_controller_.reset(); |
| |
| // `CameraEffectsController` depends on `AutozoomController`, so it must be |
| // destructed before it. |
| camera_effects_controller_.reset(); |
| |
| // NightLightControllerImpl depends on the PrefService, the window tree host |
| // manager, and `geolocation_controller_`, so it must be destructed before |
| // them. crbug.com/724231. |
| night_light_controller_ = nullptr; |
| // Similarly for DockedMagnifierController. |
| docked_magnifier_controller_ = nullptr; |
| // Similarly for PrivacyScreenController. |
| privacy_screen_controller_ = nullptr; |
| // Similarly for AutozoomControllerImpl |
| autozoom_controller_ = nullptr; |
| |
| geolocation_controller_.reset(); |
| |
| // NearbyShareDelegateImpl must be destroyed before SessionController and |
| // NearbyShareControllerImpl. |
| nearby_share_delegate_.reset(); |
| nearby_share_controller_.reset(); |
| |
| // Stop observing window activation changes before closing all windows. |
| focus_controller_->RemoveObserver(this); |
| |
| // Depends on shelf owned by RootWindowController so destroy this before the |
| // |window_tree_host_manager_|. |
| clipboard_history_controller_.reset(); |
| |
| // Should be destroyed after `clipbaord_history_controller_` and |
| // `autozoom_controller_` since they will destruct `SystemNudgeController`. |
| system_nudge_pause_manager_.reset(); |
| |
| // This also deletes all RootWindows. Note that we invoke Shutdown() on |
| // WindowTreeHostManager before resetting |window_tree_host_manager_|, since |
| // destruction of its owned RootWindowControllers relies on the value. |
| window_tree_host_manager_->Shutdown(); |
| |
| // Depends on |focus_controller_|, so must be destroyed before. |
| window_tree_host_manager_.reset(); |
| |
| // The desks controller is destroyed after the window tree host manager and |
| // before the focus controller. At this point it is guaranteed that querying |
| // the active desk is no longer needed. |
| desks_controller_.reset(); |
| |
| tab_cluster_ui_controller_.reset(); |
| |
| focus_rules_ = nullptr; |
| focus_controller_.reset(); |
| screen_position_controller_.reset(); |
| |
| display_color_manager_.reset(); |
| projecting_observer_.reset(); |
| |
| partial_magnifier_controller_.reset(); |
| |
| laser_pointer_controller_.reset(); |
| |
| if (display_change_observer_) { |
| display_manager_->configurator()->RemoveObserver( |
| display_change_observer_.get()); |
| } |
| if (display_error_observer_) { |
| display_manager_->configurator()->RemoveObserver( |
| display_error_observer_.get()); |
| } |
| display_change_observer_.reset(); |
| display_shutdown_observer_.reset(); |
| |
| display_port_observer_.reset(); |
| |
| keyboard_controller_.reset(); |
| |
| // Depends on PowerStatus. |
| battery_saver_controller_.reset(); |
| |
| PowerStatus::Shutdown(); |
| // Depends on SessionController. |
| power_event_observer_.reset(); |
| |
| session_controller_->RemoveObserver(this); |
| // TouchDevicesController depends on the PrefService and must be destructed |
| // before it. |
| touch_devices_controller_ = nullptr; |
| // DetachableBaseNotificationController depends on DetachableBaseHandler, and |
| // has to be destructed before it. |
| detachable_base_notification_controller_.reset(); |
| // DetachableBaseHandler depends on the PrefService and must be destructed |
| // before it. |
| detachable_base_handler_.reset(); |
| |
| diagnostics_log_controller_.reset(); |
| |
| firmware_update_notification_controller_.reset(); |
| |
| firmware_update_manager_.reset(); |
| |
| pcie_peripheral_notification_controller_.reset(); |
| |
| usb_peripheral_notification_controller_.reset(); |
| |
| keyboard_capability_.reset(); |
| |
| message_center_ash_impl_.reset(); |
| |
| // Destroys the MessageCenter singleton, so must happen late. |
| message_center_controller_.reset(); |
| |
| // `HoldingSpaceController` observes `SessionController` and must be |
| // destructed before it. |
| holding_space_controller_.reset(); |
| |
| // `CalendarController` observes `SessionController` and must be destructed |
| // before it. |
| calendar_controller_.reset(); |
| |
| audio_effects_controller_.reset(); |
| |
| shell_delegate_.reset(); |
| |
| multi_capture_service_client_.reset(); |
| |
| // Observes `SessionController` and must be destroyed before it. |
| federated_service_controller_.reset(); |
| |
| UsbguardClient::Shutdown(); |
| |
| // Must be shut down after detachable_base_handler_. |
| HammerdClient::Shutdown(); |
| |
| if (FwupdClient::Get()) { |
| FwupdClient::Shutdown(); |
| } |
| |
| for (auto& observer : shell_observers_) { |
| observer.OnShellDestroyed(); |
| } |
| |
| DCHECK(instance_ == this); |
| instance_ = nullptr; |
| } |
| |
| void Shell::Init( |
| ui::ContextFactory* context_factory, |
| PrefService* local_state, |
| std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory, |
| std::unique_ptr<ash::quick_pair::Mediator::Factory> |
| quick_pair_mediator_factory, |
| scoped_refptr<dbus::Bus> dbus_bus, |
| std::unique_ptr<display::NativeDisplayDelegate> native_display_delegate) { |
| native_display_delegate_ = std::move(native_display_delegate); |
| login_unlock_throughput_recorder_ = |
| std::make_unique<LoginUnlockThroughputRecorder>(); |
| |
| // Required by DetachableBaseHandler. |
| chromeos::InitializeDBusClient<HammerdClient>(dbus_bus.get()); |
| |
| chromeos::InitializeDBusClient<UsbguardClient>(dbus_bus.get()); |
| |
| local_state_ = local_state; |
| |
| if (local_state_ != nullptr) { |
| // Only construct BatterySaverController if prefs exists. It uses prefs to |
| // store the battery saver state, so testing its functionality without |
| // prefs doesn't make sense. |
| if (features::IsBatterySaverAvailable()) { |
| battery_saver_controller_ = |
| std::make_unique<BatterySaverController>(local_state_); |
| } else { |
| // It's possible that we have a new Chrome without battery saver mode |
| // available, but still have battery saver running because the previous |
| // chrome did. So unconditionally reset battery saver state. |
| BatterySaverController::ResetState(local_state_); |
| } |
| } |
| |
| // This creates the MessageCenter object which is used by some other objects |
| // initialized here, so it needs to come early. |
| message_center_controller_ = std::make_unique<MessageCenterController>(); |
| |
| message_center_ash_impl_ = std::make_unique<MessageCenterAshImpl>(); |
| |
| // Initialized early since it is used by some other objects. |
| keyboard_capability_ = std::make_unique<ui::KeyboardCapability>(); |
| |
| // These controllers call Shell::Get() in their constructors, so they cannot |
| // be in the member initialization list. |
| touch_devices_controller_ = std::make_unique<TouchDevicesController>(); |
| detachable_base_handler_ = |
| std::make_unique<DetachableBaseHandler>(local_state_); |
| detachable_base_notification_controller_ = |
| std::make_unique<DetachableBaseNotificationController>( |
| detachable_base_handler_.get()); |
| display_speaker_controller_ = std::make_unique<DisplaySpeakerController>(); |
| policy_recommendation_restorer_ = |
| std::make_unique<PolicyRecommendationRestorer>(); |
| screen_switch_check_controller_ = |
| std::make_unique<ScreenSwitchCheckController>(); |
| multidevice_notification_presenter_ = |
| std::make_unique<MultiDeviceNotificationPresenter>( |
| message_center::MessageCenter::Get()); |
| media_controller_ = std::make_unique<MediaControllerImpl>(); |
| media_notification_provider_ = |
| shell_delegate_->CreateMediaNotificationProvider(); |
| |
| tablet_mode_controller_ = std::make_unique<TabletModeController>(); |
| |
| rgb_keyboard_manager_ = |
| std::make_unique<RgbKeyboardManager>(ime_controller_.get()); |
| |
| // Observes the tablet mode controller if any hps feature is enabled. |
| if (features::IsSnoopingProtectionEnabled() || |
| features::IsQuickDimEnabled()) { |
| human_presence_orientation_controller_ = |
| std::make_unique<HumanPresenceOrientationController>(); |
| } |
| |
| // Construct SnoopingProtectionController, must be constructed after |
| // HumanPresenceOrientationController. |
| if (features::IsSnoopingProtectionEnabled()) { |
| snooping_protection_controller_ = |
| std::make_unique<SnoopingProtectionController>(); |
| } |
| |
| // Manages lifetime of DiagnosticApp logs. |
| diagnostics_log_controller_ = |
| std::make_unique<diagnostics::DiagnosticsLogController>(); |
| |
| pcie_peripheral_notification_controller_ = |
| std::make_unique<PciePeripheralNotificationController>( |
| message_center::MessageCenter::Get()); |
| |
| usb_peripheral_notification_controller_ = |
| std::make_unique<UsbPeripheralNotificationController>( |
| message_center::MessageCenter::Get()); |
| |
| accessibility_focus_ring_controller_ = |
| std::make_unique<AccessibilityFocusRingControllerImpl>(); |
| accessibility_delegate_.reset(shell_delegate_->CreateAccessibilityDelegate()); |
| accessibility_controller_ = std::make_unique<AccessibilityControllerImpl>(); |
| toast_manager_ = std::make_unique<ToastManagerImpl>(); |
| anchored_nudge_manager_ = std::make_unique<AnchoredNudgeManagerImpl>(); |
| system_nudge_pause_manager_ = std::make_unique<SystemNudgePauseManagerImpl>(); |
| |
| peripheral_battery_listener_ = std::make_unique<PeripheralBatteryListener>(); |
| |
| peripheral_battery_notifier_ = std::make_unique<PeripheralBatteryNotifier>( |
| peripheral_battery_listener_.get()); |
| power_event_observer_ = std::make_unique<PowerEventObserver>(); |
| window_cycle_controller_ = std::make_unique<WindowCycleController>(); |
| |
| capture_mode_controller_ = std::make_unique<CaptureModeController>( |
| shell_delegate_->CreateCaptureModeDelegate()); |
| |
| // Accelerometer file reader starts listening to tablet mode controller. |
| AccelerometerReader::GetInstance()->StartListenToTabletModeController(); |
| |
| // Install the custom factory early on so that views::FocusManagers for Tray, |
| // Shelf, and WallPaper could be created by the factory. |
| views::FocusManagerFactory::Install(new AshFocusManagerFactory); |
| |
| wallpaper_controller_ = WallpaperControllerImpl::Create(local_state_); |
| |
| // Initialized after |rgb_keyboard_manager_| to observe the state of rgb |
| // keyboard and |wallpaper_controller_| because we will need to observe when |
| // the extracted wallpaper color changes. |
| keyboard_backlight_color_controller_ = |
| std::make_unique<KeyboardBacklightColorController>(local_state_); |
| |
| native_cursor_manager_ = new NativeCursorManagerAsh; |
| cursor_manager_ = std::make_unique<CursorManager>( |
| base::WrapUnique(native_cursor_manager_.get())); |
| |
| InitializeDisplayManager(); |
| |
| // RefreshFontParams depends on display prefs. |
| display_manager_->RefreshFontParams(); |
| |
| // This will initialize aura::Env which requires |display_manager_| to |
| // be initialized first. |
| aura::Env* env = aura::Env::GetInstance(); |
| if (context_factory) { |
| env->set_context_factory(context_factory); |
| } |
| |
| ash_color_provider_ = std::make_unique<AshColorProvider>(); |
| ui::ColorProviderManager::Get().AppendColorProviderInitializer( |
| base::BindRepeating(AddCrosStylesColorMixer)); |
| ui::ColorProviderManager::Get().AppendColorProviderInitializer( |
| base::BindRepeating(AddAshColorMixer)); |
| |
| // Geolocation controller needs to be created before any `ScheduledFeature` |
| // subclasses such as night light and dark mode controllers because |
| // `ScheduledFeature` ctor will access `geolocation_controller_` from |
| // `Shell`. |
| geolocation_controller_ = std::make_unique<GeolocationController>( |
| SimpleGeolocationProvider::GetInstance()); |
| |
| // Night Light depends on the display manager, the display color manager, |
| // aura::Env, and geolocation controller, so initialize it after all have |
| // been initialized. |
| night_light_controller_ = std::make_unique<NightLightControllerImpl>(); |
| |
| dark_light_mode_controller_ = std::make_unique<DarkLightModeControllerImpl>(); |
| |
| color_palette_controller_ = |
| ColorPaletteController::Create(dark_light_mode_controller_.get(), |
| wallpaper_controller_.get(), local_state_); |
| |
| // Privacy Screen depends on the display manager, so initialize it after |
| // display manager was properly initialized. |
| privacy_screen_controller_ = std::make_unique<PrivacyScreenController>(); |
| |
| if (media::ShouldEnableAutoFraming()) { |
| autozoom_controller_ = std::make_unique<AutozoomControllerImpl>(); |
| } |
| |
| // Fast Pair depends on the display manager, so initialize it after |
| // display manager was properly initialized. |
| if (base::FeatureList::IsEnabled(features::kFastPair) && |
| quick_pair_mediator_factory) { |
| quick_pair_mediator_ = quick_pair_mediator_factory->BuildInstance(); |
| } |
| |
| // The WindowModalityController needs to be at the front of the input event |
| // pretarget handler list to ensure that it processes input events when modal |
| // windows are active. |
| window_modality_controller_ = |
| std::make_unique<::wm::WindowModalityController>(this, env); |
| |
| input_device_key_alias_manager_ = |
| std::make_unique<InputDeviceKeyAliasManager>(); |
| |
| // The `InputDeviceSettingsController` is a dependency of the following so it |
| // must be initialized first: |
| // - `EventRewriterController` |
| // - `InputDeviceTracker` |
| // - `KeyboardModifierMetricsRecorder` |
| // - `InputDeviceSettingsDispatcher` |
| input_device_settings_controller_ = |
| std::make_unique<InputDeviceSettingsControllerImpl>(local_state_); |
| input_device_tracker_ = std::make_unique<InputDeviceTracker>(); |
| input_device_settings_dispatcher_ = |
| std::make_unique<InputDeviceSettingsDispatcher>( |
| ui::OzonePlatform::GetInstance()->GetInputController()); |
| keyboard_modifier_metrics_recorder_ = |
| std::make_unique<KeyboardModifierMetricsRecorder>(); |
| event_rewriter_controller_ = std::make_unique<EventRewriterControllerImpl>(); |
| |
| env_filter_ = std::make_unique<::wm::CompoundEventFilter>(); |
| AddPreTargetHandler(env_filter_.get()); |
| |
| // FocusController takes ownership of AshFocusRules. |
| focus_rules_ = new AshFocusRules(); |
| focus_controller_ = std::make_unique<::wm::FocusController>(focus_rules_); |
| focus_controller_->AddObserver(this); |
| |
| // `WindowBoundsTracker` depends on `FocusController`, as it needs to track |
| // the window's activation changes. |
| if (features::IsWindowBoundsTrackerEnabled()) { |
| window_bounds_tracker_ = std::make_unique<WindowBoundsTracker>(); |
| } |
| |
| overview_controller_ = std::make_unique<OverviewController>(); |
| |
| // `GameDashboardController` has dependencies on `OverviewController` and |
| // `CaptureModeController`. |
| if (features::IsGameDashboardEnabled()) { |
| game_dashboard_controller_ = std::make_unique<GameDashboardController>( |
| shell_delegate_->CreateGameDashboardDelegate()); |
| } |
| |
| // `SnapGroupController` has dependencies on `OverviweController` and |
| // `TabletModeController`. |
| if (features::IsSnapGroupEnabled()) { |
| snap_group_controller_ = std::make_unique<SnapGroupController>(); |
| } |
| |
| screen_position_controller_ = std::make_unique<ScreenPositionController>(); |
| |
| frame_throttling_controller_ = std::make_unique<FrameThrottlingController>( |
| context_factory->GetHostFrameSinkManager()); |
| |
| if (features::IsTabClusterUIEnabled()) { |
| tab_cluster_ui_controller_ = std::make_unique<TabClusterUIController>(); |
| } |
| |
| window_tree_host_manager_->Start(); |
| AshWindowTreeHostInitParams ash_init_params; |
| window_tree_host_manager_->CreatePrimaryHost(ash_init_params); |
| |
| // Create the desks controller right after the window tree host manager is |
| // started, and before anything else is created, including the initialization |
| // of the hosts and the root window controllers. Many things may need to query |
| // the active desk, even at this early stage. For this the controller must be |
| // present at all times. The desks controller also depends on the focus |
| // controller. |
| desks_controller_ = std::make_unique<DesksController>(); |
| saved_desk_delegate_ = shell_delegate_->CreateSavedDeskDelegate(); |
| // Initialized here since it depends on desks. |
| if (base::FeatureList::IsEnabled(features::kAppLaunchAutomation)) { |
| saved_desk_controller_ = std::make_unique<SavedDeskController>(); |
| } |
| |
| Shell::SetRootWindowForNewWindows(GetPrimaryRootWindow()); |
| |
| resolution_notification_controller_ = |
| std::make_unique<ResolutionNotificationController>(); |
| |
| cursor_manager_->SetDisplay( |
| display::Screen::GetScreen()->GetPrimaryDisplay()); |
| |
| // Initialize before AcceleratorController and AshAcceleratorConfiguration. |
| accelerator_prefs_ = std::make_unique<AcceleratorPrefs>( |
| shell_delegate_->CreateAcceleratorPrefsDelegate()); |
| |
| // Must be initialized after InputMethodManager. |
| accelerator_keycode_lookup_cache_ = |
| std::make_unique<AcceleratorKeycodeLookupCache>(); |
| ash_accelerator_configuration_ = |
| std::make_unique<AshAcceleratorConfiguration>(); |
| ash_accelerator_configuration_->Initialize(); |
| accelerator_controller_ = std::make_unique<AcceleratorControllerImpl>( |
| ash_accelerator_configuration_.get()); |
| |
| clipboard_history_controller_ = |
| std::make_unique<ClipboardHistoryControllerImpl>( |
| shell_delegate_->CreateClipboardHistoryControllerDelegate()); |
| |
| // `HoldingSpaceController` must be instantiated before the shelf. |
| holding_space_controller_ = std::make_unique<HoldingSpaceController>(); |
| |
| calendar_controller_ = std::make_unique<CalendarController>(); |
| |
| if (features::IsVideoConferenceEnabled()) { |
| camera_effects_controller_ = std::make_unique<CameraEffectsController>(); |
| audio_effects_controller_ = std::make_unique<AudioEffectsController>(); |
| } |
| |
| shelf_config_ = std::make_unique<ShelfConfig>(); |
| shelf_controller_ = std::make_unique<ShelfController>(); |
| |
| shell_tab_handler_ = std::make_unique<ShellTabHandler>(this); |
| AddPreTargetHandler(shell_tab_handler_.get()); |
| magnifier_key_scroll_handler_ = MagnifierKeyScroller::CreateHandler(); |
| AddPreTargetHandler(magnifier_key_scroll_handler_.get()); |
| speech_feedback_handler_ = SpokenFeedbackToggler::CreateHandler(); |
| AddPreTargetHandler(speech_feedback_handler_.get()); |
| |
| // The order in which event filters are added is significant. |
| |
| // ui::UserActivityDetector passes events to observers, so let them get |
| // rewritten first. |
| user_activity_detector_ = std::make_unique<ui::UserActivityDetector>(); |
| |
| control_v_histogram_recorder_ = std::make_unique<ControlVHistogramRecorder>(); |
| AddPreTargetHandler(control_v_histogram_recorder_.get(), |
| ui::EventTarget::Priority::kAccessibility); |
| |
| // AcceleratorTracker should be placed before AcceleratorFilter to make sure |
| // the accelerators won't be filtered out before getting AcceleratorTracker. |
| accelerator_tracker_ = std::make_unique<AcceleratorTracker>( |
| base::make_span(kAcceleratorTrackerList, kAcceleratorTrackerListLength)); |
| AddPreTargetHandler(accelerator_tracker_.get()); |
| |
| accelerator_filter_ = std::make_unique<::wm::AcceleratorFilter>( |
| std::make_unique<PreTargetAcceleratorHandler>()); |
| AddPreTargetHandler(accelerator_filter_.get()); |
| |
| event_transformation_handler_ = |
| std::make_unique<EventTransformationHandler>(); |
| AddPreTargetHandler(event_transformation_handler_.get()); |
| |
| back_gesture_event_handler_ = std::make_unique<BackGestureEventHandler>(); |
| AddPreTargetHandler(back_gesture_event_handler_.get()); |
| |
| toplevel_window_event_handler_ = |
| std::make_unique<ToplevelWindowEventHandler>(); |
| |
| system_gesture_filter_ = std::make_unique<SystemGestureEventFilter>(); |
| AddPreTargetHandler(system_gesture_filter_.get()); |
| |
| sticky_keys_controller_ = std::make_unique<StickyKeysController>(); |
| screen_pinning_controller_ = std::make_unique<ScreenPinningController>(); |
| |
| power_prefs_ = std::make_unique<PowerPrefs>( |
| chromeos::PowerPolicyController::Get(), |
| chromeos::PowerManagerClient::Get(), local_state_); |
| |
| backlights_forced_off_setter_ = std::make_unique<BacklightsForcedOffSetter>(); |
| |
| tray_action_ = |
| std::make_unique<TrayAction>(backlights_forced_off_setter_.get()); |
| |
| lock_state_controller_ = std::make_unique<LockStateController>( |
| shutdown_controller_.get(), local_state_); |
| power_button_controller_ = std::make_unique<PowerButtonController>( |
| backlights_forced_off_setter_.get()); |
| // Pass the initial display state to PowerButtonController. |
| power_button_controller_->OnDisplayModeChanged( |
| display_configurator()->cached_displays()); |
| |
| drag_drop_controller_ = std::make_unique<DragDropController>(); |
| |
| mouse_cursor_filter_ = std::make_unique<MouseCursorEventFilter>(); |
| AddAccessibilityEventHandler( |
| mouse_cursor_filter_.get(), |
| AccessibilityEventHandlerManager::HandlerType::kCursor); |
| |
| if (features::IsAdaptiveChargingEnabled()) { |
| adaptive_charging_controller_ = |
| std::make_unique<AdaptiveChargingController>(); |
| } |
| |
| // Create Controllers that may need root window. |
| // TODO(oshima): Move as many controllers before creating |
| // RootWindowController as possible. |
| visibility_controller_ = std::make_unique<AshVisibilityController>(); |
| |
| laser_pointer_controller_ = std::make_unique<LaserPointerController>(); |
| partial_magnifier_controller_ = |
| std::make_unique<PartialMagnifierController>(); |
| |
| fullscreen_magnifier_controller_ = |
| std::make_unique<FullscreenMagnifierController>(); |
| mru_window_tracker_ = std::make_unique<MruWindowTracker>(); |
| assistant_controller_ = std::make_unique<AssistantControllerImpl>(); |
| |
| // MultiDisplayMetricsController has a dependency on `mru_window_tracker_`. |
| multi_display_metrics_controller_ = |
| std::make_unique<MultiDisplayMetricsController>(); |
| |
| mojo::PendingRemote<device::mojom::Fingerprint> ambient_fingerprint; |
| shell_delegate_->BindFingerprint( |
| ambient_fingerprint.InitWithNewPipeAndPassReceiver()); |
| ambient_controller_ = |
| std::make_unique<AmbientController>(std::move(ambient_fingerprint)); |
| |
| mojo::PendingRemote<video_capture::mojom::MultiCaptureService> |
| multi_capture_service; |
| shell_delegate_->BindMultiCaptureService( |
| multi_capture_service.InitWithNewPipeAndPassReceiver()); |
| multi_capture_service_client_ = std::make_unique<MultiCaptureServiceClient>( |
| std::move(multi_capture_service)); |
| |
| // |tablet_mode_controller_| |mru_window_tracker_|, and |
| // |assistant_controller_| are put before |app_list_controller_| as they are |
| // used in its constructor. |
| app_list_controller_ = std::make_unique<AppListControllerImpl>(); |
| |
| autoclick_controller_ = std::make_unique<AutoclickController>(); |
| |
| color_enhancement_controller_ = |
| std::make_unique<ColorEnhancementController>(); |
| |
| security_curtain_controller_ = |
| std::make_unique<curtain::SecurityCurtainControllerImpl>(this); |
| |
| docked_magnifier_controller_ = std::make_unique<DockedMagnifierController>(); |
| |
| video_detector_ = std::make_unique<VideoDetector>(); |
| |
| tooltip_controller_ = std::make_unique<views::corewm::TooltipController>( |
| std::make_unique<views::corewm::TooltipAura>( |
| base::BindRepeating(&StyleUtil::CreateAshStyleTooltipView)), |
| activation_client()); |
| AddPreTargetHandler(tooltip_controller_.get()); |
| |
| modality_filter_ = std::make_unique<SystemModalContainerEventFilter>(this); |
| AddPreTargetHandler(modality_filter_.get()); |
| |
| if (features::IsPeripheralCustomizationEnabled() || |
| ::features::IsShortcutCustomizationEnabled()) { |
| shortcut_input_handler_ = std::make_unique<ShortcutInputHandler>(); |
| AddPreTargetHandler(shortcut_input_handler_.get()); |
| } |
| |
| event_client_ = std::make_unique<EventClientImpl>(); |
| |
| resize_shadow_controller_ = std::make_unique<ResizeShadowController>(); |
| raster_scale_controller_ = std::make_unique<RasterScaleController>(); |
| shadow_controller_ = std::make_unique<::wm::ShadowController>( |
| focus_controller_.get(), std::make_unique<WmShadowControllerDelegate>(), |
| env); |
| |
| logout_confirmation_controller_ = |
| std::make_unique<LogoutConfirmationController>(); |
| |
| // Create AshTouchTransformController before |
| // WindowTreeHostManager::InitDisplays() |
| // since AshTouchTransformController listens on |
| // WindowTreeHostManager::Observer::OnDisplaysInitialized(). |
| touch_transformer_controller_ = std::make_unique<AshTouchTransformController>( |
| display_manager_.get(), |
| std::make_unique<display::DefaultTouchTransformSetter>()); |
| |
| // |system_tray_model_| should be available before |
| // |system_notification_controller_| is initialized and Shelf is created by |
| // WindowTreeHostManager::InitHosts. |
| system_tray_model_ = std::make_unique<SystemTrayModel>(); |
| |
| // The |shelf_config_| needs |app_list_controller_| and |system_tray_model_| |
| // to initialize itself. |
| shelf_config_->Init(); |
| |
| // The `shelf_controller_` needs `app_list_controller_` to initialize |
| // launcher_nudge_controller_. |
| shelf_controller_->Init(); |
| |
| nearby_share_controller_ = std::make_unique<NearbyShareControllerImpl>(); |
| nearby_share_delegate_ = shell_delegate_->CreateNearbyShareDelegate( |
| nearby_share_controller_.get()); |
| |
| // System sounds delegate should be initialized before |
| // `SystemNotificationController` is created, because |
| // `SystemNotificationController` ctor will creat an instance of |
| // `PowerSoundsController`, which will access and play the initialized sounds. |
| if (features::AreSystemSoundsEnabled()) { |
| system_sounds_delegate_ = shell_delegate_->CreateSystemSoundsDelegate(); |
| system_sounds_delegate_->Init(); |
| } |
| |
| privacy_hub_controller_ = PrivacyHubController::CreatePrivacyHubController(); |
| |
| // One of the subcontrollers accesses the SystemNotificationController. |
| system_notification_controller_ = |
| std::make_unique<SystemNotificationController>(); |
| |
| if (features::IsFocusModeEnabled()) { |
| focus_mode_controller_ = std::make_unique<FocusModeController>(); |
| } |
| |
| // WmModeController should be created before initializing the window tree |
| // hosts, since the latter will initialize the shelf on each display, which |
| // hosts the WM mode tray button. |
| if (features::IsWmModeEnabled()) { |
| wm_mode_controller_ = std::make_unique<WmModeController>(); |
| } |
| |
| if (features::IsHotspotEnabled()) { |
| hotspot_icon_animation_ = std::make_unique<HotspotIconAnimation>(); |
| hotspot_info_cache_ = std::make_unique<HotspotInfoCache>(); |
| } |
| |
| window_tree_host_manager_->InitHosts(); |
| |
| if (ash::features::IsBootAnimationEnabled()) { |
| booting_animation_controller_ = |
| std::make_unique<BootingAnimationController>(); |
| } |
| |
| // Create virtual keyboard after WindowTreeHostManager::InitHosts() since |
| // it may enable the virtual keyboard immediately, which requires a |
| // WindowTreeHostManager to host the keyboard window. |
| keyboard_controller_->CreateVirtualKeyboard(std::move(keyboard_ui_factory)); |
| |
| // Create window restore controller after `WindowTreeHostManager::InitHosts()` |
| // since it may need to add observers to root windows. |
| window_restore_controller_ = std::make_unique<WindowRestoreController>(); |
| |
| static_cast<CursorManager*>(cursor_manager_.get())->Init(); |
| |
| mojo::PendingRemote<device::mojom::Fingerprint> fingerprint; |
| shell_delegate_->BindFingerprint( |
| fingerprint.InitWithNewPipeAndPassReceiver()); |
| user_activity_notifier_ = |
| std::make_unique<ui::UserActivityPowerManagerNotifier>( |
| user_activity_detector_.get(), std::move(fingerprint)); |
| video_activity_notifier_ = |
| std::make_unique<VideoActivityNotifier>(video_detector_.get()); |
| bluetooth_state_cache_ = std::make_unique<BluetoothStateCache>(); |
| bluetooth_device_status_ui_handler_ = |
| std::make_unique<BluetoothDeviceStatusUiHandler>(); |
| bluetooth_notification_controller_ = |
| std::make_unique<BluetoothNotificationController>( |
| message_center::MessageCenter::Get()); |
| screen_orientation_controller_ = |
| std::make_unique<ScreenOrientationController>(); |
| |
| cros_display_config_ = std::make_unique<CrosDisplayConfig>(); |
| |
| screen_layout_observer_ = std::make_unique<ScreenLayoutObserver>(); |
| sms_observer_ = std::make_unique<SmsObserver>(); |
| snap_controller_ = std::make_unique<SnapControllerImpl>(); |
| key_accessibility_enabler_ = std::make_unique<KeyAccessibilityEnabler>(); |
| |
| // The compositor thread and main message loop have to be running in |
| // order to create mirror window. Run it after the main message loop |
| // is started. |
| display_manager_->CreateMirrorWindowAsyncIfAny(); |
| |
| // TODO(1091497): Consider combining DisplayHighlightController and |
| // DisplayAlignmentController. |
| display_highlight_controller_ = |
| std::make_unique<DisplayHighlightController>(); |
| |
| if (features::IsDisplayAlignmentAssistanceEnabled()) { |
| display_alignment_controller_ = |
| std::make_unique<DisplayAlignmentController>(); |
| } |
| |
| if (features::AreGlanceablesV2Enabled() || |
| features::AreGlanceablesV2EnabledForTrustedTesters()) { |
| glanceables_controller_ = std::make_unique<GlanceablesController>(); |
| } |
| post_login_glanceables_metrics_reporter_ = |
| std::make_unique<PostLoginGlanceablesMetricsRecorder>(); |
| |
| if (features::IsFocusModeEnabled()) { |
| tasks_controller_ = std::make_unique<api::TasksController>( |
| shell_delegate_->CreateTasksDelegate()); |
| } |
| |
| projector_controller_ = std::make_unique<ProjectorControllerImpl>(); |
| |
| float_controller_ = std::make_unique<FloatController>(); |
| pip_controller_ = std::make_unique<PipController>(); |
| |
| multitask_menu_nudge_delegate_ = |
| std::make_unique<MultitaskMenuNudgeDelegateAsh>(); |
| |
| if (features::IsFederatedServiceEnabled()) { |
| federated_service_controller_ = |
| std::make_unique<federated::FederatedServiceControllerImpl>(); |
| } |
| |
| if (features::IsUserEducationEnabled()) { |
| user_education_controller_ = std::make_unique<UserEducationController>( |
| shell_delegate_->CreateUserEducationDelegate()); |
| } |
| |
| if (features::IsCoralFeatureEnabled() && |
| CoralController::IsSecretKeyMatched()) { |
| coral_controller_ = std::make_unique<CoralController>(); |
| } |
| |
| if (features::IsPickerUpdateEnabled() && |
| PickerController::IsFeatureKeyMatched()) { |
| picker_controller_ = std::make_unique<PickerController>(); |
| } |
| |
| // Injects the factory which fulfills the implementation of the text context |
| // menu exclusive to CrOS. |
| views::ViewsTextServicesContextMenuChromeos::SetImplFactory( |
| base::BindRepeating( |
| [](ui::SimpleMenuModel* menu_model, views::Textfield* textfield) |
| -> std::unique_ptr<views::ViewsTextServicesContextMenu> { |
| return std::make_unique<ViewsTextServicesContextMenuAsh>(menu_model, |
| textfield); |
| })); |
| |
| // Sets the implementation of clipboard history utility functions. |
| // It is safe to pass `clipboard_history_controller_` raw pointer here. |
| // Because the function implementation is reset before |
| // `clipboard_history_controller_` is destroyed. |
| chromeos::clipboard_history::SetQueryItemDescriptorsImpl(base::BindRepeating( |
| [](ClipboardHistoryControllerImpl* controller) { |
| std::vector<crosapi::mojom::ClipboardHistoryItemDescriptor> descriptors; |
| if (clipboard_history_util::IsEnabledInCurrentMode()) { |
| const auto& items = controller->history()->GetItems(); |
| descriptors.reserve(items.size()); |
| base::ranges::transform(items, std::back_inserter(descriptors), |
| &clipboard_history_util::ItemToDescriptor); |
| } |
| return descriptors; |
| }, |
| clipboard_history_controller_.get())); |
| chromeos::clipboard_history::SetPasteClipboardItemByIdImpl( |
| base::BindRepeating( |
| [](const base::UnguessableToken& id, int event_flags, |
| crosapi::mojom::ClipboardHistoryControllerShowSource show_source) { |
| ClipboardHistoryController::Get()->PasteClipboardItemById( |
| id.ToString(), event_flags, show_source); |
| })); |
| |
| for (auto& observer : shell_observers_) { |
| observer.OnShellInitialized(); |
| } |
| |
| user_metrics_recorder_->OnShellInitialized(); |
| |
| occlusion_tracker_pauser_ = std::make_unique<OcclusionTrackerPauser>(); |
| |
| // Initialize the D-Bus bus and services for ash. |
| dbus_bus_ = dbus_bus; |
| ash_dbus_services_ = std::make_unique<AshDBusServices>(dbus_bus.get()); |
| } |
| |
| void Shell::InitializeDisplayManager() { |
| if (!native_display_delegate_) { |
| native_display_delegate_ = |
| ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(); |
| } |
| display_manager_->InitConfigurator(std::move(native_display_delegate_)); |
| display_configuration_controller_ = |
| std::make_unique<DisplayConfigurationController>( |
| display_manager_.get(), window_tree_host_manager_.get()); |
| display_configuration_observer_ = |
| std::make_unique<DisplayConfigurationObserver>(); |
| |
| // `window_bounds_tracker_` will be used to remap or restore windows on |
| // display removal, reconnection and rotation if the corresponding flag is |
| // enabled. |
| if (!features::IsWindowBoundsTrackerEnabled()) { |
| persistent_window_controller_ = |
| std::make_unique<PersistentWindowController>(); |
| } |
| |
| projecting_observer_ = |
| std::make_unique<ProjectingObserver>(display_manager_->configurator()); |
| |
| display_prefs_ = std::make_unique<DisplayPrefs>(local_state_); |
| |
| bool display_initialized = display_manager_->InitFromCommandLine(); |
| |
| if (!display_initialized) { |
| if (base::SysInfo::IsRunningOnChromeOS()) { |
| display_change_observer_ = |
| std::make_unique<display::DisplayChangeObserver>( |
| display_manager_.get()); |
| |
| display_error_observer_ = std::make_unique<DisplayErrorObserver>(); |
| display_shutdown_observer_ = std::make_unique<DisplayShutdownObserver>( |
| display_manager_->configurator()); |
| |
| display_manager_->ForceInitialConfigureWithObservers( |
| display_change_observer_.get(), display_error_observer_.get()); |
| display_initialized = true; |
| } |
| } |
| |
| display_color_manager_ = |
| std::make_unique<DisplayColorManager>(display_manager_->configurator()); |
| |
| display_port_observer_ = std::make_unique<display::DisplayPortObserver>( |
| display_manager_->configurator(), |
| base::BindRepeating([](const std::vector<uint32_t>& port_nums) { |
| TypecdClient::Get()->SetTypeCPortsUsingDisplays(port_nums); |
| })); |
| |
| if (!display_initialized) { |
| display_manager_->InitDefaultDisplay(); |
| } |
| } |
| |
| void Shell::InitRootWindow(aura::Window* root_window) { |
| DCHECK(focus_controller_); |
| DCHECK(visibility_controller_.get()); |
| |
| aura::client::SetFocusClient(root_window, focus_controller_.get()); |
| ::wm::SetActivationClient(root_window, focus_controller_.get()); |
| root_window->AddPreTargetHandler(focus_controller_.get()); |
| aura::client::SetVisibilityClient(root_window, visibility_controller_.get()); |
| aura::client::SetDragDropClient(root_window, drag_drop_controller_.get()); |
| aura::client::SetScreenPositionClient(root_window, |
| screen_position_controller_.get()); |
| aura::client::SetCursorClient(root_window, cursor_manager_.get()); |
| ::wm::SetTooltipClient(root_window, tooltip_controller_.get()); |
| aura::client::SetEventClient(root_window, event_client_.get()); |
| |
| ::wm::SetWindowMoveClient(root_window, toplevel_window_event_handler_.get()); |
| root_window->AddPreTargetHandler(toplevel_window_event_handler_.get()); |
| root_window->AddPostTargetHandler(toplevel_window_event_handler_.get()); |
| } |
| |
| void Shell::CloseAllRootWindowChildWindows() { |
| for (aura::Window* root : GetAllRootWindows()) { |
| RootWindowController* controller = RootWindowController::ForWindow(root); |
| if (controller) { |
| controller->CloseChildWindows(); |
| } else { |
| while (!root->children().empty()) { |
| aura::Window* child = root->children()[0]; |
| delete child; |
| } |
| } |
| } |
| } |
| |
| bool Shell::CanWindowReceiveEvents(aura::Window* window) { |
| RootWindowControllerList controllers = GetAllRootWindowControllers(); |
| for (RootWindowController* controller : controllers) { |
| if (controller->CanWindowReceiveEvents(window)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Shell, ui::EventTarget overrides: |
| |
| bool Shell::CanAcceptEvent(const ui::Event& event) { |
| return true; |
| } |
| |
| ui::EventTarget* Shell::GetParentTarget() { |
| return aura::Env::GetInstance(); |
| } |
| |
| std::unique_ptr<ui::EventTargetIterator> Shell::GetChildIterator() const { |
| return nullptr; |
| } |
| |
| ui::EventTargeter* Shell::GetEventTargeter() { |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| void Shell::OnWindowActivated( |
| ::wm::ActivationChangeObserver::ActivationReason reason, |
| aura::Window* gained_active, |
| aura::Window* lost_active) { |
| if (!gained_active) { |
| return; |
| } |
| |
| Shell::SetRootWindowForNewWindows(gained_active->GetRootWindow()); |
| } |
| |
| void Shell::OnFirstSessionStarted() { |
| // Enable magnifier scroll keys as there may be no mouse cursor in kiosk mode. |
| MagnifierKeyScroller::SetEnabled(session_controller_->IsRunningInAppMode()); |
| |
| // Enable long press action to toggle spoken feedback with hotrod remote |
| // which can't handle shortcuts. |
| SpokenFeedbackToggler::SetEnabled(session_controller_->IsRunningInAppMode()); |
| |
| // Reset user prefs related to contextual tooltips. |
| if (switches::ContextualNudgesResetShownCount()) { |
| contextual_tooltip::ClearPrefs(); |
| } |
| |
| // The launcher is not available before login, so start tracking usage after |
| // the session starts. |
| app_list_feature_usage_metrics_ = |
| std::make_unique<AppListFeatureUsageMetrics>(); |
| } |
| |
| void Shell::OnSessionStateChanged(session_manager::SessionState state) { |
| const bool is_session_active = state == session_manager::SessionState::ACTIVE; |
| // Initialize the |shelf_window_watcher_| when a session becomes active. |
| // Shelf itself is initialized in RootWindowController. |
| if (is_session_active && !shelf_window_watcher_) { |
| shelf_window_watcher_ = |
| std::make_unique<ShelfWindowWatcher>(shelf_controller()->model()); |
| } |
| |
| // Initialize the fwupd (firmware updater) DBus client only when the user |
| // session is active. Since the fwupd service is only relevant during an |
| // active user session, this prevents a bug in which the service would start |
| // up earlier than expected and causes a delay during boot. |
| // See b/250002264 for more details. |
| if (is_session_active && !FwupdClient::Get() && |
| !firmware_update_notification_controller_ && |
| !features::IsBlockFwupdClientEnabled()) { |
| chromeos::InitializeDBusClient<FwupdClient>(dbus_bus_.get()); |
| firmware_update_manager_ = std::make_unique<FirmwareUpdateManager>(); |
| // The notification controller is registered as an observer before |
| // requesting updates to allow a notification to be shown if a critical |
| // firmware update is found. |
| firmware_update_notification_controller_ = |
| std::make_unique<FirmwareUpdateNotificationController>( |
| message_center::MessageCenter::Get()); |
| firmware_update_manager_->RequestAllUpdates(); |
| } |
| |
| // Disable drag-and-drop during OOBE and GAIA login screens by only enabling |
| // the controller when the session is active. https://crbug.com/464118 |
| drag_drop_controller_->set_enabled(is_session_active); |
| } |
| |
| void Shell::OnLoginStatusChanged(LoginStatus login_status) { |
| UpdateAfterLoginStatusChange(login_status); |
| } |
| |
| void Shell::OnLockStateChanged(bool locked) { |
| #ifndef NDEBUG |
| // Make sure that there is no system modal in Lock layer when unlocked. |
| if (!locked) { |
| aura::Window::Windows containers = GetContainersForAllRootWindows( |
| kShellWindowId_LockSystemModalContainer, GetPrimaryRootWindow()); |
| for (aura::Window* container : containers) { |
| DCHECK(container->children().empty()); |
| } |
| } |
| #endif |
| } |
| |
| } // namespace ash |