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

Side by Side 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: fix test on chromeos 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/display/real_output_configurator_delegate.h" 5 #include "chromeos/display/real_output_configurator_delegate.h"
6 6
7 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 #include <X11/extensions/dpms.h> 9 #include <X11/extensions/dpms.h>
10 #include <X11/extensions/XInput.h> 10 #include <X11/extensions/XInput.h>
(...skipping 12 matching lines...) Expand all
23 23
24 namespace chromeos { 24 namespace chromeos {
25 25
26 namespace { 26 namespace {
27 27
28 // DPI measurements. 28 // DPI measurements.
29 const float kMmInInch = 25.4; 29 const float kMmInInch = 25.4;
30 const float kDpi96 = 96.0; 30 const float kDpi96 = 96.0;
31 const float kPixelsToMmScale = kMmInInch / kDpi96; 31 const float kPixelsToMmScale = kMmInInch / kDpi96;
32 32
33 // Prefixes of output name
34 const char kOutputPortName_VGA[] = "VGA";
35 const char kOutputPortName_HDMI[] = "HDMI";
36 const char kOutputPortName_DVI[] = "DVI";
37 const char kOutputPortName_DisplayPort[] = "DP";
38
33 bool IsInternalOutput(const XRROutputInfo* output_info) { 39 bool IsInternalOutput(const XRROutputInfo* output_info) {
34 return IsInternalOutputName(std::string(output_info->name)); 40 return IsInternalOutputName(std::string(output_info->name));
35 } 41 }
36 42
37 RRMode GetOutputNativeMode(const XRROutputInfo* output_info) { 43 RRMode GetOutputNativeMode(const XRROutputInfo* output_info) {
38 return output_info->nmode > 0 ? output_info->modes[0] : None; 44 return output_info->nmode > 0 ? output_info->modes[0] : None;
39 } 45 }
40 46
41 } // namespace 47 } // namespace
42 48
43 RealOutputConfiguratorDelegate::RealOutputConfiguratorDelegate() 49 RealOutputConfiguratorDelegate::RealOutputConfiguratorDelegate()
44 : display_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 50 : display_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
45 window_(DefaultRootWindow(display_)), 51 window_(DefaultRootWindow(display_)),
46 screen_(NULL), 52 screen_(NULL),
47 is_panel_fitting_enabled_(false) { 53 is_panel_fitting_enabled_(false),
54 next_client_id_(1) {
48 } 55 }
49 56
50 RealOutputConfiguratorDelegate::~RealOutputConfiguratorDelegate() { 57 RealOutputConfiguratorDelegate::~RealOutputConfiguratorDelegate() {
51 } 58 }
52 59
53 void RealOutputConfiguratorDelegate::SetPanelFittingEnabled(bool enabled) { 60 void RealOutputConfiguratorDelegate::SetPanelFittingEnabled(bool enabled) {
54 is_panel_fitting_enabled_ = enabled; 61 is_panel_fitting_enabled_ = enabled;
55 } 62 }
56 63
57 void RealOutputConfiguratorDelegate::InitXRandRExtension(int* event_base) { 64 void RealOutputConfiguratorDelegate::InitXRandRExtension(int* event_base) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 &mode_info.interlaced)) { 370 &mode_info.interlaced)) {
364 output.mode_infos.insert(std::make_pair(mode, mode_info)); 371 output.mode_infos.insert(std::make_pair(mode, mode_info));
365 } else { 372 } else {
366 LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode; 373 LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode;
367 } 374 }
368 } 375 }
369 376
370 return output; 377 return output;
371 } 378 }
372 379
380 bool RealOutputConfiguratorDelegate::GetHDCPState(RROutput id,
381 HDCPState* state) {
382 CHECK(screen_) << "Server not grabbed";
383 unsigned char* values = NULL;
384 int actual_format = 0;
385 unsigned long nitems = 0;
386 unsigned long bytes_after = 0;
387 Atom actual_type = None;
388 int success = 0;
389 Atom prop = XInternAtom(display_, "Content Protection", False);
390
391 bool ok = true;
392 success = XRRGetOutputProperty(display_, id, prop, 0, 100, False,
393 False, AnyPropertyType, &actual_type,
394 &actual_format, &nitems, &bytes_after,
395 &values);
396 if (actual_type == None) {
397 LOG(ERROR) << "Property 'Content Protection' does not exist";
398 ok = false;
399 } else if (success == Success && actual_type == XA_ATOM &&
400 actual_format == 32 && nitems == 1) {
401 Atom value = reinterpret_cast<Atom*>(values)[0];
402 if (value == XInternAtom(display_, "Undesired", False)) {
403 *state = HDCP_State_Undesired;
404 } else if (value == XInternAtom(display_, "Desired", False)) {
405 *state = HDCP_State_Desired;
406 } else if (value == XInternAtom(display_, "Enabled", False)) {
407 *state = HDCP_State_Enabled;
408 } else {
409 LOG(ERROR) << "Unknown property value: " << value;
410 ok = false;
411 }
412 } else {
413 LOG(ERROR) << "XRRGetOutputProperty failed";
414 ok = false;
415 }
416 if (values)
417 XFree(values);
418
419 VLOG(3) << "HDCP state: " << ok << "," << *state;
420 return ok;
421 }
422
423 bool RealOutputConfiguratorDelegate::SetHDCPState(RROutput id,
424 HDCPState state) {
425 CHECK(screen_) << "Server not grabbed";
426 Atom name = XInternAtom(display_, "Content Protection", False);
427 Atom value;
428 switch (state) {
429 case HDCP_State_Undesired:
430 value = XInternAtom(display_, "Undesired", False);
431 break;
432 case HDCP_State_Desired:
433 value = XInternAtom(display_, "Desired", False);
434 break;
435 default:
436 NOTREACHED() << "Invalid HDCP state: " << state;
437 return false;
438 }
439 unsigned char *data = reinterpret_cast<unsigned char*>(&value);
440 XRRChangeOutputProperty(display_, id, name, XA_ATOM, 32,
441 PropModeReplace, data, 1);
442 return true;
443 }
444
445 uint64_t RealOutputConfiguratorDelegate::RegisterOutputProtectionClient() {
446 return next_client_id_++;
447 }
448
449 void RealOutputConfiguratorDelegate::UnregisterOutputProtectionClient(
450 uint64_t client_id) {
451 EnableOutputProtection(client_id, OUTPUT_PROTECTION_METHOD_NONE);
452 }
453
454 bool RealOutputConfiguratorDelegate::QueryOutputProtectionLinkType(
455 RROutput id,
456 OutputLinkType *link_type) {
457 XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, id);
458 if (!output_info) {
459 return false;
460 }
461
462 bool ok = true;
463 if (output_info->connection == RR_Connected) {
464 std::string name(output_info->name);
465 if (IsInternalOutput(output_info)) {
466 *link_type = OUTPUT_LINK_TYPE_INTERNAL;
467 } else if (name.find(kOutputPortName_VGA) == 0) {
468 *link_type = OUTPUT_LINK_TYPE_VGA;
469 } else if (name.find(kOutputPortName_HDMI) == 0) {
470 *link_type = OUTPUT_LINK_TYPE_HDMI;
471 } else if (name.find(kOutputPortName_DVI) == 0) {
472 *link_type = OUTPUT_LINK_TYPE_DVI;
473 } else if (name.find(kOutputPortName_DisplayPort) == 0) {
474 *link_type = OUTPUT_LINK_TYPE_DISPLAYPORT;
475 } else {
476 DCHECK(0) << "Unknown link type: " << name;
477 ok = false;
478 }
479 } else {
480 *link_type = OUTPUT_LINK_TYPE_NONE;
481 }
482 XRRFreeOutputInfo(output_info);
483 return ok;
484 }
485
486 bool RealOutputConfiguratorDelegate::EnableOutputProtection(
487 uint64_t client_id,
488 uint32_t desired_method_mask) {
489 if (desired_method_mask == OUTPUT_PROTECTION_METHOD_NONE)
490 client_protection_requests_.erase(client_id);
491 else
492 client_protection_requests_[client_id] = desired_method_mask;
493
494 uint32_t all_desires = 0;
495 for (ProtectionRequests::const_iterator it =
496 client_protection_requests_.begin();
497 it != client_protection_requests_.end();
498 ++it) {
499 all_desires |= it->second;
500 }
501
502 for (int i = 0; i < screen_->noutput; ++i) {
503 RROutput this_id = screen_->outputs[i];
504 OutputLinkType type;
505 if (!QueryOutputProtectionLinkType(this_id, &type))
506 return false;
507
508 if ((type & OUTPUT_LINK_TYPE_HDMI) ||
509 (type & OUTPUT_LINK_TYPE_DISPLAYPORT)) {
510 HDCPState new_desired_state;
511 if (all_desires & OUTPUT_PROTECTION_METHOD_HDCP) {
512 new_desired_state = HDCP_State_Desired;
513 } else {
514 new_desired_state = HDCP_State_Undesired;
515 }
516 if (!SetHDCPState(this_id, new_desired_state))
517 return false;
518 }
519 }
520 return true;
521 }
522
523 bool RealOutputConfiguratorDelegate::QueryOutputProtectionStatus(
524 uint64_t client_id,
525 uint32_t* link_mask,
526 uint32_t* protection_mask) {
527 uint32_t enabled = 0;
528 uint32_t unfulfilled = 0;
529
530 *link_mask = 0;
531 for (int i = 0; i < screen_->noutput; ++i) {
532 RROutput this_id = screen_->outputs[i];
533 OutputLinkType type;
534 if (!QueryOutputProtectionLinkType(this_id, &type))
535 return false;
536 *link_mask |= type;
537
538 if ((type & OUTPUT_LINK_TYPE_HDMI) ||
539 (type & OUTPUT_LINK_TYPE_DISPLAYPORT)) {
540 HDCPState state;
541 RROutput this_id = screen_->outputs[i];
542 if (!GetHDCPState(this_id, &state))
543 return false;
544 if (state == HDCP_State_Enabled)
545 enabled |= OUTPUT_PROTECTION_METHOD_HDCP;
546 else
547 unfulfilled |= OUTPUT_PROTECTION_METHOD_HDCP;
548 }
549 }
550
551 // Don't reveal protections requested by other clients.
552 ProtectionRequests::iterator it = client_protection_requests_.find(client_id);
553 if (it != client_protection_requests_.end()) {
554 uint32_t requested_mask = it->second;
555 *protection_mask = enabled & ~unfulfilled & requested_mask;
556 } else {
557 *protection_mask = 0;
558 }
559 return true;
560 }
561
373 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( 562 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs(
374 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { 563 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) {
375 CHECK(screen_) << "Server not grabbed"; 564 CHECK(screen_) << "Server not grabbed";
376 // Setting the screen size will fail if any CRTC doesn't fit afterwards. 565 // Setting the screen size will fail if any CRTC doesn't fit afterwards.
377 // At the same time, turning CRTCs off and back on uses up a lot of time. 566 // At the same time, turning CRTCs off and back on uses up a lot of time.
378 // This function tries to be smart to avoid too many off/on cycles: 567 // This function tries to be smart to avoid too many off/on cycles:
379 // - We disable all the CRTCs we won't need after the FB resize. 568 // - We disable all the CRTCs we won't need after the FB resize.
380 // - We set the new modes on CRTCs, if they fit in both the old and new 569 // - We set the new modes on CRTCs, if they fit in both the old and new
381 // FBs, and park them at (0,0) 570 // FBs, and park them at (0,0)
382 // - We disable the CRTCs we will need but don't fit in the old FB. Those 571 // - We disable the CRTCs we will need but don't fit in the old FB. Those
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 << (*outputs)[i].touch_device_id << " to output #" << i; 827 << (*outputs)[i].touch_device_id << " to output #" << i;
639 break; 828 break;
640 } 829 }
641 } 830 }
642 } 831 }
643 832
644 XIFreeDeviceInfo(info); 833 XIFreeDeviceInfo(info);
645 } 834 }
646 835
647 } // namespace chromeos 836 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698