Bug 843971: Add MediaManager function to report what a window is capturing r=smaug

This commit is contained in:
Randell Jesup 2013-02-27 15:36:06 -05:00
parent 95660a9d32
commit 1987838f73
3 changed files with 94 additions and 1 deletions

View File

@ -13,6 +13,7 @@
#include "nsISupportsArray.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIDocShell.h"
// For PR_snprintf
#include "prprf.h"
@ -1299,6 +1300,81 @@ MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray **aArray)
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()

View File

@ -128,6 +128,15 @@ public:
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();
@ -425,6 +434,9 @@ private:
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;

View File

@ -5,14 +5,19 @@
#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);
};