blob: 4925a423fc6e1690fdf2588a3102d56eb26fbcc9 [file] [log] [blame]
// Copyright 2014 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.
#ifndef SERVICES_UI_WS_WINDOW_SERVER_H_
#define SERVICES_UI_WS_WINDOW_SERVER_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/ui/public/interfaces/window_manager_window_tree_factory.mojom.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "services/ui/ws/gpu_host_delegate.h"
#include "services/ui/ws/ids.h"
#include "services/ui/ws/operation.h"
#include "services/ui/ws/server_window_delegate.h"
#include "services/ui/ws/server_window_observer.h"
#include "services/ui/ws/server_window_tracker.h"
#include "services/ui/ws/user_display_manager_delegate.h"
#include "services/ui/ws/video_detector_impl.h"
namespace ui {
namespace ws {
class AccessPolicy;
class Display;
class DisplayManager;
class GpuHost;
class ServerWindow;
class ThreadedImageCursorsFactory;
class UserActivityMonitor;
class WindowManagerDisplayRoot;
class WindowManagerState;
class WindowManagerWindowTreeFactory;
class WindowServerDelegate;
class WindowTree;
class WindowTreeBinding;
enum class DisplayCreationConfig;
// WindowServer manages the set of clients of the window server (all the
// WindowTrees) as well as providing the root of the hierarchy.
class WindowServer : public ServerWindowDelegate,
public ServerWindowObserver,
public GpuHostDelegate,
public UserDisplayManagerDelegate {
public:
WindowServer(WindowServerDelegate* delegate, bool should_host_viz);
~WindowServer() override;
WindowServerDelegate* delegate() { return delegate_; }
DisplayManager* display_manager() { return display_manager_.get(); }
const DisplayManager* display_manager() const {
return display_manager_.get();
}
void SetDisplayCreationConfig(DisplayCreationConfig config);
DisplayCreationConfig display_creation_config() const {
return display_creation_config_;
}
void SetGpuHost(std::unique_ptr<GpuHost> gpu_host);
GpuHost* gpu_host() { return gpu_host_.get(); }
bool is_hosting_viz() const { return !!host_frame_sink_manager_; }
ThreadedImageCursorsFactory* GetThreadedImageCursorsFactory();
// Creates a new ServerWindow. The return value is owned by the caller, but
// must be destroyed before WindowServer.
ServerWindow* CreateServerWindow(
const viz::FrameSinkId& frame_sink_id,
const std::map<std::string, std::vector<uint8_t>>& properties);
// Returns the id for the next WindowTree.
ClientSpecificId GetAndAdvanceNextClientId();
// See description of WindowTree::Embed() for details. This assumes
// |transport_window_id| is valid.
WindowTree* EmbedAtWindow(ServerWindow* root,
mojom::WindowTreeClientPtr client,
uint32_t flags,
std::unique_ptr<AccessPolicy> access_policy);
// Adds |tree_impl_ptr| to the set of known trees. Use DestroyTree() to
// destroy the tree.
void AddTree(std::unique_ptr<WindowTree> tree_impl_ptr,
std::unique_ptr<WindowTreeBinding> binding,
mojom::WindowTreePtr tree_ptr);
WindowTree* CreateTreeForWindowManager(
mojom::WindowTreeRequest window_tree_request,
mojom::WindowTreeClientPtr window_tree_client,
bool automatically_create_display_roots);
// Invoked when a WindowTree's connection encounters an error.
void DestroyTree(WindowTree* tree);
// Returns the tree by client id.
WindowTree* GetTreeWithId(ClientSpecificId client_id);
WindowTree* GetTreeWithClientName(const std::string& client_name);
size_t num_trees() const { return tree_map_.size(); }
OperationType current_operation_type() const {
return current_operation_ ? current_operation_->type()
: OperationType::NONE;
}
// Returns true if the specified client issued the current operation.
bool IsOperationSource(ClientSpecificId client_id) const {
return current_operation_ &&
current_operation_->source_tree_id() == client_id;
}
// Invoked when a client messages a client about the change. This is used
// to avoid sending ServerChangeIdAdvanced() unnecessarily.
void OnTreeMessagedClient(ClientSpecificId id);
// Returns true if OnTreeMessagedClient() was invoked for id.
bool DidTreeMessageClient(ClientSpecificId id) const;
// Returns the WindowTree that has |window| as a root.
WindowTree* GetTreeWithRoot(const ServerWindow* window) {
return const_cast<WindowTree*>(
const_cast<const WindowServer*>(this)->GetTreeWithRoot(window));
}
const WindowTree* GetTreeWithRoot(const ServerWindow* window) const;
UserActivityMonitor* user_activity_monitor() {
return user_activity_monitor_.get();
}
WindowManagerWindowTreeFactory* window_manager_window_tree_factory() {
return window_manager_window_tree_factory_.get();
}
void BindWindowManagerWindowTreeFactory(
mojo::InterfaceRequest<mojom::WindowManagerWindowTreeFactory> request);
// Sets focus to |window|. Returns true if |window| already has focus, or
// focus was successfully changed. Returns |false| if |window| is not a valid
// window to receive focus.
bool SetFocusedWindow(ServerWindow* window);
ServerWindow* GetFocusedWindow();
void SetHighContrastMode(bool enabled);
// Returns a change id for the window manager that is associated with
// |source| and |client_change_id|. When the window manager replies
// WindowManagerChangeCompleted() is called to obtain the original source
// and client supplied change_id that initiated the called.
uint32_t GenerateWindowManagerChangeId(WindowTree* source,
uint32_t client_change_id);
// Called when a response from the window manager is obtained. Calls to
// the client that initiated the change with the change id originally
// supplied by the client.
void WindowManagerChangeCompleted(uint32_t window_manager_change_id,
bool success);
void WindowManagerCreatedTopLevelWindow(WindowTree* wm_tree,
uint32_t window_manager_change_id,
ServerWindow* window);
// Called when we get an unexpected message from the WindowManager.
// TODO(sky): decide what we want to do here.
void WindowManagerSentBogusMessage() {}
// These functions trivially delegate to all WindowTrees, which in
// term notify their clients.
void ProcessWindowBoundsChanged(
const ServerWindow* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
const base::Optional<viz::LocalSurfaceId>& local_surface_id);
void ProcessWindowTransformChanged(const ServerWindow* window,
const gfx::Transform& old_transform,
const gfx::Transform& new_transform);
void ProcessClientAreaChanged(
const ServerWindow* window,
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& new_additional_client_areas);
void ProcessCaptureChanged(const ServerWindow* new_capture,
const ServerWindow* old_capture);
void ProcessWillChangeWindowHierarchy(const ServerWindow* window,
const ServerWindow* new_parent,
const ServerWindow* old_parent);
void ProcessWindowHierarchyChanged(const ServerWindow* window,
const ServerWindow* new_parent,
const ServerWindow* old_parent);
void ProcessWindowReorder(const ServerWindow* window,
const ServerWindow* relative_window,
const mojom::OrderDirection direction);
void ProcessWindowDeleted(ServerWindow* window);
void ProcessWillChangeWindowCursor(ServerWindow* window,
const ui::CursorData& cursor);
// Sends an |event| to all WindowTrees that might be observing events. Skips
// |ignore_tree| if it is non-null. |target_window| is the target of the
// event.
void SendToPointerWatchers(const ui::Event& event,
ServerWindow* target_window,
WindowTree* ignore_tree,
int64_t display_id);
// Sets a callback to be called whenever a surface is activated. This
// corresponds a client submitting a new CompositorFrame for a Window. This
// should only be called in a test configuration.
void SetSurfaceActivationCallback(
base::OnceCallback<void(ServerWindow*)> callback);
void StartMoveLoop(uint32_t change_id,
ServerWindow* window,
WindowTree* initiator,
const gfx::Rect& revert_bounds);
void EndMoveLoop();
uint32_t GetCurrentMoveLoopChangeId();
ServerWindow* GetCurrentMoveLoopWindow();
WindowTree* GetCurrentMoveLoopInitiator();
gfx::Rect GetCurrentMoveLoopRevertBounds();
bool in_move_loop() const { return !!current_move_loop_; }
void StartDragLoop(uint32_t change_id,
ServerWindow* window,
WindowTree* initiator);
void EndDragLoop();
uint32_t GetCurrentDragLoopChangeId();
ServerWindow* GetCurrentDragLoopWindow();
WindowTree* GetCurrentDragLoopInitiator();
bool in_drag_loop() const { return !!current_drag_loop_; }
void OnDisplayReady(Display* display, bool is_first);
void OnDisplayDestroyed(Display* display);
void OnNoMoreDisplays();
WindowManagerState* GetWindowManagerState();
VideoDetectorImpl* video_detector() { return &video_detector_; }
// ServerWindowDelegate:
VizHostProxy* GetVizHostProxy() override;
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info,
ServerWindow* window) override;
// UserDisplayManagerDelegate:
bool GetFrameDecorations(mojom::FrameDecorationValuesPtr* values) override;
int64_t GetInternalDisplayId() override;
private:
struct CurrentMoveLoopState;
struct CurrentDragLoopState;
friend class Operation;
using WindowTreeMap =
std::map<ClientSpecificId, std::unique_ptr<WindowTree>>;
struct InFlightWindowManagerChange {
// Identifies the client that initiated the change.
ClientSpecificId client_id;
// Change id supplied by the client.
uint32_t client_change_id;
};
using InFlightWindowManagerChangeMap =
std::map<uint32_t, InFlightWindowManagerChange>;
bool GetAndClearInFlightWindowManagerChange(
uint32_t window_manager_change_id,
InFlightWindowManagerChange* change);
// Invoked when a client is about to execute a window server operation.
// Subsequently followed by FinishOperation() once the change is done.
//
// Changes should never nest, meaning each PrepareForOperation() must be
// balanced with a call to FinishOperation() with no PrepareForOperation()
// in between.
void PrepareForOperation(Operation* op);
// Balances a call to PrepareForOperation().
void FinishOperation();
// Updates the native cursor by figuring out what window is under the mouse
// cursor. This is run in response to events that change the bounds or window
// hierarchy.
void UpdateNativeCursorFromMouseLocation(ServerWindow* window);
void UpdateNativeCursorFromMouseLocation(
WindowManagerDisplayRoot* display_root);
// Updates the native cursor if the cursor is currently inside |window|. This
// is run in response to events that change the mouse cursor properties of
// |window|.
void UpdateNativeCursorIfOver(ServerWindow* window);
// Finds the parent client that will embed |surface_id| and claims ownership
// of the temporary reference. If no parent client is found then tell GPU to
// immediately drop the temporary reference. |window| is the ServerWindow
// that corresponds to |surface_id|.
void HandleTemporaryReferenceForNewSurface(const viz::SurfaceId& surface_id,
ServerWindow* window);
void CreateFrameSinkManager();
// Overridden from ServerWindowDelegate:
ServerWindow* GetRootWindowForDrawn(const ServerWindow* window) override;
// Overridden from ServerWindowObserver:
void OnWindowDestroyed(ServerWindow* window) override;
void OnWillChangeWindowHierarchy(ServerWindow* window,
ServerWindow* new_parent,
ServerWindow* old_parent) override;
void OnWindowHierarchyChanged(ServerWindow* window,
ServerWindow* new_parent,
ServerWindow* old_parent) override;
void OnWindowBoundsChanged(ServerWindow* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) override;
void OnWindowTransformChanged(ServerWindow* window,
const gfx::Transform& old_transform,
const gfx::Transform& new_transform) override;
void OnWindowClientAreaChanged(
ServerWindow* window,
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& new_additional_client_areas) override;
void OnWindowReordered(ServerWindow* window,
ServerWindow* relative,
mojom::OrderDirection direction) override;
void OnWillChangeWindowVisibility(ServerWindow* window) override;
void OnWindowVisibilityChanged(ServerWindow* window) override;
void OnWindowOpacityChanged(ServerWindow* window,
float old_opacity,
float new_opacity) override;
void OnWindowSharedPropertyChanged(
ServerWindow* window,
const std::string& name,
const std::vector<uint8_t>* new_data) override;
void OnWindowCursorChanged(ServerWindow* window,
const ui::CursorData& cursor) override;
void OnWindowNonClientCursorChanged(ServerWindow* window,
const ui::CursorData& cursor) override;
void OnWindowTextInputStateChanged(ServerWindow* window,
const ui::TextInputState& state) override;
void OnTransientWindowAdded(ServerWindow* window,
ServerWindow* transient_child) override;
void OnTransientWindowRemoved(ServerWindow* window,
ServerWindow* transient_child) override;
void OnWindowModalTypeChanged(ServerWindow* window,
ModalType old_modal_type) override;
// GpuHostDelegate:
void OnGpuServiceInitialized() override;
WindowServerDelegate* delegate_;
// ID to use for next WindowTree.
ClientSpecificId next_client_id_;
std::unique_ptr<DisplayManager> display_manager_;
std::unique_ptr<CurrentDragLoopState> current_drag_loop_;
std::unique_ptr<CurrentMoveLoopState> current_move_loop_;
// Set of WindowTrees.
WindowTreeMap tree_map_;
// If non-null then we're processing a client operation. The Operation is
// not owned by us (it's created on the stack by WindowTree).
Operation* current_operation_;
bool in_destructor_;
bool high_contrast_mode_ = false;
// Maps from window manager change id to the client that initiated the
// request.
InFlightWindowManagerChangeMap in_flight_wm_change_map_;
// Next id supplied to the window manager.
uint32_t next_wm_change_id_;
std::unique_ptr<GpuHost> gpu_host_;
base::OnceCallback<void(ServerWindow*)> surface_activation_callback_;
std::unique_ptr<UserActivityMonitor> user_activity_monitor_;
std::unique_ptr<WindowManagerWindowTreeFactory>
window_manager_window_tree_factory_;
viz::SurfaceId root_surface_id_;
// Incremented when the viz process is restarted.
uint32_t viz_restart_id_ = viz::BeginFrameSource::kNotRestartableId + 1;
// Provides interfaces to create and manage FrameSinks.
std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
std::unique_ptr<VizHostProxy> viz_host_proxy_;
VideoDetectorImpl video_detector_;
// System modal windows not attached to a display are added here. Once
// attached to a display they are removed.
ServerWindowTracker pending_system_modal_windows_;
DisplayCreationConfig display_creation_config_;
DISALLOW_COPY_AND_ASSIGN(WindowServer);
};
} // namespace ws
} // namespace ui
#endif // SERVICES_UI_WS_WINDOW_SERVER_H_