// Copyright 2014 The Chromium 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 "cobalt/media/blink/key_system_config_selector.h"

#include <stddef.h>
#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "cobalt/media/base/cdm_config.h"
#include "cobalt/media/base/key_systems.h"
#include "cobalt/media/base/media_permission.h"
#include "cobalt/media/base/mime_util.h"
#include "cobalt/media/blink/webmediaplayer_util.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"

namespace media {

using EmeFeatureRequirement =
    blink::WebMediaKeySystemConfiguration::Requirement;

namespace {

static EmeConfigRule GetSessionTypeConfigRule(EmeSessionTypeSupport support) {
  switch (support) {
    case EmeSessionTypeSupport::INVALID:
      NOTREACHED();
      return EmeConfigRule::NOT_SUPPORTED;
    case EmeSessionTypeSupport::NOT_SUPPORTED:
      return EmeConfigRule::NOT_SUPPORTED;
    case EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER:
      return EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED;
    case EmeSessionTypeSupport::SUPPORTED:
      return EmeConfigRule::PERSISTENCE_REQUIRED;
  }
  NOTREACHED();
  return EmeConfigRule::NOT_SUPPORTED;
}

static EmeConfigRule GetDistinctiveIdentifierConfigRule(
    EmeFeatureSupport support, EmeFeatureRequirement requirement) {
  if (support == EmeFeatureSupport::INVALID) {
    NOTREACHED();
    return EmeConfigRule::NOT_SUPPORTED;
  }

  // For NOT_ALLOWED and REQUIRED, the result is as expected. For OPTIONAL, we
  // return the most restrictive rule that is not more restrictive than for
  // NOT_ALLOWED or REQUIRED. Those values will be checked individually when
  // the option is resolved.
  //
  //                   NOT_ALLOWED    OPTIONAL       REQUIRED
  //    NOT_SUPPORTED  I_NOT_ALLOWED  I_NOT_ALLOWED  NOT_SUPPORTED
  //      REQUESTABLE  I_NOT_ALLOWED  SUPPORTED      I_REQUIRED
  //   ALWAYS_ENABLED  NOT_SUPPORTED  I_REQUIRED     I_REQUIRED
  DCHECK(support == EmeFeatureSupport::NOT_SUPPORTED ||
         support == EmeFeatureSupport::REQUESTABLE ||
         support == EmeFeatureSupport::ALWAYS_ENABLED);
  DCHECK(requirement == EmeFeatureRequirement::NotAllowed ||
         requirement == EmeFeatureRequirement::Optional ||
         requirement == EmeFeatureRequirement::Required);
  if ((support == EmeFeatureSupport::NOT_SUPPORTED &&
       requirement == EmeFeatureRequirement::Required) ||
      (support == EmeFeatureSupport::ALWAYS_ENABLED &&
       requirement == EmeFeatureRequirement::NotAllowed)) {
    return EmeConfigRule::NOT_SUPPORTED;
  }
  if (support == EmeFeatureSupport::REQUESTABLE &&
      requirement == EmeFeatureRequirement::Optional) {
    return EmeConfigRule::SUPPORTED;
  }
  if (support == EmeFeatureSupport::NOT_SUPPORTED ||
      requirement == EmeFeatureRequirement::NotAllowed) {
    return EmeConfigRule::IDENTIFIER_NOT_ALLOWED;
  }
  return EmeConfigRule::IDENTIFIER_REQUIRED;
}

static EmeConfigRule GetPersistentStateConfigRule(
    EmeFeatureSupport support, EmeFeatureRequirement requirement) {
  if (support == EmeFeatureSupport::INVALID) {
    NOTREACHED();
    return EmeConfigRule::NOT_SUPPORTED;
  }

  // For NOT_ALLOWED and REQUIRED, the result is as expected. For OPTIONAL, we
  // return the most restrictive rule that is not more restrictive than for
  // NOT_ALLOWED or REQUIRED. Those values will be checked individually when
  // the option is resolved.
  //
  // Note that even though a distinctive identifier can not be required for
  // persistent state, it may still be required for persistent sessions.
  //
  //                   NOT_ALLOWED    OPTIONAL       REQUIRED
  //    NOT_SUPPORTED  P_NOT_ALLOWED  P_NOT_ALLOWED  NOT_SUPPORTED
  //      REQUESTABLE  P_NOT_ALLOWED  SUPPORTED      P_REQUIRED
  //   ALWAYS_ENABLED  NOT_SUPPORTED  P_REQUIRED     P_REQUIRED
  DCHECK(support == EmeFeatureSupport::NOT_SUPPORTED ||
         support == EmeFeatureSupport::REQUESTABLE ||
         support == EmeFeatureSupport::ALWAYS_ENABLED);
  DCHECK(requirement == EmeFeatureRequirement::NotAllowed ||
         requirement == EmeFeatureRequirement::Optional ||
         requirement == EmeFeatureRequirement::Required);
  if ((support == EmeFeatureSupport::NOT_SUPPORTED &&
       requirement == EmeFeatureRequirement::Required) ||
      (support == EmeFeatureSupport::ALWAYS_ENABLED &&
       requirement == EmeFeatureRequirement::NotAllowed)) {
    return EmeConfigRule::NOT_SUPPORTED;
  }
  if (support == EmeFeatureSupport::REQUESTABLE &&
      requirement == EmeFeatureRequirement::Optional) {
    return EmeConfigRule::SUPPORTED;
  }
  if (support == EmeFeatureSupport::NOT_SUPPORTED ||
      requirement == EmeFeatureRequirement::NotAllowed) {
    return EmeConfigRule::PERSISTENCE_NOT_ALLOWED;
  }
  return EmeConfigRule::PERSISTENCE_REQUIRED;
}

static bool IsPersistentSessionType(
    blink::WebEncryptedMediaSessionType sessionType) {
  switch (sessionType) {
    case blink::WebEncryptedMediaSessionType::Temporary:
      return false;
    case blink::WebEncryptedMediaSessionType::PersistentLicense:
      return true;
    case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage:
      return true;
    case blink::WebEncryptedMediaSessionType::Unknown:
      break;
  }

  NOTREACHED();
  return false;
}

}  // namespace

struct KeySystemConfigSelector::SelectionRequest {
  std::string key_system;
  blink::WebVector<blink::WebMediaKeySystemConfiguration>
      candidate_configurations;
  blink::WebSecurityOrigin security_origin;
  base::Callback<void(const blink::WebMediaKeySystemConfiguration&,
                      const CdmConfig&)> succeeded_cb;
  base::Callback<void(const blink::WebString&)> not_supported_cb;
  bool was_permission_requested = false;
  bool is_permission_granted = false;
  bool are_secure_codecs_supported = false;
};

// Accumulates configuration rules to determine if a feature (additional
// configuration rule) can be added to an accumulated configuration.
class KeySystemConfigSelector::ConfigState {
 public:
  ConfigState(bool was_permission_requested, bool is_permission_granted)
      : was_permission_requested_(was_permission_requested),
        is_permission_granted_(is_permission_granted) {}

  bool IsPermissionGranted() const { return is_permission_granted_; }

  // Permission is possible if it has not been denied.
  bool IsPermissionPossible() const {
    return is_permission_granted_ || !was_permission_requested_;
  }

  bool IsIdentifierRequired() const { return is_identifier_required_; }

  bool IsIdentifierRecommended() const { return is_identifier_recommended_; }

  bool AreHwSecureCodecsRequired() const {
    return are_hw_secure_codecs_required_;
  }

  // Checks whether a rule is compatible with all previously added rules.
  bool IsRuleSupported(EmeConfigRule rule) const {
    switch (rule) {
      case EmeConfigRule::NOT_SUPPORTED:
        return false;
      case EmeConfigRule::IDENTIFIER_NOT_ALLOWED:
        return !is_identifier_required_;
      case EmeConfigRule::IDENTIFIER_REQUIRED:
        // TODO(sandersd): Confirm if we should be refusing these rules when
        // permission has been denied (as the spec currently says).
        return !is_identifier_not_allowed_ && IsPermissionPossible();
      case EmeConfigRule::IDENTIFIER_RECOMMENDED:
        return true;
      case EmeConfigRule::PERSISTENCE_NOT_ALLOWED:
        return !is_persistence_required_;
      case EmeConfigRule::PERSISTENCE_REQUIRED:
        return !is_persistence_not_allowed_;
      case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED:
        return (!is_identifier_not_allowed_ && IsPermissionPossible() &&
                !is_persistence_not_allowed_);
      case EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED:
        return !are_hw_secure_codecs_required_;
      case EmeConfigRule::HW_SECURE_CODECS_REQUIRED:
        return !are_hw_secure_codecs_not_allowed_;
      case EmeConfigRule::SUPPORTED:
        return true;
    }
    NOTREACHED();
    return false;
  }

  // Add a rule to the accumulated configuration state.
  void AddRule(EmeConfigRule rule) {
    DCHECK(IsRuleSupported(rule));
    switch (rule) {
      case EmeConfigRule::NOT_SUPPORTED:
        NOTREACHED();
        return;
      case EmeConfigRule::IDENTIFIER_NOT_ALLOWED:
        is_identifier_not_allowed_ = true;
        return;
      case EmeConfigRule::IDENTIFIER_REQUIRED:
        is_identifier_required_ = true;
        return;
      case EmeConfigRule::IDENTIFIER_RECOMMENDED:
        is_identifier_recommended_ = true;
        return;
      case EmeConfigRule::PERSISTENCE_NOT_ALLOWED:
        is_persistence_not_allowed_ = true;
        return;
      case EmeConfigRule::PERSISTENCE_REQUIRED:
        is_persistence_required_ = true;
        return;
      case EmeConfigRule::IDENTIFIER_AND_PERSISTENCE_REQUIRED:
        is_identifier_required_ = true;
        is_persistence_required_ = true;
        return;
      case EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED:
        are_hw_secure_codecs_not_allowed_ = true;
        return;
      case EmeConfigRule::HW_SECURE_CODECS_REQUIRED:
        are_hw_secure_codecs_required_ = true;
        return;
      case EmeConfigRule::SUPPORTED:
        return;
    }
    NOTREACHED();
  }

 private:
  // Whether permission to use a distinctive identifier was requested. If set,
  // |is_permission_granted_| represents the final decision.
  // (Not changed by adding rules.)
  bool was_permission_requested_;

  // Whether permission to use a distinctive identifier has been granted.
  // (Not changed by adding rules.)
  bool is_permission_granted_;

  // Whether a rule has been added that requires or blocks a distinctive
  // identifier.
  bool is_identifier_required_ = false;
  bool is_identifier_not_allowed_ = false;

  // Whether a rule has been added that recommends a distinctive identifier.
  bool is_identifier_recommended_ = false;

  // Whether a rule has been added that requires or blocks persistent state.
  bool is_persistence_required_ = false;
  bool is_persistence_not_allowed_ = false;

  // Whether a rule has been added that requires or blocks hardware-secure
  // codecs.
  bool are_hw_secure_codecs_required_ = false;
  bool are_hw_secure_codecs_not_allowed_ = false;
};

KeySystemConfigSelector::KeySystemConfigSelector(
    const KeySystems* key_systems, MediaPermission* media_permission)
    : key_systems_(key_systems),
      media_permission_(media_permission),
      weak_factory_(this) {
  DCHECK(key_systems_);
  DCHECK(media_permission_);
}

KeySystemConfigSelector::~KeySystemConfigSelector() {}

bool IsSupportedMediaFormat(const std::string& container_mime_type,
                            const std::string& codecs, bool use_aes_decryptor) {
  std::vector<std::string> codec_vector;
  ParseCodecString(codecs, &codec_vector, false);
  // AesDecryptor decrypts the stream in the demuxer before it reaches the
  // decoder so check whether the media format is supported when clear.
  SupportsType support_result =
      use_aes_decryptor
          ? IsSupportedMediaFormat(container_mime_type, codec_vector)
          : IsSupportedEncryptedMediaFormat(container_mime_type, codec_vector);
  switch (support_result) {
    case IsSupported:
      return true;
    case MayBeSupported:
      // If no codecs were specified, the best possible result is
      // MayBeSupported, indicating support for the container.
      return codec_vector.empty();
    case IsNotSupported:
      return false;
  }
  NOTREACHED();
  return false;
}

// TODO(sandersd): Move contentType parsing from Blink to here so that invalid
// parameters can be rejected. http://crbug.com/417561
bool KeySystemConfigSelector::IsSupportedContentType(
    const std::string& key_system, EmeMediaType media_type,
    const std::string& container_mime_type, const std::string& codecs,
    KeySystemConfigSelector::ConfigState* config_state) {
  // From RFC6838: "Both top-level type and subtype names are case-insensitive."
  std::string container_lower = base::ToLowerASCII(container_mime_type);

  // contentTypes must provide a codec string unless the container implies a
  // particular codec. For EME, none of the currently supported containers
  // imply a codec, so |codecs| must be provided.
  if (codecs.empty()) {
    // Since the spec didn't initially require this, add an exemption for
    // some existing containers to give clients time to adapt.
    // TODO(jrummell): Remove this exemption once the number of contentTypes
    // without codecs drops low enough (UMA added in the blink code).
    // http://crbug.com/605661.
    if (container_lower != "audio/webm" && container_lower != "video/webm" &&
        container_lower != "audio/mp4" && container_lower != "video/mp4") {
      return false;
    }
  }

  // Check that |container_mime_type| and |codecs| are supported by Chrome. This
  // is done primarily to validate extended codecs, but it also ensures that the
  // CDM cannot support codecs that Chrome does not (which could complicate the
  // robustness algorithm).
  if (!IsSupportedMediaFormat(container_lower, codecs,
                              CanUseAesDecryptor(key_system))) {
    return false;
  }

  // Check that |container_mime_type| and |codecs| are supported by the CDM.
  // This check does not handle extended codecs, so extended codec information
  // is stripped (extended codec information was checked above).
  std::vector<std::string> stripped_codec_vector;
  ParseCodecString(codecs, &stripped_codec_vector, true);
  EmeConfigRule codecs_rule = key_systems_->GetContentTypeConfigRule(
      key_system, media_type, container_lower, stripped_codec_vector);
  if (!config_state->IsRuleSupported(codecs_rule)) return false;
  config_state->AddRule(codecs_rule);

  return true;
}

bool KeySystemConfigSelector::GetSupportedCapabilities(
    const std::string& key_system, EmeMediaType media_type,
    const blink::WebVector<blink::WebMediaKeySystemMediaCapability>&
        requested_media_capabilities,
    KeySystemConfigSelector::ConfigState* config_state,
    std::vector<blink::WebMediaKeySystemMediaCapability>*
        supported_media_capabilities) {
  // From
  // https://w3c.github.io/encrypted-media/#get-supported-capabilities-for-media-type
  // 1. Let local accumulated capabilities be a local copy of partial
  //    configuration.
  //    (Skipped as we directly update |config_state|. This is safe because we
  //    only do so when at least one requested media capability is supported.)
  // 2. Let supported media capabilities be empty.
  DCHECK_EQ(supported_media_capabilities->size(), 0ul);
  // 3. For each value in requested media capabilities:
  for (size_t i = 0; i < requested_media_capabilities.size(); i++) {
    // 3.1. Let contentType be the value's contentType member.
    // 3.2. Let robustness be the value's robustness member.
    const blink::WebMediaKeySystemMediaCapability& capability =
        requested_media_capabilities[i];
    // 3.3. If contentType is the empty string, return null.
    if (capability.mimeType.isEmpty()) {
      DVLOG(2) << "Rejecting requested configuration because "
               << "a capability contentType was empty.";
      return false;
    }

    // 3.4-3.11. (Implemented by IsSupportedContentType().)
    ConfigState proposed_config_state = *config_state;
    if (!base::IsStringASCII(capability.mimeType) ||
        !base::IsStringASCII(capability.codecs) ||
        !IsSupportedContentType(
            key_system, media_type,
            base::UTF16ToASCII(base::StringPiece16(capability.mimeType)),
            base::UTF16ToASCII(base::StringPiece16(capability.codecs)),
            &proposed_config_state)) {
      continue;
    }
    // 3.12. If robustness is not the empty string, run the following steps:
    if (!capability.robustness.isEmpty()) {
      // 3.12.1. If robustness is an unrecognized value or not supported by
      //         implementation, continue to the next iteration. String
      //         comparison is case-sensitive.
      if (!base::IsStringASCII(capability.robustness)) continue;
      EmeConfigRule robustness_rule = key_systems_->GetRobustnessConfigRule(
          key_system, media_type,
          base::UTF16ToASCII(base::StringPiece16(capability.robustness)));
      if (!proposed_config_state.IsRuleSupported(robustness_rule)) continue;
      proposed_config_state.AddRule(robustness_rule);
      // 3.12.2. Add robustness to configuration.
      //         (It's already added, we use capability as configuration.)
    }
    // 3.13. If the user agent and implementation do not support playback of
    //       encrypted media data as specified by configuration, including all
    //       media types, in combination with local accumulated capabilities,
    //       continue to the next iteration.
    //       (This is handled when adding rules to |proposed_config_state|.)
    // 3.14. Add configuration to supported media capabilities.
    supported_media_capabilities->push_back(capability);
    // 3.15. Add configuration to local accumulated capabilities.
    *config_state = proposed_config_state;
  }
  // 4. If supported media capabilities is empty, return null.
  if (supported_media_capabilities->empty()) {
    DVLOG(2) << "Rejecting requested configuration because "
             << "no capabilities were supported.";
    return false;
  }
  // 5. Return media type capabilities.
  return true;
}

KeySystemConfigSelector::ConfigurationSupport
KeySystemConfigSelector::GetSupportedConfiguration(
    const std::string& key_system,
    const blink::WebMediaKeySystemConfiguration& candidate,
    ConfigState* config_state,
    blink::WebMediaKeySystemConfiguration* accumulated_configuration) {
  // From
  // http://w3c.github.io/encrypted-media/#get-supported-configuration-and-consent
  // 1. Let accumulated configuration be a new MediaKeySystemConfiguration
  //    dictionary. (Done by caller.)
  // 2. Set the label member of accumulated configuration to equal the label
  //    member of candidate configuration.
  accumulated_configuration->label = candidate.label;

  // 3. If the initDataTypes member of candidate configuration is non-empty,
  //    run the following steps:
  if (!candidate.initDataTypes.isEmpty()) {
    // 3.1. Let supported types be an empty sequence of DOMStrings.
    std::vector<blink::WebEncryptedMediaInitDataType> supported_types;

    // 3.2. For each value in candidate configuration's initDataTypes member:
    for (size_t i = 0; i < candidate.initDataTypes.size(); i++) {
      // 3.2.1. Let initDataType be the value.
      blink::WebEncryptedMediaInitDataType init_data_type =
          candidate.initDataTypes[i];

      // 3.2.2. If the implementation supports generating requests based on
      //        initDataType, add initDataType to supported types. String
      //        comparison is case-sensitive. The empty string is never
      //        supported.
      if (key_systems_->IsSupportedInitDataType(
              key_system, ConvertToEmeInitDataType(init_data_type))) {
        supported_types.push_back(init_data_type);
      }
    }

    // 3.3. If supported types is empty, return null.
    if (supported_types.empty()) {
      DVLOG(2) << "Rejecting requested configuration because "
               << "no initDataType values were supported.";
      return CONFIGURATION_NOT_SUPPORTED;
    }

    // 3.4. Set the initDataTypes member of accumulated configuration to
    //      supported types.
    accumulated_configuration->initDataTypes = supported_types;
  }

  // 4. Let distinctive identifier requirement be the value of candidate
  //    configuration's distinctiveIdentifier member.
  EmeFeatureRequirement distinctive_identifier =
      candidate.distinctiveIdentifier;

  // 5. If distinctive identifier requirement is "optional" and Distinctive
  //    Identifiers are not allowed according to restrictions, set distinctive
  //    identifier requirement to "not-allowed".
  EmeFeatureSupport distinctive_identifier_support =
      key_systems_->GetDistinctiveIdentifierSupport(key_system);
  if (distinctive_identifier == EmeFeatureRequirement::Optional) {
    if (distinctive_identifier_support == EmeFeatureSupport::INVALID ||
        distinctive_identifier_support == EmeFeatureSupport::NOT_SUPPORTED) {
      distinctive_identifier = EmeFeatureRequirement::NotAllowed;
    }
  }

  // 6. Follow the steps for distinctive identifier requirement from the
  //    following list:
  //      - "required": If the implementation does not support use of
  //         Distinctive Identifier(s) in combination with accumulated
  //         configuration and restrictions, return NotSupported.
  //      - "optional": Continue with the following steps.
  //      - "not-allowed": If the implementation requires use Distinctive
  //        Identifier(s) or Distinctive Permanent Identifier(s) in
  //        combination with accumulated configuration and restrictions,
  //        return NotSupported.
  // We also reject OPTIONAL when distinctive identifiers are ALWAYS_ENABLED and
  // permission has already been denied. This would happen anyway later.
  EmeConfigRule di_rule = GetDistinctiveIdentifierConfigRule(
      distinctive_identifier_support, distinctive_identifier);
  if (!config_state->IsRuleSupported(di_rule)) {
    DVLOG(2) << "Rejecting requested configuration because "
             << "the distinctiveIdentifier requirement was not supported.";
    return CONFIGURATION_NOT_SUPPORTED;
  }
  config_state->AddRule(di_rule);

  // 7. Set the distinctiveIdentifier member of accumulated configuration to
  //    equal distinctive identifier requirement.
  accumulated_configuration->distinctiveIdentifier = distinctive_identifier;

  // 8. Let persistent state requirement be equal to the value of candidate
  //    configuration's persistentState member.
  EmeFeatureRequirement persistent_state = candidate.persistentState;

  // 9. If persistent state requirement is "optional" and persisting state is
  //    not allowed according to restrictions, set persistent state requirement
  //    to "not-allowed".
  EmeFeatureSupport persistent_state_support =
      key_systems_->GetPersistentStateSupport(key_system);
  if (persistent_state == EmeFeatureRequirement::Optional) {
    if (persistent_state_support == EmeFeatureSupport::INVALID ||
        persistent_state_support == EmeFeatureSupport::NOT_SUPPORTED) {
      persistent_state = EmeFeatureRequirement::NotAllowed;
    }
  }

  // 10. Follow the steps for persistent state requirement from the following
  //     list:
  //       - "required": If the implementation does not support persisting
  //         state in combination with accumulated configuration and
  //         restrictions, return NotSupported.
  //       - "optional": Continue with the following steps.
  //       - "not-allowed": If the implementation requires persisting state in
  //         combination with accumulated configuration and restrictions,
  //         return NotSupported.
  EmeConfigRule ps_rule =
      GetPersistentStateConfigRule(persistent_state_support, persistent_state);
  if (!config_state->IsRuleSupported(ps_rule)) {
    DVLOG(2) << "Rejecting requested configuration because "
             << "the persistentState requirement was not supported.";
    return CONFIGURATION_NOT_SUPPORTED;
  }
  config_state->AddRule(ps_rule);

  // 11. Set the persistentState member of accumulated configuration to equal
  //     the value of persistent state requirement.
  accumulated_configuration->persistentState = persistent_state;

  // 12. Follow the steps for the first matching condition from the following
  //     list:
  //       - If the sessionTypes member is present in candidate configuration,
  //         let session types be candidate configuration's sessionTypes member.
  //       - Otherwise, let session types be [ "temporary" ].
  //         (Done in MediaKeySystemAccessInitializer.)
  blink::WebVector<blink::WebEncryptedMediaSessionType> session_types =
      candidate.sessionTypes;

  // 13. For each value in session types:
  for (size_t i = 0; i < session_types.size(); i++) {
    // 13.1. Let session type be the value.
    blink::WebEncryptedMediaSessionType session_type = session_types[i];

    // 13.2. If accumulated configuration's persistentState value is
    //       "not-allowed" and the Is persistent session type? algorithm
    //       returns true for session type return NotSupported.
    if (accumulated_configuration->persistentState ==
            EmeFeatureRequirement::NotAllowed &&
        IsPersistentSessionType(session_type)) {
      DVLOG(2) << "Rejecting requested configuration because persistent "
                  "sessions are not allowed.";
      return CONFIGURATION_NOT_SUPPORTED;
    }

    // 13.3. If the implementation does not support session type in combination
    //       with accumulated configuration and restrictions for other reasons,
    //       return NotSupported.
    EmeConfigRule session_type_rule = EmeConfigRule::NOT_SUPPORTED;
    switch (session_type) {
      case blink::WebEncryptedMediaSessionType::Unknown:
        DVLOG(2) << "Rejecting requested configuration because "
                 << "a required session type was not recognized.";
        return CONFIGURATION_NOT_SUPPORTED;
      case blink::WebEncryptedMediaSessionType::Temporary:
        session_type_rule = EmeConfigRule::SUPPORTED;
        break;
      case blink::WebEncryptedMediaSessionType::PersistentLicense:
        session_type_rule = GetSessionTypeConfigRule(
            key_systems_->GetPersistentLicenseSessionSupport(key_system));
        break;
      case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage:
        session_type_rule = GetSessionTypeConfigRule(
            key_systems_->GetPersistentReleaseMessageSessionSupport(
                key_system));
        break;
    }

    if (!config_state->IsRuleSupported(session_type_rule)) {
      DVLOG(2) << "Rejecting requested configuration because "
               << "a required session type was not supported.";
      return CONFIGURATION_NOT_SUPPORTED;
    }
    config_state->AddRule(session_type_rule);

    // 13.4. If accumulated configuration's persistentState value is "optional"
    //       and the result of running the Is persistent session type?
    //       algorithm on session type is true, change accumulated
    //       configuration's persistentState value to "required".
    if (accumulated_configuration->persistentState ==
            EmeFeatureRequirement::Optional &&
        IsPersistentSessionType(session_type)) {
      accumulated_configuration->persistentState =
          EmeFeatureRequirement::Required;
    }
  }

  // 14. Set the sessionTypes member of accumulated configuration to
  //     session types.
  accumulated_configuration->sessionTypes = session_types;

  // 15. If the videoCapabilities and audioCapabilities members in candidate
  //     configuration are both empty, return NotSupported.
  // TODO(jrummell): Enforce this once the deprecation warning is removed.
  // See http://crbug.com/616233.

  // 16. If the videoCapabilities member in candidate configuration is
  //     non-empty:
  std::vector<blink::WebMediaKeySystemMediaCapability> video_capabilities;
  if (!candidate.videoCapabilities.isEmpty()) {
    // 16.1. Let video capabilities be the result of executing the Get
    //       Supported Capabilities for Audio/Video Type algorithm on Video,
    //       candidate configuration's videoCapabilities member, accumulated
    //       configuration, and restrictions.
    // 16.2. If video capabilities is null, return NotSupported.
    if (!GetSupportedCapabilities(key_system, EmeMediaType::VIDEO,
                                  candidate.videoCapabilities, config_state,
                                  &video_capabilities)) {
      return CONFIGURATION_NOT_SUPPORTED;
    }

    // 16.3. Set the videoCapabilities member of accumulated configuration
    //       to video capabilities.
    accumulated_configuration->videoCapabilities = video_capabilities;
  } else {
    // Otherwise set the videoCapabilities member of accumulated configuration
    // to an empty sequence.
    accumulated_configuration->videoCapabilities = video_capabilities;
  }

  // 17. If the audioCapabilities member in candidate configuration is
  //     non-empty:
  std::vector<blink::WebMediaKeySystemMediaCapability> audio_capabilities;
  if (!candidate.audioCapabilities.isEmpty()) {
    // 17.1. Let audio capabilities be the result of executing the Get
    //       Supported Capabilities for Audio/Video Type algorithm on Audio,
    //       candidate configuration's audioCapabilities member, accumulated
    //       configuration, and restrictions.
    // 17.2. If audio capabilities is null, return NotSupported.
    if (!GetSupportedCapabilities(key_system, EmeMediaType::AUDIO,
                                  candidate.audioCapabilities, config_state,
                                  &audio_capabilities)) {
      return CONFIGURATION_NOT_SUPPORTED;
    }

    // 17.3. Set the audioCapabilities member of accumulated configuration
    //       to audio capabilities.
    accumulated_configuration->audioCapabilities = audio_capabilities;
  } else {
    // Otherwise set the audioCapabilities member of accumulated configuration
    // to an empty sequence.
    accumulated_configuration->audioCapabilities = audio_capabilities;
  }

  // 18. If accumulated configuration's distinctiveIdentifier value is
  //     "optional", follow the steps for the first matching condition
  //      from the following list:
  //       - If the implementation requires use Distinctive Identifier(s) or
  //         Distinctive Permanent Identifier(s) for any of the combinations
  //         in accumulated configuration, change accumulated configuration's
  //         distinctiveIdentifier value to "required".
  //       - Otherwise, change accumulated configuration's
  //         distinctiveIdentifier value to "not-allowed".
  if (accumulated_configuration->distinctiveIdentifier ==
      EmeFeatureRequirement::Optional) {
    EmeConfigRule not_allowed_rule = GetDistinctiveIdentifierConfigRule(
        key_systems_->GetDistinctiveIdentifierSupport(key_system),
        EmeFeatureRequirement::NotAllowed);
    EmeConfigRule required_rule = GetDistinctiveIdentifierConfigRule(
        key_systems_->GetDistinctiveIdentifierSupport(key_system),
        EmeFeatureRequirement::Required);
    bool not_allowed_supported =
        config_state->IsRuleSupported(not_allowed_rule);
    bool required_supported = config_state->IsRuleSupported(required_rule);
    // If a distinctive identifier is recommend and that is a possible outcome,
    // prefer that.
    if (required_supported && config_state->IsIdentifierRecommended() &&
        config_state->IsPermissionPossible()) {
      not_allowed_supported = false;
    }
    if (not_allowed_supported) {
      accumulated_configuration->distinctiveIdentifier =
          EmeFeatureRequirement::NotAllowed;
      config_state->AddRule(not_allowed_rule);
    } else if (required_supported) {
      accumulated_configuration->distinctiveIdentifier =
          EmeFeatureRequirement::Required;
      config_state->AddRule(required_rule);
    } else {
      // We should not have passed step 6.
      NOTREACHED();
      return CONFIGURATION_NOT_SUPPORTED;
    }
  }

  // 19. If accumulated configuration's persistentState value is "optional",
  //     follow the steps for the first matching condition from the following
  //     list:
  //       - If the implementation requires persisting state for any of the
  //         combinations in accumulated configuration, change accumulated
  //         configuration's persistentState value to "required".
  //       - Otherwise, change accumulated configuration's persistentState
  //         value to "not-allowed".
  if (accumulated_configuration->persistentState ==
      EmeFeatureRequirement::Optional) {
    EmeConfigRule not_allowed_rule = GetPersistentStateConfigRule(
        key_systems_->GetPersistentStateSupport(key_system),
        EmeFeatureRequirement::NotAllowed);
    EmeConfigRule required_rule = GetPersistentStateConfigRule(
        key_systems_->GetPersistentStateSupport(key_system),
        EmeFeatureRequirement::Required);
    // |distinctiveIdentifier| should not be affected after it is decided.
    DCHECK(not_allowed_rule == EmeConfigRule::NOT_SUPPORTED ||
           not_allowed_rule == EmeConfigRule::PERSISTENCE_NOT_ALLOWED);
    DCHECK(required_rule == EmeConfigRule::NOT_SUPPORTED ||
           required_rule == EmeConfigRule::PERSISTENCE_REQUIRED);
    bool not_allowed_supported =
        config_state->IsRuleSupported(not_allowed_rule);
    bool required_supported = config_state->IsRuleSupported(required_rule);
    if (not_allowed_supported) {
      accumulated_configuration->persistentState =
          EmeFeatureRequirement::NotAllowed;
      config_state->AddRule(not_allowed_rule);
    } else if (required_supported) {
      accumulated_configuration->persistentState =
          EmeFeatureRequirement::Required;
      config_state->AddRule(required_rule);
    } else {
      // We should not have passed step 5.
      NOTREACHED();
      return CONFIGURATION_NOT_SUPPORTED;
    }
  }

  // 20. If implementation in the configuration specified by the combination of
  //     the values in accumulated configuration is not supported or not allowed
  //     in the origin, return NotSupported.
  // TODO(jrummell): can we check that the CDM can't be loaded by the origin?

  // 21. If accumulated configuration's distinctiveIdentifier value is
  //     "required" and the Distinctive Identifier(s) associated with
  //     accumulated configuration are not unique per origin and profile
  //     and clearable:
  // 21.1. Update restrictions to reflect that all configurations described
  //       by accumulated configuration do not have user consent.
  // 21.2. Return ConsentDenied and restrictions.
  // (Not required as data is unique per origin and clearable.)

  // 22. Let consent status and updated restrictions be the result of running
  //     the Get Consent Status algorithm on accumulated configuration,
  //     restrictions and origin and follow the steps for the value of consent
  //     status from the following list:
  //       - "ConsentDenied": Return ConsentDenied and updated restrictions.
  //       - "InformUser": Inform the user that accumulated configuration is
  //         in use in the origin including, specifically, the information
  //         that Distinctive Identifier(s) and/or Distinctive Permanent
  //         Identifier(s) as appropriate will be used if the
  //         distinctiveIdentifier member of accumulated configuration is
  //         "required". Continue to the next step.
  //       - "Allowed": Continue to the next step.
  // Accumulated configuration's distinctiveIdentifier should be "required" or
  // "notallowed"" due to step 18. If it is "required", prompt the user for
  // consent unless it has already been granted.
  if (accumulated_configuration->distinctiveIdentifier ==
      EmeFeatureRequirement::Required) {
    // The caller is responsible for resolving what to do if permission is
    // required but has been denied (it should treat it as NOT_SUPPORTED).
    if (!config_state->IsPermissionGranted())
      return CONFIGURATION_REQUIRES_PERMISSION;
  }

  // 23. Return accumulated configuration.
  return CONFIGURATION_SUPPORTED;
}

void KeySystemConfigSelector::SelectConfig(
    const blink::WebString& key_system,
    const blink::WebVector<blink::WebMediaKeySystemConfiguration>&
        candidate_configurations,
    const blink::WebSecurityOrigin& security_origin,
    bool are_secure_codecs_supported,
    base::Callback<void(const blink::WebMediaKeySystemConfiguration&,
                        const CdmConfig&)> succeeded_cb,
    base::Callback<void(const blink::WebString&)> not_supported_cb) {
  // Continued from requestMediaKeySystemAccess(), step 6, from
  // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess
  //
  // 6.1 If keySystem is not one of the Key Systems supported by the user
  //     agent, reject promise with a NotSupportedError. String comparison
  //     is case-sensitive.
  if (!base::IsStringASCII(key_system)) {
    not_supported_cb.Run("Only ASCII keySystems are supported");
    return;
  }

  std::string key_system_ascii =
      base::UTF16ToASCII(base::StringPiece16(key_system));
  if (!key_systems_->IsSupportedKeySystem(key_system_ascii)) {
    not_supported_cb.Run("Unsupported keySystem");
    return;
  }

  // 6.2-6.4. Implemented by OnSelectConfig().
  // TODO(sandersd): This should be async, ideally not on the main thread.
  std::unique_ptr<SelectionRequest> request(new SelectionRequest());
  request->key_system = key_system_ascii;
  request->candidate_configurations = candidate_configurations;
  request->security_origin = security_origin;
  request->are_secure_codecs_supported = are_secure_codecs_supported;
  request->succeeded_cb = succeeded_cb;
  request->not_supported_cb = not_supported_cb;
  SelectConfigInternal(std::move(request));
}

void KeySystemConfigSelector::SelectConfigInternal(
    std::unique_ptr<SelectionRequest> request) {
  // Continued from requestMediaKeySystemAccess(), step 6, from
  // https://w3c.github.io/encrypted-media/#requestmediakeysystemaccess
  //
  // 6.2. Let implementation be the implementation of keySystem.
  //      (|key_systems_| fills this role.)
  // 6.3. For each value in supportedConfigurations:
  for (size_t i = 0; i < request->candidate_configurations.size(); i++) {
    // 6.3.1. Let candidate configuration be the value.
    // 6.3.2. Let supported configuration be the result of executing the Get
    //        Supported Configuration algorithm on implementation, candidate
    //        configuration, and origin.
    // 6.3.3. If supported configuration is not NotSupported, [initialize
    //        and return a new MediaKeySystemAccess object.]
    ConfigState config_state(request->was_permission_requested,
                             request->is_permission_granted);
    DCHECK(config_state.IsRuleSupported(
        EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED));
    if (!request->are_secure_codecs_supported)
      config_state.AddRule(EmeConfigRule::HW_SECURE_CODECS_NOT_ALLOWED);
    blink::WebMediaKeySystemConfiguration accumulated_configuration;
    CdmConfig cdm_config;
    ConfigurationSupport support = GetSupportedConfiguration(
        request->key_system, request->candidate_configurations[i],
        &config_state, &accumulated_configuration);
    switch (support) {
      case CONFIGURATION_NOT_SUPPORTED:
        continue;
      case CONFIGURATION_REQUIRES_PERMISSION:
        if (request->was_permission_requested) {
          DVLOG(2) << "Rejecting requested configuration because "
                   << "permission was denied.";
          continue;
        }
        {
          // Note: the GURL must not be constructed inline because
          // base::Passed(&request) sets |request| to null.
          GURL security_origin(
              blink::WebStringToGURL(request->security_origin.toString()));
          media_permission_->RequestPermission(
              MediaPermission::PROTECTED_MEDIA_IDENTIFIER, security_origin,
              base::Bind(&KeySystemConfigSelector::OnPermissionResult,
                         weak_factory_.GetWeakPtr(), base::Passed(&request)));
        }
        return;
      case CONFIGURATION_SUPPORTED:
        cdm_config.allow_distinctive_identifier =
            (accumulated_configuration.distinctiveIdentifier ==
             EmeFeatureRequirement::Required);
        cdm_config.allow_persistent_state =
            (accumulated_configuration.persistentState ==
             EmeFeatureRequirement::Required);
        cdm_config.use_hw_secure_codecs =
            config_state.AreHwSecureCodecsRequired();
        request->succeeded_cb.Run(accumulated_configuration, cdm_config);
        return;
    }
  }

  // 6.4. Reject promise with a NotSupportedError.
  request->not_supported_cb.Run(
      "None of the requested configurations were supported.");
}

void KeySystemConfigSelector::OnPermissionResult(
    std::unique_ptr<SelectionRequest> request, bool is_permission_granted) {
  request->was_permission_requested = true;
  request->is_permission_granted = is_permission_granted;
  SelectConfigInternal(std::move(request));
}

}  // namespace media
