media_drm_bridge.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/android/build_info.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/android/jni_array.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/android/jni_string.h" 10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/callback_helpers.h" 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/location.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "jni/MediaDrmBridge_jni.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/base/android/media_player_manager.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::android::AttachCurrentThread; 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using base::android::ConvertUTF8ToJavaString; 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing base::android::ConvertJavaStringToUTF8; 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing base::android::JavaByteArrayToByteVector; 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::android::ScopedJavaLocalRef; 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace media { 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic uint32 ReadUint32(const uint8_t* data) { 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 value = 0; 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < 4; ++i) 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value = (value << 8) | data[i]; 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return value; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic uint64 ReadUint64(const uint8_t* data) { 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint64 value = 0; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (int i = 0; i < 8; ++i) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch value = (value << 8) | data[i]; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return value; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The structure of an ISO CENC Protection System Specific Header (PSSH) box is 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// as follows. (See ISO/IEC FDIS 23001-7:2011(E).) 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Note: ISO boxes use big-endian values. 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// PSSH { 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 Size 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 Type 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint64 LargeSize # Field is only present if value(Size) == 1. 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 VersionAndFlags 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint8[16] SystemId 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint32 DataSize 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// uint8[DataSize] Data 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// } 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kBoxHeaderSize = 8; // Box's header contains Size and Type. 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kBoxLargeSizeSize = 8; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kPsshVersionFlagSize = 4; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kPsshSystemIdSize = 16; 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kPsshDataSizeSize = 4; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const uint32 kTencType = 0x74656e63; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const uint32 kPsshType = 0x70737368; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Tries to find a PSSH box whose "SystemId" is |uuid| in |data|, parses the 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// "Data" of the box and put it in |pssh_data|. Returns true if such a box is 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found and successfully parsed. Returns false otherwise. 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Notes: 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 1, If multiple PSSH boxes are found,the "Data" of the first matching PSSH box 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// will be set in |pssh_data|. 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 2, Only PSSH and TENC boxes are allowed in |data|. TENC boxes are skipped. 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic bool GetPsshData(const uint8* data, int data_size, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::vector<uint8>& uuid, 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8>* pssh_data) { 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* cur = data; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* data_end = data + data_size; 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int bytes_left = data_size; 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch while (bytes_left > 0) { 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* box_head = cur; 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bytes_left < kBoxHeaderSize) 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint64_t box_size = ReadUint32(cur); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 type = ReadUint32(cur + 4); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kBoxHeaderSize; 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kBoxHeaderSize; 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_size == 1) { // LargeSize is present. 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bytes_left < kBoxLargeSizeSize) 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch box_size = ReadUint64(cur); 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kBoxLargeSizeSize; 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kBoxLargeSizeSize; 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (box_size == 0) { 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch box_size = bytes_left + kBoxHeaderSize; 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* box_end = box_head + box_size; 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (data_end < box_end) 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (type == kTencType) { 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Skip 'tenc' box. 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur = box_end; 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left = data_end - cur; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (type != kPsshType) { 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kPsshBoxMinimumSize = 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kPsshVersionFlagSize + kPsshSystemIdSize + kPsshDataSizeSize; 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_end < cur + kPsshBoxMinimumSize) 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 version_and_flags = ReadUint32(cur); 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshVersionFlagSize; 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshVersionFlagSize; 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (version_and_flags != 0) 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_GE(bytes_left, kPsshSystemIdSize); 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!std::equal(uuid.begin(), uuid.end(), cur)) { 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur = box_end; 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left = data_end - cur; 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshSystemIdSize; 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshSystemIdSize; 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 data_size = ReadUint32(cur); 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cur += kPsshDataSizeSize; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bytes_left -= kPsshDataSizeSize; 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (box_end < cur + data_size) 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pssh_data->assign(cur, cur + data_size); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMediaDrmBridge* MediaDrmBridge::Create(int media_keys_id, 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::vector<uint8>& scheme_uuid, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MediaPlayerManager* manager) { 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsAvailable() || scheme_uuid.empty()) 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return NULL; 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(qinmin): check whether the uuid is valid. 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return new MediaDrmBridge(media_keys_id, scheme_uuid, manager); 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaDrmBridge::IsAvailable() { 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base::android::BuildInfo::GetInstance()->sdk_int() >= 18; 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return RegisterNativesImpl(env); 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMediaDrmBridge::MediaDrmBridge(int media_keys_id, 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::vector<uint8>& scheme_uuid, 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MediaPlayerManager* manager) 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : media_keys_id_(media_keys_id), 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scheme_uuid_(scheme_uuid), 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) manager_(manager) { 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(env); 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) j_media_drm_.Reset(Java_MediaDrmBridge_create( 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) env, j_scheme_uuid.obj(), reinterpret_cast<intptr_t>(this))); 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MediaDrmBridge::~MediaDrmBridge() { 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Java_MediaDrmBridge_release(env, j_media_drm_.obj()); 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaDrmBridge::GenerateKeyRequest(const std::string& type, 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* init_data, 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int init_data_length) { 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8> pssh_data; 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!GetPsshData(init_data, init_data_length, scheme_uuid_, &pssh_data)) 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> j_pssh_data = 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, type); 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Java_MediaDrmBridge_generateKeyRequest( 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) env, j_media_drm_.obj(), j_pssh_data.obj(), j_mime.obj()); 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaDrmBridge::AddKey(const uint8* key, int key_length, 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* init_data, int init_data_length, 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& session_id) { 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jbyteArray> j_key_data = 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::android::ToJavaByteArray(env, key, key_length); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_session_id = 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConvertUTF8ToJavaString(env, session_id); 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Java_MediaDrmBridge_addKey( 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) env, j_media_drm_.obj(), j_session_id.obj(), j_key_data.obj()); 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaDrmBridge::CancelKeyRequest(const std::string& session_id) { 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_session_id = 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConvertUTF8ToJavaString(env, session_id); 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Java_MediaDrmBridge_cancelKeyRequest( 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) env, j_media_drm_.obj(), j_session_id.obj()); 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaDrmBridge::SetMediaCryptoReadyCB(const base::Closure& closure) { 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (closure.is_null()) { 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) media_crypto_ready_cb_.Reset(); 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(media_crypto_ready_cb_.is_null()); 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!GetMediaCrypto().is_null()) { 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::MessageLoopProxy::current()->PostTask(FROM_HERE, closure); 229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) media_crypto_ready_cb_ = closure; 233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void MediaDrmBridge::OnMediaCryptoReady(JNIEnv* env, jobject) { 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!GetMediaCrypto().is_null()); 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!media_crypto_ready_cb_.is_null()) 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::ResetAndReturn(&media_crypto_ready_cb_).Run(); 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MediaDrmBridge::OnKeyMessage(JNIEnv* env, 242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jobject j_media_drm, 243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jstring j_session_id, 244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jbyteArray j_message, 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jstring j_destination_url) { 246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8> message; 248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch JavaByteArrayToByteVector(env, j_message, &message); 249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string destination_url = ConvertJavaStringToUTF8(env, j_destination_url); 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch manager_->OnKeyMessage(media_keys_id_, session_id, message, destination_url); 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaDrmBridge::OnKeyAdded(JNIEnv* env, jobject, jstring j_session_id) { 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) manager_->OnKeyAdded(media_keys_id_, session_id); 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaDrmBridge::OnKeyError(JNIEnv* env, jobject, jstring j_session_id) { 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // |j_session_id| can be NULL, in which case we'll return an empty string. 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) manager_->OnKeyError(media_keys_id_, session_id, MediaKeys::kUnknownError, 0); 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return Java_MediaDrmBridge_getMediaCrypto(env, j_media_drm_.obj()); 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)MediaDrmBridge::SecurityLevel MediaDrmBridge::GetSecurityLevel() { 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_security_level = 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Java_MediaDrmBridge_getSecurityLevel(env, j_media_drm_.obj()); 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string security_level = 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ConvertJavaStringToUTF8(env, j_security_level.obj()); 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (0 == security_level.compare("L1")) 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SECURITY_LEVEL_1; 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (0 == security_level.compare("L3")) 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SECURITY_LEVEL_3; 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(security_level.empty()); 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return SECURITY_LEVEL_NONE; 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool MediaDrmBridge::IsProtectedSurfaceRequired() { 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return MediaDrmBridge::SECURITY_LEVEL_1 == GetSecurityLevel(); 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace media 289