Bug 1420836 - Part2 - Add a class to compute the storage id.
Every version will have its own prerequisite factor to compute the storage id.
If we need to change the storage id computation algorithm, we should specialize the template class and increase the current version.
Now, we only have version 1 for computing storage id.
MozReview-Commit-ID: 52W2OOmtgI5
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/CDMStorageIdProvider.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CDMStorageIdProvider.h"
+
+namespace mozilla {
+
+UniquePtr<CDMStorageIdProviderBase>
+CDMStorageIdProviderBase::CreateProvider(int aVersion)
+{
+ UniquePtr<CDMStorageIdProviderBase> provider;
+ switch (aVersion) {
+ case CDMStorageIdProviderBase::kCDMRequestLatestVersion:
+ provider.reset(new CDMStorageIdProvider<CDMStorageIdProviderBase::kCurrentVersion>());
+ break;
+ case 1: // CDMStorageIdProviderBase::kCurrentVersion
+ provider.reset(new CDMStorageIdProvider<CDMStorageIdProviderBase::kCurrentVersion>());
+ break;
+ default:
+ MOZ_ASSERT(aVersion <= CDMStorageIdProviderBase::kCurrentVersion,
+ "Creating provider with unsupported version.");
+ break;
+ }
+ return provider;
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/CDMStorageIdProvider.h
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CDMStorageIdProvider_h_
+#define CDMStorageIdProvider_h_
+
+#include <string>
+
+#include "mozilla/UniquePtr.h"
+
+#ifdef SUPPORT_STORAGE_ID
+#include "rlz/lib/string_utils.h"
+#include "rlz/sha256.h"
+#endif
+
+/**
+ * CDM will try to request a latest version of storage id.
+ * If the storage id computation algorithm changed, we should increase the kCurrentVersion
+ * and write a template specialization for the new version.
+ * Make sure the ``CreateProvider`` returns the corresponding version of CDMStorageIdProvider.
+ */
+
+namespace mozilla {
+
+class CDMStorageIdProviderBase
+{
+protected:
+ static constexpr const char* kBrowserIdentifier =
+ "mozilla_firefox_gecko";
+
+public:
+ // Should increase the value when the storage id algorithm changed.
+ static constexpr int kCurrentVersion = 1;
+ static constexpr int kCDMRequestLatestVersion = 0;
+
+ struct PrerequisiteFactorsBase
+ {
+ virtual ~PrerequisiteFactorsBase() = default;
+ };
+
+ CDMStorageIdProviderBase() = default;
+
+ virtual ~CDMStorageIdProviderBase() = default;
+
+ virtual bool ComputeStorageId(std::string& aOutStorageId,
+ const PrerequisiteFactorsBase& aFactors) = 0;
+ virtual int GetVersion() = 0;
+
+ static UniquePtr<CDMStorageIdProviderBase> CreateProvider(int aVersion);
+};
+
+template<int VERSION>
+class CDMStorageIdProvider : public CDMStorageIdProviderBase
+{
+ friend class CDMStorageIdProviderBase;
+
+public:
+ bool ComputeStorageId(std::string& aOutStorageId,
+ const PrerequisiteFactorsBase& aFactors) override
+ {
+ MOZ_ASSERT_UNREACHABLE("CreateProvider should always return the specialization class of CDMStorageIdProvider");
+ return false;
+ }
+
+ int GetVersion() override { return VERSION; }
+
+ CDMStorageIdProvider(const CDMStorageIdProvider&) = delete;
+ void operator=(const CDMStorageIdProvider&) = delete;
+};
+
+//Current version.
+template<>
+class CDMStorageIdProvider<1> : public CDMStorageIdProviderBase
+{
+ friend class CDMStorageIdProviderBase;
+ template<typename... Args>
+ friend UniquePtr<CDMStorageIdProviderBase::PrerequisiteFactorsBase>
+ MakePrerequisiteFactors(int aVersion, Args&&... aArgs);
+
+ CDMStorageIdProvider() = default;
+
+ struct PrerequisiteFactors : PrerequisiteFactorsBase
+ {
+ PrerequisiteFactors(std::string aMachineId, std::string aOriginSalt)
+ : mMachineId(aMachineId),
+ mOriginSalt(aOriginSalt)
+ {}
+ std::string mMachineId;
+ std::string mOriginSalt;
+ };
+
+public:
+
+ // DO NOT modify the outcome of the ``ComputeStorageId``.
+ // Once the storage id computation should be changed, remember to specialize
+ // the template with the new version of storage id computation.
+ bool ComputeStorageId(std::string& aOutStorageId,
+ const PrerequisiteFactorsBase& aFactors) override
+ {
+#ifdef SUPPORT_STORAGE_ID
+ SHA256Context ctx;
+ SHA256_Begin(&ctx);
+
+ const auto& factors = static_cast<const PrerequisiteFactors&>(aFactors);
+ std::string input = factors.mMachineId + factors.mOriginSalt + CDMStorageIdProviderBase::kBrowserIdentifier;
+
+ SHA256_Update(&ctx, reinterpret_cast<const unsigned char*>(input.c_str()), input.size());
+ uint8_t digest[SHA256_LENGTH] = {0};
+ unsigned int digestLen = 0;
+ SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH);
+ if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &aOutStorageId)) {
+ return false;
+ }
+ return true;
+#else
+ MOZ_ASSERT_UNREACHABLE("This platform does not support computing storage id.");
+ return false;
+#endif
+ }
+
+ int GetVersion() override { return 1; }
+
+ CDMStorageIdProvider(const CDMStorageIdProvider&) = delete;
+ void operator=(const CDMStorageIdProvider&) = delete;
+};
+
+template<typename... Args>
+UniquePtr<CDMStorageIdProviderBase::PrerequisiteFactorsBase>
+MakePrerequisiteFactors(int aVersion, Args&&... aArgs)
+{
+ switch (aVersion) {
+ case CDMStorageIdProviderBase::kCDMRequestLatestVersion:
+ return MakeUnique<CDMStorageIdProvider<CDMStorageIdProviderBase::kCurrentVersion>::PrerequisiteFactors>(Forward<Args>(aArgs)...);
+ case 1: // CDMStorageIdProviderBase::kCurrentVersion
+ return MakeUnique<CDMStorageIdProvider<CDMStorageIdProviderBase::kCurrentVersion>::PrerequisiteFactors>(Forward<Args>(aArgs)...);
+ default:
+ MOZ_ASSERT(aVersion <= CDMStorageIdProviderBase::kCurrentVersion,
+ "Creating PrerequisiteFactor with unsupported version.");
+ return nullptr;
+ }
+}
+
+} // namespace mozilla
+
+#endif //CDMStorageIdProvider_h_
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -61,16 +61,17 @@ EXPORTS += [
'GMPVideoi420FrameImpl.h',
'GMPVideoPlaneImpl.h',
'widevine-adapter/content_decryption_module.h',
'widevine-adapter/content_decryption_module_export.h',
'widevine-adapter/content_decryption_module_ext.h',
]
UNIFIED_SOURCES += [
+ 'CDMStorageIdProvider.cpp',
'ChromiumCDMAdapter.cpp',
'ChromiumCDMCallbackProxy.cpp',
'ChromiumCDMChild.cpp',
'ChromiumCDMParent.cpp',
'ChromiumCDMProxy.cpp',
'DecryptJob.cpp',
'GMPChild.cpp',
'GMPContentChild.cpp',
@@ -115,16 +116,19 @@ IPDL_SOURCES += [
'PGMPContent.ipdl',
'PGMPService.ipdl',
'PGMPStorage.ipdl',
'PGMPTimer.ipdl',
'PGMPVideoDecoder.ipdl',
'PGMPVideoEncoder.ipdl',
]
+if CONFIG['OS_TARGET'] in ['WINNT', 'Darwin']:
+ DEFINES['SUPPORT_STORAGE_ID'] = 1;
+
# comment this out to use Unsafe Shmem for more performance
DEFINES['GMP_SAFE_SHMEM'] = True
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['MOZ_SANDBOX']:
# For sandbox includes and the include dependencies those have
LOCAL_INCLUDES += [