Backed out 6 changesets (bug 1046245) for bustage on a CLOSED TREE.

Backed out changeset 222c2f9e3bc9 (bug 1046245)
Backed out changeset 4251eef464a2 (bug 1046245)
Backed out changeset 592f4cc23197 (bug 1046245)
Backed out changeset 5bfb9a1c0550 (bug 1046245)
Backed out changeset e966a5df87b6 (bug 1046245)
Backed out changeset 609f3ca64004 (bug 1046245)
This commit is contained in:
Ryan VanderMeulen 2015-03-28 16:24:25 -04:00
parent 06fb3fb01e
commit 0ec3fab670
29 changed files with 133 additions and 1709 deletions

View File

@ -199,11 +199,6 @@ Sanitizer.prototype = {
cookieMgr.removeAll();
}
// Clear deviceIds. Done asynchronously (returns before complete).
let mediaMgr = Components.classes["@mozilla.org/mediaManagerService;1"]
.getService(Ci.nsIMediaManagerService);
mediaMgr.sanitizeDeviceIds(this.range && this.range[0]);
// Clear plugin data.
const phInterface = Ci.nsIPluginHost;
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;

View File

@ -1,67 +0,0 @@
/* 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 "mozilla/dom/MediaDeviceInfo.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/MediaManager.h"
#include "nsIScriptGlobalObject.h"
namespace mozilla {
namespace dom {
MediaDeviceInfo::MediaDeviceInfo(const nsAString& aDeviceId,
MediaDeviceKind aKind,
const nsAString& aLabel,
const nsAString& aGroupId)
: mKind(aKind)
, mDeviceId(aDeviceId)
, mLabel(aLabel)
, mGroupId(aGroupId) {}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaDeviceInfo)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaDeviceInfo)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaDeviceInfo)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaDeviceInfo)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
JSObject*
MediaDeviceInfo::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return MediaDeviceInfoBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports* MediaDeviceInfo::GetParentObject()
{
return nullptr;
}
void MediaDeviceInfo::GetDeviceId(nsString& retval)
{
retval = mDeviceId;
}
MediaDeviceKind
MediaDeviceInfo::Kind()
{
return mKind;
}
void MediaDeviceInfo::GetGroupId(nsString& retval)
{
retval = mGroupId;
}
void MediaDeviceInfo::GetLabel(nsString& retval)
{
retval = mLabel;
}
MediaDeviceKind Kind();
void GetLabel(nsString& retval);
void GetGroupId(nsString& retval);
} // namespace dom
} // namespace mozilla

View File

@ -1,60 +0,0 @@
/* 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 mozilla_dom_MediaDeviceInfo_h
#define mozilla_dom_MediaDeviceInfo_h
#include "mozilla/ErrorResult.h"
#include "nsISupportsImpl.h"
#include "mozilla/dom/BindingUtils.h"
#include "MediaDeviceInfoBinding.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
class Promise;
struct MediaStreamConstraints;
#define MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID \
{0x25091870, 0x84d6, 0x4acf, {0xaf, 0x97, 0x6e, 0xd5, 0x5b, 0xe0, 0x47, 0xb2}}
class MediaDeviceInfo final : public nsISupports, public nsWrapperCache
{
public:
explicit MediaDeviceInfo(const nsAString& aDeviceId,
MediaDeviceKind aKind,
const nsAString& aLabel,
const nsAString& aGroupId = nsString());
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaDeviceInfo)
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID)
JSObject*
WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject();
void GetDeviceId(nsString& retval);
MediaDeviceKind Kind();
void GetLabel(nsString& retval);
void GetGroupId(nsString& retval);
private:
MediaDeviceKind mKind;
nsString mDeviceId;
nsString mLabel;
nsString mGroupId;
virtual ~MediaDeviceInfo() {}
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaDeviceInfo,
MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID)
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MediaDeviceInfo_h

View File

@ -9,7 +9,6 @@
#include "mozilla/MediaManager.h"
#include "nsIEventTarget.h"
#include "nsIScriptGlobalObject.h"
#include "nsIPermissionManager.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
@ -38,109 +37,6 @@ private:
nsRefPtr<Promise> mPromise;
};
class MediaDevices::EnumDevResolver : public nsIGetUserMediaDevicesSuccessCallback
{
static bool HasAPersistentPermission(uint64_t aWindowId)
{
nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
(nsGlobalWindow::GetInnerWindowWithId(aWindowId));
if (NS_WARN_IF(!window)) {
return false;
}
// Check if this site has persistent permissions.
nsresult rv;
nsCOMPtr<nsIPermissionManager> mgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false; // no permission manager no permissions!
}
uint32_t audio = nsIPermissionManager::UNKNOWN_ACTION;
uint32_t video = nsIPermissionManager::UNKNOWN_ACTION;
{
auto* principal = window->GetExtantDoc()->NodePrincipal();
rv = mgr->TestExactPermissionFromPrincipal(principal, "microphone", &audio);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
rv = mgr->TestExactPermissionFromPrincipal(principal, "camera", &video);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
}
return audio == nsIPermissionManager::ALLOW_ACTION ||
video == nsIPermissionManager::ALLOW_ACTION;
}
public:
NS_DECL_ISUPPORTS
EnumDevResolver(Promise* aPromise, uint64_t aWindowId)
: mPromise(aPromise), mWindowId(aWindowId) {}
NS_IMETHOD
OnSuccess(nsIVariant* aDevices) override
{
// Cribbed from MediaPermissionGonk.cpp
nsIID elementIID;
uint16_t elementType;
// Create array for nsIMediaDevice
nsTArray<nsCOMPtr<nsIMediaDevice>> devices;
// Contain the fumes
{
void* rawArray;
uint32_t arrayLen;
nsresult rv;
rv = aDevices->GetAsArray(&elementType, &elementIID, &arrayLen, &rawArray);
NS_ENSURE_SUCCESS(rv, rv);
if (elementType != nsIDataType::VTYPE_INTERFACE) {
NS_Free(rawArray);
return NS_ERROR_FAILURE;
}
nsISupports **supportsArray = reinterpret_cast<nsISupports **>(rawArray);
for (uint32_t i = 0; i < arrayLen; ++i) {
nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supportsArray[i]));
devices.AppendElement(device);
NS_IF_RELEASE(supportsArray[i]); // explicitly decrease refcount for rawptr
}
NS_Free(rawArray); // explicitly free memory from nsIVariant::GetAsArray
}
nsTArray<nsRefPtr<MediaDeviceInfo>> infos;
for (auto& device : devices) {
nsString type;
device->GetType(type);
bool isVideo = type.EqualsLiteral("video");
bool isAudio = type.EqualsLiteral("audio");
if (isVideo || isAudio) {
MediaDeviceKind kind = isVideo ?
MediaDeviceKind::Videoinput : MediaDeviceKind::Audioinput;
nsString id;
nsString name;
device->GetId(id);
// Include name only if page currently has a gUM stream active or
// persistent permissions (audio or video) have been granted
if (MediaManager::Get()->IsWindowActivelyCapturing(mWindowId) ||
HasAPersistentPermission(mWindowId) ||
Preferences::GetBool("media.navigator.permission.disabled", false)) {
device->GetName(name);
}
nsRefPtr<MediaDeviceInfo> info = new MediaDeviceInfo(id, kind, name);
infos.AppendElement(info);
}
}
mPromise->MaybeResolve(infos);
return NS_OK;
}
private:
virtual ~EnumDevResolver() {}
nsRefPtr<Promise> mPromise;
uint64_t mWindowId;
};
class MediaDevices::GumRejecter : public nsIDOMGetUserMediaErrorCallback
{
public:
@ -165,17 +61,17 @@ private:
};
NS_IMPL_ISUPPORTS(MediaDevices::GumResolver, nsIDOMGetUserMediaSuccessCallback)
NS_IMPL_ISUPPORTS(MediaDevices::EnumDevResolver, nsIGetUserMediaDevicesSuccessCallback)
NS_IMPL_ISUPPORTS(MediaDevices::GumRejecter, nsIDOMGetUserMediaErrorCallback)
already_AddRefed<Promise>
MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
ErrorResult &aRv)
{
ErrorResult rv;
nsPIDOMWindow* window = GetOwner();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
nsRefPtr<Promise> p = Promise::Create(go, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
NS_ENSURE_TRUE(!rv.Failed(), nullptr);
nsRefPtr<GumResolver> resolver = new GumResolver(p);
nsRefPtr<GumRejecter> rejecter = new GumRejecter(p);
@ -185,21 +81,6 @@ MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
return p.forget();
}
already_AddRefed<Promise>
MediaDevices::EnumerateDevices(ErrorResult &aRv)
{
nsPIDOMWindow* window = GetOwner();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
nsRefPtr<Promise> p = Promise::Create(go, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
nsRefPtr<EnumDevResolver> resolver = new EnumDevResolver(p, window->WindowID());
nsRefPtr<GumRejecter> rejecter = new GumRejecter(p);
aRv = MediaManager::Get()->EnumerateDevices(window, resolver, rejecter);
return p.forget();
}
NS_IMPL_ADDREF_INHERITED(MediaDevices, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MediaDevices, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN(MediaDevices)

View File

@ -2,8 +2,8 @@
* 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 mozilla_dom_MediaDevices_h
#define mozilla_dom_MediaDevices_h
#ifndef MediaDevices_h__
#define MediaDevices_h__
#include "mozilla/ErrorResult.h"
#include "nsISupportsImpl.h"
@ -35,12 +35,8 @@ public:
already_AddRefed<Promise>
GetUserMedia(const MediaStreamConstraints& aConstraints, ErrorResult &aRv);
already_AddRefed<Promise>
EnumerateDevices(ErrorResult &aRv);
private:
class GumResolver;
class EnumDevResolver;
class GumRejecter;
virtual ~MediaDevices() {}
@ -52,4 +48,4 @@ NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MediaDevices_h
#endif // MediaDevices_h__

View File

@ -25,13 +25,6 @@
#include "nsIInterfaceRequestorUtils.h"
#include "nsIIDNService.h"
#include "nsNetUtil.h"
#include "nsPrincipal.h"
#include "nsICryptoHash.h"
#include "nsICryptoHMAC.h"
#include "nsIKeyModule.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIInputStream.h"
#include "nsILineInputStream.h"
#include "mozilla/Types.h"
#include "mozilla/PeerIdentity.h"
#include "mozilla/dom/ContentChild.h"
@ -40,11 +33,8 @@
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/GetUserMediaRequestBinding.h"
#include "mozilla/Preferences.h"
#include "mozilla/Base64.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/media/MediaChild.h"
#include "MediaTrackConstraints.h"
#include "VideoUtils.h"
#include "Latency.h"
// For PR_snprintf
@ -52,10 +42,6 @@
#include "nsJSUtils.h"
#include "nsGlobalWindow.h"
#include "nsIUUIDGenerator.h"
#include "nspr.h"
#include "nss.h"
#include "pk11pub.h"
/* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
#include "MediaEngineDefault.h"
@ -208,61 +194,45 @@ HostHasPermission(nsIURI &docURI)
return false;
}
/**
* Send an error back to content.
* Do this only on the main thread. The onSuccess callback is also passed here
* so it can be released correctly.
*/
template<class SuccessCallbackType>
class ErrorCallbackRunnable : public nsRunnable
ErrorCallbackRunnable::ErrorCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
MediaMgrError& aError,
uint64_t aWindowID)
: mError(&aError)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
public:
ErrorCallbackRunnable(
nsCOMPtr<SuccessCallbackType>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
MediaMgrError& aError,
uint64_t aWindowID)
: mError(&aError)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
NS_IMETHODIMP
Run()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
ErrorCallbackRunnable::~ErrorCallbackRunnable()
{
MOZ_ASSERT(!mOnSuccess && !mOnFailure);
}
nsCOMPtr<SuccessCallbackType> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
NS_IMETHODIMP
ErrorCallbackRunnable::Run()
{
// Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
// Only run if the window is still active.
if (!(mManager->IsWindowStillActive(mWindowID))) {
return NS_OK;
}
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window, *mError);
onFailure->OnError(error);
}
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
if (!(mManager->IsWindowStillActive(mWindowID))) {
return NS_OK;
}
private:
~ErrorCallbackRunnable()
{
MOZ_ASSERT(!mOnSuccess && !mOnFailure);
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (window) {
nsRefPtr<MediaStreamError> error = new MediaStreamError(window, *mError);
onFailure->OnError(error);
}
nsCOMPtr<SuccessCallbackType> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsRefPtr<MediaMgrError> mError;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
};
return NS_OK;
}
/**
* Invoke the "onSuccess" callback in content. The callback will take a
@ -332,50 +302,6 @@ public:
mOnFailure.swap(aOnFailure);
}
nsresult
AnonymizeId(nsAString& aId, const nsACString& aOriginKey)
{
nsresult rv;
nsCOMPtr<nsIKeyObjectFactory> factory =
do_GetService("@mozilla.org/security/keyobjectfactory;1", &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCString rawKey;
rv = Base64Decode(aOriginKey, rawKey);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIKeyObject> key;
rv = factory->KeyFromString(nsIKeyObject::HMAC, rawKey, getter_AddRefs(key));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsICryptoHMAC> hasher =
do_CreateInstance(NS_CRYPTO_HMAC_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
rv = hasher->Init(nsICryptoHMAC::SHA256, key);
if (NS_FAILED(rv)) {
return rv;
}
NS_ConvertUTF16toUTF8 id(aId);
rv = hasher->Update(reinterpret_cast<const uint8_t*> (id.get()), id.Length());
if (NS_FAILED(rv)) {
return rv;
}
nsCString mac;
rv = hasher->Finish(true, mac);
if (NS_FAILED(rv)) {
return rv;
}
aId = NS_ConvertUTF8toUTF16(mac);
return NS_OK;
}
NS_IMETHOD
Run()
{
@ -389,7 +315,7 @@ public:
nsCOMPtr<nsIWritableVariant> devices =
do_CreateInstance("@mozilla.org/variant;1");
size_t len = mDevices->Length();
int32_t len = mDevices->Length();
if (len == 0) {
// XXX
// We should in the future return an empty array, and dynamically add
@ -405,14 +331,8 @@ public:
}
nsTArray<nsIMediaDevice*> tmp(len);
for (auto& device : *mDevices) {
if (!mOriginKey.IsEmpty()) {
nsString id;
device->GetId(id);
AnonymizeId(id, mOriginKey);
device->SetId(id);
}
tmp.AppendElement(device);
for (int32_t i = 0; i < len; i++) {
tmp.AppendElement(mDevices->ElementAt(i));
}
devices->SetAsArray(nsIDataType::VTYPE_INTERFACE,
@ -426,7 +346,6 @@ public:
return NS_OK;
}
nsCString mOriginKey;
private:
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
@ -597,12 +516,6 @@ MediaDevice::GetId(nsAString& aID)
return NS_OK;
}
void
MediaDevice::SetId(const nsAString& aID)
{
mID.Assign(aID);
}
NS_IMETHODIMP
MediaDevice::GetFacingMode(nsAString& aFacingMode)
{
@ -813,26 +726,6 @@ public:
uint32_t mPlayoutDelay;
};
void
MediaOperationTask::ReturnCallbackError(nsresult rv, const char* errorLog)
{
MM_LOG(("%s , rv=%d", errorLog, rv));
NS_DispatchToMainThread(new ReleaseMediaOperationResource(mStream.forget(),
mOnTracksAvailableCallback.forget()));
nsString log;
log.AssignASCII(errorLog);
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess;
nsRefPtr<MediaMgrError> error = new MediaMgrError(
NS_LITERAL_STRING("InternalError"), log);
NS_DispatchToMainThread(
new ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>(onSuccess,
mOnFailure,
*error,
mWindowID));
}
/**
* Creates a MediaStream, attaches a listener and fires off a success callback
* to the DOM with the stream. We also pass in the error callback so it can
@ -1198,11 +1091,8 @@ public:
Fail(const nsAString& aName,
const nsAString& aMessage = EmptyString()) {
nsRefPtr<MediaMgrError> error = new MediaMgrError(aName, aMessage);
nsRefPtr<ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>> runnable =
new ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>(mOnSuccess,
mOnFailure,
*error,
mWindowID);
nsRefPtr<ErrorCallbackRunnable> runnable =
new ErrorCallbackRunnable(mOnSuccess, mOnFailure, *error, mWindowID);
// These should be empty now
MOZ_ASSERT(!mOnSuccess);
MOZ_ASSERT(!mOnFailure);
@ -1215,7 +1105,7 @@ public:
void
Run()
{
MOZ_ASSERT(!NS_IsMainThread());
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
@ -1419,30 +1309,11 @@ private:
};
#endif
class SanitizeDeviceIdsTask : public Task
{
public:
explicit SanitizeDeviceIdsTask(int64_t aSinceWhen)
: mSinceWhen(aSinceWhen) {}
void // NS_IMETHOD
Run()
{
MOZ_ASSERT(!NS_IsMainThread());
nsRefPtr<media::ChildPledge<bool>> p =
mozilla::media::SanitizeOriginKeys(mSinceWhen); // we fire and forget
}
private:
int64_t mSinceWhen;
};
/**
* Similar to GetUserMediaTask, but used for the chrome-only
* GetUserMediaDevices function. Enumerates a list of audio & video devices,
* wraps them up in nsIMediaDevice objects and returns it to the success
* callback.
*
* All code in this class runs on the MediaManager thread.
*/
class GetUserMediaDevicesTask : public Task
{
@ -1452,8 +1323,7 @@ public:
already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aOnSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aOnFailure,
uint64_t aWindowId, nsACString& aAudioLoopbackDev,
nsACString& aVideoLoopbackDev, bool aPrivileged, const nsACString& aOrigin,
bool aInPrivateBrowsing, bool aUseFakeDevices)
nsACString& aVideoLoopbackDev, bool aUseFakeDevices)
: mConstraints(aConstraints)
, mOnSuccess(aOnSuccess)
, mOnFailure(aOnFailure)
@ -1461,15 +1331,12 @@ public:
, mWindowId(aWindowId)
, mLoopbackAudioDevice(aAudioLoopbackDev)
, mLoopbackVideoDevice(aVideoLoopbackDev)
, mPrivileged(aPrivileged)
, mOrigin(aOrigin)
, mInPrivateBrowsing(aInPrivateBrowsing)
, mUseFakeDevices(aUseFakeDevices) {}
void // NS_IMETHOD
Run()
{
MOZ_ASSERT(!NS_IsMainThread());
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
nsRefPtr<MediaEngine> backend;
if (mConstraints.mFake || mUseFakeDevices)
@ -1479,45 +1346,28 @@ public:
typedef nsTArray<nsRefPtr<MediaDevice>> SourceSet;
ScopedDeletePtr<SourceSet> result(new SourceSet);
ScopedDeletePtr<SourceSet> final(new SourceSet);
if (IsOn(mConstraints.mVideo)) {
nsTArray<nsRefPtr<VideoDevice>> sources;
nsTArray<nsRefPtr<VideoDevice>> s;
GetSources(backend, GetInvariant(mConstraints.mVideo),
&MediaEngine::EnumerateVideoDevices, sources,
mLoopbackVideoDevice.get());
for (auto& source : sources) {
result->AppendElement(source);
&MediaEngine::EnumerateVideoDevices, s, mLoopbackVideoDevice.get());
for (uint32_t i = 0; i < s.Length(); i++) {
final->AppendElement(s[i]);
}
}
if (IsOn(mConstraints.mAudio)) {
nsTArray<nsRefPtr<AudioDevice>> sources;
nsTArray<nsRefPtr<AudioDevice>> s;
GetSources(backend, GetInvariant(mConstraints.mAudio),
&MediaEngine::EnumerateAudioDevices, sources,
mLoopbackAudioDevice.get());
for (auto& source : sources) {
result->AppendElement(source);
&MediaEngine::EnumerateAudioDevices, s, mLoopbackAudioDevice.get());
for (uint32_t i = 0; i < s.Length(); i++) {
final->AppendElement(s[i]);
}
}
nsRefPtr<DeviceSuccessCallbackRunnable> runnable
(new DeviceSuccessCallbackRunnable(mWindowId, mOnSuccess, mOnFailure,
result.forget()));
if (mPrivileged) {
NS_DispatchToMainThread(runnable);
} else {
// Get persistent origin-unique uuid to anonymize deviceIds back on main.
//
// GetOriginKey is an async API that returns a pledge (as promise-like
// pattern). We use .Then() to pass in a lambda to run back on this
// thread once GetOriginKey resolves asynchronously . The "runnable"
// nsRefPtr is "captured" (passed by value) into the lambda.
nsRefPtr<media::ChildPledge<nsCString>> p =
media::GetOriginKey(mOrigin, mInPrivateBrowsing);
p->Then([runnable](nsCString result) mutable {
runnable->mOriginKey = result;
NS_DispatchToMainThread(runnable);
});
}
// One of the Runnables have taken these.
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,
mOnSuccess, mOnFailure,
final.forget()));
// DeviceSuccessCallbackRunnable should have taken these.
MOZ_ASSERT(!mOnSuccess && !mOnFailure);
}
@ -1533,9 +1383,6 @@ private:
// automated media tests only.
nsCString mLoopbackAudioDevice;
nsCString mLoopbackVideoDevice;
bool mPrivileged;
nsCString mOrigin;
bool mInPrivateBrowsing;
bool mUseFakeDevices;
};
@ -1564,16 +1411,6 @@ NS_IMPL_ISUPPORTS(MediaManager, nsIMediaManagerService, nsIObserver)
/* static */ StaticRefPtr<MediaManager> MediaManager::sSingleton;
#ifdef DEBUG
/* static */ bool
MediaManager::IsInMediaThread()
{
return sSingleton?
(sSingleton->mMediaThread->thread_id() == PlatformThread::CurrentId()) :
false;
}
#endif
// NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
// thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
// from MediaManager thread.
@ -1740,8 +1577,16 @@ MediaManager::GetUserMedia(
#endif //MOZ_B2G
}
// Store the WindowID in a hash table and mark as active. The entry is removed
// when this window is closed or navigated away from.
uint64_t windowID = aWindow->WindowID();
StreamListeners* listeners = AddWindowID(windowID);
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
if (!listeners) {
listeners = new StreamListeners;
GetActiveWindows()->Put(windowID, listeners);
}
// Create a disabled listener to act as a placeholder
GetUserMediaCallbackMediaStreamListener* listener =
@ -1956,8 +1801,7 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
const MediaStreamConstraints& aConstraints,
nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnFailure,
uint64_t aInnerWindowID,
bool aPrivileged)
uint64_t aInnerWindowID)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
@ -1975,40 +1819,15 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
bool useFakeStreams =
Preferences::GetBool("media.navigator.streams.fake", false);
nsCString origin;
nsPrincipal::GetOriginForURI(aWindow->GetDocumentURI(),
getter_Copies(origin));
bool inPrivateBrowsing;
{
nsCOMPtr<nsIDocument> doc = aWindow->GetDoc();
nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
inPrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
}
MediaManager::GetMessageLoop()->PostTask(FROM_HERE,
new GetUserMediaDevicesTask(
aConstraints, onSuccess.forget(), onFailure.forget(),
(aInnerWindowID ? aInnerWindowID : aWindow->WindowID()),
loopbackAudioDevice, loopbackVideoDevice, aPrivileged, origin,
inPrivateBrowsing, useFakeStreams));
loopbackAudioDevice, loopbackVideoDevice, useFakeStreams));
return NS_OK;
}
nsresult
MediaManager::EnumerateDevices(nsPIDOMWindow* aWindow,
nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnFailure)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
MediaStreamConstraints c;
c.mVideo.SetAsBoolean() = true;
c.mAudio.SetAsBoolean() = true;
AddWindowID(aWindow->WindowID());
return GetUserMediaDevices(aWindow, c, aOnSuccess, aOnFailure, 0, false);
}
MediaEngine*
MediaManager::GetBackend(uint64_t aWindowId)
{
@ -2077,22 +1896,6 @@ MediaManager::OnNavigation(uint64_t aWindowID)
}
}
StreamListeners*
MediaManager::AddWindowID(uint64_t aWindowId)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
// Store the WindowID in a hash table and mark as active. The entry is removed
// when this window is closed or navigated away from.
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
StreamListeners* listeners = GetActiveWindows()->Get(aWindowId);
if (!listeners) {
listeners = new StreamListeners;
GetActiveWindows()->Put(aWindowId, listeners);
}
return listeners;
}
void
MediaManager::RemoveWindowID(uint64_t aWindowId)
{
@ -2206,34 +2009,8 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
prefs->RemoveObserver("media.navigator.video.default_minfps", this);
}
// Because mMediaThread is not an nsThread, we must dispatch to it so it can
// clean up BackgroundChild. Continue stopping thread once this is done.
class ShutdownTask : public Task
// Close off any remaining active windows.
{
public:
explicit ShutdownTask(nsRunnable* aReply) : mReply(aReply) {}
private:
virtual void
Run()
{
MOZ_ASSERT(MediaManager::IsInMediaThread());
mozilla::ipc::BackgroundChild::CloseForCurrentThread();
NS_DispatchToMainThread(mReply);
}
nsRefPtr<nsRunnable> mReply;
};
// Post ShutdownTask to execute on mMediaThread and pass in a lambda
// callback to be executed back on this thread once it is done.
//
// The lambda callback "captures" the 'this' pointer for member access.
// This is safe since this is guaranteed to be here since sSingleton isn't
// cleared until the lambda function clears it.
MediaManager::GetMessageLoop()->PostTask(FROM_HERE, new ShutdownTask(
media::CallbackRunnable::New([this]() mutable {
// Close off any remaining active windows.
MutexAutoLock lock(mMutex);
GetActiveWindows()->Clear();
mActiveCallbacks.Clear();
@ -2245,8 +2022,8 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
mMediaThread->Stop();
}
mBackend = nullptr;
return NS_OK;
})));
}
return NS_OK;
} else if (!strcmp(aTopic, "getUserMedia:response:allow")) {
@ -2482,17 +2259,6 @@ MediaManager::MediaCaptureWindowState(nsIDOMWindow* aWindow, bool* aVideo,
return NS_OK;
}
NS_IMETHODIMP
MediaManager::SanitizeDeviceIds(int64_t aSinceWhen)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
LOG(("%s: sinceWhen = %llu", __FUNCTION__, aSinceWhen));
MediaManager::GetMessageLoop()->PostTask(FROM_HERE,
new SanitizeDeviceIdsTask(aSinceWhen));
return NS_OK;
}
static void
StopScreensharingCallback(MediaManager *aThis,
uint64_t aWindowID,
@ -2579,24 +2345,6 @@ MediaManager::StopMediaStreams()
}
}
bool
MediaManager::IsWindowActivelyCapturing(uint64_t aWindowId)
{
nsCOMPtr<nsISupportsArray> array;
GetActiveMediaCaptureWindows(getter_AddRefs(array));
uint32_t len;
array->Count(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsISupports> window;
array->GetElementAt(i, getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(window));
if (win && win->WindowID() == aWindowId) {
return true;
}
}
return false;
}
void
GetUserMediaCallbackMediaStreamListener::AudioConfig(bool aEchoOn,
uint32_t aEcho,

View File

@ -300,6 +300,29 @@ typedef enum {
class MediaManager;
class GetUserMediaTask;
/**
* Send an error back to content.
* Do this only on the main thread. The onSuccess callback is also passed here
* so it can be released correctly.
*/
class ErrorCallbackRunnable : public nsRunnable
{
public:
ErrorCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
MediaMgrError& aError, uint64_t aWindowID);
NS_IMETHOD Run();
private:
~ErrorCallbackRunnable();
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsRefPtr<MediaMgrError> mError;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
};
class ReleaseMediaOperationResource : public nsRunnable
{
public:
@ -346,7 +369,20 @@ public:
}
void
ReturnCallbackError(nsresult rv, const char* errorLog);
ReturnCallbackError(nsresult rv, const char* errorLog)
{
MM_LOG(("%s , rv=%d", errorLog, rv));
NS_DispatchToMainThread(new ReleaseMediaOperationResource(mStream.forget(),
mOnTracksAvailableCallback.forget()));
nsString log;
log.AssignASCII(errorLog);
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess;
nsRefPtr<MediaMgrError> error = new MediaMgrError(
NS_LITERAL_STRING("InternalError"), log);
NS_DispatchToMainThread(new ErrorCallbackRunnable(onSuccess, mOnFailure,
*error, mWindowID));
}
void
Run()
@ -467,7 +503,6 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEDIADEVICE
void SetId(const nsAString& aID);
protected:
virtual ~MediaDevice() {}
explicit MediaDevice(MediaEngineSource* aSource);
@ -521,9 +556,6 @@ public:
static MediaManager* Get();
static MediaManager* GetIfExists();
static MessageLoop* GetMessageLoop();
#ifdef DEBUG
static bool IsInMediaThread();
#endif
static bool Exists()
{
@ -563,21 +595,12 @@ public:
const dom::MediaStreamConstraints& aConstraints,
nsIGetUserMediaDevicesSuccessCallback* onSuccess,
nsIDOMGetUserMediaErrorCallback* onError,
uint64_t aInnerWindowID = 0,
bool aPrivileged = true);
nsresult EnumerateDevices(nsPIDOMWindow* aWindow,
nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnFailure);
nsresult EnumerateDevices(nsPIDOMWindow* aWindow, dom::Promise& aPromise);
uint64_t aInnerWindowID = 0);
void OnNavigation(uint64_t aWindowID);
bool IsWindowActivelyCapturing(uint64_t aWindowId);
MediaEnginePrefs mPrefs;
private:
StreamListeners* AddWindowID(uint64_t aWindowId);
WindowTable *GetActiveWindows() {
NS_ASSERTION(NS_IsMainThread(), "Only access windowlist on main thread");
return &mActiveWindows;
@ -605,7 +628,6 @@ private:
WindowTable mActiveWindows;
nsClassHashtable<nsStringHashKey, GetUserMediaTask> mActiveCallbacks;
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
// Always exists
nsAutoPtr<base::Thread> mMediaThread;

View File

@ -261,16 +261,18 @@ ExtractH264CodecDetails(const nsAString& aCodec,
}
nsresult
GenerateRandomName(nsCString& aOutSalt, uint32_t aLength)
GenerateRandomPathName(nsCString& aOutSalt, uint32_t aLength)
{
nsresult rv;
nsCOMPtr<nsIRandomGenerator> rg =
do_GetService("@mozilla.org/security/random-generator;1", &rv);
if (NS_FAILED(rv)) return rv;
// For each three bytes of random data we will get four bytes of ASCII.
// For each three bytes of random data we will get four bytes of
// ASCII. Request a bit more to be safe and truncate to the length
// we want at the end.
const uint32_t requiredBytesLength =
static_cast<uint32_t>((aLength + 3) / 4 * 3);
static_cast<uint32_t>((aLength + 1) / 4 * 3);
uint8_t* buffer;
rv = rg->GenerateRandomBytes(requiredBytesLength, &buffer);
@ -284,19 +286,14 @@ GenerateRandomName(nsCString& aOutSalt, uint32_t aLength)
buffer = nullptr;
if (NS_FAILED (rv)) return rv;
aOutSalt = temp;
return NS_OK;
}
nsresult
GenerateRandomPathName(nsCString& aOutSalt, uint32_t aLength)
{
nsresult rv = GenerateRandomName(aOutSalt, aLength);
if (NS_FAILED(rv)) return rv;
temp.Truncate(aLength);
// Base64 characters are alphanumeric (a-zA-Z0-9) and '+' and '/', so we need
// to replace illegal characters -- notably '/'
aOutSalt.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
temp.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
aOutSalt = temp;
return NS_OK;
}

View File

@ -261,11 +261,7 @@ ExtractH264CodecDetails(const nsAString& aCodecs,
int16_t& aLevel);
// Use a cryptographic quality PRNG to generate raw random bytes
// and convert that to a base64 string.
nsresult
GenerateRandomName(nsCString& aOutSalt, uint32_t aLength);
// This version returns a string suitable for use as a file or URL
// and convert that to a base64 string suitable for use as a file or URL
// path. This is based on code from nsExternalAppHandler::SetUpTempFile.
nsresult
GenerateRandomPathName(nsCString& aOutSalt, uint32_t aLength);

View File

@ -146,7 +146,6 @@ EXPORTS.mozilla.dom += [
'AudioTrack.h',
'AudioTrackList.h',
'GetUserMediaRequest.h',
'MediaDeviceInfo.h',
'MediaDevices.h',
'MediaStreamError.h',
'MediaStreamTrack.h',
@ -184,7 +183,6 @@ UNIFIED_SOURCES += [
'MediaDecoder.cpp',
'MediaDecoderReader.cpp',
'MediaDecoderStateMachine.cpp',
'MediaDeviceInfo.cpp',
'MediaDevices.cpp',
'MediaManager.cpp',
'MediaRecorder.cpp',

View File

@ -12,7 +12,7 @@ interface nsIDOMWindow;
#define MEDIAMANAGERSERVICE_CONTRACTID "@mozilla.org/mediaManagerService;1"
%}
[scriptable, builtinclass, uuid(24b23e01-33fd-401f-ba25-6e52658750b0)]
[scriptable, builtinclass, uuid(9b10661f-77b3-47f7-a8de-ee58daaff5d2)]
interface nsIMediaManagerService : nsISupports
{
/* return a array of inner windows that have active captures */
@ -22,8 +22,4 @@ interface nsIMediaManagerService : nsISupports
void mediaCaptureWindowState(in nsIDOMWindow aWindow, out boolean aVideo, out boolean aAudio,
[optional] out boolean aScreenShare, [optional] out boolean aWindowShare,
[optional] out boolean aAppShare, [optional] out boolean aBrowserShare);
/* Clear per-orgin list of persistent DeviceIds stored for enumerateDevices
sinceTime is milliseconds since 1 January 1970 00:00:00 UTC. 0 = clear all */
void sanitizeDeviceIds(in long long sinceWhen);
};

View File

@ -1,175 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "MediaChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsGlobalWindow.h"
#include "mozilla/MediaManager.h"
#include "prlog.h"
#undef LOG
#if defined(PR_LOGGING)
extern PRLogModuleInfo *gMediaParentLog;
#define LOG(args) PR_LOG(gMediaParentLog, PR_LOG_DEBUG, args)
#else
#define LOG(args)
#endif
PRLogModuleInfo *gMediaChildLog;
namespace mozilla {
namespace media {
static Child* sChild;
template<typename ValueType> void
ChildPledge<ValueType>::ActorCreated(PBackgroundChild* aActor)
{
if (!sChild) {
// Create PMedia by sending a message to the parent
sChild = static_cast<Child*>(aActor->SendPMediaConstructor());
}
Run(sChild);
}
template<typename ValueType> void
ChildPledge<ValueType>::ActorFailed()
{
Pledge<ValueType>::Reject(NS_ERROR_UNEXPECTED);
}
template<typename ValueType> NS_IMPL_ADDREF(ChildPledge<ValueType>)
template<typename ValueType> NS_IMPL_RELEASE(ChildPledge<ValueType>)
template<typename ValueType> NS_INTERFACE_MAP_BEGIN(ChildPledge<ValueType>)
NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
NS_INTERFACE_MAP_END
already_AddRefed<ChildPledge<nsCString>>
GetOriginKey(const nsCString& aOrigin, bool aPrivateBrowsing)
{
class Pledge : public ChildPledge<nsCString>
{
public:
explicit Pledge(const nsCString& aOrigin, bool aPrivateBrowsing)
: mOrigin(aOrigin), mPrivateBrowsing(aPrivateBrowsing) {}
private:
~Pledge() {}
void Run(PMediaChild* aChild)
{
Child* child = static_cast<Child*>(aChild);
uint32_t id = child->AddRequestPledge(*this);
child->SendGetOriginKey(id, mOrigin, mPrivateBrowsing);
}
const nsCString mOrigin;
const bool mPrivateBrowsing;
};
nsRefPtr<ChildPledge<nsCString>> p = new Pledge(aOrigin, aPrivateBrowsing);
nsCOMPtr<nsIIPCBackgroundChildCreateCallback> cb = do_QueryObject(p);
bool ok = ipc::BackgroundChild::GetOrCreateForCurrentThread(cb);
MOZ_RELEASE_ASSERT(ok);
return p.forget();
}
already_AddRefed<ChildPledge<bool>>
SanitizeOriginKeys(const uint64_t& aSinceWhen)
{
class Pledge : public ChildPledge<bool>
{
public:
explicit Pledge(const uint64_t& aSinceWhen) : mSinceWhen(aSinceWhen) {}
private:
void Run(PMediaChild* aMedia)
{
aMedia->SendSanitizeOriginKeys(mSinceWhen);
mValue = true;
LOG(("SanitizeOriginKeys since %llu", mSinceWhen));
Resolve();
}
const uint64_t mSinceWhen;
};
nsRefPtr<ChildPledge<bool>> p = new Pledge(aSinceWhen);
nsCOMPtr<nsIIPCBackgroundChildCreateCallback> cb = do_QueryObject(p);
bool ok = ipc::BackgroundChild::GetOrCreateForCurrentThread(cb);
MOZ_RELEASE_ASSERT(ok);
return p.forget();
}
Child::Child()
{
#if defined(PR_LOGGING)
if (!gMediaChildLog) {
gMediaChildLog = PR_NewLogModule("MediaChild");
}
#endif
LOG(("media::Child: %p", this));
MOZ_COUNT_CTOR(Child);
}
Child::~Child()
{
LOG(("~media::Child: %p", this));
sChild = nullptr;
MOZ_COUNT_DTOR(Child);
}
uint32_t Child::sRequestCounter = 0;
uint32_t
Child::AddRequestPledge(ChildPledge<nsCString>& aPledge)
{
uint32_t id = ++sRequestCounter;
nsRefPtr<ChildPledge<nsCString>> ptr(&aPledge);
mRequestPledges.AppendElement(PledgeEntry(id, ptr));
return id;
}
already_AddRefed<ChildPledge<nsCString>>
Child::RemoveRequestPledge(uint32_t aRequestId)
{
for (PledgeEntry& entry : mRequestPledges) {
if (entry.first == aRequestId) {
nsRefPtr<ChildPledge<nsCString>> ref;
ref.swap(entry.second);
mRequestPledges.RemoveElement(entry);
return ref.forget();
}
}
MOZ_ASSERT_UNREACHABLE("Received response with no matching media::ChildPledge!");
return nullptr;
}
bool
Child::RecvGetOriginKeyResponse(const int& aRequestId, const nsCString& aKey)
{
nsRefPtr<ChildPledge<nsCString>> pledge = RemoveRequestPledge(aRequestId);
if (pledge) {
pledge->Resolve(aKey);
}
return true;
}
PMediaChild*
AllocPMediaChild()
{
Child* obj = new Child();
obj->AddRef();
return obj;
}
bool
DeallocPMediaChild(media::PMediaChild *aActor)
{
static_cast<Child*>(aActor)->Release();
return true;
}
}
}

View File

@ -1,74 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 mozilla_MediaChild_h
#define mozilla_MediaChild_h
#include "mozilla/dom/ContentChild.h"
#include "mozilla/media/PMediaChild.h"
#include "mozilla/media/PMediaParent.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#include "MediaUtils.h"
namespace mozilla {
namespace media {
// media::Child implements proxying to the chrome process for some media-related
// functions, for the moment just:
//
// GetOriginKey() - get a cookie-like persisted unique key for a given origin.
// SanitizeOriginKeys() - reset persisted unique keys.
// GetOriginKey and SanitizeOriginKeys are asynchronous APIs that return pledges
// (promise-like objects) with the future value. Use pledge.Then(func) to access.
class Child;
template<typename ValueType>
class ChildPledge : public Pledge<ValueType>,
public nsIIPCBackgroundChildCreateCallback
{
friend Child;
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
NS_DECL_ISUPPORTS
public:
explicit ChildPledge() {};
protected:
virtual ~ChildPledge() {}
virtual void Run(PMediaChild* aMedia) = 0;
};
already_AddRefed<ChildPledge<nsCString>>
GetOriginKey(const nsCString& aOrigin, bool aPrivateBrowsing);
already_AddRefed<ChildPledge<bool>>
SanitizeOriginKeys(const uint64_t& aSinceWhen);
class Child : public PMediaChild
{
NS_INLINE_DECL_REFCOUNTING(Child)
public:
Child();
bool RecvGetOriginKeyResponse(const int& aRequestId, const nsCString& aKey);
uint32_t AddRequestPledge(ChildPledge<nsCString>& aPledge);
already_AddRefed<ChildPledge<nsCString>> RemoveRequestPledge(uint32_t aRequestId);
private:
virtual ~Child();
typedef std::pair<uint32_t,nsRefPtr<ChildPledge<nsCString>>> PledgeEntry;
static uint32_t sRequestCounter;
nsTArray<PledgeEntry> mRequestPledges;
};
PMediaChild* AllocPMediaChild();
bool DeallocPMediaChild(PMediaChild *aActor);
} // namespace media
} // namespace mozilla
#endif // mozilla_MediaChild_h

View File

@ -1,456 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "MediaParent.h"
#include "mozilla/Base64.h"
#include <mozilla/StaticMutex.h>
#include "MediaUtils.h"
#include "MediaEngine.h"
#include "VideoUtils.h"
#include "nsThreadUtils.h"
#include "nsNetUtil.h"
#include "nsILineInputStream.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsISupportsImpl.h"
#include "prlog.h"
#undef LOG
#if defined(PR_LOGGING)
PRLogModuleInfo *gMediaParentLog;
#define LOG(args) PR_LOG(gMediaParentLog, PR_LOG_DEBUG, args)
#else
#define LOG(args)
#endif
// A file in the profile dir is used to persist mOriginKeys used to anonymize
// deviceIds to be unique per origin, to avoid them being supercookies.
#define ORIGINKEYS_FILE "enumerate_devices.txt"
#define ORIGINKEYS_VERSION "1"
namespace mozilla {
namespace media {
static StaticMutex gMutex;
static ParentSingleton* sParentSingleton = nullptr;
class ParentSingleton : public nsISupports
{
NS_DECL_ISUPPORTS
class OriginKey
{
public:
static const size_t DecodedLength = 18;
OriginKey(const nsACString& aKey, int64_t aSecondsStamp)
: mKey(aKey)
, mSecondsStamp(aSecondsStamp) {}
nsCString mKey; // Base64 encoded.
int64_t mSecondsStamp;
};
class OriginKeysTable
{
public:
OriginKeysTable() {}
nsresult
GetOriginKey(const nsACString& aOrigin, nsCString& result)
{
OriginKey* key;
if (!mKeys.Get(aOrigin, &key)) {
nsCString salt; // Make a new one
nsresult rv = GenerateRandomName(salt, key->DecodedLength * 4 / 3);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
key = new OriginKey(salt, PR_Now() / PR_USEC_PER_SEC);
mKeys.Put(aOrigin, key);
}
result = key->mKey;
return NS_OK;
}
static PLDHashOperator
HashCleaner(const nsACString& aOrigin, nsAutoPtr<OriginKey>& aOriginKey,
void *aUserArg)
{
OriginKey* since = static_cast<OriginKey*>(aUserArg);
LOG((((aOriginKey->mSecondsStamp >= since->mSecondsStamp)?
"%s: REMOVE %lld >= %lld" :
"%s: KEEP %lld < %lld"),
__FUNCTION__, aOriginKey->mSecondsStamp, since->mSecondsStamp));
return (aOriginKey->mSecondsStamp >= since->mSecondsStamp)?
PL_DHASH_REMOVE : PL_DHASH_NEXT;
}
void Clear(int64_t aSinceWhen)
{
// Avoid int64_t* <-> void* casting offset
OriginKey since(nsCString(), aSinceWhen / PR_USEC_PER_SEC);
mKeys.Enumerate(HashCleaner, &since);
}
protected:
nsClassHashtable<nsCStringHashKey, OriginKey> mKeys;
};
class OriginKeysLoader : public OriginKeysTable
{
public:
OriginKeysLoader()
{
Load();
}
nsresult
GetOriginKey(const nsACString& aOrigin, nsCString& result)
{
auto before = mKeys.Count();
OriginKeysTable::GetOriginKey(aOrigin, result);
if (mKeys.Count() != before) {
Save();
}
return NS_OK;
}
already_AddRefed<nsIFile>
GetFile()
{
if (!mProfileDir) {
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(mProfileDir));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
}
nsCOMPtr<nsIFile> file;
nsresult rv = mProfileDir->Clone(getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
file->Append(NS_LITERAL_STRING(ORIGINKEYS_FILE));
return file.forget();
}
// Format of file is key secondsstamp origin (first line is version #):
//
// 1
// rOMAAbFujNwKyIpj4RJ3Wt5Q 1424733961 http://fiddle.jshell.net
// rOMAAbFujNwKyIpj4RJ3Wt5Q 1424734841 http://mozilla.github.io
// etc.
nsresult Read()
{
nsCOMPtr<nsIFile> file = GetFile();
if (NS_WARN_IF(!file)) {
return NS_ERROR_UNEXPECTED;
}
bool exists;
nsresult rv = file->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
return NS_OK;
}
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsILineInputStream> i = do_QueryInterface(stream);
MOZ_ASSERT(i);
nsCString line;
bool hasMoreLines;
rv = i->ReadLine(line, &hasMoreLines);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!line.EqualsLiteral(ORIGINKEYS_VERSION)) {
// If version on disk is newer than we can understand then ignore it.
return NS_OK;
}
while (hasMoreLines) {
rv = i->ReadLine(line, &hasMoreLines);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Read key secondsstamp origin.
// Ignore any lines that don't fit format in the comment above exactly.
int32_t f = line.FindChar(' ');
if (f < 0) {
continue;
}
const nsACString& key = Substring(line, 0, f);
const nsACString& s = Substring(line, f+1);
f = s.FindChar(' ');
if (f < 0) {
continue;
}
int64_t secondsstamp = nsCString(Substring(s, 0, f)).ToInteger64(&rv);
if (NS_FAILED(rv)) {
continue;
}
const nsACString& origin = Substring(s, f+1);
// Validate key
if (key.Length() != OriginKey::DecodedLength) {
continue;
}
nsCString dummy;
rv = Base64Decode(key, dummy);
if (NS_FAILED(rv)) {
continue;
}
mKeys.Put(origin, new OriginKey(key, secondsstamp));
}
return NS_OK;
}
static PLDHashOperator
HashWriter(const nsACString& aOrigin, OriginKey* aOriginKey, void *aUserArg)
{
auto* stream = static_cast<nsIOutputStream *>(aUserArg);
nsCString buffer;
buffer.Append(aOriginKey->mKey);
buffer.Append(' ');
buffer.AppendInt(aOriginKey->mSecondsStamp);
buffer.Append(' ');
buffer.Append(aOrigin);
buffer.Append('\n');
uint32_t count;
nsresult rv = stream->Write(buffer.Data(), buffer.Length(), &count);
if (NS_WARN_IF(NS_FAILED(rv)) || count != buffer.Length()) {
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
nsresult
Write()
{
nsCOMPtr<nsIFile> file = GetFile();
if (NS_WARN_IF(!file)) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIOutputStream> stream;
nsresult rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(stream), file);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoCString buffer;
buffer.AppendLiteral(ORIGINKEYS_VERSION);
buffer.Append('\n');
uint32_t count;
rv = stream->Write(buffer.Data(), buffer.Length(), &count);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (count != buffer.Length()) {
return NS_ERROR_UNEXPECTED;
}
mKeys.EnumerateRead(HashWriter, stream.get());
nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(stream);
MOZ_ASSERT(safeStream);
rv = safeStream->Finish();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult Load()
{
nsresult rv = Read();
if (NS_WARN_IF(NS_FAILED(rv))) {
Delete();
}
return rv;
}
nsresult Save()
{
nsresult rv = Write();
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_WARNING("Failed to write data for EnumerateDevices id-persistence.");
Delete();
}
return rv;
}
void Clear(int64_t aSinceWhen)
{
OriginKeysTable::Clear(aSinceWhen);
Delete();
Save();
}
nsresult Delete()
{
nsCOMPtr<nsIFile> file = GetFile();
if (NS_WARN_IF(!file)) {
return NS_ERROR_UNEXPECTED;
}
nsresult rv = file->Remove(false);
if (rv == NS_ERROR_FILE_NOT_FOUND) {
return NS_OK;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
private:
nsCOMPtr<nsIFile> mProfileDir;
};
private:
virtual ~ParentSingleton()
{
sParentSingleton = nullptr;
LOG((__PRETTY_FUNCTION__));
}
public:
static ParentSingleton* Get()
{
// Protect creation of singleton and access from multiple Background threads.
//
// Multiple Background threads happen because sanitize.js calls us from the
// chrome process and gets a thread separate from the one servicing ipc from
// the content process.
StaticMutexAutoLock lock(gMutex);
if (!sParentSingleton) {
sParentSingleton = new ParentSingleton();
}
return sParentSingleton;
}
OriginKeysLoader mOriginKeys;
OriginKeysTable mPrivateBrowsingOriginKeys;
};
NS_IMPL_ISUPPORTS0(ParentSingleton)
bool
Parent::RecvGetOriginKey(const int& aRequestId,
const nsCString& aOrigin,
const bool& aPrivateBrowsing)
{
// Hand over to stream-transport thread.
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(sts);
nsRefPtr<ParentSingleton> singleton(mSingleton);
nsRefPtr<PledgeRunnable<nsCString>> p = PledgeRunnable<nsCString>::New(
[singleton, aOrigin, aPrivateBrowsing](nsCString& aResult) {
if (aPrivateBrowsing) {
singleton->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, aResult);
} else {
singleton->mOriginKeys.GetOriginKey(aOrigin, aResult);
}
return NS_OK;
});
nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
nsRefPtr<media::Parent> keepAlive(this);
p->Then([this, keepAlive, aRequestId](const nsCString& aKey) mutable {
if (!mDestroyed) {
unused << SendGetOriginKeyResponse(aRequestId, aKey);
}
return NS_OK;
});
return true;
}
bool
Parent::RecvSanitizeOriginKeys(const uint64_t& aSinceWhen)
{
// Hand over to stream-transport thread.
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(sts);
nsRefPtr<ParentSingleton> singleton(mSingleton);
nsRefPtr<PledgeRunnable<bool>> p = PledgeRunnable<bool>::New(
[singleton, aSinceWhen](bool) {
singleton->mPrivateBrowsingOriginKeys.Clear(aSinceWhen);
singleton->mOriginKeys.Clear(aSinceWhen);
return NS_OK;
});
nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return true;
}
void
Parent::ActorDestroy(ActorDestroyReason aWhy)
{
// No more IPC from here
mDestroyed = true;
LOG((__PRETTY_FUNCTION__));
}
Parent::Parent()
: mSingleton(ParentSingleton::Get())
, mDestroyed(false)
{
#if defined(PR_LOGGING)
if (!gMediaParentLog)
gMediaParentLog = PR_NewLogModule("MediaParent");
#endif
LOG(("media::Parent: %p", this));
MOZ_COUNT_CTOR(Parent);
}
Parent::~Parent()
{
LOG(("~media::Parent: %p", this));
MOZ_COUNT_DTOR(Parent);
}
PMediaParent*
AllocPMediaParent()
{
Parent* obj = new Parent();
obj->AddRef();
return obj;
}
bool
DeallocPMediaParent(media::PMediaParent *aActor)
{
static_cast<Parent*>(aActor)->Release();
return true;
}
}
}

View File

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 mozilla_MediaParent_h
#define mozilla_MediaParent_h
#include "MediaChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/media/PMediaParent.h"
namespace mozilla {
namespace media {
// media::Parent implements the chrome-process side of ipc for media::Child APIs
class ParentSingleton;
class Parent : public PMediaParent
{
NS_INLINE_DECL_REFCOUNTING(Parent)
public:
virtual bool RecvGetOriginKey(const int& aRequestId,
const nsCString& aOrigin,
const bool& aPrivateBrowsing) override;
virtual bool RecvSanitizeOriginKeys(const uint64_t& aSinceWhen) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
Parent();
private:
virtual ~Parent();
nsRefPtr<ParentSingleton> mSingleton;
bool mDestroyed;
};
PMediaParent* AllocPMediaParent();
bool DeallocPMediaParent(PMediaParent *aActor);
} // namespace media
} // namespace mozilla
#endif // mozilla_MediaParent_h

View File

@ -1,13 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "MediaUtils.h"
namespace mozilla {
namespace media {
}
}

View File

@ -1,197 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 mozilla_MediaUtils_h
#define mozilla_MediaUtils_h
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
namespace mozilla {
namespace media {
// A media::Pledge is a promise-like pattern for c++ that takes lambda functions.
//
// Asynchronous APIs that proxy to the chrome process and back, may return a
// pledge to allow callers to use pledge.Then() to specify a lambda function to
// invoke with the result once the asynchronous API resolves later back on the
// same thread.
//
// An advantage of this pattern is that lambdas allow "capturing" of local
// variables, much like closures in JavaScript.
template<typename ValueType>
class Pledge
{
// TODO: Remove workaround once mozilla allows std::function from <functional>
class FunctorsBase
{
public:
FunctorsBase() {}
virtual void Succeed(const ValueType& result) = 0;
virtual void Fail(nsresult rv) = 0;
virtual ~FunctorsBase() {};
};
public:
explicit Pledge() : mDone(false), mResult(NS_OK) {}
template<typename OnSuccessType>
void Then(OnSuccessType aOnSuccess)
{
Then(aOnSuccess, [](nsresult){});
}
template<typename OnSuccessType, typename OnFailureType>
void Then(OnSuccessType aOnSuccess, OnFailureType aOnFailure)
{
class F : public FunctorsBase
{
public:
F(OnSuccessType& aOnSuccess, OnFailureType& aOnFailure)
: mOnSuccess(aOnSuccess), mOnFailure(aOnFailure) {}
void Succeed(const ValueType& result)
{
mOnSuccess(result);
}
void Fail(nsresult rv)
{
mOnFailure(rv);
};
OnSuccessType mOnSuccess;
OnFailureType mOnFailure;
};
mFunctors = new F(aOnSuccess, aOnFailure);
if (mDone) {
if (mResult == NS_OK) {
mFunctors->Succeed(mValue);
} else {
mFunctors->Fail(mResult);
}
}
}
protected:
void Resolve(const ValueType& aValue)
{
mValue = aValue;
Resolve();
}
void Resolve()
{
if (!mDone) {
mDone = true;
MOZ_ASSERT(mResult == NS_OK);
if (mFunctors) {
mFunctors->Succeed(mValue);
}
}
}
void Reject(nsresult rv)
{
if (!mDone) {
mDone = true;
mResult = rv;
if (mFunctors) {
mFunctors->Fail(mResult);
}
}
}
ValueType mValue;
protected:
bool mDone;
nsresult mResult;
private:
nsAutoPtr<FunctorsBase> mFunctors;
};
// General purpose runnable that also acts as a Pledge for the resulting value.
// Use PledgeRunnable<>::New() factory function to use with lambdas.
template<typename ValueType>
class PledgeRunnable : public Pledge<ValueType>, public nsRunnable
{
public:
template<typename OnRunType>
static PledgeRunnable<ValueType>*
New(OnRunType aOnRun)
{
class P : public PledgeRunnable<ValueType>
{
public:
explicit P(OnRunType& aOnRun)
: mOriginThread(NS_GetCurrentThread())
, mOnRun(aOnRun)
, mHasRun(false) {}
private:
virtual ~P() {}
NS_IMETHODIMP
Run()
{
if (!mHasRun) {
P::mResult = mOnRun(P::mValue);
mHasRun = true;
return mOriginThread->Dispatch(this, NS_DISPATCH_NORMAL);
}
bool on;
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(mOriginThread->IsOnCurrentThread(&on)));
MOZ_RELEASE_ASSERT(on);
if (NS_SUCCEEDED(P::mResult)) {
P::Resolve();
} else {
P::Reject(P::mResult);
}
return NS_OK;
}
nsCOMPtr<nsIThread> mOriginThread;
OnRunType mOnRun;
bool mHasRun;
};
return new P(aOnRun);
}
protected:
virtual ~PledgeRunnable() {}
};
// General purpose runnable with an eye toward lambdas
namespace CallbackRunnable
{
template<typename OnRunType>
class Impl : public nsRunnable
{
public:
explicit Impl(OnRunType& aOnRun) : mOnRun(aOnRun) {}
private:
NS_IMETHODIMP
Run()
{
return mOnRun();
}
OnRunType mOnRun;
};
template<typename OnRunType>
Impl<OnRunType>*
New(OnRunType aOnRun)
{
return new Impl<OnRunType>(aOnRun);
}
}
}
}
#endif // mozilla_MediaUtils_h

View File

@ -1,35 +0,0 @@
/* 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 protocol PContent;
include protocol PBackground;
namespace mozilla {
namespace media {
protocol PMedia
{
manager PBackground;
parent:
/**
* Requests a persistent unique secret key for each origin.
* Has no expiry, but is cleared by age along with cookies.
* This is needed by mediaDevices.enumerateDevices() to produce persistent
* deviceIds that wont work cross-origin.
*/
GetOriginKey(uint32_t aRequestId, nsCString aOrigin, bool aPrivateBrowsing);
/**
* On clear cookies. Fire and forget.
*/
SanitizeOriginKeys(uint64_t aSinceWhen);
child:
GetOriginKeyResponse(uint32_t aRequestId, nsCString key);
__delete__();
};
} // namespace media
} // namespace mozilla

View File

@ -37,22 +37,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
]
]
EXPORTS.mozilla.media += ['MediaChild.h',
'MediaParent.h',
'MediaUtils.h'
]
UNIFIED_SOURCES += ['MediaChild.cpp',
'MediaParent.cpp',
'MediaUtils.cpp'
]
IPDL_SOURCES += [
'PMedia.ipdl',
]
# /dom/base needed for nsGlobalWindow.h in MediaChild.cpp
LOCAL_INCLUDES += [
'/dom/base',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

View File

@ -644,8 +644,6 @@ var interfaceNamesInGlobalScope =
"LocalMediaStream",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Location",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MediaDeviceInfo",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MediaDevices",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -1,22 +0,0 @@
/* -*- Mode: IDL; 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/.
*
* The origin of this IDL file is
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html
*/
enum MediaDeviceKind {
"audioinput",
"audiooutput",
"videoinput"
};
[Func="Navigator::HasUserMediaSupport"]
interface MediaDeviceInfo {
readonly attribute DOMString deviceId;
readonly attribute MediaDeviceKind kind;
readonly attribute DOMString label;
readonly attribute DOMString groupId;
};

View File

@ -12,12 +12,12 @@
[Func="Navigator::HasUserMediaSupport"]
interface MediaDevices : EventTarget {
// attribute EventHandler ondevicechange;
// attribute EventHandler ondevicechange;
//
// void enumerateDevices (MediaDeviceInfoCallback resultCallback);
//
// static Dictionary getSupportedConstraints (DOMString kind);
[Throws]
Promise<sequence<MediaDeviceInfo>> enumerateDevices();
[Throws]
[Throws, Func="Navigator::HasUserMediaSupport"]
Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
};

View File

@ -262,7 +262,6 @@ WEBIDL_FILES = [
'ListBoxObject.webidl',
'LocalMediaStream.webidl',
'Location.webidl',
'MediaDeviceInfo.webidl',
'MediaDevices.webidl',
'MediaElementAudioSourceNode.webidl',
'MediaError.webidl',

View File

@ -7,7 +7,6 @@
#include "ActorsChild.h" // IndexedDB
#include "BroadcastChannelChild.h"
#include "FileDescriptorSetChild.h"
#include "mozilla/media/MediaChild.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/cache/ActorUtils.h"
@ -282,18 +281,6 @@ BackgroundChildImpl::DeallocPCacheStreamControlChild(PCacheStreamControlChild* a
return true;
}
media::PMediaChild*
BackgroundChildImpl::AllocPMediaChild()
{
return media::AllocPMediaChild();
}
bool
BackgroundChildImpl::DeallocPMediaChild(media::PMediaChild *aActor)
{
return media::DeallocPMediaChild(aActor);
}
} // namespace ipc
} // namespace mozilla

View File

@ -71,12 +71,6 @@ protected:
virtual bool
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor) override;
virtual PMediaChild*
AllocPMediaChild() override;
virtual bool
DeallocPMediaChild(PMediaChild* aActor) override;
virtual PVsyncChild*
AllocPVsyncChild() override;

View File

@ -6,7 +6,6 @@
#include "BroadcastChannelParent.h"
#include "FileDescriptorSetParent.h"
#include "mozilla/media/MediaParent.h"
#include "mozilla/AppProcessChecker.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/ContentParent.h"
@ -361,18 +360,6 @@ BackgroundParentImpl::DeallocPBroadcastChannelParent(
return true;
}
media::PMediaParent*
BackgroundParentImpl::AllocPMediaParent()
{
return media::AllocPMediaParent();
}
bool
BackgroundParentImpl::DeallocPMediaParent(media::PMediaParent *aActor)
{
return media::DeallocPMediaParent(aActor);
}
namespace {
class RegisterServiceWorkerCallback final : public nsRunnable

View File

@ -84,12 +84,6 @@ protected:
virtual bool
DeallocPBroadcastChannelParent(PBroadcastChannelParent* aActor) override;
virtual PMediaParent*
AllocPMediaParent() override;
virtual bool
DeallocPMediaParent(PMediaParent* aActor) override;
virtual bool
RecvRegisterServiceWorker(const ServiceWorkerRegistrationData& aData)
override;

View File

@ -11,7 +11,6 @@ include protocol PCacheStorage;
include protocol PCacheStreamControl;
include protocol PFileDescriptorSet;
include protocol PVsync;
include protocol PMedia;
include DOMTypes;
include PBackgroundSharedTypes;
@ -35,7 +34,6 @@ sync protocol PBackground
manages PCacheStreamControl;
manages PFileDescriptorSet;
manages PVsync;
manages PMedia;
parent:
// Only called at startup during mochitests to check the basic infrastructure.
@ -44,7 +42,6 @@ parent:
PBackgroundIDBFactory(LoggingInfo loggingInfo);
PVsync();
PMedia();
PBroadcastChannel(PrincipalInfo pInfo, nsString origin, nsString channel);

View File

@ -169,7 +169,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssLoadingComponent, nsNSSComponent,
Init)
using namespace mozilla::psm;
namespace {
// Use the special factory constructor for everything this module implements,
@ -199,9 +199,9 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPkcs11)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCertPicker)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsNTLMAuthModule, InitTest)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsCryptoHash)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsCryptoHMAC)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsKeyObject)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsKeyObjectFactory)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCryptoHMAC)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObject)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus)