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 <[email protected]>
+ 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 <[email protected]>
+
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))