Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: chromeos/display/real_output_configurator_delegate.cc

Issue 24039002: Pepper API implementation for output protection. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: avoid PostTask methods in dtor Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromeos/display/real_output_configurator_delegate.cc
diff --git a/chromeos/display/real_output_configurator_delegate.cc b/chromeos/display/real_output_configurator_delegate.cc
index 6d0c78254112c5e678f0149aefc181cb6ebd448e..3313f0349e8eb7ba95e8a409614682f57b8255cb 100644
--- a/chromeos/display/real_output_configurator_delegate.cc
+++ b/chromeos/display/real_output_configurator_delegate.cc
@@ -30,6 +30,12 @@ const float kMmInInch = 25.4;
const float kDpi96 = 96.0;
const float kPixelsToMmScale = kMmInInch / kDpi96;
+// Prefixes of putput name
+const char kOutputPortName_VGA[] = "VGA";
+const char kOutputPortName_HDMI[] = "HDMI";
+const char kOutputPortName_DVI[] = "DVI";
+const char kOutputPortName_DisplayPort[] = "DP";
+
bool IsInternalOutput(const XRROutputInfo* output_info) {
return IsInternalOutputName(std::string(output_info->name));
}
@@ -370,6 +376,212 @@ RealOutputConfiguratorDelegate::InitOutputSnapshot(
return output;
}
+bool RealOutputConfiguratorDelegate::GetHDCPState(RROutput id,
+ HDCPState* state) {
+ CHECK(screen_) << "Server not grabbed";
+ unsigned char* values = NULL;
+ int actual_format;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ Atom actual_type;
+ int success;
dmichael (off chromium) 2013/09/09 20:37:15 please initialize these (same for other variables
kcwu 2013/09/10 12:50:21 Done.
+ Atom prop = XInternAtom(display_, "Content Protection", False);
+
+ bool ok = true;
+ success = XRRGetOutputProperty(display_, id, prop, 0, 100, False,
+ False, AnyPropertyType, &actual_type,
+ &actual_format, &nitems, &bytes_after,
+ &values);
+ if (actual_type == None) {
+ LOG(ERROR) << "Property 'Content Protection' does not exist";
+ ok = false;
+ } else if (success == Success && actual_type == XA_ATOM &&
+ actual_format == 32 && nitems == 1) {
+ Atom value = reinterpret_cast<Atom*>(values)[0];
+ if (value == XInternAtom(display_, "Undesired", False))
+ *state = HDCP_State_Undesired;
+ else if (value == XInternAtom(display_, "Desired", False))
+ *state = HDCP_State_Desired;
+ else if (value == XInternAtom(display_, "Enabled", False))
+ *state = HDCP_State_Enabled;
+ else {
+ LOG(ERROR) << "Unknown property value: " << value;
+ ok = false;
+ }
+ } else {
+ LOG(ERROR) << "XRRGetOutputProperty failed";
+ ok = false;
+ }
+ if (values)
+ XFree(values);
+
+ VLOG(3) << "HDCP state: " << ok << "," << *state;
+ return ok;
+}
+
+bool RealOutputConfiguratorDelegate::SetHDCPState(RROutput id,
+ HDCPState state) {
+ CHECK(screen_) << "Server not grabbed";
+ Atom name = XInternAtom(display_, "Content Protection", False);
+ unsigned long value;
+ switch (state) {
+ case HDCP_State_Undesired:
+ value = XInternAtom(display_, "Undesired", False);
dmichael (off chromium) 2013/09/09 20:37:15 It looks like this function returns type "Atom"...
kcwu 2013/09/10 12:50:21 Done.
+ break;
+ case HDCP_State_Desired:
+ value = XInternAtom(display_, "Desired", False);
+ break;
+ default:
+ DCHECK(0) << "Invalid HDCP state: " << state;
+ return false;
+ }
+ unsigned char *data = (unsigned char*)&value;
dmichael (off chromium) 2013/09/09 20:37:15 Please do not use C-style casts. I think you want
kcwu 2013/09/10 12:50:21 Done.
kcwu 2013/09/10 12:50:21 Done.
+ XRRChangeOutputProperty(display_, id, name, XA_ATOM, 32,
+ PropModeReplace, data, 1);
+ return true;
+}
+
+bool DetermineLinkType(const XRROutputInfo* output_info,
dmichael (off chromium) 2013/09/09 20:37:15 const-reference?
kcwu 2013/09/10 12:50:21 Existing code, IsInternalOutput() takes const-poin
dmichael (off chromium) 2013/09/11 18:22:45 Yes. It looks like IsInternalOutput assumes that t
kcwu 2013/09/12 18:22:08 Done.
+ PP_OutputProtectionLinkType_Private* link_type) {
+ std::string name(output_info->name);
+ if (IsInternalOutput(output_info)) {
+ *link_type = PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL;
+ } else if (name.find(kOutputPortName_VGA) == 0) {
+ *link_type = PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA;
+ } else if (name.find(kOutputPortName_HDMI) == 0) {
+ *link_type = PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI;
+ } else if (name.find(kOutputPortName_DisplayPort) == 0) {
+ *link_type = PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT;
+ } else {
+ DCHECK(0) << "Unknown link type: " << name;
+ return false;
+ }
+ return true;
+}
+
+bool RealOutputConfiguratorDelegate::GetOutputLinkType(
dmichael (off chromium) 2013/09/09 20:37:15 Type->Types? It looks like you can retrieve more t
kcwu 2013/09/10 12:50:21 Done.
+ std::vector<PP_OutputProtectionLinkType_Private>& link_type) {
dmichael (off chromium) 2013/09/09 20:37:15 out-params should be by pointer: http://google-sty
kcwu 2013/09/10 12:50:21 Done.
+ CHECK(screen_) << "Server not grabbed";
+ bool result = true;
+ for (int i = 0; i < screen_->noutput; ++i) {
+ RROutput this_id = screen_->outputs[i];
+ XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, this_id);
dmichael (off chromium) 2013/09/09 20:37:15 Can this return NULL? It looks like it can: http:/
kcwu 2013/09/10 12:50:21 Done. BTW, this is copied from existing code, line
+ if (output_info->connection != RR_Connected) {
+ XRRFreeOutputInfo(output_info);
dmichael (off chromium) 2013/09/09 20:37:15 optional suggestion: You could use scoped_ptr<XRRO
kcwu 2013/09/10 12:50:21 Done.
+ link_type.push_back(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE);
+ continue;
dmichael (off chromium) 2013/09/09 20:37:15 Why not just use an else? And I'd maybe flip the c
kcwu 2013/09/10 12:50:21 Done.
+ }
+
+ PP_OutputProtectionLinkType_Private type;
+ if (DetermineLinkType(output_info, &type))
+ link_type.push_back(type);
+ else
+ result = false;
+ XRRFreeOutputInfo(output_info);
+ }
+ return result;
+}
+
+bool RealOutputConfiguratorDelegate::GetOutputLinkMask(uint32_t* link_mask) {
+ std::vector<PP_OutputProtectionLinkType_Private> link_type;
+ *link_mask = 0;
+ if (!GetOutputLinkType(link_type))
+ return false;
+
+ for (std::vector<PP_OutputProtectionLinkType_Private>::const_iterator it =
+ link_type.begin(); it != link_type.end(); ++it) {
+ *link_mask |= *it;
+ }
+ return true;
+}
+
+bool RealOutputConfiguratorDelegate::GetProtectionMethods(
+ uint32_t* protection_mask) {
+ CHECK(screen_) << "Server not grabbed";
+ std::vector<PP_OutputProtectionLinkType_Private> link_type;
+ if (!GetOutputLinkType(link_type))
+ return false;
+
+ uint32_t enabled = 0;
+ uint32_t unfulfiled = 0;
+
+ DCHECK(screen_->noutput == (int)link_type.size());
dmichael (off chromium) 2013/09/09 20:37:15 no C-style casts http://google-styleguide.googleco
kcwu 2013/09/10 12:50:21 Done.
dmichael (off chromium) 2013/09/11 18:22:45 nit: It's usually better to static_cast the type t
kcwu 2013/09/12 18:22:08 Use DCHECK_EQ() instead as Dale suggested.
+ for (int i = 0; i < screen_->noutput; ++i) {
+ PP_OutputProtectionLinkType_Private type = link_type[i];
+ if (type & (PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI |
+ PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT)) {
dmichael (off chromium) 2013/09/09 20:37:15 optional nit: I would find it more readable as: if
kcwu 2013/09/10 12:50:21 Done.
+ HDCPState state;
+ RROutput this_id = screen_->outputs[i];
+ if (!GetHDCPState(this_id, &state))
+ return false;
+ if (state == HDCP_State_Enabled)
+ enabled |= PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP;
+ else
+ unfulfiled |= PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP;
+ }
+ }
+ *protection_mask = enabled & ~unfulfiled;
dmichael (off chromium) 2013/09/09 20:37:15 I don't really understand the APIs we're using...
kcwu 2013/09/10 12:50:21 Yes, content owner would like to playback their co
+ return true;
+}
+
+uint32_t RealOutputConfiguratorDelegate::GetCombinedProtectionRequest() {
+ uint32_t combined_requirement = 0;
+ for (ProtectionRequests::const_iterator it =
+ client_protection_request_.begin();
+ it != client_protection_request_.end();
+ ++it) {
+ combined_requirement |= it->second;
+ }
+ return combined_requirement;
+}
+
+bool RealOutputConfiguratorDelegate::EnableOutputProtection(
+ chrome::PepperOutputProtectionHost* client, uint32_t desired_method_mask) {
+ if (desired_method_mask == PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE)
+ client_protection_request_.erase(client);
+ else
+ client_protection_request_[client] = desired_method_mask;
+
+ uint32_t all_desires = GetCombinedProtectionRequest();
+ std::vector<PP_OutputProtectionLinkType_Private> link_type;
+ if (!GetOutputLinkType(link_type))
dmichael (off chromium) 2013/09/09 20:37:15 You do this a lot. Might it make sense to have som
kcwu 2013/09/10 12:50:21 Right. It is not used otherwhere GrabServer is. An
+ return false;
+ bool ok = true;
+ for (int i = 0; i < screen_->noutput; ++i) {
+ RROutput this_id = screen_->outputs[i];
+ PP_OutputProtectionLinkType_Private type = link_type[i];
+ if (type & (PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI |
+ PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT)) {
dmichael (off chromium) 2013/09/09 20:37:15 ditto, I somewhat prefer separate bit masking and
kcwu 2013/09/10 12:50:21 Done.
+ if (all_desires & PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP) {
+ ok = SetHDCPState(this_id, HDCP_State_Desired);
+ } else {
+ ok = SetHDCPState(this_id, HDCP_State_Undesired);
+ }
+ }
+
+ if (!ok)
+ return false;
+ }
+ return true;
+}
+
+bool RealOutputConfiguratorDelegate::QueryOutputProtectionStatus(
+ chrome::PepperOutputProtectionHost* client,
+ uint32_t* link_mask,
+ uint32_t* protection_mask) {
+ bool ok = GetProtectionMethods(protection_mask) &&
+ GetOutputLinkMask(link_mask);
dmichael (off chromium) 2013/09/09 20:37:15 nit: 4-space indent
kcwu 2013/09/10 12:50:21 Done.
+ ProtectionRequests::iterator it = client_protection_request_.find(client);
+
+ // Don't reveal protections requested by other clients.
+ if (it != client_protection_request_.end()) {
+ *protection_mask &= it->second;
+ } else {
+ *protection_mask = 0;
+ }
+ return ok;
+}
+
void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs(
const std::vector<OutputConfigurator::OutputSnapshot>& outputs) {
CHECK(screen_) << "Server not grabbed";

Powered by Google App Engine
This is Rietveld 408576698