author | Shih-Chiang Chien <schien@mozilla.com> |
Wed, 23 Oct 2013 19:10:42 +0800 | |
changeset 166131 | ddf19de28a0eafec4b804503828d0dd0b513f583 |
parent 166130 | ac029c297e1adec13e1b994e98b35edfbf210e99 |
child 166132 | 8f125ace663169b472dfb6f64fe3e0cdef963109 |
push id | 3066 |
push user | akeybl@mozilla.com |
push date | Mon, 09 Dec 2013 19:58:46 +0000 |
treeherder | mozilla-beta@a31a0dce83aa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jesup |
bugs | 926289 |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/media/MediaManager.cpp | file | annotate | diff | comparison | revisions | |
dom/media/MediaManager.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -1,30 +1,33 @@ /* 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 "MediaManager.h" #include "MediaStreamGraph.h" #include "GetUserMediaRequest.h" +#include "nsHashPropertyBag.h" #ifdef MOZ_WIDGET_GONK #include "nsIAudioManager.h" #endif +#include "nsIAppsService.h" #include "nsIDOMFile.h" #include "nsIEventTarget.h" #include "nsIUUIDGenerator.h" #include "nsIScriptGlobalObject.h" #include "nsIPopupWindowManager.h" #include "nsISupportsArray.h" #include "nsIDocShell.h" #include "nsIDocument.h" #include "nsISupportsPrimitives.h" #include "nsIInterfaceRequestorUtils.h" -#include "mozilla/dom/ContentChild.h" +#include "nsIScriptSecurityManager.h" +#include "mozilla/dom/TabChild.h" #include "mozilla/dom/MediaStreamTrackBinding.h" #include "mozilla/dom/GetUserMediaRequestBinding.h" // For PR_snprintf #include "prprf.h" #include "nsJSUtils.h" #include "nsDOMFile.h" @@ -133,16 +136,55 @@ static nsresult ValidateTrackConstraints nsresult rv = CompareDictionaries(aCx, track.mMandatory.Value(), aNormalized.mMandatory, aOutUnknownConstraint); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; } +static already_AddRefed<nsHashPropertyBag> +CreateRecordingDeviceEventsSubject(nsPIDOMWindow* aWindow, + const bool aIsAudio, + const bool aIsVideo) +{ + MOZ_ASSERT(aWindow); + + nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag(); + props->SetPropertyAsBool(NS_LITERAL_STRING("isAudio"), aIsAudio); + props->SetPropertyAsBool(NS_LITERAL_STRING("isVideo"), aIsVideo); + + nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell(); + if (docShell) { + bool isApp; + DebugOnly<nsresult> rv = docShell->GetIsApp(&isApp); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + nsString requestURL; + if (isApp) { + rv = docShell->GetAppManifestURL(requestURL); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + } else { + nsCString pageURL; + nsCOMPtr<nsIURI> docURI = aWindow->GetDocumentURI(); + MOZ_ASSERT(docURI); + + rv = docURI->GetSpec(pageURL); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + requestURL = NS_ConvertUTF8toUTF16(pageURL); + } + + props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), requestURL); + props->SetPropertyAsBool(NS_LITERAL_STRING("isApp"), isApp); + } + + return props.forget(); +} + /** * Send an error back to content. The error is the form a string. * Do this only on the main thread. The success callback is also passed here * so it can be released correctly. */ class ErrorCallbackRunnable : public nsRunnable { public: @@ -579,17 +621,17 @@ public: // Dispatch to the media thread to ask it to start the sources, // because that can take a while. // Pass ownership of trackunion to the MediaOperationRunnable // to ensure it's kept alive until the MediaOperationRunnable runs (at least). nsIThread *mediaThread = MediaManager::GetThread(); nsRefPtr<MediaOperationRunnable> runnable( new MediaOperationRunnable(MEDIA_START, mListener, trackunion, tracksAvailableCallback, - mAudioSource, mVideoSource, false)); + mAudioSource, mVideoSource, false, mWindowID)); mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); #ifdef MOZ_WEBRTC // Right now these configs are only of use if webrtc is available nsresult rv; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); @@ -1725,17 +1767,17 @@ GetUserMediaCallbackMediaStreamListener: nsRefPtr<MediaOperationRunnable> runnable; // We can't take a chance on blocking here, so proxy this to another // thread. // Pass a ref to us (which is threadsafe) so it can query us for the // source stream info. runnable = new MediaOperationRunnable(MEDIA_STOP, this, nullptr, nullptr, mAudioSource, mVideoSource, - mFinished); + mFinished, mWindowID); mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); } // Called from the MediaStreamGraph thread void GetUserMediaCallbackMediaStreamListener::NotifyFinished(MediaStreamGraph* aGraph) { mFinished = true; @@ -1782,20 +1824,27 @@ GetUserMediaNotificationEvent::Run() break; case STOPPING: msg = NS_LITERAL_STRING("shutdown"); if (mListener) { mListener->SetStopped(); } break; } - obs->NotifyObservers(nullptr, + + nsCOMPtr<nsPIDOMWindow> window = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + MOZ_ASSERT(window); + + nsRefPtr<nsHashPropertyBag> props = + CreateRecordingDeviceEventsSubject(window, mIsAudio, mIsVideo); + + obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props), "recording-device-events", msg.get()); // Forward recording events to parent process. // The events are gathered in chrome process and used for recording indicator if (XRE_GetProcessType() != GeckoProcessType_Default) { - unused << dom::ContentChild::GetSingleton()->SendRecordingDeviceEvents(msg); + unused << dom::TabChild::GetFrom(window)->SendRecordingDeviceEvents(msg, mIsAudio, mIsVideo); } return NS_OK; } } // namespace mozilla
--- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -199,36 +199,42 @@ private: class GetUserMediaNotificationEvent: public nsRunnable { public: enum GetUserMediaStatus { STARTING, STOPPING }; GetUserMediaNotificationEvent(GetUserMediaCallbackMediaStreamListener* aListener, - GetUserMediaStatus aStatus) - : mListener(aListener), mStatus(aStatus) {} + GetUserMediaStatus aStatus, + bool aIsAudio, bool aIsVideo, uint64_t aWindowID) + : mListener(aListener) , mStatus(aStatus) , mIsAudio(aIsAudio) + , mIsVideo(aIsVideo), mWindowID(aWindowID) {} GetUserMediaNotificationEvent(GetUserMediaStatus aStatus, already_AddRefed<DOMMediaStream> aStream, - DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback) + DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback, + bool aIsAudio, bool aIsVideo, uint64_t aWindowID) : mStream(aStream), mOnTracksAvailableCallback(aOnTracksAvailableCallback), - mStatus(aStatus) {} + mStatus(aStatus), mIsAudio(aIsAudio), mIsVideo(aIsVideo), mWindowID(aWindowID) {} virtual ~GetUserMediaNotificationEvent() { } NS_IMETHOD Run() MOZ_OVERRIDE; protected: nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe nsRefPtr<DOMMediaStream> mStream; nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback; GetUserMediaStatus mStatus; + bool mIsAudio; + bool mIsVideo; + uint64_t mWindowID; }; typedef enum { MEDIA_START, MEDIA_STOP } MediaOperation; // Generic class for running long media operations like Start off the main @@ -239,24 +245,26 @@ class MediaOperationRunnable : public ns public: // so we can send Stop without AddRef()ing from the MSG thread MediaOperationRunnable(MediaOperation aType, GetUserMediaCallbackMediaStreamListener* aListener, DOMMediaStream* aStream, DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback, MediaEngineSource* aAudioSource, MediaEngineSource* aVideoSource, - bool aNeedsFinish) + bool aNeedsFinish, + uint64_t aWindowID) : mType(aType) , mStream(aStream) , mOnTracksAvailableCallback(aOnTracksAvailableCallback) , mAudioSource(aAudioSource) , mVideoSource(aVideoSource) , mListener(aListener) , mFinish(aNeedsFinish) + , mWindowID(aWindowID) {} ~MediaOperationRunnable() { // MediaStreams can be released on any thread. } NS_IMETHOD @@ -298,17 +306,20 @@ public: MM_LOG(("started all sources")); // Forward mOnTracksAvailableCallback to GetUserMediaNotificationEvent, // because mOnTracksAvailableCallback needs to be added to mStream // on the main thread. nsRefPtr<GetUserMediaNotificationEvent> event = new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING, mStream.forget(), - mOnTracksAvailableCallback.forget()); + mOnTracksAvailableCallback.forget(), + mAudioSource != nullptr, + mVideoSource != nullptr, + mWindowID); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); } break; case MEDIA_STOP: { NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread"); if (mAudioSource) { @@ -319,17 +330,21 @@ public: mVideoSource->Stop(source, kVideoTrack); mVideoSource->Deallocate(); } // Do this after stopping all tracks with EndTrack() if (mFinish) { source->Finish(); } nsRefPtr<GetUserMediaNotificationEvent> event = - new GetUserMediaNotificationEvent(mListener, GetUserMediaNotificationEvent::STOPPING); + new GetUserMediaNotificationEvent(mListener, + GetUserMediaNotificationEvent::STOPPING, + mAudioSource != nullptr, + mVideoSource != nullptr, + mWindowID); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); } break; default: MOZ_ASSERT(false,"invalid MediaManager operation"); break; @@ -340,16 +355,17 @@ public: private: MediaOperation mType; nsRefPtr<DOMMediaStream> mStream; nsAutoPtr<DOMMediaStream::OnTracksAvailableCallback> mOnTracksAvailableCallback; nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe bool mFinish; + uint64_t mWindowID; }; typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners; typedef nsClassHashtable<nsUint64HashKey, StreamListeners> WindowTable; class MediaDevice : public nsIMediaDevice { public: