mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 797796: Hookup getUserMedia backend with frontend UI; r=jesup
This commit is contained in:
parent
8c1c3fe18b
commit
2fa83b8747
@ -7,9 +7,13 @@
|
||||
#include "MediaStreamGraph.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIPopupWindowManager.h"
|
||||
|
||||
// For PR_snprintf
|
||||
#include "prprf.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@ -385,6 +389,29 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Denied()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
|
||||
error->OnError(NS_LITERAL_STRING("PERMISSION_DENIED"));
|
||||
} else {
|
||||
NS_DispatchToMainThread(new ErrorCallbackRunnable(
|
||||
mSuccess, mError, NS_LITERAL_STRING("PERMISSION_DENIED"), mWindowID
|
||||
));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SetDevice(MediaDevice* aDevice)
|
||||
{
|
||||
mDevice = aDevice;
|
||||
mDeviceChosen = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SelectDevice()
|
||||
{
|
||||
@ -627,16 +654,6 @@ MediaManager::GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* UI integration point. Check for permission with the user!
|
||||
* No UI for picture:true here, since user permission is implied by the
|
||||
* preview dialog that will be shown by GetUserMediaRunnable in SendPicture.
|
||||
*/
|
||||
if (!aPrivileged && !picture) {
|
||||
// To be filled in by code from bug 729522. If permission is denied, call
|
||||
// onError, and do not continue.
|
||||
}
|
||||
|
||||
// Store the WindowID in a hash table and mark as active. The entry is removed
|
||||
// when this window is closed or navigated away from.
|
||||
uint64_t windowID = aWindow->WindowID();
|
||||
@ -655,7 +672,7 @@ MediaManager::GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
|
||||
*
|
||||
* If a fake stream was requested, we force the use of the default backend.
|
||||
*/
|
||||
nsCOMPtr<nsIRunnable> gUMRunnable;
|
||||
nsRefPtr<GetUserMediaRunnable> gUMRunnable;
|
||||
if (fake) {
|
||||
// Fake stream from default backend.
|
||||
gUMRunnable = new GetUserMediaRunnable(
|
||||
@ -679,15 +696,50 @@ MediaManager::GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
|
||||
if (picture) {
|
||||
// ShowFilePickerForMimeType() must run on the Main Thread! (on Android)
|
||||
NS_DispatchToMainThread(gUMRunnable);
|
||||
} else {
|
||||
// Reuse the same thread to save memory.
|
||||
} else if (aPrivileged) {
|
||||
if (!mMediaThread) {
|
||||
rv = NS_NewThread(getter_AddRefs(mMediaThread));
|
||||
nsresult rv = NS_NewThread(getter_AddRefs(mMediaThread));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mMediaThread->Dispatch(gUMRunnable, NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
// Ask for user permission, and dispatch runnable (or not) when a response
|
||||
// is received via an observer notification. Each call is paired with its
|
||||
// runnable by a GUID.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Generate a call ID.
|
||||
nsID id;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char buffer[NSID_LENGTH];
|
||||
id.ToProvidedString(buffer);
|
||||
NS_ConvertUTF8toUTF16 callID(buffer);
|
||||
|
||||
// Store the current callback.
|
||||
mActiveCallbacks.Put(callID, gUMRunnable);
|
||||
|
||||
// Construct JSON structure with both the windowID and the callID.
|
||||
nsAutoString data;
|
||||
data.Append(NS_LITERAL_STRING("{\"windowID\":"));
|
||||
|
||||
// Convert window ID to string.
|
||||
char windowBuffer[32];
|
||||
PR_snprintf(windowBuffer, 32, "%llu", aWindow->GetOuterWindow()->WindowID());
|
||||
data.Append(NS_ConvertUTF8toUTF16(windowBuffer));
|
||||
|
||||
data.Append(NS_LITERAL_STRING(", \"callID\":\""));
|
||||
data.Append(callID);
|
||||
data.Append(NS_LITERAL_STRING("\"}"));
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
obs->NotifyObservers(aParams, "getUserMedia:request", data.get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -762,16 +814,62 @@ nsresult
|
||||
MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
if (strcmp(aTopic, "xpcom-shutdown")) {
|
||||
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.
|
||||
mActiveWindows.Clear();
|
||||
mActiveCallbacks.Clear();
|
||||
sSingleton = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->RemoveObserver(this, "xpcom-shutdown");
|
||||
if (!strcmp(aTopic, "getUserMedia:response:allow")) {
|
||||
nsString key(aData);
|
||||
nsRefPtr<nsRunnable> runnable;
|
||||
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Close off any remaining active windows.
|
||||
mActiveWindows.Clear();
|
||||
sSingleton = nullptr;
|
||||
// Reuse the same thread to save memory.
|
||||
if (!mMediaThread) {
|
||||
nsresult rv = NS_NewThread(getter_AddRefs(mMediaThread));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (aSubject) {
|
||||
// A particular device was chosen by the user.
|
||||
nsCOMPtr<nsIMediaDevice> device = do_QueryInterface(aSubject);
|
||||
if (device) {
|
||||
GetUserMediaRunnable* gUMRunnable =
|
||||
static_cast<GetUserMediaRunnable*>(runnable.get());
|
||||
gUMRunnable->SetDevice(static_cast<MediaDevice*>(device.get()));
|
||||
}
|
||||
}
|
||||
|
||||
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
mActiveCallbacks.Remove(key);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!strcmp(aTopic, "getUserMedia:response:deny")) {
|
||||
nsString key(aData);
|
||||
nsRefPtr<nsRunnable> runnable;
|
||||
if (mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
|
||||
GetUserMediaRunnable* gUMRunnable =
|
||||
static_cast<GetUserMediaRunnable*>(runnable.get());
|
||||
gUMRunnable->Denied();
|
||||
mActiveCallbacks.Remove(key);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsObserverService.h"
|
||||
|
||||
#include "nsPIDOMWindow.h"
|
||||
@ -151,6 +152,8 @@ public:
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
obs->AddObserver(sSingleton, "xpcom-shutdown", false);
|
||||
obs->AddObserver(sSingleton, "getUserMedia:response:allow", false);
|
||||
obs->AddObserver(sSingleton, "getUserMedia:response:deny", false);
|
||||
}
|
||||
return sSingleton;
|
||||
}
|
||||
@ -176,6 +179,7 @@ private:
|
||||
: mBackend(nullptr)
|
||||
, mMediaThread(nullptr) {
|
||||
mActiveWindows.Init();
|
||||
mActiveCallbacks.Init();
|
||||
};
|
||||
MediaManager(MediaManager const&) {};
|
||||
|
||||
@ -186,6 +190,7 @@ private:
|
||||
MediaEngine* mBackend;
|
||||
nsCOMPtr<nsIThread> mMediaThread;
|
||||
WindowTable mActiveWindows;
|
||||
nsRefPtrHashtable<nsStringHashKey, nsRunnable> mActiveCallbacks;
|
||||
|
||||
static nsRefPtr<MediaManager> sSingleton;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user