Prevent crash when accessing WebAVPlayerController.delegate.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Feb 2015 19:40:57 +0000 (19:40 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Feb 2015 19:40:57 +0000 (19:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140893

Patch by Jeremy Jones <jeremyj@apple.com> on 2015-02-02
Reviewed by Darin Adler.

Source/WebCore:

This patch aims to prevent a null delegate access during invalidation by adding null checks before accessing the delegate, by making explicit the recreation of m_playerController, and by consolidating and correcting the teardown sequence.

* WebCore.exp.in:
* platform/ios/WebVideoFullscreenInterface.h: add resetMediaState()
* platform/ios/WebVideoFullscreenInterfaceAVKit.h: ditto.
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(-[WebAVPlayerController playerViewController:shouldExitFullScreenWithReason:]): Check for null before accessing delegate.
(-[WebAVPlayerController play:]): ditto.
(-[WebAVPlayerController pause:]): ditto.
(-[WebAVPlayerController togglePlayback:]): ditto.
(-[WebAVPlayerController setPlaying:]): ditto.
(-[WebAVPlayerController beginScrubbing:]): ditto.
(-[WebAVPlayerController endScrubbing:]): ditto.
(-[WebAVPlayerController seekToTime:]): ditto.
(-[WebAVPlayerController beginScanningForward:]): ditto.
(-[WebAVPlayerController endScanningForward:]): ditto.
(-[WebAVPlayerController beginScanningBackward:]): ditto.
(-[WebAVPlayerController endScanningBackward:]): ditto.
(-[WebAVPlayerController seekToBeginning:]): ditto.
(-[WebAVPlayerController seekToEnd:]): ditto.
(-[WebAVPlayerController setCurrentAudioMediaSelectionOption:]): ditto.
(-[WebAVPlayerController setCurrentLegibleMediaSelectionOption:]): ditto.
(-[WebAVPlayerController layoutSublayersOfLayer:]): ditto.
(WebVideoFullscreenInterfaceAVKit::WebVideoFullscreenInterfaceAVKit): initialize m_playerController
(WebVideoFullscreenInterfaceAVKit::resetMediaState): Added.
(WebVideoFullscreenInterfaceAVKit::setDuration): remove playerController()
(WebVideoFullscreenInterfaceAVKit::setCurrentTime): ditto.
(WebVideoFullscreenInterfaceAVKit::setRate): ditto.
(WebVideoFullscreenInterfaceAVKit::setVideoDimensions): ditto.
(WebVideoFullscreenInterfaceAVKit::setSeekableRanges): ditto.
(WebVideoFullscreenInterfaceAVKit::setCanPlayFastReverse): ditto.
(WebVideoFullscreenInterfaceAVKit::setAudioMediaSelectionOptions): ditto.
(WebVideoFullscreenInterfaceAVKit::setLegibleMediaSelectionOptions): ditto.
(WebVideoFullscreenInterfaceAVKit::setExternalPlayback): ditto.
(WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal): ditto.
(WebVideoFullscreenInterfaceAVKit::enterFullscreenStandard): ditto.
(WebVideoFullscreenInterfaceAVKit::cleanupFullscreenInternal): consolidated cleanup code from invalidate()
(WebVideoFullscreenInterfaceAVKit::invalidate): consolidate cleanup code.
(WebVideoFullscreenInterfaceAVKit::playerController): Deleted.
* platform/ios/WebVideoFullscreenModelVideoElement.mm:
(WebVideoFullscreenModelVideoElement::setVideoElement): call resetMediaState()

Source/WebKit2:

Plumb new resetMediaState() through IPC interface WebVideoFullscreenManagerProxy.

* UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
* UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
(WebKit::WebVideoFullscreenManagerProxy::invalidate): remove redundant set to nullptr.
* WebProcess/ios/WebVideoFullscreenManager.h:
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::resetMediaState):

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

Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/platform/ios/WebVideoFullscreenInterface.h
Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.h
Source/WebCore/platform/ios/WebVideoFullscreenInterfaceAVKit.mm
Source/WebCore/platform/ios/WebVideoFullscreenModelVideoElement.mm
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in
Source/WebKit2/UIProcess/ios/WebVideoFullscreenManagerProxy.mm
Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.h
Source/WebKit2/WebProcess/ios/WebVideoFullscreenManager.mm

index 10b49f1..3cfeea4 100644 (file)
@@ -1,3 +1,52 @@
+2015-02-02  Jeremy Jones  <jeremyj@apple.com>
+
+        Prevent crash when accessing WebAVPlayerController.delegate.
+        https://bugs.webkit.org/show_bug.cgi?id=140893
+
+        Reviewed by Darin Adler.
+
+        This patch aims to prevent a null delegate access during invalidation by adding null checks before accessing the delegate, by making explicit the recreation of m_playerController, and by consolidating and correcting the teardown sequence.
+
+        * WebCore.exp.in:
+        * platform/ios/WebVideoFullscreenInterface.h: add resetMediaState()
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.h: ditto.
+        * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+        (-[WebAVPlayerController playerViewController:shouldExitFullScreenWithReason:]): Check for null before accessing delegate.
+        (-[WebAVPlayerController play:]): ditto.
+        (-[WebAVPlayerController pause:]): ditto.
+        (-[WebAVPlayerController togglePlayback:]): ditto.
+        (-[WebAVPlayerController setPlaying:]): ditto.
+        (-[WebAVPlayerController beginScrubbing:]): ditto.
+        (-[WebAVPlayerController endScrubbing:]): ditto.
+        (-[WebAVPlayerController seekToTime:]): ditto.
+        (-[WebAVPlayerController beginScanningForward:]): ditto.
+        (-[WebAVPlayerController endScanningForward:]): ditto.
+        (-[WebAVPlayerController beginScanningBackward:]): ditto.
+        (-[WebAVPlayerController endScanningBackward:]): ditto.
+        (-[WebAVPlayerController seekToBeginning:]): ditto.
+        (-[WebAVPlayerController seekToEnd:]): ditto.
+        (-[WebAVPlayerController setCurrentAudioMediaSelectionOption:]): ditto.
+        (-[WebAVPlayerController setCurrentLegibleMediaSelectionOption:]): ditto.
+        (-[WebAVPlayerController layoutSublayersOfLayer:]): ditto.
+        (WebVideoFullscreenInterfaceAVKit::WebVideoFullscreenInterfaceAVKit): initialize m_playerController
+        (WebVideoFullscreenInterfaceAVKit::resetMediaState): Added.
+        (WebVideoFullscreenInterfaceAVKit::setDuration): remove playerController()
+        (WebVideoFullscreenInterfaceAVKit::setCurrentTime): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setRate): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setVideoDimensions): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setSeekableRanges): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setCanPlayFastReverse): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setAudioMediaSelectionOptions): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setLegibleMediaSelectionOptions): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setExternalPlayback): ditto.
+        (WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal): ditto.
+        (WebVideoFullscreenInterfaceAVKit::enterFullscreenStandard): ditto.
+        (WebVideoFullscreenInterfaceAVKit::cleanupFullscreenInternal): consolidated cleanup code from invalidate()
+        (WebVideoFullscreenInterfaceAVKit::invalidate): consolidate cleanup code.
+        (WebVideoFullscreenInterfaceAVKit::playerController): Deleted.
+        * platform/ios/WebVideoFullscreenModelVideoElement.mm:
+        (WebVideoFullscreenModelVideoElement::setVideoElement): call resetMediaState()
+
 2015-02-02  Darin Adler  <darin@apple.com>
 
         REGRESSION (r170576): Storage leaks in parsing of CSS image sizes
index a8ac87b..e4a421b 100644 (file)
@@ -3483,6 +3483,7 @@ __ZN7WebCore32WebVideoFullscreenInterfaceAVKit11setDurationEd
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit14exitFullscreenENS_7IntRectE
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit14setCurrentTimeEdd
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit15enterFullscreenEv
+__ZN7WebCore32WebVideoFullscreenInterfaceAVKit15resetMediaStateEv
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit15setupFullscreenER7CALayerNS_7IntRectEP6UIViewjb
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit17cleanupFullscreenEv
 __ZN7WebCore32WebVideoFullscreenInterfaceAVKit17setSeekableRangesERKNS_10TimeRangesE
index d457e4f..64c8716 100644 (file)
@@ -44,6 +44,7 @@ public:
     enum ExternalPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
     
     virtual ~WebVideoFullscreenInterface() { };
+    virtual void resetMediaState() = 0;
     virtual void setDuration(double) = 0;
     virtual void setCurrentTime(double currentTime, double anchorTime) = 0;
     virtual void setRate(bool isPlaying, float playbackRate) = 0;
index 3f71ba2..af95147 100644 (file)
@@ -73,6 +73,7 @@ public:
     WEBCORE_EXPORT void setWebVideoFullscreenModel(WebVideoFullscreenModel*);
     WEBCORE_EXPORT void setWebVideoFullscreenChangeObserver(WebVideoFullscreenChangeObserver*);
     
+    WEBCORE_EXPORT virtual void resetMediaState() override;
     WEBCORE_EXPORT virtual void setDuration(double) override;
     WEBCORE_EXPORT virtual void setCurrentTime(double currentTime, double anchorTime) override;
     WEBCORE_EXPORT virtual void setRate(bool isPlaying, float playbackRate) override;
@@ -95,6 +96,7 @@ public:
     bool mayAutomaticallyShowVideoOptimized();
 
 protected:
+    void beginSession();
     void setupFullscreenInternal(PlatformLayer&, IntRect initialRect, UIView *, HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
     void enterFullscreenOptimized();
     void enterFullscreenStandard();
@@ -118,8 +120,6 @@ protected:
     bool m_exitCompleted;
     bool m_enterRequested;
 
-    WebAVPlayerController *playerController();
-    
     void doEnterFullscreen();
 };
 
index 2e507d6..70ec613 100644 (file)
@@ -86,6 +86,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
     WebAVMediaSelectionOption *_currentLegibleMediaSelectionOption;
 }
 
+-(void)resetState;
+
 @property (retain) AVPlayerController* playerControllerProxy;
 @property (assign) WebVideoFullscreenModel* delegate;
 @property (assign) WebVideoFullscreenInterfaceAVKit* fullscreenInterface;
@@ -154,6 +156,37 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
     [super dealloc];
 }
 
+-(void)resetState {
+    self.contentDuration = 0;
+    self.maxTime = 0;
+    self.contentDurationWithinEndTimes = 0;
+    self.loadedTimeRanges = @[];
+    
+    self.canPlay = NO;
+    self.canPause = NO;
+    self.canTogglePlayback = NO;
+    self.hasEnabledAudio = NO;
+    self.canSeek = NO;
+    self.minTime = 0;
+    self.status = AVPlayerControllerStatusUnknown;
+    
+    self.timing = nil;
+    self.rate = 0;
+    
+    self.hasEnabledVideo = NO;
+    self.contentDimensions = CGSizeMake(0, 0);
+    
+    self.seekableTimeRanges = [NSMutableArray array];
+    
+    self.canScanBackward = NO;
+    
+    self.audioMediaSelectionOptions = nil;
+    self.currentAudioMediaSelectionOption = nil;
+    
+    self.legibleMediaSelectionOptions = nil;
+    self.currentLegibleMediaSelectionOption = nil;
+}
+
 - (AVPlayer*) player {
     return nil;
 }
@@ -168,9 +201,12 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 {
     UNUSED_PARAM(playerViewController);
     UNUSED_PARAM(reason);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return YES;
+    
     if (reason == AVPlayerViewControllerExitFullScreenReasonDoneButtonTapped || reason == AVPlayerViewControllerExitFullScreenReasonRemoteControlStopEventReceived)
         self.delegate->pause();
+    
     self.delegate->requestExitFullscreen();
     return NO;
 }
@@ -178,21 +214,24 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)play:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->play();
 }
 
 - (void)pause:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->pause();
 }
 
 - (void)togglePlayback:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->togglePlayState();
 }
 
@@ -203,12 +242,13 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 
 - (void)setPlaying:(BOOL)playing
 {
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     if (playing)
         self.delegate->play();
     else
         self.delegate->pause();
-    }
+}
 
 + (NSSet *)keyPathsForValuesAffectingPlaying
 {
@@ -218,20 +258,23 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)beginScrubbing:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->beginScrubbing();
 }
 
 - (void)endScrubbing:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->endScrubbing();
 }
 
 - (void)seekToTime:(NSTimeInterval)time
 {
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->fastSeek(time);
 }
 
@@ -294,28 +337,32 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)beginScanningForward:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->beginScanningForward();
 }
 
 - (void)endScanningForward:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->endScanning();
 }
 
 - (void)beginScanningBackward:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->beginScanningBackward();
 }
 
 - (void)endScanningBackward:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     self.delegate->endScanning();
 }
 
@@ -337,8 +384,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)seekToBeginning:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
-
+    if (!self.delegate)
+        return;
     self.delegate->seekToTime(-INFINITY);
 }
 
@@ -365,8 +412,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)seekToEnd:(id)sender
 {
     UNUSED_PARAM(sender);
-    ASSERT(self.delegate);
-
+    if (!self.delegate)
+        return;
     self.delegate->seekToTime(INFINITY);
 }
 
@@ -419,7 +466,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
     [_currentAudioMediaSelectionOption release];
     _currentAudioMediaSelectionOption = [option retain];
     
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     
     NSInteger index = NSNotFound;
     
@@ -442,7 +490,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
     [_currentLegibleMediaSelectionOption release];
     _currentLegibleMediaSelectionOption = [option retain];
     
-    ASSERT(self.delegate);
+    if (!self.delegate)
+        return;
     
     NSInteger index = NSNotFound;
     
@@ -465,7 +514,8 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 - (void)layoutSublayersOfLayer:(CALayer *)layer
 {
     CGRect layerBounds = [layer bounds];
-    self.delegate->setVideoLayerFrame(CGRectMake(0, 0, CGRectGetWidth(layerBounds), CGRectGetHeight(layerBounds)));
+    if (self.delegate)
+        self.delegate->setVideoLayerFrame(CGRectMake(0, 0, CGRectGetWidth(layerBounds), CGRectGetHeight(layerBounds)));
     
     [CATransaction begin];
     for (CALayer *sublayer in [layer sublayers]) {
@@ -614,28 +664,32 @@ SOFT_LINK_CONSTANT(CoreMedia, kCMTimeIndefinite, CMTime)
 @end
 
 WebVideoFullscreenInterfaceAVKit::WebVideoFullscreenInterfaceAVKit()
-    : m_videoFullscreenModel(nullptr)
+    : m_playerController(adoptNS([[WebAVPlayerController alloc] init]))
+    , m_videoFullscreenModel(nullptr)
     , m_fullscreenChangeObserver(nullptr)
     , m_mode(HTMLMediaElement::VideoFullscreenModeNone)
     , m_exitRequested(false)
     , m_exitCompleted(false)
     , m_enterRequested(false)
 {
+    [m_playerController setFullscreenInterface:this];
 }
 
-WebAVPlayerController *WebVideoFullscreenInterfaceAVKit::playerController()
+void WebVideoFullscreenInterfaceAVKit::resetMediaState()
 {
-    if (!m_playerController)
-    {
-        m_playerController = adoptNS([[WebAVPlayerController alloc] init]);
-        if (m_videoFullscreenModel)
-            [m_playerController setDelegate:m_videoFullscreenModel];
-        [m_playerController setFullscreenInterface:this];
-    }
-    return m_playerController.get();
+    RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
+    
+    dispatch_async(dispatch_get_main_queue(), [strongThis] {
+        if (!strongThis->m_playerController) {
+            strongThis->m_playerController = adoptNS([[WebAVPlayerController alloc] init]);
+            [strongThis->m_playerController setDelegate:strongThis->m_videoFullscreenModel];
+            [strongThis->m_playerController setFullscreenInterface:strongThis.get()];
+            
+        } else
+            [strongThis->m_playerController resetState];
+    });
 }
 
-
 void WebVideoFullscreenInterfaceAVKit::setWebVideoFullscreenModel(WebVideoFullscreenModel* model)
 {
     m_videoFullscreenModel = model;
@@ -652,7 +706,7 @@ void WebVideoFullscreenInterfaceAVKit::setDuration(double duration)
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, duration] {
-        WebAVPlayerController* playerController = strongThis->playerController();
+        WebAVPlayerController* playerController = strongThis->m_playerController.get();
 
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=127017 use correct values instead of duration for all these
         playerController.contentDuration = duration;
@@ -676,10 +730,10 @@ void WebVideoFullscreenInterfaceAVKit::setCurrentTime(double currentTime, double
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, currentTime, anchorTime] {
-        NSTimeInterval anchorTimeStamp = ![strongThis->playerController() rate] ? NAN : anchorTime;
+        NSTimeInterval anchorTimeStamp = ![strongThis->m_playerController rate] ? NAN : anchorTime;
         AVValueTiming *timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime
             anchorTimeStamp:anchorTimeStamp rate:0];
-        strongThis->playerController().timing = timing;
+        [strongThis->m_playerController setTiming:timing];
     });
 }
 
@@ -688,7 +742,7 @@ void WebVideoFullscreenInterfaceAVKit::setRate(bool isPlaying, float playbackRat
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, isPlaying, playbackRate] {
-        strongThis->playerController().rate = isPlaying ? playbackRate : 0.;
+        [strongThis->m_playerController setRate:isPlaying ? playbackRate : 0.];
     });
 }
 
@@ -697,8 +751,8 @@ void WebVideoFullscreenInterfaceAVKit::setVideoDimensions(bool hasVideo, float w
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, hasVideo, width, height] {
-        strongThis->playerController().hasEnabledVideo = hasVideo;
-        strongThis->playerController().contentDimensions = CGSizeMake(width, height);
+        [strongThis->m_playerController setHasEnabledVideo:hasVideo];
+        [strongThis->m_playerController setContentDimensions:CGSizeMake(width, height)];
     });
 }
 
@@ -718,7 +772,7 @@ void WebVideoFullscreenInterfaceAVKit::setSeekableRanges(const TimeRanges& timeR
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, seekableRanges] {
-        strongThis->playerController().seekableTimeRanges = seekableRanges.get();
+        [strongThis->m_playerController setSeekableTimeRanges:seekableRanges.get()];
     });
 }
 
@@ -727,7 +781,7 @@ void WebVideoFullscreenInterfaceAVKit::setCanPlayFastReverse(bool canPlayFastRev
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [strongThis, canPlayFastReverse] {
-        strongThis->playerController().canScanBackward = canPlayFastReverse;
+        [strongThis->m_playerController setCanScanBackward:canPlayFastReverse];
     });
 }
 
@@ -748,9 +802,9 @@ void WebVideoFullscreenInterfaceAVKit::setAudioMediaSelectionOptions(const Vecto
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
     
     dispatch_async(dispatch_get_main_queue(), [webOptions, strongThis, selectedIndex] {
-        strongThis->playerController().audioMediaSelectionOptions = webOptions.get();
+        [strongThis->m_playerController setAudioMediaSelectionOptions:webOptions.get()];
         if (selectedIndex < [webOptions count])
-            strongThis->playerController().currentAudioMediaSelectionOption = [webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)];
+            [strongThis->m_playerController setCurrentAudioMediaSelectionOption:[webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)]];
     });
 }
 
@@ -760,9 +814,9 @@ void WebVideoFullscreenInterfaceAVKit::setLegibleMediaSelectionOptions(const Vec
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
 
     dispatch_async(dispatch_get_main_queue(), [webOptions, strongThis, selectedIndex] {
-        strongThis->playerController().legibleMediaSelectionOptions = webOptions.get();
+        [strongThis->m_playerController setLegibleMediaSelectionOptions:webOptions.get()];
         if (selectedIndex < [webOptions count])
-            strongThis->playerController().currentLegibleMediaSelectionOption = [webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)];
+            [strongThis->m_playerController setCurrentLegibleMediaSelectionOption:[webOptions objectAtIndex:static_cast<NSUInteger>(selectedIndex)]];
     });
 }
 
@@ -777,7 +831,7 @@ void WebVideoFullscreenInterfaceAVKit::setExternalPlayback(bool enabled, Externa
     RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
 
     dispatch_async(dispatch_get_main_queue(), [strongThis, enabled, localizedDeviceName, externalPlaybackType] {
-        WebAVPlayerController* playerController = strongThis->playerController();
+        WebAVPlayerController* playerController = strongThis->m_playerController.get();
         playerController.externalPlaybackAirPlayDeviceLocalizedName = localizedDeviceName;
         playerController.externalPlaybackType = externalPlaybackType;
         playerController.externalPlaybackActive = enabled;
@@ -821,17 +875,17 @@ void WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal(PlatformLayer& vi
     [m_videoLayer removeFromSuperlayer];
 
     m_videoLayerContainer = [WebAVVideoLayer videoLayer];
-    [m_videoLayerContainer setHidden:playerController().externalPlaybackActive];
+    [m_videoLayerContainer setHidden:[m_playerController isExternalPlaybackActive]];
     [m_videoLayerContainer setVideoSublayer:m_videoLayer.get()];
 
-    CGSize videoSize = playerController().contentDimensions;
+    CGSize videoSize = [m_playerController contentDimensions];
     CGRect videoRect = CGRectMake(0, 0, videoSize.width, videoSize.height);
     [m_videoLayerContainer setVideoRect:videoRect];
 
     m_playerViewController = adoptNS([allocAVPlayerViewControllerInstance() initWithVideoLayer:m_videoLayerContainer.get()]);
     [m_playerViewController setShowsPlaybackControls:NO];
-    [m_playerViewController setPlayerController:(AVPlayerController *)playerController()];
-    [m_playerViewController setDelegate:playerController()];
+    [m_playerViewController setPlayerController:(AVPlayerController *)m_playerController.get()];
+    [m_playerViewController setDelegate:m_playerController.get()];
     [m_playerViewController setAllowsOptimizedFullscreen:allowOptimizedFullscreen];
 
     [m_videoLayerContainer setPlayerViewController:m_playerViewController.get()];
@@ -1015,18 +1069,31 @@ void WebVideoFullscreenInterfaceAVKit::cleanupFullscreenInternal()
         if (m_parentWindow)
             [[getUIApplicationClass() sharedApplication] _setStatusBarOrientation:[m_parentWindow interfaceOrientation]];
     }
+    
+    [m_playerController setDelegate:nil];
+    [m_playerController setFullscreenInterface:nil];
+    
     [m_playerViewController setDelegate:nil];
+    [m_playerViewController setPlayerController:nil];
+    
+    if (m_mode & HTMLMediaElement::VideoFullscreenModeOptimized)
+        [m_playerViewController cancelOptimizedFullscreen];
+    if (m_mode & HTMLMediaElement::VideoFullscreenModeStandard)
+        [m_playerViewController exitFullScreenAnimated:NO completionHandler:nil];
+    
     [[m_playerViewController view] removeFromSuperview];
     if (m_viewController)
         [m_playerViewController removeFromParentViewController];
-    [m_playerViewController setPlayerController:nil];
-    m_playerViewController = nil;
+    
     [m_videoLayer removeFromSuperlayer];
-    m_videoLayer = nil;
     [m_videoLayerContainer removeFromSuperlayer];
     [m_videoLayerContainer setPlayerViewController:nil];
-    m_videoLayerContainer = nil;
     [[m_viewController view] removeFromSuperview];
+    
+    m_videoLayer = nil;
+    m_videoLayerContainer = nil;
+    m_playerViewController = nil;
+    m_playerController = nil;
     m_viewController = nil;
     m_window = nil;
     m_parentView = nil;
@@ -1042,31 +1109,10 @@ void WebVideoFullscreenInterfaceAVKit::cleanupFullscreenInternal()
 
 void WebVideoFullscreenInterfaceAVKit::invalidate()
 {
-    [m_window setHidden:YES];
-    [m_window setRootViewController:nil];
-    m_window = nil;
     m_videoFullscreenModel = nil;
-    if (m_mode & HTMLMediaElement::VideoFullscreenModeOptimized)
-        [m_playerViewController cancelOptimizedFullscreen];
-    if (m_mode & HTMLMediaElement::VideoFullscreenModeStandard)
-        [m_playerViewController exitFullScreenAnimated:NO completionHandler:nil];
-    m_playerController = nil;
-    [m_playerViewController setDelegate:nil];
-    [[m_playerViewController view] removeFromSuperview];
-    if (m_viewController)
-        [m_playerViewController removeFromParentViewController];
-    [m_playerViewController setPlayerController:nil];
-    m_playerViewController = nil;
-    [m_videoLayer removeFromSuperlayer];
-    m_videoLayer = nil;
-    [m_videoLayerContainer removeFromSuperlayer];
-    [m_videoLayerContainer setPlayerViewController:nil];
-    m_videoLayerContainer = nil;
-    [[m_viewController view] removeFromSuperview];
-    [m_playerController setFullscreenInterface:nil];
-    m_viewController = nil;
-    m_parentView = nil;
-    m_parentWindow = nil;
+    m_fullscreenChangeObserver = nil;
+    
+    cleanupFullscreenInternal();
 }
 
 void WebVideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen()
index db9d946..902c91b 100644 (file)
@@ -67,6 +67,9 @@ void WebVideoFullscreenModelVideoElement::setVideoElement(HTMLVideoElement* vide
     if (m_videoElement == videoElement)
         return;
 
+    if (m_videoFullscreenInterface)
+        m_videoFullscreenInterface->resetMediaState();
+    
     if (m_videoElement && m_isListening) {
         for (auto eventName : observedEventNames())
             m_videoElement->removeEventListener(eventName, this, false);
index 021e788..f3f2319 100644 (file)
@@ -1,3 +1,19 @@
+2015-02-02  Jeremy Jones  <jeremyj@apple.com>
+
+        Prevent crash when accessing WebAVPlayerController.delegate.
+        https://bugs.webkit.org/show_bug.cgi?id=140893
+
+        Reviewed by Darin Adler.
+
+        Plumb new resetMediaState() through IPC interface WebVideoFullscreenManagerProxy.
+
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
+        * UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
+        (WebKit::WebVideoFullscreenManagerProxy::invalidate): remove redundant set to nullptr.
+        * WebProcess/ios/WebVideoFullscreenManager.h:
+        * WebProcess/ios/WebVideoFullscreenManager.mm:
+        (WebKit::WebVideoFullscreenManager::resetMediaState):
+
 2015-02-01  Chris Dumez  <cdumez@apple.com>
 
         Use more references in HistoryItem
index 578e0c3..b763b03 100644 (file)
@@ -22,6 +22,7 @@
 
 #if PLATFORM(IOS)
 messages -> WebVideoFullscreenManagerProxy {
+    ResetMediaState()
     SetCurrentTime(double currentTime, double hostTime)
     SetVideoDimensions(bool hasVideo, unsigned width, unsigned height)
     SetSeekableRangesVector(Vector<std::pair<double, double>> ranges);
index 53ddd01..fba214a 100644 (file)
@@ -68,9 +68,6 @@ void WebVideoFullscreenManagerProxy::invalidate()
 {
     WebVideoFullscreenInterfaceAVKit::invalidate();
 
-    setWebVideoFullscreenModel(nullptr);
-    setWebVideoFullscreenChangeObserver(nullptr);
-
     m_page->process().removeMessageReceiver(Messages::WebVideoFullscreenManagerProxy::messageReceiverName(), m_page->pageID());
     m_page = nullptr;
 
index e7095b0..4f536a6 100644 (file)
@@ -68,6 +68,7 @@ protected:
     virtual bool operator==(const EventListener& rhs) override { return static_cast<WebCore::EventListener*>(this) == &rhs; }
     
     // FullscreenInterface
+    virtual void resetMediaState() override;
     virtual void setDuration(double) override;
     virtual void setCurrentTime(double currentTime, double anchorTime) override;
     virtual void setRate(bool isPlaying, float playbackRate) override;
index 742e9db..04a4604 100644 (file)
@@ -119,6 +119,11 @@ void WebVideoFullscreenManager::exitVideoFullscreen()
     m_page->send(Messages::WebVideoFullscreenManagerProxy::ExitFullscreen(clientRectForElement(videoElement.get())), m_page->pageID());
 }
 
+void WebVideoFullscreenManager::resetMediaState()
+{
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::ResetMediaState(), m_page->pageID());
+}
+    
 void WebVideoFullscreenManager::setDuration(double duration)
 {
     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetDuration(duration), m_page->pageID());