Skip to content

Commit

Permalink
Cherry-pick 49ad76e. rdar://problem/109220107
Browse files Browse the repository at this point in the history
    [iOS] AVCatpureDeviceManager should set userPreferrerCamera
    https://bugs.webkit.org/show_bug.cgi?id=256882
    rdar://109220107

    Reviewed by Eric Carlson.

    Before https://bugs.webkit.org/show_bug.cgi?id=255451, we were forcing the default camera to be the front camera using media constraints.
    This was blocking edfaulting to higher priority cameras, hence the fix.
    The drawback is that we are now fully relying on systemPreferredCamera to select the default camera.
    systemPreferredCamera might change depending on which camera was last used by the application.
    We do not want that behavior, so we use userPreferredCamera to state that we are more interested in the front camera than in the back cameras.
    Other camneras should still be higher priority if available.

    Manually tested.

    * Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h:
    * Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm:
    (WebCore::AVCaptureDeviceManager::computeCaptureDevices):
    (WebCore::AVCaptureDeviceManager::refreshCaptureDevicesInternal):
    (WebCore::AVCaptureDeviceManager::setUserPreferredCamera):
    (WebCore::AVCaptureDeviceManager::refreshCaptureDevices): Deleted.

    Canonical link: https://commits.webkit.org/264165@main

Identifier: 263769.41@safari-7616.1.14.10-branch
  • Loading branch information
youennf authored and MyahCobbs committed May 19, 2023
1 parent fe600fa commit bbc8deb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class AVCaptureDeviceManager final : public CaptureDeviceManager {
public:
static AVCaptureDeviceManager& singleton();

void refreshCaptureDevices(CompletionHandler<void()>&& = [] { });
void refreshCaptureDevices() { refreshCaptureDevicesInternal([] { }, ShouldSetUserPreferredCamera::No); };

private:
static bool isAvailable();
Expand All @@ -66,6 +66,10 @@ class AVCaptureDeviceManager final : public CaptureDeviceManager {
Vector<CaptureDevice> retrieveCaptureDevices();
RetainPtr<NSArray> currentCameras();

enum class ShouldSetUserPreferredCamera : bool { No, Yes };
void refreshCaptureDevicesInternal(CompletionHandler<void()>&&, ShouldSetUserPreferredCamera);
void setUserPreferredCamera();

RetainPtr<WebCoreAVCaptureDeviceManagerObserver> m_objcObserver;
Vector<CaptureDevice> m_devices;
RetainPtr<NSMutableArray> m_avCaptureDevices;
Expand Down
25 changes: 21 additions & 4 deletions Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ -(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary*)
void AVCaptureDeviceManager::computeCaptureDevices(CompletionHandler<void()>&& callback)
{
if (!m_isInitialized) {
refreshCaptureDevices([this, callback = WTFMove(callback)]() mutable {
refreshCaptureDevicesInternal([this, callback = WTFMove(callback)]() mutable {
m_isInitialized = true;
callback();
});
}, ShouldSetUserPreferredCamera::Yes);
return;
}
callback();
Expand Down Expand Up @@ -208,9 +208,11 @@ static inline bool isVideoDevice(AVCaptureDevice *device)
return deviceList;
}

void AVCaptureDeviceManager::refreshCaptureDevices(CompletionHandler<void()>&& callback)
void AVCaptureDeviceManager::refreshCaptureDevicesInternal(CompletionHandler<void()>&& callback, ShouldSetUserPreferredCamera shouldSetUserPreferredCamera)
{
m_dispatchQueue->dispatch([this, callback = WTFMove(callback)]() mutable {
m_dispatchQueue->dispatch([this, callback = WTFMove(callback), shouldSetUserPreferredCamera]() mutable {
if (shouldSetUserPreferredCamera == ShouldSetUserPreferredCamera::Yes)
setUserPreferredCamera();
RunLoop::main().dispatch([this, callback = WTFMove(callback), deviceList = crossThreadCopy(retrieveCaptureDevices())]() mutable {
bool deviceHasChanged = m_devices.size() != deviceList.size();
if (!deviceHasChanged) {
Expand Down Expand Up @@ -260,6 +262,21 @@ static inline bool isVideoDevice(AVCaptureDevice *device)
[PAL::getAVCaptureDeviceDiscoverySessionClass() removeObserver:m_objcObserver.get() forKeyPath:@"devices"];
}

void AVCaptureDeviceManager::setUserPreferredCamera()
{
#if PLATFORM(IOS_FAMILY)
if ([PAL::getAVCaptureDeviceClass() respondsToSelector:@selector(setUserPreferredCamera:)]) {
auto currentDevices = currentCameras();
for (AVCaptureDevice *platformDevice in currentDevices.get()) {
if (isVideoDevice(platformDevice) && [platformDevice position] == AVCaptureDevicePositionFront) {
[PAL::getAVCaptureDeviceClass() setUserPreferredCamera:platformDevice];
break;
}
}
}
#endif
}

void AVCaptureDeviceManager::registerForDeviceNotifications()
{
[[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() selector:@selector(deviceConnectedDidChange:) name:AVCaptureDeviceWasConnectedNotification object:nil];
Expand Down

0 comments on commit bbc8deb

Please sign in to comment.