Title: [246215] trunk/Source/WebCore
Revision
246215
Author
you...@apple.com
Date
2019-06-07 15:12:25 -0700 (Fri, 07 Jun 2019)

Log Message

mediaDevices.enumerateDevices() doesn't list the system default audio devices with deviceId as "default"
https://bugs.webkit.org/show_bug.cgi?id=198577
<rdar://problem/51454067>

Reviewed by Eric Carlson.

Make the system default microphone/camera be the first in the list.
This ensures that getUserMedia without constraints will pick these devices.
This also ensures enumerateDevices will show these default devices as first in the list.
Make sure that a default device change will refresh the list.

For CoreAudioCaptureSource, we always add the default system input device in the list of capture devices.

Covered by manual testing.

* platform/mediastream/mac/AVCaptureDeviceManager.h:
* platform/mediastream/mac/AVCaptureDeviceManager.mm:
(WebCore::toCaptureDevice):
(WebCore::AVCaptureDeviceManager::isMatchingExistingCaptureDevice):
(WebCore::AVCaptureDeviceManager::refreshCaptureDevices):
* platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp:
(WebCore::getDefaultDeviceID):
(WebCore::CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (246214 => 246215)


--- trunk/Source/WebCore/ChangeLog	2019-06-07 21:49:28 UTC (rev 246214)
+++ trunk/Source/WebCore/ChangeLog	2019-06-07 22:12:25 UTC (rev 246215)
@@ -1,5 +1,31 @@
 2019-06-07  Youenn Fablet  <you...@apple.com>
 
+        mediaDevices.enumerateDevices() doesn't list the system default audio devices with deviceId as "default"
+        https://bugs.webkit.org/show_bug.cgi?id=198577
+        <rdar://problem/51454067>
+
+        Reviewed by Eric Carlson.
+
+        Make the system default microphone/camera be the first in the list.
+        This ensures that getUserMedia without constraints will pick these devices.
+        This also ensures enumerateDevices will show these default devices as first in the list.
+        Make sure that a default device change will refresh the list.
+
+        For CoreAudioCaptureSource, we always add the default system input device in the list of capture devices.
+
+        Covered by manual testing.
+
+        * platform/mediastream/mac/AVCaptureDeviceManager.h:
+        * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+        (WebCore::toCaptureDevice):
+        (WebCore::AVCaptureDeviceManager::isMatchingExistingCaptureDevice):
+        (WebCore::AVCaptureDeviceManager::refreshCaptureDevices):
+        * platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp:
+        (WebCore::getDefaultDeviceID):
+        (WebCore::CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices):
+
+2019-06-07  Youenn Fablet  <you...@apple.com>
+
         A MediaStreamTrack cannot modify whether being a capture track or not
         https://bugs.webkit.org/show_bug.cgi?id=198669
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h (246214 => 246215)


--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h	2019-06-07 21:49:28 UTC (rev 246214)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h	2019-06-07 22:12:25 UTC (rev 246215)
@@ -51,8 +51,6 @@
 
     static AVCaptureDeviceManager& singleton();
 
-    void deviceDisconnected(AVCaptureDevice*);
-
     void refreshCaptureDevices();
 
 protected:
@@ -64,6 +62,7 @@
     void registerForDeviceNotifications();
     Vector<CaptureDevice>& captureDevicesInternal();
     void updateCachedAVCaptureDevices();
+    bool isMatchingExistingCaptureDevice(AVCaptureDevice*);
 
     RetainPtr<WebCoreAVCaptureDeviceManagerObserver> m_objcObserver;
     Vector<CaptureDevice> m_devices;

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm (246214 => 246215)


--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm	2019-06-07 21:49:28 UTC (rev 246214)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm	2019-06-07 22:12:25 UTC (rev 246215)
@@ -122,6 +122,29 @@
 
 }
 
+static inline CaptureDevice toCaptureDevice(AVCaptureDevice *device)
+{
+    CaptureDevice captureDevice { device.uniqueID, CaptureDevice::DeviceType::Camera, device.localizedName };
+    captureDevice.setEnabled(deviceIsAvailable(device));
+    return captureDevice;
+}
+
+bool AVCaptureDeviceManager::isMatchingExistingCaptureDevice(AVCaptureDevice *device)
+{
+    auto existingCaptureDevice = captureDeviceFromPersistentID(device.uniqueID);
+    if (!existingCaptureDevice)
+        return false;
+
+    return deviceIsAvailable(device) == existingCaptureDevice.enabled();
+}
+
+static inline bool isDefaultVideoCaptureDeviceFirst(const Vector<CaptureDevice>& devices, const String& defaultDeviceID)
+{
+    if (devices.isEmpty())
+        return false;
+    return devices[0].persistentId() == defaultDeviceID;
+}
+
 void AVCaptureDeviceManager::refreshCaptureDevices()
 {
     if (!m_avCaptureDevices) {
@@ -131,22 +154,27 @@
 
     updateCachedAVCaptureDevices();
 
-    bool deviceHasChanged = false;
     auto* currentDevices = [PAL::getAVCaptureDeviceClass() devices];
     Vector<CaptureDevice> deviceList;
+
+    auto* defaultVideoDevice = [PAL::getAVCaptureDeviceClass() defaultDeviceWithMediaType: AVMediaTypeVideo];
+
+    bool deviceHasChanged = false;
+    if (defaultVideoDevice) {
+        deviceList.append(toCaptureDevice(defaultVideoDevice));
+        deviceHasChanged = !isDefaultVideoCaptureDeviceFirst(captureDevices(), defaultVideoDevice.uniqueID);
+    }
     for (AVCaptureDevice *platformDevice in currentDevices) {
-
         if (![platformDevice hasMediaType:AVMediaTypeVideo] && ![platformDevice hasMediaType:AVMediaTypeMuxed])
             continue;
 
-        CaptureDevice captureDevice(platformDevice.uniqueID, CaptureDevice::DeviceType::Camera, platformDevice.localizedName);
-        captureDevice.setEnabled(deviceIsAvailable(platformDevice));
-
-        CaptureDevice existingCaptureDevice = captureDeviceFromPersistentID(platformDevice.uniqueID);
-        if (!existingCaptureDevice || (existingCaptureDevice && existingCaptureDevice.type() == CaptureDevice::DeviceType::Camera && captureDevice.enabled() != existingCaptureDevice.enabled()))
+        if (!deviceHasChanged && !isMatchingExistingCaptureDevice(platformDevice))
             deviceHasChanged = true;
 
-        deviceList.append(WTFMove(captureDevice));
+        if (platformDevice.uniqueID == defaultVideoDevice.uniqueID)
+            continue;
+
+        deviceList.append(toCaptureDevice(platformDevice));
     }
 
     if (deviceHasChanged || m_devices.size() != deviceList.size()) {

Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp (246214 => 246215)


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp	2019-06-07 21:49:28 UTC (rev 246214)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureDeviceManager.cpp	2019-06-07 22:12:25 UTC (rev 246215)
@@ -102,6 +102,18 @@
     return !device.label().isEmpty() && !device.label().startsWith("VPAUAggregateAudioDevice");
 }
 
+static inline Optional<CoreAudioCaptureDevice> getDefaultCaptureInputDevice()
+{
+    AudioObjectPropertyAddress address { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+    UInt32 propertySize = sizeof(AudioDeviceID);
+    AudioDeviceID deviceID = kAudioDeviceUnknown;
+    auto err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &address, 0, nullptr, &propertySize, &deviceID);
+
+    if (err != noErr || deviceID == kAudioDeviceUnknown)
+        return { };
+    return CoreAudioCaptureDevice::create(deviceID);
+}
+
 Vector<CoreAudioCaptureDevice>& CoreAudioCaptureDeviceManager::coreAudioCaptureDevices()
 {
     static bool initialized;
@@ -128,7 +140,12 @@
         AudioObjectPropertyAddress address = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
         auto err = AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &address, dispatch_get_main_queue(), m_listenerBlock);
         if (err)
-            LOG_ERROR("CoreAudioCaptureDeviceManager::devices(%p) AudioObjectAddPropertyListener returned error %d (%.4s)", this, (int)err, (char*)&err);
+            LOG_ERROR("CoreAudioCaptureDeviceManager::devices(%p) AudioObjectAddPropertyListener for kAudioHardwarePropertyDevices returned error %d (%.4s)", this, (int)err, (char*)&err);
+
+        address = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+        err = AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &address, dispatch_get_main_queue(), m_listenerBlock);
+        if (err)
+            LOG_ERROR("CoreAudioCaptureDeviceManager::devices(%p) AudioObjectAddPropertyListener for kAudioHardwarePropertyDefaultInputDevice returned error %d (%.4s)", this, (int)err, (char*)&err);
     }
 
     return m_coreAudioCaptureDevices;
@@ -143,7 +160,6 @@
     return WTF::nullopt;
 }
 
-
 void CoreAudioCaptureDeviceManager::refreshAudioCaptureDevices(NotifyIfDevicesHaveChanged notify)
 {
     AudioObjectPropertyAddress address = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -162,7 +178,13 @@
         return;
     }
 
+    auto defaultInputDevice = getDefaultCaptureInputDevice();
     bool haveDeviceChanges = false;
+    if (defaultInputDevice && !m_coreAudioCaptureDevices.isEmpty() && m_coreAudioCaptureDevices.first().deviceID() != defaultInputDevice->deviceID()) {
+        m_coreAudioCaptureDevices = Vector<CoreAudioCaptureDevice>::from(WTFMove(*defaultInputDevice));
+        haveDeviceChanges = true;
+    }
+
     for (size_t i = 0; i < deviceCount; i++) {
         AudioObjectID deviceID = deviceIDs[i];
         if (!deviceHasInputStreams(deviceID))
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to