168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/browser/media/android/media_drm_credential_manager.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/android/jni_android.h"
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/android/scoped_java_ref.h"
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/bind.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/callback_helpers.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "jni/MediaDrmCredentialManager_jni.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "media/base/android/media_drm_bridge.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "url/gurl.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using base::android::ScopedJavaGlobalRef;
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaDrmCredentialManagerCallback(
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ScopedJavaGlobalRef<jobject>& j_media_drm_credential_manager_callback,
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool succeeded) {
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  content::Java_MediaDrmCredentialManagerCallback_onCredentialResetFinished(
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      env, j_media_drm_credential_manager_callback.obj(), succeeded);
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace content {
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaDrmCredentialManager::MediaDrmCredentialManager() {};
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaDrmCredentialManager::~MediaDrmCredentialManager() {};
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaDrmCredentialManager* MediaDrmCredentialManager::GetInstance() {
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return Singleton<MediaDrmCredentialManager>::get();
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaDrmCredentialManager::ResetCredentials(
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ResetCredentialsCB& reset_credentials_cb) {
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Ignore reset request if one is already in progress.
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!reset_credentials_cb_.is_null())
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reset_credentials_cb_ = reset_credentials_cb;
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // First reset the L3 credential.
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ResetCredentialsInternal(media::MediaDrmBridge::SECURITY_LEVEL_3)) {
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // TODO(qinmin): We should post a task instead.
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    base::ResetAndReturn(&reset_credentials_cb_).Run(false);
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ResetCredentials(
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    JNIEnv* env,
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    jclass clazz,
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    jobject j_media_drm_credential_manager_callback) {
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaDrmCredentialManager* media_drm_credential_manager =
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      MediaDrmCredentialManager::GetInstance();
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaGlobalRef<jobject> j_scoped_media_drm_credential_manager_callback;
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  j_scoped_media_drm_credential_manager_callback.Reset(
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      env, j_media_drm_credential_manager_callback);
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaDrmCredentialManager::ResetCredentialsCB callback_runner =
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&MediaDrmCredentialManagerCallback,
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 j_scoped_media_drm_credential_manager_callback);
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  media_drm_credential_manager->ResetCredentials(callback_runner);
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void MediaDrmCredentialManager::OnResetCredentialsCompleted(
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SecurityLevel security_level, bool success) {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (security_level == media::MediaDrmBridge::SECURITY_LEVEL_3 && success) {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ResetCredentialsInternal(media::MediaDrmBridge::SECURITY_LEVEL_1))
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return;
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    success = false;
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::ResetAndReturn(&reset_credentials_cb_).Run(success);
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  media_drm_bridge_.reset();
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool MediaDrmCredentialManager::ResetCredentialsInternal(
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SecurityLevel security_level) {
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  media_drm_bridge_ =
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      media::MediaDrmBridge::CreateSessionless(kWidevineKeySystem);
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!media_drm_bridge_)
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResetCredentialsCB reset_credentials_cb =
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&MediaDrmCredentialManager::OnResetCredentialsCompleted,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this), security_level);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!media_drm_bridge_->SetSecurityLevel(security_level)) {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // No need to reset credentials for unsupported |security_level|.
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE, base::Bind(reset_credentials_cb, true));
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media_drm_bridge_->ResetDeviceCredentials(reset_credentials_cb);
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool MediaDrmCredentialManager::RegisterMediaDrmCredentialManager(JNIEnv* env) {
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return RegisterNativesImpl(env);
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace content
118