blob: d06de0ec998a574b2a1a54f1ebbd94cbc9aa7d6a [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_MANAGER2_H_
#define SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_MANAGER2_H_
#include <fuchsia/hardware/display/cpp/fidl.h>
#include <fuchsia/ui/display/cpp/fidl.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/zx/channel.h>
#include <zircon/pixelformat.h>
#include <vector>
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/ui/scenic/lib/display/display_controller.h"
#include "src/ui/scenic/lib/display/display_controller_listener.h"
namespace scenic_impl {
namespace display {
// Implements the |fuchsia::ui::display::DisplayManager| protocol. Notifies protocol clients
// of new or removed displays and allows changing of display configuration. Every display is
// associated with a DisplayRef which can also be used as a parameter to other apis (e.g. Scenic).
// Additionally, allows an internal (within Scenic) client to claim the display and
class DisplayManager2 : public fuchsia::ui::display::DisplayManager {
public:
DisplayManager2();
// |fuchsia::ui::display::DisplayManager|
void AddDisplayListener(fidl::InterfaceHandle<fuchsia::ui::display::DisplayListener>
display_listener_interface_handle) override;
// Remaining methods are not part of the FIDL protocol.
// Called by initializing code whenever a new DisplayzController is discovered, or by tests.
void AddDisplayController(
std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller,
std::unique_ptr<DisplayControllerListener> controller_listener);
DisplayControllerUniquePtr ClaimDisplay(zx_koid_t display_ref_koid);
DisplayControllerUniquePtr ClaimFirstDisplayDeprecated();
const fxl::WeakPtr<DisplayManager2> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
// For testing purposes only.
const std::string& last_error() { return last_error_; }
DisplayManager2(const DisplayManager2&) = delete;
DisplayManager2(DisplayManager2&&) = delete;
DisplayManager2& operator=(const DisplayManager2&) = delete;
DisplayManager2& operator=(DisplayManager2&&) = delete;
private:
struct DisplayInfoPrivate {
// |id| assigned by the DisplayController.
uint64_t id = 0;
zx_koid_t display_ref_koid = 0;
std::vector<zx_pixel_format_t> pixel_formats;
// Interface for the DisplayController that this display is connected to.
std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller;
// Also stores the key version of the DisplayRef.
fuchsia::ui::display::Info info;
};
// Internal data structure that holds the DisplayController interface and
// associated info (listener, list of Displays).
struct DisplayControllerPrivate {
// If a a client has called ClaimDisplay(), this will be non-null and point
// to the DisplayController passed to the client. This pointer is nulled
// out by the custom deleter for the DisplayController.
DisplayController* claimed_dc = nullptr;
std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller;
std::unique_ptr<DisplayControllerListener> listener;
std::vector<DisplayInfoPrivate> displays;
// The latest value of the OnClientOwnershipChange event from the
// display controller.
bool has_ownership = false;
};
using DisplayControllerPrivateUniquePtr =
std::unique_ptr<DisplayControllerPrivate, std::function<void(DisplayControllerPrivate*)>>;
void RemoveOnInvalid(DisplayControllerPrivate* dc);
void OnDisplaysChanged(DisplayControllerPrivate* dc,
std::vector<fuchsia::hardware::display::Info> displays_added,
std::vector<uint64_t> displays_removed);
void OnDisplayOwnershipChanged(DisplayControllerPrivate* dc, bool has_ownership);
std::tuple<DisplayControllerPrivate*, DisplayInfoPrivate*> FindDisplay(
zx_koid_t display_ref_koid);
DisplayControllerPrivate* FindDisplayControllerPrivate(DisplayController* dc);
static DisplayInfoPrivate NewDisplayInfoPrivate(
fuchsia::hardware::display::Info hardware_display_info,
std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> controller);
static void InvokeDisplayAddedForListener(
const fidl::InterfacePtr<fuchsia::ui::display::DisplayListener>& listener,
const DisplayInfoPrivate& display_info_private);
static void InvokeDisplayOwnershipChangedForListener(
const fidl::InterfacePtr<fuchsia::ui::display::DisplayListener>& listener,
DisplayControllerPrivate* dc, bool has_ownership);
// Helper functions for lists of DisplayInfoPrivate.
static bool HasDisplayWithId(const std::vector<DisplayManager2::DisplayInfoPrivate>& displays,
uint64_t display_id);
static std::optional<DisplayManager2::DisplayInfoPrivate> RemoveDisplayWithId(
std::vector<DisplayInfoPrivate>* displays, uint64_t display_id);
std::vector<DisplayControllerPrivateUniquePtr> display_controllers_private_;
fidl::InterfacePtrSet<fuchsia::ui::display::DisplayListener> display_listeners_;
std::string last_error_;
fxl::WeakPtrFactory<DisplayManager2> weak_factory_; // must be last
};
} // namespace display
} // namespace scenic_impl
#endif // SRC_UI_SCENIC_LIB_DISPLAY_DISPLAY_MANAGER2_H_