void MediaManager::OnNavigation(uint64_t aWindowID) { NS_ASSERTION(NS_IsMainThread(), "OnNavigation called off main thread"); // Invalidate this window. The runnables check this value before making // a call to content. // This is safe since we're on main-thread, and the windowlist can only // be added to from the main-thread StreamListeners* listeners = GetWindowListeners(aWindowID); if (!listeners) { return; } uint32_t length = listeners->Length(); for (uint32_t i = 0; i < length; i++) { nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener = listeners->ElementAt(i); listener->Invalidate(); listener->Remove(); } listeners->Clear(); GetActiveWindows()->Remove(aWindowID); }
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; }
void MediaManager::RemoveFromWindowList(uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener) { NS_ASSERTION(NS_IsMainThread(), "RemoveFromWindowList called off main thread"); // This is defined as safe on an inactive GUMCMSListener aListener->Remove(); // really queues the remove StreamListeners* listeners = GetWindowListeners(aWindowID); if (!listeners) { return; } listeners->RemoveElement(aListener); if (listeners->Length() == 0) { RemoveWindowID(aWindowID); // listeners has been deleted here // get outer windowID nsPIDOMWindow *window = static_cast<nsPIDOMWindow*> (nsGlobalWindow::GetInnerWindowWithId(aWindowID)); if (window) { nsPIDOMWindow *outer = window->GetOuterWindow(); if (outer) { uint64_t outerID = outer->WindowID(); // Notify the UI that this window no longer has gUM active char windowBuffer[32]; PR_snprintf(windowBuffer, sizeof(windowBuffer), "%llu", outerID); nsAutoString data; data.Append(NS_ConvertUTF8toUTF16(windowBuffer)); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); obs->NotifyObservers(nullptr, "recording-window-ended", data.get()); LOG(("Sent recording-window-ended for window %llu (outer %llu)", aWindowID, outerID)); } else { LOG(("No outer window for inner %llu", aWindowID)); } } else { LOG(("No inner window for %llu", aWindowID)); } } }
void MediaManager::RemoveFromWindowList(uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener) { NS_ASSERTION(NS_IsMainThread(), "RemoveFromWindowList called off main thread"); // This is defined as safe on an inactive GUMCMSListener aListener->Remove(); // really queues the remove StreamListeners* listeners = GetWindowListeners(aWindowID); if (!listeners) { return; } listeners->RemoveElement(aListener); if (listeners->Length() == 0) { RemoveWindowID(aWindowID); // listeners has been deleted here } }
void MediaManager::OnNavigation(PRUint64 aWindowID) { // Invalidate this window. The runnables check this value before making // a call to content. StreamListeners* listeners = mActiveWindows.Get(aWindowID); if (!listeners) { return; } PRUint32 length = listeners->Length(); for (PRUint32 i = 0; i < length; i++) { nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener = listeners->ElementAt(i); listener->Invalidate(); listener = nsnull; } listeners->Clear(); mActiveWindows.Remove(aWindowID); }