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 |