mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 05:44:20 +00:00
Bug 1050802: Backend to allow stopping sharing for screen/window for a WindowID r=jib
This commit is contained in:
parent
6aeef44c14
commit
74c0fb3f1e
@ -1992,13 +1992,23 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
|
||||
} else if (!strcmp(aTopic, "getUserMedia:revoke")) {
|
||||
nsresult rv;
|
||||
uint64_t windowID = nsString(aData).ToInteger64(&rv);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("Revoking MediaCapture access for window %llu",windowID));
|
||||
OnNavigation(windowID);
|
||||
// may be windowid or screen:windowid
|
||||
nsDependentString data(aData);
|
||||
if (Substring(data, 0, strlen("screen:")).EqualsLiteral("screen:")) {
|
||||
uint64_t windowID = PromiseFlatString(Substring(data, strlen("screen:"))).ToInteger64(&rv);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("Revoking Screeen/windowCapture access for window %llu", windowID));
|
||||
StopScreensharing(windowID);
|
||||
}
|
||||
} else {
|
||||
uint64_t windowID = nsString(aData).ToInteger64(&rv);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("Revoking MediaCapture access for window %llu", windowID));
|
||||
OnNavigation(windowID);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -2148,6 +2158,67 @@ MediaManager::MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVide
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX abstract out the iteration over all children and provide a function pointer and data ptr
|
||||
|
||||
void
|
||||
MediaManager::StopScreensharing(uint64_t aWindowID)
|
||||
{
|
||||
// We need to stop window/screensharing for all streams in all innerwindows that
|
||||
// correspond to that outerwindow.
|
||||
|
||||
nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
|
||||
(nsGlobalWindow::GetInnerWindowWithId(aWindowID));
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
StopScreensharing(window);
|
||||
}
|
||||
|
||||
void
|
||||
MediaManager::StopScreensharing(nsPIDOMWindow *aWindow)
|
||||
{
|
||||
// We need to stop window/screensharing for 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, and tell them to stop
|
||||
// window/screensharing
|
||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
||||
if (piWin) {
|
||||
if (piWin->IsInnerWindow() || piWin->GetCurrentInnerWindow()) {
|
||||
uint64_t windowID;
|
||||
if (piWin->IsInnerWindow()) {
|
||||
windowID = piWin->WindowID();
|
||||
} else {
|
||||
windowID = piWin->GetCurrentInnerWindow()->WindowID();
|
||||
}
|
||||
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
|
||||
if (listeners) {
|
||||
uint32_t length = listeners->Length();
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
listeners->ElementAt(i)->StopScreenWindowSharing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate any children of *this* window (iframes, etc)
|
||||
nsCOMPtr<nsIDocShell> docShell = piWin->GetDocShell();
|
||||
if (docShell) {
|
||||
int32_t i, count;
|
||||
docShell->GetChildCount(&count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
docShell->GetChildAt(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsPIDOMWindow> win = item ? item->GetWindow() : nullptr;
|
||||
|
||||
if (win) {
|
||||
StopScreensharing(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaManager::StopMediaStreams()
|
||||
{
|
||||
@ -2182,6 +2253,26 @@ GetUserMediaCallbackMediaStreamListener::Invalidate()
|
||||
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
// Doesn't kill audio
|
||||
// XXX refactor to combine with Invalidate()?
|
||||
void
|
||||
GetUserMediaCallbackMediaStreamListener::StopScreenWindowSharing()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
if (mVideoSource && !mStopped &&
|
||||
(mVideoSource->GetMediaSource() == MediaSourceType::Screen ||
|
||||
mVideoSource->GetMediaSource() == MediaSourceType::Window)) {
|
||||
// Stop the whole stream if there's no audio; just the video track if we have both
|
||||
nsRefPtr<MediaOperationRunnable> runnable(
|
||||
new MediaOperationRunnable(mAudioSource ? MEDIA_STOP_TRACK : MEDIA_STOP,
|
||||
this, nullptr, nullptr,
|
||||
nullptr, mVideoSource,
|
||||
mFinished, mWindowID, nullptr));
|
||||
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Called from the MediaStreamGraph thread
|
||||
void
|
||||
GetUserMediaCallbackMediaStreamListener::NotifyFinished(MediaStreamGraph* aGraph)
|
||||
@ -2242,6 +2333,9 @@ GetUserMediaNotificationEvent::Run()
|
||||
mListener->SetStopped();
|
||||
}
|
||||
break;
|
||||
case STOPPED_TRACK:
|
||||
msg = NS_LITERAL_STRING("shutdown");
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
|
||||
|
@ -99,6 +99,8 @@ public:
|
||||
return mStream->AsSourceStream();
|
||||
}
|
||||
|
||||
void StopScreenWindowSharing();
|
||||
|
||||
// mVideo/AudioSource are set by Activate(), so we assume they're capturing
|
||||
// if set and represent a real capture device.
|
||||
bool CapturingVideo()
|
||||
@ -119,13 +121,13 @@ public:
|
||||
bool CapturingScreen()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
return mVideoSource && !mStopped &&
|
||||
return mVideoSource && !mStopped && !mVideoSource->IsAvailable() &&
|
||||
mVideoSource->GetMediaSource() == MediaSourceType::Screen;
|
||||
}
|
||||
bool CapturingWindow()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
return mVideoSource && !mStopped &&
|
||||
return mVideoSource && !mStopped && !mVideoSource->IsAvailable() &&
|
||||
mVideoSource->GetMediaSource() == MediaSourceType::Window;
|
||||
}
|
||||
|
||||
@ -246,7 +248,8 @@ class GetUserMediaNotificationEvent: public nsRunnable
|
||||
public:
|
||||
enum GetUserMediaStatus {
|
||||
STARTING,
|
||||
STOPPING
|
||||
STOPPING,
|
||||
STOPPED_TRACK
|
||||
};
|
||||
GetUserMediaNotificationEvent(GetUserMediaCallbackMediaStreamListener* aListener,
|
||||
GetUserMediaStatus aStatus,
|
||||
@ -283,6 +286,7 @@ class GetUserMediaNotificationEvent: public nsRunnable
|
||||
typedef enum {
|
||||
MEDIA_START,
|
||||
MEDIA_STOP,
|
||||
MEDIA_STOP_TRACK,
|
||||
MEDIA_DIRECT_LISTENERS
|
||||
} MediaOperation;
|
||||
|
||||
@ -426,6 +430,7 @@ public:
|
||||
break;
|
||||
|
||||
case MEDIA_STOP:
|
||||
case MEDIA_STOP_TRACK:
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
|
||||
if (mAudioSource) {
|
||||
@ -440,9 +445,12 @@ public:
|
||||
if (mBool) {
|
||||
source->Finish();
|
||||
}
|
||||
|
||||
nsIRunnable *event =
|
||||
new GetUserMediaNotificationEvent(mListener,
|
||||
GetUserMediaNotificationEvent::STOPPING,
|
||||
mType == MEDIA_STOP ?
|
||||
GetUserMediaNotificationEvent::STOPPING :
|
||||
GetUserMediaNotificationEvent::STOPPED_TRACK,
|
||||
mAudioSource != nullptr,
|
||||
mVideoSource != nullptr,
|
||||
mWindowID);
|
||||
@ -595,6 +603,9 @@ private:
|
||||
bool* aAudio, bool *aScreenShare,
|
||||
bool* aWindowShare);
|
||||
|
||||
void StopScreensharing(uint64_t aWindowID);
|
||||
void StopScreensharing(nsPIDOMWindow *aWindow);
|
||||
|
||||
void StopMediaStreams();
|
||||
|
||||
// ONLY access from MainThread so we don't need to lock
|
||||
|
Loading…
x
Reference in New Issue
Block a user