Unreviewed, rolling out r244627.
[WebKit-https.git] / Source / WebCore / platform / graphics / avfoundation / MediaSelectionGroupAVFObjC.mm
index b7fde8e..f782d8b 100644 (file)
 
 #if ENABLE(VIDEO_TRACK)
 
-#import "SoftLinking.h"
 #import <AVFoundation/AVAsset.h>
 #import <AVFoundation/AVMediaSelectionGroup.h>
 #import <AVFoundation/AVPlayerItem.h>
 #import <objc/runtime.h>
-#import <wtf/HashMap.h>
-#import <wtf/HashSet.h>
+#import <wtf/Language.h>
+#import <wtf/SoftLinking.h>
+#import <wtf/text/WTFString.h>
 
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 
 SOFT_LINK_CLASS(AVFoundation, AVMediaSelectionGroup)
 SOFT_LINK_CLASS(AVFoundation, AVMediaSelectionOption)
 
+#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
+#include <MediaAccessibility/MediaAccessibility.h>
+#include "MediaAccessibilitySoftLink.h"
+#endif
+
 namespace WebCore {
 
-PassRefPtr<MediaSelectionOptionAVFObjC> MediaSelectionOptionAVFObjC::create(MediaSelectionGroupAVFObjC& group, AVMediaSelectionOption *option)
+Ref<MediaSelectionOptionAVFObjC> MediaSelectionOptionAVFObjC::create(MediaSelectionGroupAVFObjC& group, AVMediaSelectionOption *option)
 {
-    return adoptRef(new MediaSelectionOptionAVFObjC(group, option));
+    return adoptRef(*new MediaSelectionOptionAVFObjC(group, option));
 }
 
 MediaSelectionOptionAVFObjC::MediaSelectionOptionAVFObjC(MediaSelectionGroupAVFObjC& group, AVMediaSelectionOption *option)
@@ -80,18 +85,17 @@ int MediaSelectionOptionAVFObjC::index() const
     return [[m_group->avMediaSelectionGroup() options] indexOfObject:m_mediaSelectionOption.get()];
 }
 
-PassRefPtr<MediaSelectionGroupAVFObjC> MediaSelectionGroupAVFObjC::create(AVPlayerItem *item, AVMediaSelectionGroup *group)
+Ref<MediaSelectionGroupAVFObjC> MediaSelectionGroupAVFObjC::create(AVPlayerItem *item, AVMediaSelectionGroup *group, const Vector<String>& characteristics)
 {
-    return adoptRef(new MediaSelectionGroupAVFObjC(item, group));
+    return adoptRef(*new MediaSelectionGroupAVFObjC(item, group, characteristics));
 }
 
-MediaSelectionGroupAVFObjC::MediaSelectionGroupAVFObjC(AVPlayerItem *item, AVMediaSelectionGroup *group)
+MediaSelectionGroupAVFObjC::MediaSelectionGroupAVFObjC(AVPlayerItem *item, AVMediaSelectionGroup *group, const Vector<String>& characteristics)
     : m_playerItem(item)
     , m_mediaSelectionGroup(group)
-    , m_selectedOption(nullptr)
-    , m_selectionTimer(this, &MediaSelectionGroupAVFObjC::selectionTimerFired)
+    , m_selectionTimer(*this, &MediaSelectionGroupAVFObjC::selectionTimerFired)
 {
-    updateOptions();
+    updateOptions(characteristics);
 }
 
 MediaSelectionGroupAVFObjC::~MediaSelectionGroupAVFObjC()
@@ -100,34 +104,68 @@ MediaSelectionGroupAVFObjC::~MediaSelectionGroupAVFObjC()
         option->clearGroup();
 }
 
-void MediaSelectionGroupAVFObjC::updateOptions()
+void MediaSelectionGroupAVFObjC::updateOptions(const Vector<String>& characteristics)
 {
     RetainPtr<NSSet> newAVOptions = adoptNS([[NSSet alloc] initWithArray:[getAVMediaSelectionGroupClass() playableMediaSelectionOptionsFromArray:[m_mediaSelectionGroup options]]]);
     RetainPtr<NSMutableSet> oldAVOptions = adoptNS([[NSMutableSet alloc] initWithCapacity:m_options.size()]);
     for (auto& avOption : m_options.keys())
-        [oldAVOptions addObject:avOption];
+        [oldAVOptions addObject:(__bridge AVMediaSelectionOption *)avOption];
 
-    RetainPtr<NSMutableSet> addedAVOptions = [newAVOptions mutableCopy];
+    RetainPtr<NSMutableSet> addedAVOptions = adoptNS([newAVOptions mutableCopy]);
     [addedAVOptions minusSet:oldAVOptions.get()];
 
-    RetainPtr<NSMutableSet> removedAVOptions = [oldAVOptions mutableCopy];
+    RetainPtr<NSMutableSet> removedAVOptions = adoptNS([oldAVOptions mutableCopy]);
     [removedAVOptions minusSet:newAVOptions.get()];
 
     for (AVMediaSelectionOption* removedAVOption in removedAVOptions.get()) {
         if (m_selectedOption && removedAVOption == m_selectedOption->avMediaSelectionOption())
             m_selectedOption = nullptr;
 
-        m_options.remove(removedAVOption);
+        m_options.remove((__bridge CFTypeRef)removedAVOption);
     }
-
+    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
     AVMediaSelectionOption* selectedOption = [m_playerItem selectedMediaOptionInMediaSelectionGroup:m_mediaSelectionGroup.get()];
-
+    ALLOW_DEPRECATED_DECLARATIONS_END
     for (AVMediaSelectionOption* addedAVOption in addedAVOptions.get()) {
-        RefPtr<MediaSelectionOptionAVFObjC> addedOption = MediaSelectionOptionAVFObjC::create(*this, addedAVOption);
+        auto addedOption = MediaSelectionOptionAVFObjC::create(*this, addedAVOption);
         if (addedAVOption == selectedOption)
-            m_selectedOption = addedOption.get();
-        m_options.set(addedAVOption, addedOption.release());
+            m_selectedOption = addedOption.ptr();
+        m_options.set((__bridge CFTypeRef)addedAVOption, WTFMove(addedOption));
     }
+
+    if (!m_shouldSelectOptionAutomatically)
+        return;
+
+    RetainPtr<NSMutableArray> nsLanguages = adoptNS([[NSMutableArray alloc] initWithCapacity:userPreferredLanguages().size()]);
+    for (auto& language : userPreferredLanguages())
+        [nsLanguages addObject:(NSString*)language];
+    NSArray* filteredOptions = [getAVMediaSelectionGroupClass() mediaSelectionOptionsFromArray:[m_mediaSelectionGroup options] filteredAndSortedAccordingToPreferredLanguages:nsLanguages.get()];
+
+    if (![filteredOptions count] && characteristics.isEmpty())
+        return;
+
+    // If no options match our language selection, search for matching characteristics across all the group's options
+    if (![filteredOptions count])
+        filteredOptions = [m_mediaSelectionGroup options];
+
+    RetainPtr<NSMutableArray> nsCharacteristics = adoptNS([[NSMutableArray alloc] initWithCapacity:characteristics.size()]);
+    for (auto& characteristic : characteristics)
+        [nsCharacteristics addObject:(NSString *)characteristic];
+
+    NSArray* optionsWithCharacteristics = [getAVMediaSelectionGroupClass() mediaSelectionOptionsFromArray:filteredOptions withMediaCharacteristics:nsCharacteristics.get()];
+    if (optionsWithCharacteristics && [optionsWithCharacteristics count])
+        filteredOptions = optionsWithCharacteristics;
+
+    if (![filteredOptions count])
+        return;
+
+    AVMediaSelectionOption* preferredOption = [filteredOptions objectAtIndex:0];
+    if (m_selectedOption && m_selectedOption->avMediaSelectionOption() == preferredOption)
+        return;
+
+    ASSERT(m_options.contains((__bridge CFTypeRef)preferredOption));
+    m_selectedOption = m_options.get((__bridge CFTypeRef)preferredOption);
+    m_selectionTimer.startOneShot(0_s);
 }
 
 void MediaSelectionGroupAVFObjC::setSelectedOption(MediaSelectionOptionAVFObjC* option)
@@ -135,13 +173,14 @@ void MediaSelectionGroupAVFObjC::setSelectedOption(MediaSelectionOptionAVFObjC*
     if (m_selectedOption == option)
         return;
 
+    m_shouldSelectOptionAutomatically = false;
     m_selectedOption = option;
     if (m_selectionTimer.isActive())
         m_selectionTimer.stop();
-    m_selectionTimer.startOneShot(0);
+    m_selectionTimer.startOneShot(0_s);
 }
 
-void MediaSelectionGroupAVFObjC::selectionTimerFired(Timer&)
+void MediaSelectionGroupAVFObjC::selectionTimerFired()
 {
     [m_playerItem selectMediaOption:(m_selectedOption ? m_selectedOption->avMediaSelectionOption() : nil) inMediaSelectionGroup:m_mediaSelectionGroup.get()];
 }