diff --git a/accessible/ipc/win/HandlerProvider.h b/accessible/ipc/win/HandlerProvider.h index aba9df203dfb..b608c5260207 100644 --- a/accessible/ipc/win/HandlerProvider.h +++ b/accessible/ipc/win/HandlerProvider.h @@ -15,6 +15,7 @@ #include "mozilla/mscom/StructStream.h" #include "mozilla/Mutex.h" #include "mozilla/UniquePtr.h" +#include "HandlerData.h" struct NEWEST_IA2_INTERFACE; diff --git a/devtools/client/themes/rules.css b/devtools/client/themes/rules.css index 5d6fc004c454..e19c019d849a 100644 --- a/devtools/client/themes/rules.css +++ b/devtools/client/themes/rules.css @@ -402,7 +402,6 @@ } .ruleview-newproperty { - /* (enable checkbox width: 12px) + (expander width: 15px) */ margin-inline-start: -10px; } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 8ad34d69b539..45b795595477 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2385,6 +2385,17 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority, } } +#if defined(XP_WIN) + // Send the info needed to join the browser process's audio session. + nsID id; + nsString sessionName; + nsString iconPath; + if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName, + iconPath))) { + Unused << SendSetAudioSessionData(id, sessionName, iconPath); + } +#endif + #ifdef MOZ_CONTENT_SANDBOX bool shouldSandbox = true; MaybeFileDesc brokerFd = void_t(); @@ -2416,16 +2427,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority, KillHard("SandboxInitFailed"); } #endif -#if defined(XP_WIN) - // Send the info needed to join the browser process's audio session. - nsID id; - nsString sessionName; - nsString iconPath; - if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName, - iconPath))) { - Unused << SendSetAudioSessionData(id, sessionName, iconPath); - } -#endif { RefPtr swr = ServiceWorkerRegistrar::Get(); diff --git a/testing/geckodriver/CHANGES.md b/testing/geckodriver/CHANGES.md index c156162b02b6..282b1656bab7 100644 --- a/testing/geckodriver/CHANGES.md +++ b/testing/geckodriver/CHANGES.md @@ -8,9 +8,12 @@ Unreleased ### Added +- New `--jsdebugger` flag to open the Browser Toolbox when Firefox + launches. This is useful for debugging Marionette internals. + - Introduced the temporary, boolean capability - `moz:useNonSpecCompliantPointerOrigin` to - disable the WebDriver conforming behavior of calculating the Pointer Origin. + `moz:useNonSpecCompliantPointerOrigin` to disable the WebDriver + conforming behavior of calculating the Pointer Origin. ### Changed diff --git a/testing/geckodriver/README.md b/testing/geckodriver/README.md index f29f7a84a154..d596a2ec1a7a 100644 --- a/testing/geckodriver/README.md +++ b/testing/geckodriver/README.md @@ -570,6 +570,13 @@ A helpful trick is that it is possible to bind to 0 to get the system to atomically assign a free port. +#### --jsdebugger + +Attach [browser toolbox] debugger when Firefox starts. This is +useful for debugging [Marionette] internals. + +[browser toolbox]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Toolbox + #### -v[v] Increases the logging verbosity by to debug level when passing a single diff --git a/testing/geckodriver/src/main.rs b/testing/geckodriver/src/main.rs index 4902535470d6..3c645fb356df 100644 --- a/testing/geckodriver/src/main.rs +++ b/testing/geckodriver/src/main.rs @@ -123,6 +123,10 @@ fn app<'a, 'b>() -> App<'a, 'b> { .long("connect-existing") .requires("marionette_port") .help("Connect to an existing Firefox instance")) + .arg(Arg::with_name("jsdebugger") + .long("jsdebugger") + .takes_value(false) + .help("Attach browser toolbox debugger for Firefox")) .arg(Arg::with_name("verbosity") .short("v") .multiple(true) @@ -190,9 +194,10 @@ fn run() -> ProgramResult { let settings = MarionetteSettings { port: marionette_port, - binary: binary, + binary, + log_level, connect_existing: matches.is_present("connect_existing"), - log_level: log_level, + jsdebugger: matches.is_present("jsdebugger"), }; let handler = MarionetteHandler::new(settings); let listening = webdriver::server::start(addr, handler, &extension_routes()[..]) diff --git a/testing/geckodriver/src/marionette.rs b/testing/geckodriver/src/marionette.rs index e4d9ec78ca28..7d9c2b33d719 100644 --- a/testing/geckodriver/src/marionette.rs +++ b/testing/geckodriver/src/marionette.rs @@ -382,6 +382,10 @@ pub struct MarionetteSettings { pub binary: Option, pub connect_existing: bool, + /// Brings up the Browser Toolbox when starting Firefox, + /// letting you debug internals. + pub jsdebugger: bool, + /// Optionally increase Marionette's verbosity by providing a log /// level. The Gecko default is LogLevel::Info for optimised /// builds and LogLevel::Debug for debug builds. @@ -462,17 +466,20 @@ impl MarionetteHandler { let mut runner = FirefoxRunner::new(&binary, profile); + // https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting runner - // double-dashed flags are not accepted on Windows systems - .arg("-marionette") - // https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting .env("MOZ_CRASHREPORTER", "1") .env("MOZ_CRASHREPORTER_NO_REPORT", "1") .env("MOZ_CRASHREPORTER_SHUTDOWN", "1"); + // double-dashed flags are not accepted on Windows systems + runner.arg("-marionette"); + if self.settings.jsdebugger { + runner.arg("-jsdebugger"); + } if let Some(args) = options.args.as_ref() { runner.args(args); - }; + } let browser_proc = runner.start() .map_err(|e| { @@ -500,6 +507,14 @@ impl MarionetteHandler { prefs.insert_slice(&extra_prefs[..]); + if self.settings.jsdebugger { + prefs.insert("devtools.browsertoolbox.panel", Pref::new("jsdebugger".to_owned())); + prefs.insert("devtools.debugger.remote-enabled", Pref::new(true)); + prefs.insert("devtools.chrome.enabled", Pref::new(true)); + prefs.insert("devtools.debugger.prompt-connection", Pref::new(false)); + prefs.insert("marionette.debugging.clicktostart", Pref::new(true)); + } + if let Some(ref level) = self.current_log_level { prefs.insert("marionette.log.level", Pref::new(level.to_string())); }; diff --git a/widget/windows/AudioSession.cpp b/widget/windows/AudioSession.cpp index 9b06df81949d..6a222dcf39bc 100644 --- a/widget/windows/AudioSession.cpp +++ b/widget/windows/AudioSession.cpp @@ -20,6 +20,7 @@ #include "nsThreadUtils.h" #include "nsXULAppAPI.h" #include "mozilla/Attributes.h" +#include "mozilla/Mutex.h" #include @@ -54,6 +55,8 @@ public: STDMETHODIMP OnSessionDisconnected(AudioSessionDisconnectReason aReason); private: nsresult OnSessionDisconnectedInternal(); + nsresult CommitAudioSessionData(); + public: STDMETHODIMP OnSimpleVolumeChanged(float aVolume, BOOL aMute, @@ -86,6 +89,8 @@ protected: nsString mIconPath; nsID mSessionGroupingParameter; SessionState mState; + // Guards the IAudioSessionControl + mozilla::Mutex mMutex; ThreadSafeAutoRefCnt mRefCnt; NS_DECL_OWNINGTHREAD @@ -127,7 +132,8 @@ RecvAudioSessionData(const nsID& aID, AudioSession* AudioSession::sService = nullptr; -AudioSession::AudioSession() +AudioSession::AudioSession() : + mMutex("AudioSessionControl") { mState = UNINITIALIZED; } @@ -254,6 +260,7 @@ AudioSession::Start() return NS_ERROR_FAILURE; } + MutexAutoLock lock(mMutex); hr = manager->GetAudioSessionControl(&GUID_NULL, 0, getter_AddRefs(mAudioSessionControl)); @@ -262,25 +269,6 @@ AudioSession::Start() return NS_ERROR_FAILURE; } - hr = mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter, - nullptr); - if (FAILED(hr)) { - StopInternal(); - return NS_ERROR_FAILURE; - } - - hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr); - if (FAILED(hr)) { - StopInternal(); - return NS_ERROR_FAILURE; - } - - hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr); - if (FAILED(hr)) { - StopInternal(); - return NS_ERROR_FAILURE; - } - // Increments refcount of 'this'. hr = mAudioSessionControl->RegisterAudioSessionNotification(this); if (FAILED(hr)) { @@ -288,6 +276,11 @@ AudioSession::Start() return NS_ERROR_FAILURE; } + nsCOMPtr runnable = + NewRunnableMethod("AudioSession::CommitAudioSessionData", + this, &AudioSession::CommitAudioSessionData); + NS_DispatchToMainThread(runnable); + mState = STARTED; return NS_OK; @@ -296,6 +289,8 @@ AudioSession::Start() void AudioSession::StopInternal() { + mMutex.AssertCurrentThreadOwns(); + if (mAudioSessionControl && (mState == STARTED || mState == STOPPED)) { // Decrement refcount of 'this' @@ -318,6 +313,7 @@ AudioSession::Stop() RefPtr kungFuDeathGrip; kungFuDeathGrip.swap(sService); + MutexAutoLock lock(mMutex); StopInternal(); } @@ -374,6 +370,39 @@ AudioSession::SetSessionData(const nsID& aID, return NS_OK; } +nsresult +AudioSession::CommitAudioSessionData() +{ + MutexAutoLock lock(mMutex); + + if (!mAudioSessionControl) { + // Stop() was called before we had a chance to do this. + return NS_OK; + } + + HRESULT hr = + mAudioSessionControl->SetGroupingParam((LPGUID)&mSessionGroupingParameter, + nullptr); + if (FAILED(hr)) { + StopInternal(); + return NS_ERROR_FAILURE; + } + + hr = mAudioSessionControl->SetDisplayName(mDisplayName.get(), nullptr); + if (FAILED(hr)) { + StopInternal(); + return NS_ERROR_FAILURE; + } + + hr = mAudioSessionControl->SetIconPath(mIconPath.get(), nullptr); + if (FAILED(hr)) { + StopInternal(); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + STDMETHODIMP AudioSession::OnChannelVolumeChanged(DWORD aChannelCount, float aChannelVolumeArray[], @@ -419,15 +448,20 @@ AudioSession::OnSessionDisconnected(AudioSessionDisconnectReason aReason) nsresult AudioSession::OnSessionDisconnectedInternal() { - if (!mAudioSessionControl) - return NS_OK; + { + // We need to release the mutex before we call Start(). + MutexAutoLock lock(mMutex); - // When successful, UnregisterAudioSessionNotification will decrement the - // refcount of 'this'. Start will re-increment it. In the interim, - // we'll need to reference ourselves. - RefPtr kungFuDeathGrip(this); - mAudioSessionControl->UnregisterAudioSessionNotification(this); - mAudioSessionControl = nullptr; + if (!mAudioSessionControl) + return NS_OK; + + // When successful, UnregisterAudioSessionNotification will decrement the + // refcount of 'this'. Start will re-increment it. In the interim, + // we'll need to reference ourselves. + RefPtr kungFuDeathGrip(this); + mAudioSessionControl->UnregisterAudioSessionNotification(this); + mAudioSessionControl = nullptr; + } mState = AUDIO_SESSION_DISCONNECTED; CoUninitialize();