nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) { NS_ASSERTION(NS_IsMainThread(), "Observer invoked off the main thread"); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (!strcmp(aTopic, "xpcom-shutdown")) { obs->RemoveObserver(this, "xpcom-shutdown"); obs->RemoveObserver(this, "getUserMedia:response:allow"); obs->RemoveObserver(this, "getUserMedia:response:deny"); obs->RemoveObserver(this, "getUserMedia:revoke"); // Close off any remaining active windows. { MutexAutoLock lock(mMutex); GetActiveWindows()->Clear(); mActiveCallbacks.Clear(); sSingleton = nullptr; } return NS_OK; } if (!strcmp(aTopic, "getUserMedia:response:allow")) { nsString key(aData); nsRefPtr<nsRunnable> runnable; if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { return NS_OK; } mActiveCallbacks.Remove(key); if (aSubject) { // A particular device or devices were chosen by the user. // NOTE: does not allow setting a device to null; assumes nullptr GetUserMediaRunnable* gUMRunnable = static_cast<GetUserMediaRunnable*>(runnable.get()); nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject)); MOZ_ASSERT(array); uint32_t len = 0; array->Count(&len); MOZ_ASSERT(len); if (!len) { gUMRunnable->Denied(); // neither audio nor video were selected return NS_OK; } for (uint32_t i = 0; i < len; i++) { nsCOMPtr<nsISupports> supports; array->GetElementAt(i,getter_AddRefs(supports)); nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supports)); MOZ_ASSERT(device); // shouldn't be returning anything else... if (device) { nsString type; device->GetType(type); if (type.EqualsLiteral("video")) { gUMRunnable->SetVideoDevice(static_cast<MediaDevice*>(device.get())); } else if (type.EqualsLiteral("audio")) { gUMRunnable->SetAudioDevice(static_cast<MediaDevice*>(device.get())); } else { NS_WARNING("Unknown device type in getUserMedia"); } } } } // Reuse the same thread to save memory. mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); return NS_OK; } if (!strcmp(aTopic, "getUserMedia:response:deny")) { nsString key(aData); nsRefPtr<nsRunnable> runnable; if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { return NS_OK; } mActiveCallbacks.Remove(key); GetUserMediaRunnable* gUMRunnable = static_cast<GetUserMediaRunnable*>(runnable.get()); gUMRunnable->Denied(); return NS_OK; } 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); } return NS_OK; } return NS_OK; }
nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) { NS_ASSERTION(NS_IsMainThread(), "Observer invoked off the main thread"); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (!strcmp(aTopic, "xpcom-shutdown")) { obs->RemoveObserver(this, "xpcom-shutdown"); obs->RemoveObserver(this, "getUserMedia:response:allow"); obs->RemoveObserver(this, "getUserMedia:response:deny"); // Close off any remaining active windows. { MutexAutoLock lock(mMutex); GetActiveWindows()->Clear(); mActiveCallbacks.Clear(); sSingleton = nullptr; } return NS_OK; } if (!strcmp(aTopic, "getUserMedia:response:allow")) { nsString key(aData); nsRefPtr<nsRunnable> runnable; if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { return NS_OK; } mActiveCallbacks.Remove(key); if (aSubject) { // A particular device was chosen by the user. // NOTE: does not allow setting a device to null; assumes nullptr nsCOMPtr<nsIMediaDevice> device = do_QueryInterface(aSubject); if (device) { GetUserMediaRunnable* gUMRunnable = static_cast<GetUserMediaRunnable*>(runnable.get()); nsString type; device->GetType(type); if (type.EqualsLiteral("video")) { gUMRunnable->SetVideoDevice(static_cast<MediaDevice*>(device.get())); } else if (type.EqualsLiteral("audio")) { gUMRunnable->SetAudioDevice(static_cast<MediaDevice*>(device.get())); } else { NS_WARNING("Unknown device type in getUserMedia"); } } } // Reuse the same thread to save memory. mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); return NS_OK; } if (!strcmp(aTopic, "getUserMedia:response:deny")) { nsString key(aData); nsRefPtr<nsRunnable> runnable; if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { return NS_OK; } mActiveCallbacks.Remove(key); GetUserMediaRunnable* gUMRunnable = static_cast<GetUserMediaRunnable*>(runnable.get()); gUMRunnable->Denied(); return NS_OK; } return NS_OK; }