17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/android/media_drm_bridge.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <algorithm> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/android/build_info.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/android/jni_array.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/android/jni_string.h" 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/callback_helpers.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/containers/hash_tables.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/lazy_instance.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/location.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_util.h" 196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/sys_byteorder.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "jni/MediaDrmBridge_jni.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::android::AttachCurrentThread; 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::android::ConvertUTF8ToJavaString; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing base::android::ConvertJavaStringToUTF8; 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing base::android::JavaByteArrayToByteVector; 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::android::ScopedJavaLocalRef; 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace media { 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic uint32 ReadUint32(const uint8_t* data) { 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 value = 0; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < 4; ++i) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value = (value << 8) | data[i]; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return value; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic uint64 ReadUint64(const uint8_t* data) { 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint64 value = 0; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < 8; ++i) 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value = (value << 8) | data[i]; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return value; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The structure of an ISO CENC Protection System Specific Header (PSSH) box is 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// as follows. (See ISO/IEC FDIS 23001-7:2011(E).) 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Note: ISO boxes use big-endian values. 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PSSH { 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 Size 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 Type 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint64 LargeSize # Field is only present if value(Size) == 1. 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 VersionAndFlags 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint8[16] SystemId 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 DataSize 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint8[DataSize] Data 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// } 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kBoxHeaderSize = 8; // Box's header contains Size and Type. 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kBoxLargeSizeSize = 8; 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kPsshVersionFlagSize = 4; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kPsshSystemIdSize = 16; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kPsshDataSizeSize = 4; 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const uint32 kTencType = 0x74656e63; 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const uint32 kPsshType = 0x70737368; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const uint8 kWidevineUuid[16] = { 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED }; 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)typedef std::vector<uint8> UUID; 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class KeySystemUuidManager { 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) KeySystemUuidManager(); 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UUID GetUUID(const std::string& key_system); 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void AddMapping(const std::string& key_system, const UUID& uuid); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string> GetPlatformKeySystemNames(); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef base::hash_map<std::string, UUID> KeySystemUuidMap; 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) KeySystemUuidMap key_system_uuid_map_; 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(KeySystemUuidManager); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)KeySystemUuidManager::KeySystemUuidManager() { 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Widevine is always supported in Android. 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) key_system_uuid_map_[kWidevineKeySystem] = 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UUID(kWidevineUuid, kWidevineUuid + arraysize(kWidevineUuid)); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)UUID KeySystemUuidManager::GetUUID(const std::string& key_system) { 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (it == key_system_uuid_map_.end()) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return UUID(); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return it->second; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void KeySystemUuidManager::AddMapping(const std::string& key_system, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const UUID& uuid) { 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(it == key_system_uuid_map_.end()) 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Shouldn't overwrite an existing key system."; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (it != key_system_uuid_map_.end()) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) key_system_uuid_map_[key_system] = uuid; 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::vector<std::string> KeySystemUuidManager::GetPlatformKeySystemNames() { 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string> key_systems; 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != key_system_uuid_map_.end(); ++it) { 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Rule out the key system handled by Chrome explicitly. 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (it->first != kWidevineKeySystem) 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) key_systems.push_back(it->first); 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return key_systems; 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::LazyInstance<KeySystemUuidManager>::Leaky g_key_system_uuid_manager = 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// "Data" of the box and put it in |pssh_data|. Returns true if such a box is 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found and successfully parsed. Returns false otherwise. 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Notes: 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// will be set in |pssh_data|. 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic bool GetPsshData(const uint8* data, int data_size, 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const UUID& uuid, 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8>* pssh_data) { 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* cur = data; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* data_end = data + data_size; 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int bytes_left = data_size; 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (bytes_left > 0) { 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* box_head = cur; 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bytes_left < kBoxHeaderSize) 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint64_t box_size = ReadUint32(cur); 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 type = ReadUint32(cur + 4); 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kBoxHeaderSize; 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kBoxHeaderSize; 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_size == 1) { // LargeSize is present. 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bytes_left < kBoxLargeSizeSize) 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch box_size = ReadUint64(cur); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kBoxLargeSizeSize; 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kBoxLargeSizeSize; 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (box_size == 0) { 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch box_size = bytes_left + kBoxHeaderSize; 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* box_end = box_head + box_size; 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (data_end < box_end) 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (type == kTencType) { 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Skip 'tenc' box. 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur = box_end; 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left = data_end - cur; 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (type != kPsshType) { 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kPsshBoxMinimumSize = 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPsshVersionFlagSize + kPsshSystemIdSize + kPsshDataSizeSize; 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_end < cur + kPsshBoxMinimumSize) 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 version_and_flags = ReadUint32(cur); 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshVersionFlagSize; 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshVersionFlagSize; 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (version_and_flags != 0) 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_GE(bytes_left, kPsshSystemIdSize); 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!std::equal(uuid.begin(), uuid.end(), cur)) { 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur = box_end; 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left = data_end - cur; 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshSystemIdSize; 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshSystemIdSize; 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 data_size = ReadUint32(cur); 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshDataSizeSize; 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshDataSizeSize; 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_end < cur + data_size) 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pssh_data->assign(cur, cur + data_size); 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static MediaDrmBridge::SecurityLevel GetSecurityLevelFromString( 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& security_level_str) { 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (0 == security_level_str.compare("L1")) 21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return MediaDrmBridge::SECURITY_LEVEL_1; 21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (0 == security_level_str.compare("L3")) 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return MediaDrmBridge::SECURITY_LEVEL_3; 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(security_level_str.empty()); 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return MediaDrmBridge::SECURITY_LEVEL_NONE; 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static std::string GetSecurityLevelString( 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaDrmBridge::SecurityLevel security_level) { 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (security_level) { 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case MediaDrmBridge::SECURITY_LEVEL_NONE: 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ""; 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case MediaDrmBridge::SECURITY_LEVEL_1: 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "L1"; 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case MediaDrmBridge::SECURITY_LEVEL_3: 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "L3"; 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ""; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Checks whether |key_system| is supported with |container_mime_type|. Only 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// checks |key_system| support if |container_mime_type| is empty. 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// TODO(xhwang): The |container_mime_type| is not the same as contentType in 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// the EME spec. Revisit this once the spec issue with initData type is 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// resolved. 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic bool IsKeySystemSupportedWithTypeImpl( 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& key_system, 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& container_mime_type) { 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!MediaDrmBridge::IsAvailable()) 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (scheme_uuid.empty()) 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch JNIEnv* env = AttachCurrentThread(); 247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ScopedJavaLocalRef<jstring> j_container_mime_type = 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ConvertUTF8ToJavaString(env, container_mime_type); 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return Java_MediaDrmBridge_isCryptoSchemeSupported( 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch env, j_scheme_uuid.obj(), j_container_mime_type.obj()); 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaDrmBridge::IsAvailable() { 2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaDrmBridge::IsSecureDecoderRequired(SecurityLevel security_level) { 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(IsAvailable()); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return SECURITY_LEVEL_1 == security_level; 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SecurityLevel security_level) { 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsAvailable()) 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<MediaDrmBridge> media_drm_bridge = 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaDrmBridge::CreateSessionless(key_system); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!media_drm_bridge) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return media_drm_bridge->SetSecurityLevel(security_level); 27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static void AddKeySystemUuidMapping(JNIEnv* env, jclass clazz, 2816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) jstring j_key_system, 2826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) jobject j_buffer) { 2836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string key_system = ConvertJavaStringToUTF8(env, j_key_system); 2846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) uint8* buffer = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer)); 2856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) UUID uuid(buffer, buffer + 16); 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) g_key_system_uuid_manager.Get().AddMapping(key_system, uuid); 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return g_key_system_uuid_manager.Get().GetPlatformKeySystemNames(); 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { 296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!key_system.empty()); 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return IsKeySystemSupportedWithTypeImpl(key_system, ""); 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// static 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MediaDrmBridge::IsKeySystemSupportedWithType( 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& key_system, 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& container_mime_type) { 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!key_system.empty() && !container_mime_type.empty()); 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return RegisterNativesImpl(env); 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MediaDrmBridge::MediaDrmBridge(const std::vector<uint8>& scheme_uuid, 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionCreatedCB& session_created_cb, 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionMessageCB& session_message_cb, 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionReadyCB& session_ready_cb, 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionClosedCB& session_closed_cb, 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionErrorCB& session_error_cb) 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : scheme_uuid_(scheme_uuid), 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_created_cb_(session_created_cb), 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_message_cb_(session_message_cb), 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_ready_cb_(session_ready_cb), 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_closed_cb_(session_closed_cb), 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_error_cb_(session_error_cb) { 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(env); 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) j_media_drm_.Reset(Java_MediaDrmBridge_create( 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MediaDrmBridge::~MediaDrmBridge() { 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) player_tracker_.NotifyCdmUnset(); 33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!j_media_drm_.is_null()) 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Java_MediaDrmBridge_release(env, j_media_drm_.obj()); 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& key_system, 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionCreatedCB& session_created_cb, 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionMessageCB& session_message_cb, 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionReadyCB& session_ready_cb, 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionClosedCB& session_closed_cb, 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SessionErrorCB& session_error_cb) { 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<MediaDrmBridge> media_drm_bridge; 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsAvailable()) 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return media_drm_bridge.Pass(); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UUID scheme_uuid = g_key_system_uuid_manager.Get().GetUUID(key_system); 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (scheme_uuid.empty()) 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return media_drm_bridge.Pass(); 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid, 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_created_cb, 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_message_cb, 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_ready_cb, 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_closed_cb, 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_error_cb)); 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (media_drm_bridge->j_media_drm_.is_null()) 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media_drm_bridge.reset(); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return media_drm_bridge.Pass(); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateSessionless( 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& key_system) { 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MediaDrmBridge::Create(key_system, 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SessionCreatedCB(), 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SessionMessageCB(), 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SessionReadyCB(), 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SessionClosedCB(), 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SessionErrorCB()); 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string security_level_str = GetSecurityLevelString(security_level); 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (security_level_str.empty()) 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_security_level = 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConvertUTF8ToJavaString(env, security_level_str); 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Java_MediaDrmBridge_setSecurityLevel( 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) env, j_media_drm_.obj(), j_security_level.obj()); 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool MediaDrmBridge::CreateSession(uint32 session_id, 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& content_type, 395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* init_data, 396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int init_data_length) { 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!session_created_cb_.is_null()) 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "CreateSession called on a sessionless MediaDrmBridge object."; 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 403c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ScopedJavaLocalRef<jbyteArray> j_init_data; 404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Caller should always use "video/*" content types. 405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK_EQ(0u, content_type.find("video/")); 406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Widevine MediaDrm plugin only accepts the "data" part of the PSSH box as 408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the init data when using MP4 container. 409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (std::equal(scheme_uuid_.begin(), scheme_uuid_.end(), kWidevineUuid) && 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch content_type == "video/mp4") { 411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<uint8> pssh_data; 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) 413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch j_init_data = 415c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); 416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch j_init_data = 418c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::android::ToJavaByteArray(env, init_data, init_data_length); 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 420c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_mime = 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConvertUTF8ToJavaString(env, content_type); 423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_MediaDrmBridge_createSession( 424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch env, j_media_drm_.obj(), session_id, j_init_data.obj(), j_mime.obj()); 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaDrmBridge::LoadSession(uint32 session_id, 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& web_session_id) { 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // MediaDrmBridge doesn't support loading sessions. 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::UpdateSession(uint32 session_id, 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* response, 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int response_length) { 43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DVLOG(1) << __FUNCTION__; 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!session_ready_cb_.is_null()) 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << __FUNCTION__ << " called on a sessionless MediaDrmBridge object."; 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> j_response = 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::android::ToJavaByteArray(env, response, response_length); 445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_MediaDrmBridge_updateSession( 446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) env, j_media_drm_.obj(), session_id, j_response.obj()); 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::ReleaseSession(uint32 session_id) { 450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << __FUNCTION__; 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!session_closed_cb_.is_null()) 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << __FUNCTION__ << " called on a sessionless MediaDrmBridge object."; 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Java_MediaDrmBridge_releaseSession(env, j_media_drm_.obj(), session_id); 4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int MediaDrmBridge::RegisterPlayer(const base::Closure& new_key_cb, 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Closure& cdm_unset_cb) { 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return player_tracker_.RegisterPlayer(new_key_cb, cdm_unset_cb); 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaDrmBridge::UnregisterPlayer(int registration_id) { 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) player_tracker_.UnregisterPlayer(registration_id); 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) { 469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (closure.is_null()) { 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) media_crypto_ready_cb_.Reset(); 471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(media_crypto_ready_cb_.is_null()); 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!GetMediaCrypto().is_null()) { 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::MessageLoopProxy::current()->PostTask(FROM_HERE, closure); 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) media_crypto_ready_cb_ = closure; 482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) { 485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!GetMediaCrypto().is_null()); 486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!media_crypto_ready_cb_.is_null()) 487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::ResetAndReturn(&media_crypto_ready_cb_).Run(); 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::OnSessionCreated(JNIEnv* env, 491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jobject j_media_drm, 492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jint j_session_id, 493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jstring j_web_session_id) { 494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 session_id = j_session_id; 495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string web_session_id = ConvertJavaStringToUTF8(env, j_web_session_id); 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_created_cb_.Run(session_id, web_session_id); 497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::OnSessionMessage(JNIEnv* env, 500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jobject j_media_drm, 501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jint j_session_id, 502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jbyteArray j_message, 503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jstring j_destination_url) { 504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 session_id = j_session_id; 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8> message; 506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JavaByteArrayToByteVector(env, j_message, &message); 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL destination_gurl = GURL(ConvertJavaStringToUTF8(env, j_destination_url)); 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!destination_gurl.is_valid() && !destination_gurl.is_empty()) { 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(WARNING) << "SessionMessage destination_url is invalid : " 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << destination_gurl.possibly_invalid_spec(); 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_message_cb_.Run(session_id, message, destination_gurl); 514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::OnSessionReady(JNIEnv* env, 517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jobject j_media_drm, 518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jint j_session_id) { 519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 session_id = j_session_id; 520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_ready_cb_.Run(session_id); 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(xhwang/jrummell): Move this when usableKeyIds/keyschange are 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // implemented. 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch player_tracker_.NotifyNewKey(); 5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::OnSessionClosed(JNIEnv* env, 527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jobject j_media_drm, 528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jint j_session_id) { 529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 session_id = j_session_id; 530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_closed_cb_.Run(session_id); 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaDrmBridge::OnSessionError(JNIEnv* env, 534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jobject j_media_drm, 535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) jint j_session_id) { 536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 session_id = j_session_id; 537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); 5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { 541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); 543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { 546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_security_level = 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); 54958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string security_level_str = 550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ConvertJavaStringToUTF8(env, j_security_level.obj()); 55158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return GetSecurityLevelFromString(security_level_str); 552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaDrmBridge::IsProtectedSurfaceRequired() { 55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return IsSecureDecoderRequired(GetSecurityLevel()); 556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaDrmBridge::ResetDeviceCredentials( 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResetCredentialsCB& callback) { 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(reset_credentials_cb_.is_null()); 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reset_credentials_cb_ = callback; 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Java_MediaDrmBridge_resetDeviceCredentials(env, j_media_drm_.obj()); 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaDrmBridge::OnResetDeviceCredentialsCompleted( 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env, jobject, bool success) { 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::ResetAndReturn(&reset_credentials_cb_).Run(success); 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace media 572