Chromium Code Reviews| Index: chrome/browser/media/android/cdm/media_drm_storage_impl.cc |
| diff --git a/chrome/browser/media/android/cdm/media_drm_storage_impl.cc b/chrome/browser/media/android/cdm/media_drm_storage_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..fe1d187ab8132c801f44d9b8101520c4ef03bbd4 |
| --- /dev/null |
| +++ b/chrome/browser/media/android/cdm/media_drm_storage_impl.cc |
| @@ -0,0 +1,200 @@ |
| +// Copyright 2016 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 "chrome/browser/media/android/cdm/media_drm_storage_impl.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/optional.h" |
| +#include "chrome/browser/profiles/profile.h" |
|
xhwang
2017/03/23 05:25:26
yucliu: This is the only place where this file dep
yucliu1
2017/03/23 16:36:49
This would be helpful!
https://cs.chromium.org/ch
|
| +#include "components/pref_registry/pref_registry_syncable.h" |
| +#include "components/prefs/pref_service.h" |
| +#include "components/prefs/scoped_user_pref_update.h" |
| +#include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "mojo/public/cpp/bindings/strong_binding.h" |
| + |
| +// The storage will be managed by PrefService. All data will be store as a |
| +// dictionary under the key "media.media_drm_storage". The dictionary is |
| +// structured as follows: |
| +// |
| +// { |
| +// $origin: { |
| +// "origin_id": $origin_id |
|
yucliu1
2017/03/23 01:07:16
So origin_id is a random string, right? Who's resp
xhwang
2017/03/23 05:22:06
Good question. It's just a random string. In theor
|
| +// "creation_time": $provision_time |
| +// $session_id: { |
| +// "key_set_id": $key_set_id, |
| +// "mime_type": $mime_type, |
| +// "creation_time": $creation_time |
| +// }, |
| +// # more session_id map... |
| +// }, |
| +// # more origin map... |
| +// } |
| + |
| +namespace chrome { |
| + |
| +namespace { |
| + |
| +const char kMediaDrmStorage[] = "media.media_drm_storage"; |
| +const char kKeySetId[] = "key_set_id"; |
| +const char kMimeType[] = "mime_type"; |
| +const char kCreationTime[] = "creation_time"; |
| + |
| +std::unique_ptr<base::DictionaryValue> CreateOriginDictionary() { |
| + auto dict = base::MakeUnique<base::DictionaryValue>(); |
| + // TODO(xhwang): Base64 encode the |key_set_id|? |
| + // TODO(xhwang): Add creation time. |
| + dict->SetDouble(kCreationTime, base::Time::Now().ToDoubleT()); |
| + return dict; |
| +} |
| + |
| +std::unique_ptr<base::DictionaryValue> CreateSessionDictionary( |
| + const std::vector<uint8_t>& key_set_id, |
| + const std::string& mime_type) { |
| + auto dict = base::MakeUnique<base::DictionaryValue>(); |
| + // TODO(xhwang): Base64 encode the |key_set_id|? |
| + // TODO(xhwang): Add creation time. |
| + dict->SetString(kKeySetId, |
| + std::string(reinterpret_cast<const char*>(key_set_id.data()), |
| + key_set_id.size())); |
| + dict->SetString(kMimeType, mime_type); |
| + return dict; |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +void MediaDrmStorageImpl::RegisterProfilePrefs( |
| + user_prefs::PrefRegistrySyncable* registry) { |
| + registry->RegisterDictionaryPref(kMediaDrmStorage, |
| + new base::DictionaryValue()); |
| +} |
| + |
| +// static |
| +void MediaDrmStorageImpl::Create(content::RenderFrameHost* render_frame_host, |
| + media::mojom::MediaDrmStorageRequest request) { |
| + DVLOG(2) << __func__; |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(render_frame_host); |
| + |
| + content::WebContents* web_contents = |
| + content::WebContents::FromRenderFrameHost(render_frame_host); |
| + if (!web_contents) |
| + return; |
| + |
| + content::BrowserContext* browser_context = web_contents->GetBrowserContext(); |
| + if (!browser_context) |
| + return; |
| + |
| + Profile* profile = Profile::FromBrowserContext(browser_context); |
| + if (!profile) |
| + return; |
| + |
| + PrefService* pref_service = profile->GetPrefs(); |
| + if (!pref_service) |
| + return; |
| + |
| + mojo::MakeStrongBinding(base::MakeUnique<MediaDrmStorageImpl>(pref_service), |
| + std::move(request)); |
| +} |
| + |
| +MediaDrmStorageImpl::MediaDrmStorageImpl(PrefService* pref_service) |
| + : pref_service_(pref_service), weak_factory_(this) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(pref_service); |
| +} |
| + |
| +MediaDrmStorageImpl::~MediaDrmStorageImpl() { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| +} |
| + |
| +void MediaDrmStorageImpl::Initialize(const url::Origin& origin) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(!origin.unique()); |
| + origin_ = origin.Serialize(); |
| +} |
| + |
| +void MediaDrmStorageImpl::OnProvisioned(const OnProvisionedCallback& callback) { |
| + DVLOG(2) << __func__; |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(!origin_.empty()); |
| + |
| + DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); |
| + base::DictionaryValue* storage_dict = update.Get(); |
| + DCHECK(storage_dict); |
| + |
| + // The origin string may contain dots. Do not use path expansion. |
| + if (storage_dict->GetDictionaryWithoutPathExpansion(origin_, nullptr)) { |
| + DVLOG(1) << __func__ |
| + << ": Failed to save persistent session data; entry for origin " |
| + << origin_ << " already exists."; |
| + callback.Run(false); |
| + return; |
| + } |
| + |
| + storage_dict->SetWithoutPathExpansion(origin_, CreateOriginDictionary()); |
| + callback.Run(true); |
| +} |
| + |
| +void MediaDrmStorageImpl::SavePersistentSession( |
| + const std::string& session_id, |
| + const std::vector<uint8_t>& key_set_id, |
| + const std::string& mime_type, |
| + const SavePersistentSessionCallback& callback) { |
| + DVLOG(2) << __func__; |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(!origin_.empty()); |
| + |
| + DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); |
| + base::DictionaryValue* storage_dict = update.Get(); |
| + DCHECK(storage_dict); |
| + |
| + base::DictionaryValue* origin_dict = nullptr; |
| + // The origin string may contain dots. Do not use path expansion. |
| + storage_dict->GetDictionaryWithoutPathExpansion(origin_, &origin_dict); |
| + if (!origin_dict) { |
| + DVLOG(1) << __func__ |
| + << ": Failed to save persistent session data; entry for origin " |
| + << origin_ << " does not exist."; |
| + callback.Run(false); |
|
yucliu1
2017/03/23 01:07:16
A bigger questions here, what should we do if erro
xhwang
2017/03/23 05:22:06
In most cases, we should never fail. The only legi
|
| + return; |
| + } |
| + |
| + if (origin_dict->GetDictionaryWithoutPathExpansion(session_id, nullptr)) { |
| + DVLOG(1) << __func__ << ": Session ID already exists"; |
| + callback.Run(false); |
| + return; |
| + } |
| + |
| + origin_dict->SetWithoutPathExpansion( |
| + session_id, CreateSessionDictionary(key_set_id, mime_type)); |
| + |
| + callback.Run(true); |
| +} |
| + |
| +void MediaDrmStorageImpl::LoadPersistentSession( |
| + const std::string& session_id, |
| + const LoadPersistentSessionCallback& callback) { |
| + DVLOG(2) << __func__; |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(!origin_.empty()); |
| + |
| + NOTIMPLEMENTED(); |
| + callback.Run(false, base::nullopt, base::nullopt); |
| +} |
| + |
| +void MediaDrmStorageImpl::RemovePersistentSession( |
| + const std::string& session_id, |
| + const RemovePersistentSessionCallback& callback) { |
| + DVLOG(2) << __func__; |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + DCHECK(!origin_.empty()); |
| + |
| + NOTIMPLEMENTED(); |
| + callback.Run(false); |
| +} |
| + |
| +} // namespace chrome |