mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1060179 - Store and retrieve EME node id. r=jesup
This commit is contained in:
parent
c46ad3053d
commit
2dc76780b9
@ -4,6 +4,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "GMPService.h"
|
#include "GMPService.h"
|
||||||
|
#include "prio.h"
|
||||||
#include "prlog.h"
|
#include "prlog.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPParent.h"
|
||||||
#include "GMPVideoDecoderParent.h"
|
#include "GMPVideoDecoderParent.h"
|
||||||
@ -26,6 +27,11 @@
|
|||||||
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
|
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
|
||||||
#include "mozilla/Sandbox.h"
|
#include "mozilla/Sandbox.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "nsAppDirectoryServiceDefs.h"
|
||||||
|
#include "nsDirectoryServiceUtils.h"
|
||||||
|
#include "nsDirectoryServiceDefs.h"
|
||||||
|
#include "nsHashKeys.h"
|
||||||
|
#include "nsIFile.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -155,7 +161,7 @@ GeckoMediaPluginService::~GeckoMediaPluginService()
|
|||||||
MOZ_ASSERT(mAsyncShutdownPlugins.IsEmpty());
|
MOZ_ASSERT(mAsyncShutdownPlugins.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
nsresult
|
||||||
GeckoMediaPluginService::Init()
|
GeckoMediaPluginService::Init()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
@ -170,9 +176,26 @@ GeckoMediaPluginService::Init()
|
|||||||
prefs->AddObserver("media.gmp.plugin.crash", this, false);
|
prefs->AddObserver("media.gmp.plugin.crash", this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Directory service is main thread only, so cache the profile dir here
|
||||||
|
// so that we can use it off main thread.
|
||||||
|
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mStorageBaseDir));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mStorageBaseDir->AppendNative(NS_LITERAL_CSTRING("gmp"));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mStorageBaseDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Kick off scanning for plugins
|
// Kick off scanning for plugins
|
||||||
nsCOMPtr<nsIThread> thread;
|
nsCOMPtr<nsIThread> thread;
|
||||||
unused << GetThread(getter_AddRefs(thread));
|
return GetThread(getter_AddRefs(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -855,6 +878,86 @@ GeckoMediaPluginService::ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld)
|
|||||||
NS_DispatchToCurrentThread(WrapRunnableNM(&Dummy, aOld));
|
NS_DispatchToCurrentThread(WrapRunnableNM(&Dummy, aOld));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
GeckoMediaPluginService::GetStorageDir(nsIFile** aOutFile)
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF(!mStorageBaseDir)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return mStorageBaseDir->Clone(aOutFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
WriteToFile(nsIFile* aPath,
|
||||||
|
const nsCString& aFileName,
|
||||||
|
const nsCString& aData)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIFile> path;
|
||||||
|
nsresult rv = aPath->Clone(getter_AddRefs(path));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = path->AppendNative(aFileName);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRFileDesc* f = nullptr;
|
||||||
|
rv = path->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, PR_IRWXU, &f);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t len = PR_Write(f, aData.get(), aData.Length());
|
||||||
|
PR_Close(f);
|
||||||
|
if (NS_WARN_IF(len < 0 || (size_t)len != aData.Length())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
ReadFromFile(nsIFile* aPath,
|
||||||
|
const nsCString& aFileName,
|
||||||
|
nsCString& aOutData,
|
||||||
|
int32_t aMaxLength)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIFile> path;
|
||||||
|
nsresult rv = aPath->Clone(getter_AddRefs(path));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = path->AppendNative(aFileName);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRFileDesc* f = nullptr;
|
||||||
|
rv = path->OpenNSPRFileDesc(PR_RDONLY | PR_CREATE_FILE, PR_IRWXU, &f);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size = PR_Seek(f, 0, PR_SEEK_END);
|
||||||
|
PR_Seek(f, 0, PR_SEEK_SET);
|
||||||
|
|
||||||
|
if (size > aMaxLength) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
aOutData.SetLength(size);
|
||||||
|
|
||||||
|
auto len = PR_Read(f, aOutData.BeginWriting(), size);
|
||||||
|
PR_Close(f);
|
||||||
|
if (NS_WARN_IF(len != size)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
GeckoMediaPluginService::GetNodeId(const nsAString& aOrigin,
|
GeckoMediaPluginService::GetNodeId(const nsAString& aOrigin,
|
||||||
const nsAString& aTopLevelOrigin,
|
const nsAString& aTopLevelOrigin,
|
||||||
@ -867,14 +970,116 @@ GeckoMediaPluginService::GetNodeId(const nsAString& aOrigin,
|
|||||||
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
|
NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
|
||||||
(aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing")));
|
(aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing")));
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
const uint32_t NodeIdSaltLength = 32;
|
||||||
|
|
||||||
|
if (aInPrivateBrowsing ||
|
||||||
|
aOrigin.EqualsLiteral("null") ||
|
||||||
|
aOrigin.IsEmpty() ||
|
||||||
|
aTopLevelOrigin.EqualsLiteral("null") ||
|
||||||
|
aTopLevelOrigin.IsEmpty()) {
|
||||||
|
// Non-persistent session; just generate a random node id.
|
||||||
|
nsAutoCString salt;
|
||||||
|
rv = GenerateRandomPathName(salt, NodeIdSaltLength);
|
||||||
|
aOutId = salt;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, try to see if we've previously generated and stored salt
|
||||||
|
// for this origin pair.
|
||||||
|
nsCOMPtr<nsIFile> path; // $profileDir/gmp/
|
||||||
|
rv = GetStorageDir(getter_AddRefs(path));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = path->AppendNative(NS_LITERAL_CSTRING("id"));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $profileDir/gmp/id/
|
||||||
|
rv = path->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||||
|
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t hash = AddToHash(HashString(aOrigin),
|
||||||
|
HashString(aTopLevelOrigin));
|
||||||
|
nsAutoCString hashStr;
|
||||||
|
hashStr.AppendInt((int64_t)hash);
|
||||||
|
|
||||||
|
// $profileDir/gmp/id/$hash
|
||||||
|
rv = path->AppendNative(hashStr);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = path->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||||
|
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> saltFile;
|
||||||
|
rv = path->Clone(getter_AddRefs(saltFile));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = saltFile->AppendNative(NS_LITERAL_CSTRING("salt"));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsAutoCString salt;
|
nsAutoCString salt;
|
||||||
nsresult rv = GenerateRandomPathName(salt, 32);
|
bool exists = false;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
rv = saltFile->Exists(&exists);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
if (!exists) {
|
||||||
|
// No stored salt for this origin. Generate salt, and store it and
|
||||||
|
// the origin on disk.
|
||||||
|
nsresult rv = GenerateRandomPathName(salt, NodeIdSaltLength);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(salt.Length() == NodeIdSaltLength);
|
||||||
|
|
||||||
|
// $profileDir/gmp/id/$hash/salt
|
||||||
|
rv = WriteToFile(path, NS_LITERAL_CSTRING("salt"), salt);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $profileDir/gmp/id/$hash/origin
|
||||||
|
rv = WriteToFile(path,
|
||||||
|
NS_LITERAL_CSTRING("origin"),
|
||||||
|
NS_ConvertUTF16toUTF8(aOrigin));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $profileDir/gmp/id/$hash/topLevelOrigin
|
||||||
|
rv = WriteToFile(path,
|
||||||
|
NS_LITERAL_CSTRING("topLevelOrigin"),
|
||||||
|
NS_ConvertUTF16toUTF8(aTopLevelOrigin));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rv = ReadFromFile(path,
|
||||||
|
NS_LITERAL_CSTRING("salt"),
|
||||||
|
salt,
|
||||||
|
NodeIdSaltLength);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aOutId = salt;
|
aOutId = salt;
|
||||||
|
|
||||||
// TODO: Store salt, so it can be retrieved in subsequent sessions.
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public:
|
|||||||
static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
|
static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
|
||||||
|
|
||||||
GeckoMediaPluginService();
|
GeckoMediaPluginService();
|
||||||
void Init();
|
nsresult Init();
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_MOZIGECKOMEDIAPLUGINSERVICE
|
NS_DECL_MOZIGECKOMEDIAPLUGINSERVICE
|
||||||
@ -111,6 +111,8 @@ private:
|
|||||||
|
|
||||||
nsTArray<nsRefPtr<GMPParent>> mAsyncShutdownPlugins; // GMP Thread only.
|
nsTArray<nsRefPtr<GMPParent>> mAsyncShutdownPlugins; // GMP Thread only.
|
||||||
nsCOMPtr<nsITimer> mAsyncShutdownTimeout; // GMP Thread only.
|
nsCOMPtr<nsITimer> mAsyncShutdownTimeout; // GMP Thread only.
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> mStorageBaseDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gmp
|
} // namespace gmp
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "plhash.h"
|
#include "plhash.h"
|
||||||
#include "nsDirectoryServiceUtils.h"
|
#include "nsDirectoryServiceUtils.h"
|
||||||
#include "nsDirectoryServiceDefs.h"
|
#include "nsDirectoryServiceDefs.h"
|
||||||
|
#include "nsAppDirectoryServiceDefs.h"
|
||||||
#include "GMPParent.h"
|
#include "GMPParent.h"
|
||||||
#include "gmp-storage.h"
|
#include "gmp-storage.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
@ -35,26 +36,8 @@ extern PRLogModuleInfo* GetGMPLog();
|
|||||||
|
|
||||||
namespace gmp {
|
namespace gmp {
|
||||||
|
|
||||||
class GetTempDirTask : public nsRunnable
|
// We store the records in files in the profile dir.
|
||||||
{
|
// $profileDir/gmp/storage/$nodeId/
|
||||||
public:
|
|
||||||
NS_IMETHOD Run() {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> tmpFile;
|
|
||||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile));
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpFile->GetPath(mPath);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsString mPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
// We store the records in files in the system temp dir.
|
|
||||||
static nsresult
|
static nsresult
|
||||||
GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
|
GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
|
||||||
{
|
{
|
||||||
@ -62,22 +45,28 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
|
|||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directory service is main thread only...
|
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||||
nsRefPtr<GetTempDirTask> task = new GetTempDirTask();
|
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
if (NS_WARN_IF(!mps)) {
|
||||||
mozilla::SyncRunnable::DispatchToThread(mainThread, task);
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> tmpFile;
|
nsCOMPtr<nsIFile> tmpFile;
|
||||||
nsresult rv = NS_NewLocalFile(task->mPath, false, getter_AddRefs(tmpFile));
|
nsresult rv = mps->GetStorageDir(getter_AddRefs(tmpFile));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = tmpFile->AppendNative(nsDependentCString("mozilla-gmp-storage"));
|
rv = tmpFile->AppendNative(NS_LITERAL_CSTRING("storage"));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
|
||||||
|
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
rv = tmpFile->AppendNative(aNodeId);
|
rv = tmpFile->AppendNative(aNodeId);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
#include "nsIThread.idl"
|
#include "nsIThread.idl"
|
||||||
#include "nsIPrincipal.idl"
|
#include "nsIPrincipal.idl"
|
||||||
|
#include "nsIFile.idl"
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
@ -25,7 +26,7 @@ class GMPVideoHost;
|
|||||||
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
||||||
[ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
|
[ptr] native GMPAudioDecoderProxy(GMPAudioDecoderProxy);
|
||||||
|
|
||||||
[scriptable, uuid(3d811f9f-e1f8-48a5-a385-3657a641ee76)]
|
[scriptable, uuid(e5cde76d-f926-4b3f-84ff-62864c7a750a)]
|
||||||
interface mozIGeckoMediaPluginService : nsISupports
|
interface mozIGeckoMediaPluginService : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -96,4 +97,10 @@ interface mozIGeckoMediaPluginService : nsISupports
|
|||||||
ACString getNodeId(in AString origin,
|
ACString getNodeId(in AString origin,
|
||||||
in AString topLevelOrigin,
|
in AString topLevelOrigin,
|
||||||
in bool inPrivateBrowsingMode);
|
in bool inPrivateBrowsingMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the directory to use as the base for storing data about GMPs.
|
||||||
|
*/
|
||||||
|
nsIFile getStorageDir();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user