blob: 87f52274271c658cebec4833a056e5c2982d8821 [file] [log] [blame]
// Copyright 2017 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.
#include "garnet/lib/ui/gfx/displays/display_watcher.h"
#include <fcntl.h>
#include <lib/fidl/cpp/message.h>
#include <zircon/device/display-controller.h>
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/logging.h"
namespace scenic_impl {
namespace gfx {
static const std::string kDisplayDir = "/dev/class/display-controller";
DisplayWatcher::DisplayWatcher() = default;
DisplayWatcher::~DisplayWatcher() = default;
void DisplayWatcher::WaitForDisplay(DisplayReadyCallback callback) {
FXL_DCHECK(!device_watcher_);
// See declare_args() in lib/ui/gfx/BUILD.gn
#if SCENIC_VULKAN_SWAPCHAIN == 2
// This is just for testing, so notify that there's a fake display.
callback(fxl::UniqueFD(-1), ZX_HANDLE_INVALID, ZX_HANDLE_INVALID);
#else
device_watcher_ = fsl::DeviceWatcher::Create(
kDisplayDir, [this, callback = std::move(callback)](
int dir_fd, std::string filename) mutable {
HandleDevice(std::move(callback), dir_fd, filename);
});
#endif
}
void DisplayWatcher::HandleDevice(DisplayReadyCallback callback, int dir_fd,
std::string filename) {
device_watcher_.reset();
// Get display info.
std::string path = kDisplayDir + "/" + filename;
FXL_LOG(INFO) << "Scenic: Acquired display controller " << path << ".("
<< filename << ")";
fxl::UniqueFD fd(open(path.c_str(), O_RDWR));
if (!fd.is_valid()) {
FXL_DLOG(ERROR) << "Failed to open " << path << ": errno=" << errno;
callback(fxl::UniqueFD(), zx::channel());
return;
}
zx::channel dc_handle;
if (ioctl_display_controller_get_handle(
fd.get(), dc_handle.reset_and_get_address()) != sizeof(zx_handle_t)) {
FXL_DLOG(ERROR) << "Failed to get device channel";
callback(fxl::UniqueFD(), zx::channel());
return;
}
callback(std::move(fd), std::move(dc_handle));
}
} // namespace gfx
} // namespace scenic_impl