| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/exo/wm_helper_chromeos.h" |
| |
| #include "ash/frame_throttler/frame_throttling_controller.h" |
| #include "ash/public/cpp/shell_window_ids.h" |
| #include "ash/shell.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller.h" |
| #include "base/bind.h" |
| #include "base/callback_helpers.h" |
| #include "base/memory/singleton.h" |
| #include "base/time/time.h" |
| #include "chromeos/dbus/power/power_manager_client.h" |
| #include "chromeos/dbus/power_manager/backlight.pb.h" |
| #include "components/exo/wm_helper.h" |
| #include "ui/aura/client/drag_drop_client.h" |
| #include "ui/aura/client/drag_drop_delegate.h" |
| #include "ui/aura/client/focus_client.h" |
| #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" |
| #include "ui/base/dragdrop/drag_drop_types.h" |
| #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/layer.h" |
| #include "ui/display/manager/display_configurator.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/types/display_snapshot.h" |
| #include "ui/display/util/display_util.h" |
| #include "ui/wm/core/capture_controller.h" |
| #include "ui/wm/public/activation_client.h" |
| |
| namespace exo { |
| namespace { |
| |
| aura::Window* GetPrimaryRoot() { |
| return ash::Shell::Get()->GetPrimaryRootWindow(); |
| } |
| |
| } // namespace |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // WMHelperChromeOS, public: |
| |
| WMHelperChromeOS::WMHelperChromeOS() : vsync_timing_manager_(this) { |
| auto* power_manager = chromeos::PowerManagerClient::Get(); |
| // May be null in tests |
| if (power_manager) |
| power_manager->AddObserver(this); |
| } |
| |
| WMHelperChromeOS::~WMHelperChromeOS() { |
| auto* power_manager = chromeos::PowerManagerClient::Get(); |
| if (power_manager) |
| power_manager->RemoveObserver(this); |
| } |
| |
| WMHelperChromeOS* WMHelperChromeOS::GetInstance() { |
| return static_cast<WMHelperChromeOS*>(WMHelper::GetInstance()); |
| } |
| |
| void WMHelperChromeOS::AddTabletModeObserver( |
| ash::TabletModeObserver* observer) { |
| ash::Shell::Get()->tablet_mode_controller()->AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemoveTabletModeObserver( |
| ash::TabletModeObserver* observer) { |
| ash::Shell::Get()->tablet_mode_controller()->RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::AddDisplayConfigurationObserver( |
| ash::WindowTreeHostManager::Observer* observer) { |
| ash::Shell::Get()->window_tree_host_manager()->AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemoveDisplayConfigurationObserver( |
| ash::WindowTreeHostManager::Observer* observer) { |
| ash::Shell::Get()->window_tree_host_manager()->RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::AddFrameThrottlingObserver() { |
| ash::FrameThrottlingController* controller = |
| ash::Shell::Get()->frame_throttling_controller(); |
| if (!controller->HasArcObserver(&vsync_timing_manager_)) { |
| ash::Shell::Get()->frame_throttling_controller()->AddArcObserver( |
| &vsync_timing_manager_); |
| } |
| } |
| |
| void WMHelperChromeOS::RemoveFrameThrottlingObserver() { |
| ash::Shell::Get()->frame_throttling_controller()->RemoveArcObserver( |
| &vsync_timing_manager_); |
| } |
| |
| void WMHelperChromeOS::AddPowerObserver(WMHelper::PowerObserver* observer) { |
| power_observers_.AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemovePowerObserver(WMHelper::PowerObserver* observer) { |
| power_observers_.RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::AddActivationObserver( |
| wm::ActivationChangeObserver* observer) { |
| ash::Shell::Get()->activation_client()->AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemoveActivationObserver( |
| wm::ActivationChangeObserver* observer) { |
| ash::Shell::Get()->activation_client()->RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::AddFocusObserver( |
| aura::client::FocusChangeObserver* observer) { |
| aura::client::GetFocusClient(GetPrimaryRoot())->AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemoveFocusObserver( |
| aura::client::FocusChangeObserver* observer) { |
| aura::client::GetFocusClient(GetPrimaryRoot())->RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::AddDragDropObserver(DragDropObserver* observer) { |
| drag_drop_observers_.AddObserver(observer); |
| } |
| |
| void WMHelperChromeOS::RemoveDragDropObserver(DragDropObserver* observer) { |
| drag_drop_observers_.RemoveObserver(observer); |
| } |
| |
| void WMHelperChromeOS::SetDragDropDelegate(aura::Window* window) { |
| aura::client::SetDragDropDelegate(window, this); |
| } |
| |
| void WMHelperChromeOS::ResetDragDropDelegate(aura::Window* window) { |
| aura::client::SetDragDropDelegate(window, nullptr); |
| } |
| |
| VSyncTimingManager& WMHelperChromeOS::GetVSyncTimingManager() { |
| return vsync_timing_manager_; |
| } |
| |
| void WMHelperChromeOS::OnDragEntered(const ui::DropTargetEvent& event) { |
| for (DragDropObserver& observer : drag_drop_observers_) |
| observer.OnDragEntered(event); |
| } |
| |
| aura::client::DragUpdateInfo WMHelperChromeOS::OnDragUpdated( |
| const ui::DropTargetEvent& event) { |
| aura::client::DragUpdateInfo drag_info( |
| ui::DragDropTypes::DRAG_NONE, |
| ui::DataTransferEndpoint(ui::EndpointType::kUnknownVm)); |
| |
| for (DragDropObserver& observer : drag_drop_observers_) { |
| auto observer_drag_info = observer.OnDragUpdated(event); |
| drag_info.drag_operation = |
| drag_info.drag_operation | observer_drag_info.drag_operation; |
| if (observer_drag_info.data_endpoint.type() != |
| drag_info.data_endpoint.type()) |
| drag_info.data_endpoint = observer_drag_info.data_endpoint; |
| } |
| return drag_info; |
| } |
| |
| void WMHelperChromeOS::OnDragExited() { |
| for (DragDropObserver& observer : drag_drop_observers_) |
| observer.OnDragExited(); |
| } |
| |
| aura::client::DragDropDelegate::DropCallback WMHelperChromeOS::GetDropCallback( |
| const ui::DropTargetEvent& event) { |
| std::vector<WMHelper::DragDropObserver::DropCallback> drop_callbacks; |
| for (DragDropObserver& observer : drag_drop_observers_) { |
| WMHelper::DragDropObserver::DropCallback drop_cb = |
| observer.GetDropCallback(); |
| if (!drop_cb.is_null()) { |
| drop_callbacks.push_back(std::move(drop_cb)); |
| } |
| } |
| return base::BindOnce(&WMHelperChromeOS::PerformDrop, |
| weak_ptr_factory_.GetWeakPtr(), |
| std::move(drop_callbacks)); |
| } |
| |
| void WMHelperChromeOS::SuspendDone(base::TimeDelta sleep_duration) { |
| for (PowerObserver& observer : power_observers_) |
| observer.SuspendDone(); |
| } |
| |
| void WMHelperChromeOS::ScreenBrightnessChanged( |
| const power_manager::BacklightBrightnessChange& change) { |
| for (PowerObserver& observer : power_observers_) |
| observer.ScreenBrightnessChanged(change.percent()); |
| } |
| |
| void WMHelperChromeOS::LidEventReceived( |
| chromeos::PowerManagerClient::LidState state, |
| base::TimeTicks timestamp) { |
| for (PowerObserver& observer : power_observers_) |
| observer.LidEventReceived(state == |
| chromeos::PowerManagerClient::LidState::OPEN); |
| } |
| |
| void WMHelperChromeOS::AddVSyncParameterObserver( |
| mojo::PendingRemote<viz::mojom::VSyncParameterObserver> observer) { |
| GetPrimaryRoot()->layer()->GetCompositor()->AddVSyncParameterObserver( |
| std::move(observer)); |
| } |
| |
| const display::ManagedDisplayInfo& WMHelperChromeOS::GetDisplayInfo( |
| int64_t display_id) const { |
| return ash::Shell::Get()->display_manager()->GetDisplayInfo(display_id); |
| } |
| |
| const std::vector<uint8_t>& WMHelperChromeOS::GetDisplayIdentificationData( |
| int64_t display_id) const { |
| const auto& displays = |
| ash::Shell::Get()->display_configurator()->cached_displays(); |
| |
| for (display::DisplaySnapshot* display : displays) |
| if (display->display_id() == display_id) |
| return display->edid(); |
| |
| static std::vector<uint8_t> no_data; |
| return no_data; |
| } |
| |
| bool WMHelperChromeOS::GetActiveModeForDisplayId( |
| int64_t display_id, |
| display::ManagedDisplayMode* mode) const { |
| return ash::Shell::Get()->display_manager()->GetActiveModeForDisplayId( |
| display_id, mode); |
| } |
| |
| aura::Window* WMHelperChromeOS::GetPrimaryDisplayContainer(int container_id) { |
| return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), |
| container_id); |
| } |
| |
| aura::Window* WMHelperChromeOS::GetActiveWindow() const { |
| return ash::Shell::Get()->activation_client()->GetActiveWindow(); |
| } |
| |
| aura::Window* WMHelperChromeOS::GetFocusedWindow() const { |
| aura::client::FocusClient* focus_client = |
| aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); |
| return focus_client->GetFocusedWindow(); |
| } |
| |
| aura::Window* WMHelperChromeOS::GetRootWindowForNewWindows() const { |
| return ash::Shell::GetRootWindowForNewWindows(); |
| } |
| |
| aura::client::CursorClient* WMHelperChromeOS::GetCursorClient() { |
| return aura::client::GetCursorClient(ash::Shell::GetPrimaryRootWindow()); |
| } |
| |
| aura::client::DragDropClient* WMHelperChromeOS::GetDragDropClient() { |
| return aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()); |
| } |
| |
| void WMHelperChromeOS::AddPreTargetHandler(ui::EventHandler* handler) { |
| ash::Shell::Get()->AddPreTargetHandler(handler); |
| } |
| |
| void WMHelperChromeOS::PrependPreTargetHandler(ui::EventHandler* handler) { |
| ash::Shell::Get()->AddPreTargetHandler( |
| handler, ui::EventTarget::Priority::kAccessibility); |
| } |
| |
| void WMHelperChromeOS::RemovePreTargetHandler(ui::EventHandler* handler) { |
| ash::Shell::Get()->RemovePreTargetHandler(handler); |
| } |
| |
| void WMHelperChromeOS::AddPostTargetHandler(ui::EventHandler* handler) { |
| ash::Shell::Get()->AddPostTargetHandler(handler); |
| } |
| |
| void WMHelperChromeOS::RemovePostTargetHandler(ui::EventHandler* handler) { |
| ash::Shell::Get()->RemovePostTargetHandler(handler); |
| } |
| |
| bool WMHelperChromeOS::InTabletMode() const { |
| return ash::Shell::Get()->tablet_mode_controller()->InTabletMode(); |
| } |
| |
| double WMHelperChromeOS::GetDefaultDeviceScaleFactor() const { |
| return exo::GetDefaultDeviceScaleFactor(); |
| } |
| |
| double WMHelperChromeOS::GetDeviceScaleFactorForWindow( |
| aura::Window* window) const { |
| if (default_scale_cancellation_) |
| return exo::GetDefaultDeviceScaleFactor(); |
| const display::Screen* screen = display::Screen::GetScreen(); |
| display::Display display = screen->GetDisplayNearestWindow(window); |
| return display.device_scale_factor(); |
| } |
| |
| void WMHelperChromeOS::SetDefaultScaleCancellation( |
| bool default_scale_cancellation) { |
| default_scale_cancellation_ = default_scale_cancellation; |
| } |
| |
| WMHelper::LifetimeManager* WMHelperChromeOS::GetLifetimeManager() { |
| return &lifetime_manager_; |
| } |
| |
| aura::client::CaptureClient* WMHelperChromeOS::GetCaptureClient() { |
| return wm::CaptureController::Get(); |
| } |
| |
| float GetDefaultDeviceScaleFactor() { |
| if (!display::HasInternalDisplay()) |
| return 1.0; |
| |
| if (display::Display::HasForceDeviceScaleFactor()) |
| return display::Display::GetForcedDeviceScaleFactor(); |
| |
| display::DisplayManager* display_manager = |
| ash::Shell::Get()->display_manager(); |
| const display::ManagedDisplayInfo& display_info = |
| display_manager->GetDisplayInfo(display::Display::InternalDisplayId()); |
| DCHECK(display_info.display_modes().size()); |
| return display_info.display_modes()[0].device_scale_factor(); |
| } |
| |
| void WMHelperChromeOS::PerformDrop( |
| std::vector<WMHelper::DragDropObserver::DropCallback> drop_callbacks, |
| std::unique_ptr<ui::OSExchangeData> data, |
| ui::mojom::DragOperation& output_drag_op) { |
| for (auto& drop_cb : drop_callbacks) { |
| auto operation = ui::mojom::DragOperation::kNone; |
| std::move(drop_cb).Run(operation); |
| if (operation != ui::mojom::DragOperation::kNone) |
| output_drag_op = operation; |
| } |
| } |
| |
| } // namespace exo |