blob: 040f8edc5ae02fba445287b2f7ad07b4e48e789a [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/base/android/media_drm_storage_bridge.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/android/callback_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/unguessable_token.h"
#include "jni/MediaDrmStorageBridge_jni.h"
#include "media/base/android/android_util.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaByteArrayToByteVector;
using base::android::JavaParamRef;
using base::android::RunCallbackAndroid;
using base::android::ScopedJavaLocalRef;
using base::android::ToJavaByteArray;
namespace media {
MediaDrmStorageBridge::MediaDrmStorageBridge()
: task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_factory_(this) {}
MediaDrmStorageBridge::~MediaDrmStorageBridge() = default;
void MediaDrmStorageBridge::Initialize(const CreateStorageCB& create_storage_cb,
base::OnceClosure init_cb) {
DCHECK(create_storage_cb);
impl_ = create_storage_cb.Run();
impl_->Initialize(base::BindOnce(&MediaDrmStorageBridge::OnInitialized,
weak_factory_.GetWeakPtr(),
std::move(init_cb)));
}
void MediaDrmStorageBridge::OnProvisioned(
JNIEnv* env,
const JavaParamRef<jobject>& j_storage,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::OnProvisioned, impl_->AsWeakPtr(),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
// Bind callback to WeakPtr in case callback is called
// after object is deleted.
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())))));
}
void MediaDrmStorageBridge::OnLoadInfo(
JNIEnv* env,
const JavaParamRef<jobject>& j_storage,
const JavaParamRef<jbyteArray>& j_session_id,
// Callback<PersistentInfo>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
std::string session_id = JavaBytesToString(env, j_session_id);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::LoadPersistentSession, impl_->AsWeakPtr(),
session_id,
base::BindOnce(&MediaDrmStorageBridge::OnSessionDataLoaded,
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())),
session_id)));
}
void MediaDrmStorageBridge::OnSaveInfo(
JNIEnv* env,
const JavaParamRef<jobject>& j_storage,
const JavaParamRef<jobject>& j_persist_info,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
std::vector<uint8_t> key_set_id;
JavaByteArrayToByteVector(
env, Java_PersistentInfo_keySetId(env, j_persist_info).obj(),
&key_set_id);
std::string mime = ConvertJavaStringToUTF8(
env, Java_PersistentInfo_mimeType(env, j_persist_info));
std::string session_id = JavaBytesToString(
env, Java_PersistentInfo_emeId(env, j_persist_info).obj());
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::SavePersistentSession, impl_->AsWeakPtr(),
session_id,
MediaDrmStorage::SessionData(std::move(key_set_id), std::move(mime)),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())))));
}
void MediaDrmStorageBridge::OnClearInfo(
JNIEnv* env,
const JavaParamRef<jobject>& j_storage,
const JavaParamRef<jbyteArray>& j_session_id,
// Callback<Boolean>
const JavaParamRef<jobject>& j_callback) {
DCHECK(impl_);
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&MediaDrmStorage::RemovePersistentSession, impl_->AsWeakPtr(),
JavaBytesToString(env, j_session_id),
base::BindOnce(&MediaDrmStorageBridge::RunAndroidBoolCallback,
weak_factory_.GetWeakPtr(),
base::Passed(CreateJavaObjectPtr(j_callback.obj())))));
}
void MediaDrmStorageBridge::RunAndroidBoolCallback(JavaObjectPtr j_callback,
bool success) {
RunCallbackAndroid(*j_callback, success);
}
void MediaDrmStorageBridge::OnInitialized(
base::OnceClosure init_cb,
const base::UnguessableToken& origin_id) {
DCHECK(origin_id_.empty());
if (origin_id)
origin_id_ = origin_id.ToString();
std::move(init_cb).Run();
}
void MediaDrmStorageBridge::OnSessionDataLoaded(
JavaObjectPtr j_callback,
const std::string& session_id,
std::unique_ptr<MediaDrmStorage::SessionData> session_data) {
if (!session_data) {
RunCallbackAndroid(*j_callback, ScopedJavaLocalRef<jobject>());
return;
}
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jbyteArray> j_eme_id = StringToJavaBytes(env, session_id);
ScopedJavaLocalRef<jbyteArray> j_key_set_id = ToJavaByteArray(
env, session_data->key_set_id.data(), session_data->key_set_id.size());
ScopedJavaLocalRef<jstring> j_mime =
ConvertUTF8ToJavaString(env, session_data->mime_type);
RunCallbackAndroid(*j_callback, Java_PersistentInfo_create(
env, j_eme_id, j_key_set_id, j_mime));
}
} // namespace media