Commit ff39d429 authored by Gil Dekel's avatar Gil Dekel Committed by Commit Bot

ozone/drm: Add privacy-screen modifier in DisplayConfigurator

Certain chromebooks now come with panels that have integrated privacy
screens on them. This CL exposes an API in DisplayConfigurator to
set the KMS property, privacy-screen, to the desired state.

Bug: b/147451643
Test: tested locally on a test device
Change-Id: Iafa61365ce20c147eaa672cf33d8d3c6104bcb89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2015648
Commit-Queue: Gil Dekel <gildekel@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735158}
parent 988c98a5
......@@ -177,6 +177,8 @@ bool FakeDisplayDelegate::SetGammaCorrection(
return false;
}
void FakeDisplayDelegate::SetPrivacyScreen(int64_t display_id, bool enabled) {}
void FakeDisplayDelegate::AddObserver(NativeDisplayObserver* observer) {
observers_.AddObserver(observer);
}
......
......@@ -99,6 +99,7 @@ class FAKE_DISPLAY_EXPORT FakeDisplayDelegate : public NativeDisplayDelegate,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void AddObserver(NativeDisplayObserver* observer) override;
void RemoveObserver(NativeDisplayObserver* observer) override;
FakeDisplayController* GetFakeDisplayController() override;
......
......@@ -259,6 +259,11 @@ Builder& Builder::SetHighDPI() {
return SetDPI(326); // Retina-ish.
}
Builder& Builder::SetPrivacyScreen(PrivacyScreenState state) {
privacy_screen_state_ = state;
return *this;
}
const DisplayMode* Builder::AddOrFindDisplayMode(const gfx::Size& size) {
for (auto& mode : modes_) {
if (mode->size() == size)
......
......@@ -69,6 +69,7 @@ class FAKE_DISPLAY_EXPORT FakeDisplaySnapshot : public DisplaySnapshot {
Builder& SetLowDPI();
// Sets physical_size for high DPI display.
Builder& SetHighDPI();
Builder& SetPrivacyScreen(PrivacyScreenState state);
private:
// Returns a display mode with |size|. If there is no existing mode, insert
......
......@@ -782,6 +782,31 @@ bool DisplayConfigurator::SetGammaCorrection(
display_id, degamma_lut, gamma_lut));
}
bool DisplayConfigurator::SetPrivacyScreen(int64_t display_id, bool enabled) {
for (DisplaySnapshot* display : cached_displays_) {
if (display->display_id() != display_id)
continue;
if (display->type() != DISPLAY_CONNECTION_TYPE_INTERNAL) {
LOG(ERROR) << "[Display ID: " << display_id
<< "] Privacy screen is not supported for external displays "
"at this time.";
return false;
}
if (display->privacy_screen_state() == kNotSupported) {
LOG(ERROR) << "Display with ID " << display_id
<< " does not support the privacy-screen property.";
return false;
}
native_display_delegate_->SetPrivacyScreen(display_id, enabled);
return true;
}
return false;
}
chromeos::DisplayPowerState DisplayConfigurator::GetRequestedPowerState()
const {
return requested_power_state_.value_or(chromeos::DISPLAY_POWER_ALL_ON);
......
......@@ -266,6 +266,11 @@ class DISPLAY_MANAGER_EXPORT DisplayConfigurator
const std::vector<GammaRampRGBEntry>& degamma_lut,
const std::vector<GammaRampRGBEntry>& gamma_lut);
// Enabled/disable the privacy screen on the display with |display_id|.
// For this to succeed the display must be internal and support the privacy
// screen feature.
bool SetPrivacyScreen(int64_t display_id, bool enabled);
// Returns the requested power state if set or the default power state.
chromeos::DisplayPowerState GetRequestedPowerState() const;
......
......@@ -1361,6 +1361,63 @@ TEST_F(DisplayConfiguratorTest, SuspendResumeWithMultipleDisplays) {
configurator_.display_state());
}
TEST_F(DisplayConfiguratorTest, EnablePrivacyScreenOnSupportedEmbeddedDisplay) {
outputs_[0] = FakeDisplaySnapshot::Builder()
.SetId(kDisplayIds[0])
.SetNativeMode(small_mode_.Clone())
.SetCurrentMode(small_mode_.Clone())
.AddMode(big_mode_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetIsAspectPerservingScaling(true)
.SetPrivacyScreen(kDisabled)
.Build();
state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
InitWithOutputs(&small_mode_);
observer_.Reset();
EXPECT_TRUE(configurator_.SetPrivacyScreen(kDisplayIds[0], true));
EXPECT_EQ(SetPrivacyScreenAction(kDisplayIds[0], true),
log_->GetActionsAndClear());
}
TEST_F(DisplayConfiguratorTest,
EnablePrivacyScreenOnUnsupportedEmbeddedDisplay) {
outputs_[0] = FakeDisplaySnapshot::Builder()
.SetId(kDisplayIds[0])
.SetNativeMode(big_mode_.Clone())
.SetCurrentMode(big_mode_.Clone())
.AddMode(small_mode_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetIsAspectPerservingScaling(true)
.SetPrivacyScreen(kNotSupported)
.Build();
state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
InitWithOutputs(&big_mode_);
observer_.Reset();
EXPECT_FALSE(configurator_.SetPrivacyScreen(kDisplayIds[0], true));
EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
}
TEST_F(DisplayConfiguratorTest, EnablePrivacyScreenOnExternalDisplay) {
outputs_[0] = FakeDisplaySnapshot::Builder()
.SetId(kDisplayIds[0])
.SetNativeMode(small_mode_.Clone())
.SetCurrentMode(small_mode_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetIsAspectPerservingScaling(true)
.SetPrivacyScreen(kNotSupported)
.Build();
state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
InitWithOutputs(&small_mode_);
observer_.Reset();
EXPECT_FALSE(configurator_.SetPrivacyScreen(kDisplayIds[0], true));
EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
}
class DisplayConfiguratorMultiMirroringTest : public DisplayConfiguratorTest {
public:
DisplayConfiguratorMultiMirroringTest() = default;
......
......@@ -69,6 +69,11 @@ std::string SetGammaCorrectionAction(
gamma_table.c_str());
}
std::string SetPrivacyScreenAction(int64_t display_id, bool enabled) {
return base::StringPrintf("set_privacy_screen(id=%" PRId64 ",state=%d)",
display_id, enabled);
}
std::string JoinActions(const char* action, ...) {
std::string actions;
......
......@@ -57,6 +57,10 @@ std::string SetGammaCorrectionAction(
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
// Returns a string describing a TestNativedisplaydelegate::SetPrivacyScreen()
// call.
std::string SetPrivacyScreenAction(int64_t display_id, bool enabled);
// Joins a sequence of strings describing actions (e.g. kScreenDim) such
// that they can be compared against a string returned by
// ActionLogger::GetActionsAndClear(). The list of actions must be
......
......@@ -146,6 +146,11 @@ bool TestNativeDisplayDelegate::SetGammaCorrection(
return true;
}
void TestNativeDisplayDelegate::SetPrivacyScreen(int64_t display_id,
bool enabled) {
log_->AppendAction(SetPrivacyScreenAction(display_id, enabled));
}
void TestNativeDisplayDelegate::AddObserver(NativeDisplayObserver* observer) {
observers_.AddObserver(observer);
}
......
......@@ -72,6 +72,7 @@ class TestNativeDisplayDelegate : public NativeDisplayDelegate {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void AddObserver(NativeDisplayObserver* observer) override;
void RemoveObserver(NativeDisplayObserver* observer) override;
FakeDisplayController* GetFakeDisplayController() override;
......
......@@ -86,6 +86,9 @@ class DISPLAY_TYPES_EXPORT NativeDisplayDelegate {
const std::vector<GammaRampRGBEntry>& degamma_lut,
const std::vector<GammaRampRGBEntry>& gamma_lut) = 0;
// Sets the privacy screen state on the display with |display_id|.
virtual void SetPrivacyScreen(int64_t display_id, bool enabled) = 0;
virtual void AddObserver(NativeDisplayObserver* observer) = 0;
virtual void RemoveObserver(NativeDisplayObserver* observer) = 0;
......
......@@ -155,6 +155,10 @@ IPC_MESSAGE_CONTROL3(OzoneGpuMsg_SetGammaCorrection,
std::vector<display::GammaRampRGBEntry>, // Degamma lut
std::vector<display::GammaRampRGBEntry>) // Gamma lut
// Set the privacy screen state of the display with |display_id|
IPC_MESSAGE_CONTROL2(OzoneGpuMsg_SetPrivacyScreen,
int64_t /* display_id */,
bool /* enabled */)
//------------------------------------------------------------------------------
// Browser Messages
// These messages are from the GPU to the browser process.
......
......@@ -20,6 +20,8 @@ namespace {
const char kContentProtection[] = "Content Protection";
const char kPrivacyScreen[] = "privacy-screen";
struct ContentProtectionMapping {
const char* name;
display::HDCPState state;
......@@ -200,4 +202,25 @@ void DrmDisplay::SetGammaCorrection(
}
}
// TODO(gildekel): consider reformatting this to use the new DRM API or cache
// |privacy_screen_property| after crrev.com/c/1715751 lands.
void DrmDisplay::SetPrivacyScreen(bool enabled) {
if (!connector_)
return;
ScopedDrmPropertyPtr privacy_screen_property(
drm_->GetProperty(connector_.get(), kPrivacyScreen));
if (!privacy_screen_property) {
LOG(ERROR) << "'" << kPrivacyScreen << "' property doesn't exist.";
return;
}
if (!drm_->SetProperty(connector_->connector_id,
privacy_screen_property->prop_id, enabled)) {
LOG(ERROR) << (enabled ? "Enabling" : "Disabling") << " property '"
<< kPrivacyScreen << "' failed!";
}
}
} // namespace ui
......@@ -54,6 +54,7 @@ class DrmDisplay {
void SetGammaCorrection(
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
void SetPrivacyScreen(bool enabled);
private:
ScreenManager* screen_manager_; // Not owned.
......
......@@ -239,6 +239,16 @@ void DrmGpuDisplayManager::SetGammaCorrection(
display->SetGammaCorrection(degamma_lut, gamma_lut);
}
void DrmGpuDisplayManager::SetPrivacyScreen(int64_t display_id, bool enabled) {
DrmDisplay* display = FindDisplay(display_id);
if (!display) {
LOG(ERROR) << "There is no display with ID " << display_id;
return;
}
display->SetPrivacyScreen(enabled);
}
DrmDisplay* DrmGpuDisplayManager::FindDisplay(int64_t display_id) {
for (const auto& display : displays_) {
if (display->display_id() == display_id)
......
......@@ -58,6 +58,7 @@ class DrmGpuDisplayManager {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
void SetPrivacyScreen(int64_t display_id, bool enabled);
private:
DrmDisplay* FindDisplay(int64_t display_id);
......
......@@ -394,6 +394,10 @@ void DrmThread::SetGammaCorrection(
display_manager_->SetGammaCorrection(display_id, degamma_lut, gamma_lut);
}
void DrmThread::SetPrivacyScreen(int64_t display_id, bool enabled) {
display_manager_->SetPrivacyScreen(display_id, enabled);
}
void DrmThread::AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver) {
TRACE_EVENT0("drm", "DrmThread::AddDrmDeviceReceiver");
......
......@@ -164,6 +164,7 @@ class DrmThread : public base::Thread,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void GetDeviceCursor(
mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver)
override;
......
......@@ -58,6 +58,7 @@ bool DrmThreadMessageProxy::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetHDCPState, OnSetHDCPState)
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetColorMatrix, OnSetColorMatrix)
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetGammaCorrection, OnSetGammaCorrection)
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetPrivacyScreen, OnSetPrivacyScreen)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -235,6 +236,15 @@ void DrmThreadMessageProxy::OnSetGammaCorrection(
degamma_lut, gamma_lut));
}
void DrmThreadMessageProxy::OnSetPrivacyScreen(int64_t display_id,
bool enabled) {
DCHECK(drm_thread_->IsRunning());
drm_thread_->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&DrmThread::SetPrivacyScreen,
base::Unretained(drm_thread_), display_id, enabled));
}
void DrmThreadMessageProxy::OnRefreshNativeDisplaysCallback(
MovableDisplaySnapshots displays) const {
sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(
......
......@@ -75,6 +75,7 @@ class DrmThreadMessageProxy : public IPC::MessageFilter,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
void OnSetPrivacyScreen(int64_t display_id, bool enabled);
void OnRefreshNativeDisplaysCallback(MovableDisplaySnapshots displays) const;
void OnConfigureNativeDisplayCallback(int64_t display_id, bool success) const;
void OnDisableNativeDisplayCallback(int64_t display_id, bool success) const;
......
......@@ -117,6 +117,10 @@ void DrmDisplayHost::SetGammaCorrection(
gamma_lut);
}
void DrmDisplayHost::SetPrivacyScreen(bool enabled) {
sender_->GpuSetPrivacyScreen(snapshot_->display_id(), enabled);
}
void DrmDisplayHost::OnGpuProcessLaunched() {}
void DrmDisplayHost::OnGpuThreadReady() {
......
......@@ -40,6 +40,7 @@ class DrmDisplayHost : public GpuThreadObserver {
void SetGammaCorrection(
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
void SetPrivacyScreen(bool enabled);
// Called when the IPC from the GPU process arrives to answer the above
// commands.
......
......@@ -321,6 +321,11 @@ bool DrmGpuPlatformSupportHost::GpuDestroyWindow(
return Send(new OzoneGpuMsg_DestroyWindow(widget));
}
bool DrmGpuPlatformSupportHost::GpuSetPrivacyScreen(int64_t display_id,
bool enabled) {
return Send(new OzoneGpuMsg_SetPrivacyScreen(display_id, enabled));
}
bool DrmGpuPlatformSupportHost::GpuCreateWindow(
gfx::AcceleratedWidget widget,
const gfx::Rect& initial_bounds) {
......
......@@ -85,6 +85,7 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) override;
// Services needed by DrmWindowHost
bool GpuDestroyWindow(gfx::AcceleratedWidget widget) override;
......
......@@ -91,6 +91,12 @@ bool DrmNativeDisplayDelegate::SetGammaCorrection(
return true;
}
void DrmNativeDisplayDelegate::SetPrivacyScreen(int64_t display_id,
bool enabled) {
DrmDisplayHost* display = display_manager_->GetDisplay(display_id);
display->SetPrivacyScreen(enabled);
}
void DrmNativeDisplayDelegate::AddObserver(
display::NativeDisplayObserver* observer) {
observers_.AddObserver(observer);
......
......@@ -44,6 +44,7 @@ class DrmNativeDisplayDelegate : public display::NativeDisplayDelegate {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void AddObserver(display::NativeDisplayObserver* observer) override;
void RemoveObserver(display::NativeDisplayObserver* observer) override;
display::FakeDisplayController* GetFakeDisplayController() override;
......
......@@ -57,6 +57,7 @@ class GpuThreadAdapter {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) = 0;
virtual bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) = 0;
// Services needed by DrmWindowHost
virtual bool GpuDestroyWindow(gfx::AcceleratedWidget widget) = 0;
......
......@@ -257,6 +257,14 @@ bool HostDrmDevice::GpuSetGammaCorrection(
return true;
}
bool HostDrmDevice::GpuSetPrivacyScreen(int64_t display_id, bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
if (!IsConnected())
return false;
drm_device_->SetPrivacyScreen(display_id, enabled);
return true;
}
void HostDrmDevice::GpuConfigureNativeDisplayCallback(int64_t display_id,
bool success) const {
......
......@@ -80,6 +80,7 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) override;
// Services needed by DrmWindowHost
bool GpuDestroyWindow(gfx::AcceleratedWidget widget) override;
......
......@@ -76,6 +76,9 @@ interface DrmDevice {
array<display.mojom.GammaRampRGBEntry> degamma_lut,
array<display.mojom.GammaRampRGBEntry> gamma_lut);
// Sets the state of the privacy screen feature.
SetPrivacyScreen(int64 display_id, bool enabled);
// Provides a DeviceCursor interface. The provided interface needs to be
// associated because the AcceleratedWidgets referenced by its methods are
// registered via CreateWindow() in this interface.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment