Refactoring: eliminate raw pointer usage in Fullscreen code
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Sep 2018 18:39:51 +0000 (18:39 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Sep 2018 18:39:51 +0000 (18:39 +0000)
commit565c49731c9f11beeb7a1157339202adc60f99c2
treee46c43eeb8d013e76f11231c7dd7ab514f8f4feb
parentcae01da3747ef77024fe6c958c9b28900c46c4c1
Refactoring: eliminate raw pointer usage in Fullscreen code
https://bugs.webkit.org/show_bug.cgi?id=188747
<rdar://problem/43541164>

Reviewed by Alex Christensen.

Source/WebCore:

Two sources of raw pointers in the Fullscreen code:
- Model classes (PlaybackSessionModel and VideoFullscreenModel) aren't ref-able, so
  they are passed around as raw references.
- Observer classes (PlaybackSessionModelClient and VideoFullscreenModelClient, and
  VideoFullscreenChangeObserver) are also passed around as raw pointers, but shouldn't
  be ref-able.

Make Model classes ref-able by adding ref() and deref() which call virtual refModel and
derefModel methods, overridden by implementing subclasses. Make every concrete observer
inherit from CanMakeWeakPtr, and every registration method take WeakPtr wrappers around
the client interface.

Since every Interface class now holds a strong reference to its Model classes, and each
Model class holds a weak reference to all its clients, no explicit invalidate() method
is necessary.

Notes:

- Since the weak pointer methods need to be able to downcast to the abstract base class,
  observers need to inherit publically (rather than privately) from those base classes.
- Media element Models should compose EventListener rather than inheriting from it, since
  EventListener has its own RefCount.
- WeakPtrs can't be held in HashSets (because they change value, and therefore hash, when
  their underlying object is destroyed), so clients should be stored in a Vector instead.
- Interfaces should be given all required Refs at creation time, so that they can store
  those parameters as Refs instead of RefPtrs.

* platform/cocoa/PlaybackSessionInterface.h:
(WebCore::PlaybackSessionInterface::~PlaybackSessionInterface): Deleted.
* platform/cocoa/PlaybackSessionModel.h:
(WebCore::PlaybackSessionModel::ref):
(WebCore::PlaybackSessionModel::deref):
(WebCore::PlaybackSessionModel::~PlaybackSessionModel): Deleted.
* platform/cocoa/PlaybackSessionModelMediaElement.h:
* platform/cocoa/PlaybackSessionModelMediaElement.mm:
(WebCore::PlaybackSessionModelMediaElement::PlaybackSessionModelMediaElement):
(WebCore::PlaybackSessionModelMediaElement::~PlaybackSessionModelMediaElement):
(WebCore::PlaybackSessionModelMediaElement::setMediaElement):
(WebCore::PlaybackSessionModelMediaElement::updateForEventName):
(WebCore::PlaybackSessionModelMediaElement::addClient):
(WebCore::PlaybackSessionModelMediaElement::removeClient):
(WebCore::PlaybackSessionModelMediaElement::updateMediaSelectionOptions):
(WebCore::PlaybackSessionModelMediaElement::updateMediaSelectionIndices):
(WebCore::PlaybackSessionModelMediaElement::handleEvent): Deleted.
* platform/cocoa/VideoFullscreenChangeObserver.h:
(WebCore::VideoFullscreenChangeObserver::~VideoFullscreenChangeObserver): Deleted.
* platform/cocoa/VideoFullscreenModel.h:
(WebCore::VideoFullscreenModel::ref):
(WebCore::VideoFullscreenModel::deref):
(WebCore::VideoFullscreenModel::~VideoFullscreenModel): Deleted.
* platform/cocoa/VideoFullscreenModelVideoElement.h:
* platform/cocoa/VideoFullscreenModelVideoElement.mm:
(VideoFullscreenModelVideoElement::VideoFullscreenModelVideoElement):
(VideoFullscreenModelVideoElement::setVideoElement):
(VideoFullscreenModelVideoElement::addClient):
(VideoFullscreenModelVideoElement::removeClient):
(VideoFullscreenModelVideoElement::setHasVideo):
(VideoFullscreenModelVideoElement::setVideoDimensions):
(VideoFullscreenModelVideoElement::willEnterPictureInPicture):
(VideoFullscreenModelVideoElement::didEnterPictureInPicture):
(VideoFullscreenModelVideoElement::failedToEnterPictureInPicture):
(VideoFullscreenModelVideoElement::willExitPictureInPicture):
(VideoFullscreenModelVideoElement::didExitPictureInPicture):
(VideoFullscreenModelVideoElement::handleEvent): Deleted.
* platform/ios/PlaybackSessionInterfaceAVKit.h:
(WebCore::PlaybackSessionInterfaceAVKit::create):
(WebCore::PlaybackSessionInterfaceAVKit::playbackSessionModel const):
(): Deleted.
* platform/ios/PlaybackSessionInterfaceAVKit.mm:
(WebCore::PlaybackSessionInterfaceAVKit::PlaybackSessionInterfaceAVKit):
(WebCore::PlaybackSessionInterfaceAVKit::~PlaybackSessionInterfaceAVKit):
(WebCore::PlaybackSessionInterfaceAVKit::invalidate): Deleted.
* platform/ios/VideoFullscreenInterfaceAVKit.h:
* platform/ios/VideoFullscreenInterfaceAVKit.mm:
(-[WebAVPlayerLayer layoutSublayers]):
(-[WebAVPlayerLayer resolveBounds]):
(-[WebAVPlayerLayer setVideoGravity:]):
(VideoFullscreenInterfaceAVKit::create):
(VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit):
(VideoFullscreenInterfaceAVKit::~VideoFullscreenInterfaceAVKit):
(VideoFullscreenInterfaceAVKit::setVideoFullscreenChangeObserver):
(VideoFullscreenInterfaceAVKit::applicationDidBecomeActive):
(VideoFullscreenInterfaceAVKit::setupFullscreen):
(VideoFullscreenInterfaceAVKit::presentingViewController):
(VideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen):
(VideoFullscreenInterfaceAVKit::preparedToExitFullscreen):
(VideoFullscreenInterfaceAVKit::willStartPictureInPicture):
(VideoFullscreenInterfaceAVKit::didStartPictureInPicture):
(VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture):
(VideoFullscreenInterfaceAVKit::willStopPictureInPicture):
(VideoFullscreenInterfaceAVKit::didStopPictureInPicture):
(VideoFullscreenInterfaceAVKit::shouldExitFullscreenWithReason):
(VideoFullscreenInterfaceAVKit::doSetup):
(VideoFullscreenInterfaceAVKit::setMode):
(VideoFullscreenInterfaceAVKit::clearMode):
(VideoFullscreenInterfaceAVKit::setVideoFullscreenModel): Deleted.
(VideoFullscreenInterfaceAVKit::invalidate): Deleted.
* platform/ios/WebAVPlayerController.h:
* platform/ios/WebAVPlayerController.mm:
(-[WebAVPlayerController delegate]):
(-[WebAVPlayerController playbackSessionInterface]):
(-[WebAVPlayerController setPlaybackSessionInterface:]):
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(VideoFullscreenControllerContext::didCleanupFullscreen):
(VideoFullscreenControllerContext::addClient):
(VideoFullscreenControllerContext::removeClient):
(VideoFullscreenControllerContext::willEnterPictureInPicture):
(VideoFullscreenControllerContext::didEnterPictureInPicture):
(VideoFullscreenControllerContext::failedToEnterPictureInPicture):
(VideoFullscreenControllerContext::willExitPictureInPicture):
(VideoFullscreenControllerContext::didExitPictureInPicture):
(VideoFullscreenControllerContext::setUpFullscreen):
* platform/mac/PlaybackSessionInterfaceMac.h:
* platform/mac/PlaybackSessionInterfaceMac.mm:
(WebCore::PlaybackSessionInterfaceMac::create):
(WebCore::PlaybackSessionInterfaceMac::PlaybackSessionInterfaceMac):
(WebCore::PlaybackSessionInterfaceMac::playbackSessionModel const):
(WebCore::PlaybackSessionInterfaceMac::rateChanged):
(WebCore::PlaybackSessionInterfaceMac::beginScrubbing):
(WebCore::PlaybackSessionInterfaceMac::endScrubbing):
(WebCore::PlaybackSessionInterfaceMac::setPlayBackControlsManager):
(WebCore::PlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming):
(WebCore::PlaybackSessionInterfaceMac::~PlaybackSessionInterfaceMac): Deleted.
(WebCore::PlaybackSessionInterfaceMac::invalidate): Deleted.
* platform/mac/VideoFullscreenInterfaceMac.h:
(WebCore::VideoFullscreenInterfaceMac::create):
(WebCore::VideoFullscreenInterfaceMac::videoFullscreenModel const):
(WebCore::VideoFullscreenInterfaceMac::playbackSessionModel const):
(WebCore::VideoFullscreenInterfaceMac::videoFullscreenChangeObserver const):
* platform/mac/VideoFullscreenInterfaceMac.mm:
(-[WebVideoFullscreenInterfaceMacObjC setUpPIPForVideoView:withFrame:inWindow:]):
(-[WebVideoFullscreenInterfaceMacObjC boundsDidChangeForVideoViewContainer:]):
(-[WebVideoFullscreenInterfaceMacObjC pipDidClose:]):
(-[WebVideoFullscreenInterfaceMacObjC pipActionPlay:]):
(-[WebVideoFullscreenInterfaceMacObjC pipActionPause:]):
(-[WebVideoFullscreenInterfaceMacObjC pipActionStop:]):
(WebCore::VideoFullscreenInterfaceMac::VideoFullscreenInterfaceMac):
(WebCore::VideoFullscreenInterfaceMac::~VideoFullscreenInterfaceMac):
(WebCore::VideoFullscreenInterfaceMac::setVideoFullscreenChangeObserver):
(WebCore::VideoFullscreenInterfaceMac::setMode):
(WebCore::VideoFullscreenInterfaceMac::clearMode):
(WebCore::VideoFullscreenInterfaceMac::invalidate):
(WebCore::VideoFullscreenInterfaceMac::requestHideAndExitPiP):
(WebCore::VideoFullscreenInterfaceMac::setVideoFullscreenModel): Deleted.
* platform/mac/WebPlaybackControlsManager.mm:
(-[WebPlaybackControlsManager seekToTime:toleranceBefore:toleranceAfter:]):
(-[WebPlaybackControlsManager setCurrentAudioTouchBarMediaSelectionOption:]):
(-[WebPlaybackControlsManager setCurrentLegibleTouchBarMediaSelectionOption:]):
(-[WebPlaybackControlsManager togglePlayback]):
(-[WebPlaybackControlsManager setPlaying:]):
(-[WebPlaybackControlsManager isPlaying]):
(-[WebPlaybackControlsManager togglePictureInPicture]):

Source/WebKit:

Adopt those Ref and WeakPtr changes made in WebCore.

* UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
(WebKit::PlaybackSessionModelContext::addClient):
(WebKit::PlaybackSessionModelContext::removeClient):
(WebKit::PlaybackSessionModelContext::durationChanged):
(WebKit::PlaybackSessionModelContext::currentTimeChanged):
(WebKit::PlaybackSessionModelContext::bufferedTimeChanged):
(WebKit::PlaybackSessionModelContext::rateChanged):
(WebKit::PlaybackSessionModelContext::seekableRangesChanged):
(WebKit::PlaybackSessionModelContext::canPlayFastReverseChanged):
(WebKit::PlaybackSessionModelContext::audioMediaSelectionOptionsChanged):
(WebKit::PlaybackSessionModelContext::legibleMediaSelectionOptionsChanged):
(WebKit::PlaybackSessionModelContext::audioMediaSelectionIndexChanged):
(WebKit::PlaybackSessionModelContext::legibleMediaSelectionIndexChanged):
(WebKit::PlaybackSessionModelContext::externalPlaybackChanged):
(WebKit::PlaybackSessionModelContext::wirelessVideoPlaybackDisabledChanged):
(WebKit::PlaybackSessionModelContext::mutedChanged):
(WebKit::PlaybackSessionModelContext::volumeChanged):
(WebKit::PlaybackSessionModelContext::pictureInPictureActiveChanged):
(WebKit::PlaybackSessionManagerProxy::invalidate):
(WebKit::PlaybackSessionManagerProxy::createModelAndInterface):
(WebKit::PlaybackSessionManagerProxy::removeClientForContext):
* UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
* UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
(WebKit::VideoFullscreenModelContext::create):
(WebKit::VideoFullscreenModelContext::VideoFullscreenModelContext):
(WebKit::VideoFullscreenModelContext::addClient):
(WebKit::VideoFullscreenModelContext::removeClient):
(WebKit::VideoFullscreenModelContext::willEnterPictureInPicture):
(WebKit::VideoFullscreenModelContext::didEnterPictureInPicture):
(WebKit::VideoFullscreenModelContext::failedToEnterPictureInPicture):
(WebKit::VideoFullscreenModelContext::willExitPictureInPicture):
(WebKit::VideoFullscreenModelContext::didExitPictureInPicture):
(WebKit::VideoFullscreenManagerProxy::invalidate):
(WebKit::VideoFullscreenManagerProxy::createModelAndInterface):
(WebKit::VideoFullscreenManagerProxy::removeClientForContext):
(WebKit::VideoFullscreenModelContext::~VideoFullscreenModelContext): Deleted.
* UIProcess/ios/fullscreen/WKFullScreenViewController.mm:
(WKFullScreenViewControllerPlaybackSessionModelClient::setInterface):
(WKFullScreenViewControllerVideoFullscreenModelClient::setInterface):
(-[WKFullScreenViewController videoControlsManagerDidChange]):
(-[WKFullScreenViewController _togglePiPAction:]):
* UIProcess/mac/WKFullScreenWindowController.mm:
(WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface):
* WebProcess/cocoa/PlaybackSessionManager.h:
* WebProcess/cocoa/PlaybackSessionManager.mm:
(WebKit::PlaybackSessionInterfaceContext::PlaybackSessionInterfaceContext):
(WebKit::PlaybackSessionManager::~PlaybackSessionManager):
(WebKit::PlaybackSessionManager::createModelAndInterface):
(WebKit::PlaybackSessionManager::removeContext):
(WebKit::PlaybackSessionInterfaceContext::~PlaybackSessionInterfaceContext): Deleted.
* WebProcess/cocoa/VideoFullscreenManager.h:
(WebKit::VideoFullscreenInterfaceContext::create):
(WebKit::VideoFullscreenInterfaceContext::createWeakPtr):
* WebProcess/cocoa/VideoFullscreenManager.mm:
(WebKit::VideoFullscreenInterfaceContext::VideoFullscreenInterfaceContext):
(WebKit::VideoFullscreenManager::~VideoFullscreenManager):
(WebKit::VideoFullscreenManager::createModelAndInterface):
(WebKit::VideoFullscreenManager::removeContext):

Source/WebKitLegacy/mac:

PlaybackSessionInterface no longer has an invalidate() method.

* WebView/WebView.mm:
(-[WebView _clearPlaybackControlsManager]):

Source/WTF:

* WTF.xcodeproj/project.pbxproj:
* wtf/WeakPtrContainer.h: Added.

LayoutTests:

Test was causing false pass results due to the webkitPresentationMode being correctly set
to "inline" during the close() operation; modify the test to only perform the close()
operation when the presetation mode is changed to "picture-in-picture".

* media/controls/ipad/close-page-with-picture-in-picture-video-assertion-failure.html:
* media/controls/ipad/resources/picture-in-picture.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236605 268f45cc-cd09-0410-ab3c-d52691b4dbfc
40 files changed:
LayoutTests/ChangeLog
LayoutTests/media/controls/ipad/close-page-with-picture-in-picture-video-assertion-failure.html
LayoutTests/media/controls/ipad/resources/picture-in-picture.html
Source/WTF/ChangeLog
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/WeakPtrContainer.h [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/cocoa/PlaybackSessionInterface.h
Source/WebCore/platform/cocoa/PlaybackSessionModel.h
Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h
Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm
Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h
Source/WebCore/platform/cocoa/VideoFullscreenModel.h
Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.h
Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.mm
Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h
Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm
Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h
Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm
Source/WebCore/platform/ios/WebAVPlayerController.h
Source/WebCore/platform/ios/WebAVPlayerController.mm
Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm
Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h
Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm
Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.h
Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm
Source/WebCore/platform/mac/WebPlaybackControlsManager.mm
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h
Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm
Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h
Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm
Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm
Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm
Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h
Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm
Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h
Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebView.mm