author | Randell Jesup <rjesup@jesup.org> |
Wed, 27 Feb 2013 15:36:06 -0500 | |
changeset 123206 | 3c22e7998e22325b6a2111da7c9c965595e5e18c |
parent 123205 | e125dce45cb734475fff25e1823202b3494ccc87 |
child 123207 | 58c7e618c860b6d37e8c55178b60c74e0c879eba |
push id | 24373 |
push user | ryanvm@gmail.com |
push date | Thu, 28 Feb 2013 01:36:21 +0000 |
treeherder | mozilla-central@8cb9d6981978 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 843971 |
milestone | 22.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
|
--- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -8,16 +8,17 @@ #include "nsIDOMFile.h" #include "nsIEventTarget.h" #include "nsIUUIDGenerator.h" #include "nsIScriptGlobalObject.h" #include "nsIPopupWindowManager.h" #include "nsISupportsArray.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" +#include "nsIDocShell.h" // For PR_snprintf #include "prprf.h" #include "nsJSUtils.h" #include "nsDOMFile.h" #include "nsGlobalWindow.h" @@ -1294,16 +1295,91 @@ MediaManager::GetActiveMediaCaptureWindo return rv; mActiveWindows.EnumerateRead(WindowsHashToArrayFunc, array); *aArray = array; return NS_OK; } +NS_IMETHODIMP +MediaManager::MediaCaptureWindowState(nsIDOMWindow* aWindow, bool* aVideo, + bool* aAudio) +{ + *aVideo = false; + *aAudio = false; + + nsresult rv = MediaCaptureWindowStateInternal(aWindow, aVideo, aAudio); +#ifdef DEBUG + nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow); + LOG(("%s: window %lld capturing %s %s", __FUNCTION__, piWin ? piWin->WindowID() : -1, + *aVideo ? "video" : "", *aAudio ? "audio" : "")); +#endif + return rv; +} + +nsresult +MediaManager::MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo, + bool* aAudio) +{ + // We need to return the union of all streams in all innerwindows that + // correspond to that outerwindow. + + // Iterate the docshell tree to find all the child windows, find + // all the listeners for each one, get the booleans, and merge the + // results. + nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow); + if (piWin) { + if (piWin->GetCurrentInnerWindow() || piWin->IsInnerWindow()) { + uint64_t windowID; + if (piWin->GetCurrentInnerWindow()) { + windowID = piWin->GetCurrentInnerWindow()->WindowID(); + } else { + windowID = piWin->WindowID(); + } + StreamListeners* listeners = GetActiveWindows()->Get(windowID); + if (listeners) { + uint32_t length = listeners->Length(); + for (uint32_t i = 0; i < length; ++i) { + nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener = + listeners->ElementAt(i); + if (listener->CapturingVideo()) { + *aVideo = true; + } + if (listener->CapturingAudio()) { + *aAudio = true; + } + if (*aAudio && *aVideo) { + return NS_OK; // no need to continue iterating + } + } + } + } + + // iterate any children of *this* window (iframes, etc) + nsCOMPtr<nsIDocShellTreeNode> node = + do_QueryInterface(piWin->GetDocShell()); + if (node) { + int32_t i, count; + node->GetChildCount(&count); + for (i = 0; i < count; ++i) { + nsCOMPtr<nsIDocShellTreeItem> item; + node->GetChildAt(i, getter_AddRefs(item)); + nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(item); + + MediaCaptureWindowStateInternal(win, aVideo, aAudio); + if (*aAudio && *aVideo) { + return NS_OK; // no need to continue iterating + } + } + } + } + return NS_OK; +} + // Can be invoked from EITHER MainThread or MSG thread void GetUserMediaCallbackMediaStreamListener::Invalidate() { nsRefPtr<MediaOperationRunnable> runnable; // We can't take a chance on blocking here, so proxy this to another // thread.
--- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -123,16 +123,25 @@ public: { NS_ASSERTION(mStream,"Getting stream from never-activated GUMCMSListener"); if (!mStream) { return nullptr; } return mStream->AsSourceStream(); } + bool CapturingVideo() + { + return mVideoSource && mLastEndTimeVideo > 0 && !mFinished; + } + bool CapturingAudio() + { + return mAudioSource && mLastEndTimeAudio > 0 && !mFinished; + } + // implement in .cpp to avoid circular dependency with MediaOperationRunnable // Can be invoked from EITHER MainThread or MSG thread void Invalidate(); void AudioConfig(bool aEchoOn, uint32_t aEcho, bool aAgcOn, uint32_t aAGC, bool aNoiseOn, uint32_t aNoise) @@ -420,16 +429,19 @@ private: mActiveWindows.Init(); mActiveCallbacks.Init(); } ~MediaManager() { delete mBackend; } + nsresult MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo, + bool* aAudio); + // ONLY access from MainThread so we don't need to lock WindowTable mActiveWindows; nsRefPtrHashtable<nsStringHashKey, nsRunnable> mActiveCallbacks; // Always exists nsCOMPtr<nsIThread> mMediaThread; Mutex mMutex; // protected with mMutex:
--- a/dom/media/nsIMediaManager.idl +++ b/dom/media/nsIMediaManager.idl @@ -1,18 +1,23 @@ /* 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 "nsISupports.idl" interface nsISupportsArray; +interface nsIDOMWindow; %{C++ #define NS_MEDIAMANAGERSERVICE_CID {0xabc622ea, 0x9655, 0x4123, {0x80, 0xd9, 0x22, 0x62, 0x1b, 0xdd, 0x54, 0x65}} #define MEDIAMANAGERSERVICE_CONTRACTID "@mozilla.org/mediaManagerService;1" %} -[scriptable, builtinclass, uuid(afe82ff1-2caa-4304-85da-0158a5dee56b)] +[scriptable, builtinclass, uuid(2efff6ab-0e3e-4cc4-8f9b-4aaca59a1140)] interface nsIMediaManagerService : nsISupports { + /* return a array of inner windows that have active captures */ readonly attribute nsISupportsArray activeMediaCaptureWindows; + + /* Get the capture state for the given window and all descendant windows (iframes, etc) */ + void mediaCaptureWindowState(in nsIDOMWindow aWindow, out boolean aVideo, out boolean aAudio); };