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