[iOS] AirPlay device name is sometimes wrong
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2018 14:55:42 +0000 (14:55 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2018 14:55:42 +0000 (14:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184543
<rdar://problem/39105498>

Reviewed by Jer Noble.

Source/WebCore:

No new tests, this can only be tested with a specific hardware setup.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::exernalDeviceDisplayNameForPlayer): Get the device name from the AVOutputContext
when possible.

Source/WebCore/PAL:

* pal/spi/mac/AVFoundationSPI.h: Declare more AVOutputContext SPI.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230708 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

index d45ae7b..d79e202 100644 (file)
@@ -1,3 +1,17 @@
+2018-04-17  Eric Carlson  <eric.carlson@apple.com>
+
+        [iOS] AirPlay device name is sometimes wrong
+        https://bugs.webkit.org/show_bug.cgi?id=184543
+        <rdar://problem/39105498>
+
+        Reviewed by Jer Noble.
+
+        No new tests, this can only be tested with a specific hardware setup.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::exernalDeviceDisplayNameForPlayer): Get the device name from the AVOutputContext
+        when possible.
+
 2018-04-17  Carlos Alberto Lopez Perez  <clopez@igalia.com>
 
         [GTK] Build fix after r230529 (WaylandCompositorDisplay leaks its wl_display)
index 30e790d..eed87a0 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-17  Eric Carlson  <eric.carlson@apple.com>
+
+        [iOS] AirPlay device name is sometimes wrong
+        https://bugs.webkit.org/show_bug.cgi?id=184543
+        <rdar://problem/39105498>
+
+        Reviewed by Jer Noble.
+
+        * pal/spi/mac/AVFoundationSPI.h: Declare more AVOutputContext SPI.
+
 2018-04-16  Brent Fulgham  <bfulgham@apple.com>
 
         [macOS] Don't establish unneeded Dock connections
index 2cb7cf9..23ed4e2 100644 (file)
@@ -31,7 +31,7 @@
 #if USE(APPLE_INTERNAL_SDK)
 
 #import <AVFoundation/AVAssetCache_Private.h>
-#import <AVFoundation/AVOutputContext.h>
+#import <AVFoundation/AVOutputContext_Private.h>
 #import <AVFoundation/AVPlayerItem_Private.h>
 #import <AVFoundation/AVPlayerLayer_Private.h>
 #import <AVFoundation/AVPlayer_Private.h>
@@ -58,23 +58,39 @@ NS_ASSUME_NONNULL_BEGIN
 NS_ASSUME_NONNULL_END
 #endif // (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000)
 
-#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) || PLATFORM(IOS)
 
 NS_ASSUME_NONNULL_BEGIN
 
 @class AVOutputContext;
+@class AVOutputDevice;
 @interface AVOutputContext : NSObject <NSSecureCoding>
 @property (nonatomic, readonly) NSString *deviceName;
 + (instancetype)outputContext;
++ (nullable AVOutputContext *)sharedAudioPresentationOutputContext;
+@property (readonly) BOOL supportsMultipleOutputDevices;
+@property (readonly) NSArray<AVOutputDevice *> *outputDevices;
 @end
 
+#if !PLATFORM(IOS)
 @interface AVPlayer (AVPlayerExternalPlaybackSupportPrivate)
 @property (nonatomic, retain) AVOutputContext *outputContext;
 @end
+#else
+typedef NS_ENUM(NSInteger, AVPlayerExternalPlaybackType) {
+    AVPlayerExternalPlaybackTypeNone,
+    AVPlayerExternalPlaybackTypeAirPlay,
+    AVPlayerExternalPlaybackTypeTVOut,
+};
+
+@interface AVPlayer (AVPlayerExternalPlaybackSupportPrivate)
+@property (nonatomic, readonly) AVPlayerExternalPlaybackType externalPlaybackType;
+@end
+#endif
 
 NS_ASSUME_NONNULL_END
 
-#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) || PLATFORM(IOS)
 
 #import <AVFoundation/AVAssetCache.h>
 NS_ASSUME_NONNULL_BEGIN
@@ -95,18 +111,6 @@ NS_ASSUME_NONNULL_END
 
 #endif // PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
 
-#if PLATFORM(IOS)
-typedef NS_ENUM(NSInteger, AVPlayerExternalPlaybackType) {
-    AVPlayerExternalPlaybackTypeNone,
-    AVPlayerExternalPlaybackTypeAirPlay,
-    AVPlayerExternalPlaybackTypeTVOut,
-};
-
-@interface AVPlayer (AVPlayerExternalPlaybackSupportPrivate)
-@property (nonatomic, readonly) AVPlayerExternalPlaybackType externalPlaybackType;
-@end
-#endif
-
 #if !PLATFORM(IOS)
 
 #pragma mark -
index 0804b02..a8037ec 100644 (file)
@@ -37,8 +37,9 @@
 #import <pal/spi/mac/AVFoundationSPI.h>
 #import <wtf/MainThread.h>
 
-typedef AVOutputContext AVOutputContextType;
-typedef AVOutputDeviceMenuController AVOutputDeviceMenuControllerType;
+typedef AVOutputContext AVOutputContextWKType;
+typedef AVOutputDeviceMenuController AVOutputDeviceMenuControllerWKType;
+
 
 SOFTLINK_AVKIT_FRAMEWORK()
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
@@ -86,7 +87,7 @@ Ref<MediaPlaybackTarget> MediaPlaybackTargetPickerMac::playbackTarget()
     return WebCore::MediaPlaybackTargetMac::create(context);
 }
 
-AVOutputDeviceMenuControllerType *MediaPlaybackTargetPickerMac::devicePicker()
+AVOutputDeviceMenuControllerWKType *MediaPlaybackTargetPickerMac::devicePicker()
 {
     if (!getAVOutputDeviceMenuControllerClass())
         return nullptr;
@@ -94,7 +95,7 @@ AVOutputDeviceMenuControllerType *MediaPlaybackTargetPickerMac::devicePicker()
     if (!m_outputDeviceMenuController) {
         LOG(Media, "MediaPlaybackTargetPickerMac::devicePicker - allocating picker");
 
-        RetainPtr<AVOutputContextType> context = adoptNS([allocAVOutputContextInstance() init]);
+        RetainPtr<AVOutputContextWKType> context = adoptNS([allocAVOutputContextInstance() init]);
         m_outputDeviceMenuController = adoptNS([allocAVOutputDeviceMenuControllerInstance() initWithOutputContext:context.get()]);
 
         [m_outputDeviceMenuController.get() addObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDeviceAvailableKeyName options:NSKeyValueObservingOptionNew context:nullptr];
index 6a12f28..7368f2a 100644 (file)
@@ -222,6 +222,7 @@ typedef AVMediaSelectionOption AVMediaSelectionOptionType;
 SOFT_LINK_CLASS(AVFoundation, AVPlayerItemLegibleOutput)
 SOFT_LINK_CLASS(AVFoundation, AVMediaSelectionGroup)
 SOFT_LINK_CLASS(AVFoundation, AVMediaSelectionOption)
+SOFT_LINK_CLASS(AVFoundation, AVOutputContext)
 
 SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicLegible, NSString *)
 SOFT_LINK_POINTER(AVFoundation, AVMediaTypeSubtitle, NSString *)
@@ -2787,11 +2788,26 @@ MediaPlayer::WirelessPlaybackTargetType MediaPlayerPrivateAVFoundationObjC::wire
 static NSString *exernalDeviceDisplayNameForPlayer(AVPlayerType *player)
 {
 #if HAVE(CELESTIAL)
-    NSString *displayName = nil;
-
     if (!AVFoundationLibrary())
         return nil;
 
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+    if ([getAVOutputContextClass() respondsToSelector:@selector(sharedAudioPresentationOutputContext)]) {
+        AVOutputContext *outputContext = [getAVOutputContextClass() sharedAudioPresentationOutputContext];
+
+        if (![outputContext respondsToSelector:@selector(supportsMultipleOutputDevices)]
+            || ![outputContext supportsMultipleOutputDevices]
+            || ![outputContext respondsToSelector:@selector(outputDevices)])
+            return [outputContext deviceName];
+
+        auto outputDeviceNames = adoptNS([[NSMutableArray alloc] init]);
+        for (AVOutputDevice *outputDevice in [outputContext outputDevices])
+            [outputDeviceNames addObject:[[outputDevice name] copy]];
+
+        return [outputDeviceNames componentsJoinedByString:@" + "];
+    }
+#endif
+
     if (player.externalPlaybackType != AVPlayerExternalPlaybackTypeAirPlay)
         return nil;
 
@@ -2799,6 +2815,7 @@ static NSString *exernalDeviceDisplayNameForPlayer(AVPlayerType *player)
     if (!pickableRoutes.count)
         return nil;
 
+    NSString *displayName = nil;
     for (NSDictionary *pickableRoute in pickableRoutes) {
         if (![pickableRoute[AVController_RouteDescriptionKey_RouteCurrentlyPicked] boolValue])
             continue;