[iOS] Make sure the first camera device in the list is the front camera
https://bugs.webkit.org/show_bug.cgi?id=199811
<rdar://problem/53125157>

Reviewed by Jer Noble.

Some websites call getUserMedia with a deviceId constraint and theey pick the
first deviceId in the list provided by enumerateDevices.
On iOS, this is the back camera which is often not what is expected by WebRTC applications.
Instead, make sure the first camera device is the front camera.

Manually tested.

* platform/mediastream/mac/AVCaptureDeviceManager.mm:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@247489 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 38100a6..8e92e15 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,20 @@
+2019-07-16  Youenn Fablet  <youenn@apple.com>
+
+        [iOS] Make sure the first camera device in the list is the front camera
+        https://bugs.webkit.org/show_bug.cgi?id=199811
+        <rdar://problem/53125157>
+
+        Reviewed by Jer Noble.
+
+        Some websites call getUserMedia with a deviceId constraint and theey pick the
+        first deviceId in the list provided by enumerateDevices.
+        On iOS, this is the back camera which is often not what is expected by WebRTC applications.
+        Instead, make sure the first camera device is the front camera.
+
+        Manually tested.
+
+        * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+
 2019-07-16  Chris Dumez  <cdumez@apple.com>
 
         Speed up StorageManager::getValues()
diff --git a/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm b/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm
index 50e4596..2fdc866 100644
--- a/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm
+++ b/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm
@@ -145,6 +145,11 @@
     return devices[0].persistentId() == defaultDeviceID;
 }
 
+static inline bool isVideoDevice(AVCaptureDevice *device)
+{
+    return [device hasMediaType:AVMediaTypeVideo] || [device hasMediaType:AVMediaTypeMuxed];
+}
+
 void AVCaptureDeviceManager::refreshCaptureDevices()
 {
     if (!m_avCaptureDevices) {
@@ -158,6 +163,20 @@
     Vector<CaptureDevice> deviceList;
 
     auto* defaultVideoDevice = [PAL::getAVCaptureDeviceClass() defaultDeviceWithMediaType: AVMediaTypeVideo];
+#if PLATFORM(IOS)
+    if ([defaultVideoDevice position] != AVCaptureDevicePositionFront) {
+        defaultVideoDevice = nullptr;
+        for (AVCaptureDevice *platformDevice in currentDevices) {
+            if (!isVideoDevice(platformDevice))
+                continue;
+
+            if ([platformDevice position] == AVCaptureDevicePositionFront) {
+                defaultVideoDevice = platformDevice;
+                break;
+            }
+        }
+    }
+#endif
 
     bool deviceHasChanged = false;
     if (defaultVideoDevice) {
@@ -165,7 +184,7 @@
         deviceHasChanged = !isDefaultVideoCaptureDeviceFirst(captureDevices(), defaultVideoDevice.uniqueID);
     }
     for (AVCaptureDevice *platformDevice in currentDevices) {
-        if (![platformDevice hasMediaType:AVMediaTypeVideo] && ![platformDevice hasMediaType:AVMediaTypeMuxed])
+        if (!isVideoDevice(platformDevice))
             continue;
 
         if (!deviceHasChanged && !isMatchingExistingCaptureDevice(platformDevice))