Bug 1531833 - When the input is voice, activate the global communication mode. r=pehrsons
authorPaul Adenot <paul@paul.cx>
Tue, 16 Apr 2019 15:42:42 +0000
changeset 469694 0a351368e1f7
parent 469693 d47604394f78
child 469695 c749a1823112
push id35879
push usernerli@mozilla.com
push dateTue, 16 Apr 2019 22:01:48 +0000
treeherdermozilla-central@12a60898fdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1531833
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1531833 - When the input is voice, activate the global communication mode. r=pehrsons Differential Revision: https://phabricator.services.mozilla.com/D21738
dom/media/CubebUtils.cpp
dom/media/CubebUtils.h
dom/media/GraphDriver.cpp
dom/media/webrtc/MediaEngineWebRTC.cpp
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -142,16 +142,24 @@ bool sCubebDisableDeviceSwitching = true
 #ifdef MOZ_CUBEB_REMOTING
 bool sCubebSandbox = false;
 size_t sAudioIPCPoolSize;
 size_t sAudioIPCStackSize;
 #endif
 StaticAutoPtr<char> sBrandName;
 StaticAutoPtr<char> sCubebBackendName;
 StaticAutoPtr<char> sCubebOutputDeviceName;
+#ifdef MOZ_WIDGET_ANDROID
+// Counts the number of time a request for switching to global "communication
+// mode" has been received. If this is > 0, global communication mode is to be
+// enabled. If it is 0, the global communication mode is to be disabled.
+// This allows to correctly track the global behaviour to adopt accross
+// asynchronous GraphDriver changes, on Android.
+int sInCommunicationCount = 0;
+#endif
 
 const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties";
 
 const char* AUDIOSTREAM_BACKEND_ID_STR[] = {
     "jack",  "pulse",       "alsa",  "audiounit", "audioqueue", "wasapi",
     "winmm", "directsound", "sndio", "opensl",    "audiotrack", "kai"};
 /* Index for failures to create an audio stream the first time. */
 const int CUBEB_BACKEND_INIT_FAILURE_FIRST =
@@ -306,17 +314,29 @@ cubeb* GetCubebContext() {
 void ForceSetCubebContext(cubeb* aCubebContext) {
   StaticMutexAutoLock lock(sMutex);
   sCubebContext = aCubebContext;
   sCubebState = CubebState::Initialized;
 }
 
 void SetInCommunication(bool aInCommunication) {
 #ifdef MOZ_WIDGET_ANDROID
-  java::GeckoAppShell::SetCommunicationAudioModeOn(aInCommunication);
+  StaticMutexAutoLock lock(sMutex);
+  if (aInCommunication) {
+    sInCommunicationCount++;
+  } else {
+    MOZ_ASSERT(sInCommunicationCount > 0);
+    sInCommunicationCount--;
+  }
+
+  if (sInCommunicationCount == 1) {
+    java::GeckoAppShell::SetCommunicationAudioModeOn(true);
+  } else if (sInCommunicationCount == 0) {
+    java::GeckoAppShell::SetCommunicationAudioModeOn(false);
+  }
 #endif
 }
 
 bool InitPreferredSampleRate() {
   StaticMutexAutoLock lock(sMutex);
   if (sPreferredSampleRate != 0) {
     return true;
   }
--- a/dom/media/CubebUtils.h
+++ b/dom/media/CubebUtils.h
@@ -8,16 +8,18 @@
 #  define CubebUtils_h_
 
 #  include "cubeb/cubeb.h"
 #  include "nsString.h"
 #  include "mozilla/RefPtr.h"
 
 class AudioDeviceInfo;
 
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(cubeb_stream_prefs)
+
 namespace mozilla {
 namespace CubebUtils {
 
 typedef cubeb_devid AudioDeviceID;
 
 // Initialize Audio Library. Some Audio backends require initializing the
 // library before using it.
 void InitLibrary();
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -490,26 +490,36 @@ AudioCallbackDriver::AudioCallbackDriver
   mInitShutdownThread->SetIdleThreadTimeout(
       PR_MillisecondsToInterval(kIdleThreadTimeoutMs));
 
 #if defined(XP_WIN)
   if (XRE_IsContentProcess()) {
     audio::AudioNotificationReceiver::Register(this);
   }
 #endif
+  if (aAudioInputType == AudioInputType::Voice) {
+    LOG(LogLevel::Debug, ("VOICE."));
+    mInputDevicePreference = CUBEB_DEVICE_PREF_VOICE;
+    CubebUtils::SetInCommunication(true);
+  } else {
+    mInputDevicePreference = CUBEB_DEVICE_PREF_ALL;
+  }
 }
 
 AudioCallbackDriver::~AudioCallbackDriver() {
   MOZ_ASSERT(mPromisesForOperation.IsEmpty());
   MOZ_ASSERT(!mAddedMixer);
 #if defined(XP_WIN)
   if (XRE_IsContentProcess()) {
     audio::AudioNotificationReceiver::Unregister(this);
   }
 #endif
+  if (mInputDevicePreference == CUBEB_DEVICE_PREF_VOICE) {
+    CubebUtils::SetInCommunication(false);
+  }
 }
 
 bool IsMacbookOrMacbookAir() {
 #ifdef XP_MACOSX
   size_t len = 0;
   sysctlbyname("hw.model", NULL, &len, NULL, 0);
   if (len) {
     UniquePtr<char[]> model(new char[len]);
@@ -585,16 +595,19 @@ bool AudioCallbackDriver::Init() {
 
   mBuffer = AudioCallbackBufferWrapper<AudioDataValue>(mOutputChannels);
   mScratchBuffer =
       SpillBuffer<AudioDataValue, WEBAUDIO_BLOCK_SIZE * 2>(mOutputChannels);
 
   output.channels = mOutputChannels;
   output.layout = CUBEB_LAYOUT_UNDEFINED;
   output.prefs = CubebUtils::GetDefaultStreamPrefs();
+  if (mInputDevicePreference == CUBEB_DEVICE_PREF_VOICE) {
+    output.prefs |= static_cast<cubeb_stream_prefs>(CUBEB_STREAM_PREF_VOICE);
+  }
 
   uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output);
 
   // Macbook and MacBook air don't have enough CPU to run very low latency
   // MediaStreamGraphs, cap the minimal latency to 512 frames int this case.
   if (IsMacbookOrMacbookAir()) {
     latency_frames = std::max((uint32_t)512, latency_frames);
   }
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -175,19 +175,24 @@ void MediaEngineWebRTC::EnumerateMicroph
       RefPtr<MediaDevice> device = MakeRefPtr<MediaDevice>(
           source, source->GetName(), NS_ConvertUTF8toUTF16(source->GetUUID()),
           source->GetGroupId(), NS_LITERAL_STRING(""));
       if (devices[i]->Preferred()) {
 #ifdef DEBUG
         if (!foundPreferredDevice) {
           foundPreferredDevice = true;
         } else {
+          // This is possible on windows, there is a default communication
+          // device, and a default device:
+          // See https://bugzilla.mozilla.org/show_bug.cgi?id=1542739
+#ifndef XP_WIN
           MOZ_ASSERT(!foundPreferredDevice,
                      "Found more than one preferred audio input device"
                      "while enumerating");
+#endif
         }
 #endif
         aDevices->InsertElementAt(0, device);
       } else {
         aDevices->AppendElement(device);
       }
     }
   }