Home | History | Annotate | Download | only in crypto
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/media/crypto/key_systems.h"
      6 
      7 #include <map>
      8 
      9 #include "base/lazy_instance.h"
     10 #include "base/logging.h"
     11 #include "base/strings/string_util.h"
     12 #include "content/renderer/media/crypto/key_systems_info.h"
     13 #include "net/base/mime_util.h"
     14 #include "third_party/WebKit/public/platform/WebCString.h"
     15 #include "third_party/WebKit/public/platform/WebString.h"
     16 
     17 namespace content {
     18 
     19 // Convert a WebString to ASCII, falling back on an empty string in the case
     20 // of a non-ASCII string.
     21 static std::string ToASCIIOrEmpty(const WebKit::WebString& string) {
     22   return IsStringASCII(string) ? UTF16ToASCII(string) : std::string();
     23 }
     24 
     25 class KeySystems {
     26  public:
     27   bool IsSupportedKeySystem(const std::string& key_system);
     28 
     29   bool IsSupportedKeySystemWithMediaMimeType(
     30       const std::string& mime_type,
     31       const std::vector<std::string>& codecs,
     32       const std::string& key_system);
     33 
     34  private:
     35   friend struct base::DefaultLazyInstanceTraits<KeySystems>;
     36 
     37   typedef base::hash_set<std::string> CodecMappings;
     38   typedef std::map<std::string, CodecMappings> MimeTypeMappings;
     39   typedef std::map<std::string, MimeTypeMappings> KeySystemMappings;
     40 
     41   KeySystems();
     42 
     43   bool IsSupportedKeySystemWithContainerAndCodec(
     44       const std::string& mime_type,
     45       const std::string& codec,
     46       const std::string& key_system);
     47 
     48   KeySystemMappings key_system_map_;
     49 
     50   DISALLOW_COPY_AND_ASSIGN(KeySystems);
     51 };
     52 
     53 static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER;
     54 
     55 KeySystems::KeySystems() {
     56   // Initialize the supported media type/key system combinations.
     57   for (int i = 0; i < kNumSupportedFormatKeySystemCombinations; ++i) {
     58     const MediaFormatAndKeySystem& combination =
     59         kSupportedFormatKeySystemCombinations[i];
     60     std::vector<std::string> mime_type_codecs;
     61     net::ParseCodecString(combination.codecs_list,
     62                           &mime_type_codecs,
     63                           false);
     64 
     65     CodecMappings codecs;
     66     for (size_t j = 0; j < mime_type_codecs.size(); ++j)
     67       codecs.insert(mime_type_codecs[j]);
     68     // Support the MIME type string alone, without codec(s) specified.
     69     codecs.insert(std::string());
     70 
     71     // Key systems can be repeated, so there may already be an entry.
     72     KeySystemMappings::iterator key_system_iter =
     73         key_system_map_.find(combination.key_system);
     74     if (key_system_iter == key_system_map_.end()) {
     75       MimeTypeMappings mime_types_map;
     76       mime_types_map[combination.mime_type] = codecs;
     77       key_system_map_[combination.key_system] = mime_types_map;
     78     } else {
     79       MimeTypeMappings& mime_types_map = key_system_iter->second;
     80       // mime_types_map may not be repeated for a given key system.
     81       DCHECK(mime_types_map.find(combination.mime_type) ==
     82              mime_types_map.end());
     83       mime_types_map[combination.mime_type] = codecs;
     84     }
     85   }
     86 }
     87 
     88 bool KeySystems::IsSupportedKeySystem(const std::string& key_system) {
     89   bool is_supported = key_system_map_.find(key_system) != key_system_map_.end();
     90   return is_supported && IsSystemCompatible(key_system);
     91 }
     92 
     93 bool KeySystems::IsSupportedKeySystemWithContainerAndCodec(
     94     const std::string& mime_type,
     95     const std::string& codec,
     96     const std::string& key_system) {
     97   KeySystemMappings::const_iterator key_system_iter =
     98       key_system_map_.find(key_system);
     99   if (key_system_iter == key_system_map_.end())
    100     return false;
    101 
    102   const MimeTypeMappings& mime_types_map = key_system_iter->second;
    103   MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type);
    104   if (mime_iter == mime_types_map.end())
    105     return false;
    106 
    107   const CodecMappings& codecs = mime_iter->second;
    108   return (codecs.find(codec) != codecs.end()) && IsSystemCompatible(key_system);
    109 }
    110 
    111 bool KeySystems::IsSupportedKeySystemWithMediaMimeType(
    112     const std::string& mime_type,
    113     const std::vector<std::string>& codecs,
    114     const std::string& key_system) {
    115   // This method is only used by the canPlaytType() path (not the EME methods),
    116   // so we check for suppressed key_systems here.
    117   if(IsCanPlayTypeSuppressed(key_system))
    118     return false;
    119 
    120   if (codecs.empty())
    121     return IsSupportedKeySystemWithContainerAndCodec(
    122         mime_type, std::string(), key_system);
    123 
    124   for (size_t i = 0; i < codecs.size(); ++i) {
    125     if (!IsSupportedKeySystemWithContainerAndCodec(
    126             mime_type, codecs[i], key_system))
    127       return false;
    128   }
    129 
    130   return true;
    131 }
    132 
    133 bool IsSupportedKeySystem(const WebKit::WebString& key_system) {
    134   return g_key_systems.Get().IsSupportedKeySystem(ToASCIIOrEmpty(key_system));
    135 }
    136 
    137 bool IsSupportedKeySystemWithMediaMimeType(
    138     const std::string& mime_type,
    139     const std::vector<std::string>& codecs,
    140     const std::string& key_system) {
    141   return g_key_systems.Get().IsSupportedKeySystemWithMediaMimeType(
    142       mime_type, codecs, key_system);
    143 }
    144 
    145 std::string KeySystemNameForUMA(const WebKit::WebString& key_system) {
    146   return KeySystemNameForUMAInternal(key_system);
    147 }
    148 
    149 bool CanUseAesDecryptor(const std::string& key_system) {
    150   return CanUseBuiltInAesDecryptor(key_system);
    151 }
    152 
    153 #if defined(ENABLE_PEPPER_CDMS)
    154 std::string GetPepperType(const std::string& key_system) {
    155   for (int i = 0; i < kNumKeySystemToPepperTypeMapping; ++i) {
    156     if (kKeySystemToPepperTypeMapping[i].key_system == key_system)
    157       return kKeySystemToPepperTypeMapping[i].type;
    158   }
    159 
    160   return std::string();
    161 }
    162 #endif  // defined(ENABLE_PEPPER_CDMS)
    163 
    164 #if defined(OS_ANDROID)
    165 std::vector<uint8> GetUUID(const std::string& key_system) {
    166   for (int i = 0; i < kNumKeySystemToUUIDMapping; ++i) {
    167     if (kKeySystemToUUIDMapping[i].key_system == key_system)
    168       return std::vector<uint8>(kKeySystemToUUIDMapping[i].uuid,
    169                                 kKeySystemToUUIDMapping[i].uuid + 16);
    170   }
    171   return std::vector<uint8>();
    172 }
    173 #endif  // defined(OS_ANDROID)
    174 
    175 }  // namespace content
    176