WebKit Bugzilla
Attachment 347841 Details for
Bug 188747
: Refactoring: eliminate raw pointer usage in Fullscreen code
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188747-20180822135212.patch (text/plain), 149.62 KB, created by
Jer Noble
on 2018-08-22 13:52:13 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2018-08-22 13:52:13 PDT
Size:
149.62 KB
patch
obsolete
>Subversion Revision: 235089 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index eac1685f75400fd21535b435f22da825030e45b8..da17134ad663a74a4ec10943ca11dc06609e0a33 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,14 @@ >+2018-08-22 Jer Noble <jer.noble@apple.com> >+ >+ Refactoring: eliminate raw pointer usage in Fullscreen code >+ https://bugs.webkit.org/show_bug.cgi?id=188747 >+ <rdar://problem/43541164> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WTF.xcodeproj/project.pbxproj: >+ * wtf/WeakPtrContainer.h: Added. >+ > 2018-08-19 Yusuke Suzuki <yusukesuzuki@slowstart.org> > > [WTF] Add WTF::unalignedLoad and WTF::unalignedStore >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 39fa429adf4e06361a0d19b5bbd907ac70bf5d27..f0cfa7dbd16aee9344b0c2f39df3979c83688041 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,164 @@ >+2018-08-22 Jer Noble <jer.noble@apple.com> >+ >+ Refactoring: eliminate raw pointer usage in Fullscreen code >+ https://bugs.webkit.org/show_bug.cgi?id=188747 >+ <rdar://problem/43541164> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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]): >+ > 2018-08-20 Jeremy Jones <jeremyj@apple.com> > > UIWebView crashes while attempting to play youtube video on phone >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 7ab364a65b01bfbf9ea342601135fa8f192c898a..46f792d0c4bd96ca72d6352b6afd3b20735a34cf 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,73 @@ >+2018-08-22 Jer Noble <jer.noble@apple.com> >+ >+ Refactoring: eliminate raw pointer usage in Fullscreen code >+ https://bugs.webkit.org/show_bug.cgi?id=188747 >+ <rdar://problem/43541164> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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): >+ > 2018-08-20 Tim Horton <timothy_horton@apple.com> > > Fix the iOSMac build with unified sources >diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj >index 45b5ceaecf0e02ec5d65167787675c689d35245d..76f6cf9247dfe6c35bf7445a3d96bc60042f7a97 100644 >--- a/Source/WTF/WTF.xcodeproj/project.pbxproj >+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj >@@ -605,6 +605,7 @@ > C4F8A93619C65EB400B2B15D /* Stopwatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stopwatch.h; sourceTree = "<group>"; }; > C6F050790D9C432A99085E75 /* ASCIILiteral.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASCIILiteral.cpp; sourceTree = "<group>"; }; > C8F597CA2A57417FBAB92FD6 /* RandomDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomDevice.cpp; sourceTree = "<group>"; }; >+ CD2D0D10212C76E60018C784 /* WeakPtrContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakPtrContainer.h; sourceTree = "<group>"; }; > CD5497AA15857D0300B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; }; > CD5497AB15857D0300B5BC30 /* MediaTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaTime.h; sourceTree = "<group>"; }; > CD6D9FCD1EEF3AD4008B0671 /* Algorithms.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Algorithms.h; sourceTree = "<group>"; }; >@@ -1136,6 +1137,7 @@ > 0F66B2891DC97BAB004A1D3F /* WallTime.h */, > 83ABB3C020B3823200BA3306 /* WeakObjCPtr.h */, > 974CFC8D16A4F327006D5404 /* WeakPtr.h */, >+ CD2D0D10212C76E60018C784 /* WeakPtrContainer.h */, > 0F3501631BB258C800F0A2A3 /* WeakRandom.h */, > 0FE4479A1B7AAA03009498EB /* WordLock.cpp */, > 0FE4479B1B7AAA03009498EB /* WordLock.h */, >diff --git a/Source/WTF/wtf/WeakPtrContainer.h b/Source/WTF/wtf/WeakPtrContainer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..5340943a62420ed8adba8817111645825264f4e9 >--- /dev/null >+++ b/Source/WTF/wtf/WeakPtrContainer.h >@@ -0,0 +1,81 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include <wtf/Vector.h> >+#include <wtf/WeakPtr.h> >+ >+namespace WTF { >+ >+template <typename T> >+class WeakPtrContainer { >+public: >+ void add(WeakPtr<T>&& ptr) >+ { >+ m_members.append(WTFMove(ptr)); >+ } >+ >+ void remove(T& ptr) >+ { >+ m_members.removeAll(&ptr); >+ } >+ >+ void clear() >+ { >+ m_members.clear(); >+ } >+ >+ bool isEmpty() const >+ { >+ return m_members.isEmpty(); >+ } >+ >+ void removeNullMembers() >+ { >+ m_members.removeAllMatching([] (auto& ptr) { return !ptr; }); >+ } >+ >+ template <typename F> >+ void forEachNonNullMember(F&& f) >+ { >+ bool hasNullMembers = false; >+ for (auto& member : m_members) { >+ if (member) >+ f(*member); >+ else >+ hasNullMembers = true; >+ } >+ >+ if (hasNullMembers) >+ removeNullMembers(); >+ } >+private: >+ Vector<WeakPtr<T>> m_members; >+}; >+ >+} >+ >+using WTF::WeakPtrContainer; >diff --git a/Source/WebCore/platform/cocoa/PlaybackSessionInterface.h b/Source/WebCore/platform/cocoa/PlaybackSessionInterface.h >index cdf2bbfbddd7e2f935dc2b3cd49f55081884754b..db7b58fa9e045bb349554595f42c82029147098e 100644 >--- a/Source/WebCore/platform/cocoa/PlaybackSessionInterface.h >+++ b/Source/WebCore/platform/cocoa/PlaybackSessionInterface.h >@@ -27,16 +27,11 @@ > > #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) > >-#include <wtf/Forward.h> >-#include <wtf/Vector.h> >- > namespace WebCore { > >-class TimeRanges; >- > class PlaybackSessionInterface { > public: >- virtual ~PlaybackSessionInterface() { }; >+ virtual ~PlaybackSessionInterface() = default; > virtual void resetMediaState() = 0; > }; > >diff --git a/Source/WebCore/platform/cocoa/PlaybackSessionModel.h b/Source/WebCore/platform/cocoa/PlaybackSessionModel.h >index 1c4f0e3aee94113f70814ae850c84d44e77e2e99..08d82a4519a2ef6ec66a8344367f5f6a7d9f3319 100644 >--- a/Source/WebCore/platform/cocoa/PlaybackSessionModel.h >+++ b/Source/WebCore/platform/cocoa/PlaybackSessionModel.h >@@ -30,6 +30,7 @@ > #include <wtf/Forward.h> > #include <wtf/Ref.h> > #include <wtf/Vector.h> >+#include <wtf/WeakPtr.h> > > namespace WebCore { > >@@ -39,8 +40,12 @@ struct MediaSelectionOption; > > class PlaybackSessionModel { > public: >- virtual ~PlaybackSessionModel() { }; >- virtual void addClient(PlaybackSessionModelClient&) = 0; >+ virtual ~PlaybackSessionModel() = default; >+ >+ void ref() { refPlaybackSessionModel(); } >+ void deref() { derefPlaybackSessionModel(); } >+ >+ virtual void addClient(WeakPtr<PlaybackSessionModelClient>&&) = 0; > virtual void removeClient(PlaybackSessionModelClient&) = 0; > > virtual void play() = 0; >@@ -84,6 +89,10 @@ public: > virtual bool isMuted() const = 0; > virtual double volume() const = 0; > virtual bool isPictureInPictureActive() const = 0; >+ >+private: >+ virtual void refPlaybackSessionModel() = 0; >+ virtual void derefPlaybackSessionModel() = 0; > }; > > class PlaybackSessionModelClient { >diff --git a/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h b/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h >index f5927dce035a7de7c0c6c9046e6d5b0204cac8d3..860de152a2240cd17eebb56f154e522d5b2a02d0 100644 >--- a/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h >+++ b/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h >@@ -30,9 +30,8 @@ > #include "EventListener.h" > #include "HTMLMediaElementEnums.h" > #include "PlaybackSessionModel.h" >-#include <wtf/HashSet.h> > #include <wtf/RefPtr.h> >-#include <wtf/Vector.h> >+#include <wtf/WeakPtrContainer.h> > > namespace WebCore { > >@@ -41,7 +40,10 @@ class HTMLMediaElement; > class TextTrack; > class PlaybackSessionInterface; > >-class PlaybackSessionModelMediaElement final : public PlaybackSessionModel, public EventListener { >+class PlaybackSessionModelMediaElement final >+ : public RefCounted<PlaybackSessionModelMediaElement> >+ , public CanMakeWeakPtr<PlaybackSessionModelMediaElement> >+ , public PlaybackSessionModel { > public: > static Ref<PlaybackSessionModelMediaElement> create() > { >@@ -51,11 +53,9 @@ public: > WEBCORE_EXPORT void setMediaElement(HTMLMediaElement*); > HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); } > >- WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event&) final; > void updateForEventName(const WTF::AtomicString&); >- bool operator==(const EventListener& rhs) const final { return static_cast<const WebCore::EventListener*>(this) == &rhs; } > >- WEBCORE_EXPORT void addClient(PlaybackSessionModelClient&); >+ WEBCORE_EXPORT void addClient(WeakPtr<PlaybackSessionModelClient>&&); > WEBCORE_EXPORT void removeClient(PlaybackSessionModelClient&); > WEBCORE_EXPORT void play() final; > WEBCORE_EXPORT void pause() final; >@@ -96,19 +96,27 @@ public: > double volume() const final; > bool isPictureInPictureActive() const final; > >+ using RefCounted::ref; >+ using RefCounted::deref; >+ > protected: > WEBCORE_EXPORT PlaybackSessionModelMediaElement(); > > private: >+ void refPlaybackSessionModel() final { ref(); } >+ void derefPlaybackSessionModel() final { deref(); } >+ > void progressEventTimerFired(); > static const Vector<WTF::AtomicString>& observedEventNames(); > const WTF::AtomicString& eventNameAll(); > >+ class MediaElementEventListener; >+ > RefPtr<HTMLMediaElement> m_mediaElement; >- bool m_isListening { false }; >- HashSet<PlaybackSessionModelClient*> m_clients; >+ WeakPtrContainer<PlaybackSessionModelClient> m_clients; > Vector<RefPtr<TextTrack>> m_legibleTracksForMenu; > Vector<RefPtr<AudioTrack>> m_audioTracksForMenu; >+ Ref<MediaElementEventListener> m_eventListener; > > double playbackStartedTime() const; > void updateMediaSelectionOptions(); >diff --git a/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm b/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm >index a11b70c1ed296ce0cd1ec1798df61d17fd0273d7..5e973009cf61de5815850ee081594f18ef40ce32 100644 >--- a/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm >+++ b/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm >@@ -46,14 +46,34 @@ > #import <wtf/SoftLinking.h> > > namespace WebCore { >+ >+class PlaybackSessionModelMediaElement::MediaElementEventListener final : public EventListener { >+public: >+ MediaElementEventListener(WeakPtr<PlaybackSessionModelMediaElement>&& parent) >+ : EventListener(CPPEventListenerType) >+ , m_parent(WTFMove(parent)) >+ { >+ } >+private: >+ void handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event& event) final >+ { >+ if (m_parent) >+ m_parent->updateForEventName(event.type()); >+ } >+ bool operator==(const EventListener& rhs) const final { return static_cast<const WebCore::EventListener*>(this) == &rhs; } >+ >+ WeakPtr<PlaybackSessionModelMediaElement> m_parent; >+}; > > PlaybackSessionModelMediaElement::PlaybackSessionModelMediaElement() >- : EventListener(EventListener::CPPEventListenerType) >+ : m_eventListener(adoptRef(*new MediaElementEventListener(makeWeakPtr(*this)))) > { > } > > PlaybackSessionModelMediaElement::~PlaybackSessionModelMediaElement() > { >+ m_clients.clear(); >+ setMediaElement(nullptr); > } > > void PlaybackSessionModelMediaElement::setMediaElement(HTMLMediaElement* mediaElement) >@@ -63,51 +83,43 @@ void PlaybackSessionModelMediaElement::setMediaElement(HTMLMediaElement* mediaEl > > auto& events = eventNames(); > >- if (m_mediaElement && m_isListening) { >+ if (m_mediaElement) { > for (auto& eventName : observedEventNames()) >- m_mediaElement->removeEventListener(eventName, *this, false); >+ m_mediaElement->removeEventListener(eventName, m_eventListener.copyRef(), false); > if (auto* audioTracks = m_mediaElement->audioTracks()) { >- audioTracks->removeEventListener(events.addtrackEvent, *this, false); >- audioTracks->removeEventListener(events.changeEvent, *this, false); >- audioTracks->removeEventListener(events.removetrackEvent, *this, false); >+ audioTracks->removeEventListener(events.addtrackEvent, m_eventListener.copyRef(), false); >+ audioTracks->removeEventListener(events.changeEvent, m_eventListener.copyRef(), false); >+ audioTracks->removeEventListener(events.removetrackEvent, m_eventListener.copyRef(), false); > } > > if (auto* textTracks = m_mediaElement->audioTracks()) { >- textTracks->removeEventListener(events.addtrackEvent, *this, false); >- textTracks->removeEventListener(events.changeEvent, *this, false); >- textTracks->removeEventListener(events.removetrackEvent, *this, false); >+ textTracks->removeEventListener(events.addtrackEvent, m_eventListener.copyRef(), false); >+ textTracks->removeEventListener(events.changeEvent, m_eventListener.copyRef(), false); >+ textTracks->removeEventListener(events.removetrackEvent, m_eventListener.copyRef(), false); > } >- } >- m_isListening = false; >- >- if (m_mediaElement) > m_mediaElement->resetPlaybackSessionState(); >+ } > > m_mediaElement = mediaElement; > > if (m_mediaElement) { > for (auto& eventName : observedEventNames()) >- m_mediaElement->addEventListener(eventName, *this, false); >+ m_mediaElement->addEventListener(eventName, m_eventListener.copyRef(), false); > > auto& audioTracks = m_mediaElement->ensureAudioTracks(); >- audioTracks.addEventListener(events.addtrackEvent, *this, false); >- audioTracks.addEventListener(events.changeEvent, *this, false); >- audioTracks.addEventListener(events.removetrackEvent, *this, false); >+ audioTracks.addEventListener(events.addtrackEvent, m_eventListener.copyRef(), false); >+ audioTracks.addEventListener(events.changeEvent, m_eventListener.copyRef(), false); >+ audioTracks.addEventListener(events.removetrackEvent, m_eventListener.copyRef(), false); > > auto& textTracks = m_mediaElement->ensureTextTracks(); >- textTracks.addEventListener(events.addtrackEvent, *this, false); >- textTracks.addEventListener(events.changeEvent, *this, false); >- textTracks.addEventListener(events.removetrackEvent, *this, false); >+ textTracks.addEventListener(events.addtrackEvent, m_eventListener.copyRef(), false); >+ textTracks.addEventListener(events.changeEvent, m_eventListener.copyRef(), false); >+ textTracks.addEventListener(events.removetrackEvent, m_eventListener.copyRef(), false); > } > > updateForEventName(eventNameAll()); > } > >-void PlaybackSessionModelMediaElement::handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event& event) >-{ >- updateForEventName(event.type()); >-} >- > void PlaybackSessionModelMediaElement::updateForEventName(const WTF::AtomicString& eventName) > { > if (m_clients.isEmpty()) >@@ -117,51 +129,46 @@ void PlaybackSessionModelMediaElement::updateForEventName(const WTF::AtomicStrin > > if (all > || eventName == eventNames().durationchangeEvent) { >- double duration = this->duration(); >- for (auto client : m_clients) >- client->durationChanged(duration); >+ m_clients.forEachNonNullMember([duration = duration()] (auto& client) { >+ client.durationChanged(duration); >+ }); > // These is no standard event for minFastReverseRateChange; duration change is a reasonable proxy for it. > // It happens every time a new item becomes ready to play. >- bool canPlayFastReverse = this->canPlayFastReverse(); >- for (auto client : m_clients) >- client->canPlayFastReverseChanged(canPlayFastReverse); >+ m_clients.forEachNonNullMember([canPlayFastReverse = canPlayFastReverse()] (auto& client) { >+ client.canPlayFastReverseChanged(canPlayFastReverse); >+ }); > } > > if (all > || eventName == eventNames().playEvent > || eventName == eventNames().playingEvent) { >- for (auto client : m_clients) >- client->playbackStartedTimeChanged(playbackStartedTime()); >+ m_clients.forEachNonNullMember([playbackStartedTime = playbackStartedTime()] (auto& client) { >+ client.playbackStartedTimeChanged(playbackStartedTime); >+ }); > } > > if (all > || eventName == eventNames().pauseEvent > || eventName == eventNames().playEvent > || eventName == eventNames().ratechangeEvent) { >- bool isPlaying = this->isPlaying(); >- float playbackRate = this->playbackRate(); >- for (auto client : m_clients) >- client->rateChanged(isPlaying, playbackRate); >+ m_clients.forEachNonNullMember([isPlaying = isPlaying(), playbackRate = playbackRate()] (auto& client) { >+ client.rateChanged(isPlaying, playbackRate); >+ }); > } > > if (all > || eventName == eventNames().timeupdateEvent) { >- auto currentTime = this->currentTime(); >- auto anchorTime = [[NSProcessInfo processInfo] systemUptime]; >- for (auto client : m_clients) >- client->currentTimeChanged(currentTime, anchorTime); >+ m_clients.forEachNonNullMember([currentTime = currentTime(), anchorTime = [[NSProcessInfo processInfo] systemUptime]] (auto& client) { >+ client.currentTimeChanged(currentTime, anchorTime); >+ }); > } > > if (all > || eventName == eventNames().progressEvent) { >- auto bufferedTime = this->bufferedTime(); >- auto seekableRanges = this->seekableRanges(); >- auto seekableTimeRangesLastModifiedTime = this->seekableTimeRangesLastModifiedTime(); >- auto liveUpdateInterval = this->liveUpdateInterval(); >- for (auto client : m_clients) { >- client->bufferedTimeChanged(bufferedTime); >- client->seekableRangesChanged(seekableRanges, seekableTimeRangesLastModifiedTime, liveUpdateInterval); >- } >+ m_clients.forEachNonNullMember([bufferedTime = bufferedTime(), seekableRanges = seekableRanges(), seekableTimeRangesLastModifiedTime = seekableTimeRangesLastModifiedTime(), liveUpdateInterval = liveUpdateInterval()] (auto& client) { >+ client.bufferedTimeChanged(bufferedTime); >+ client.seekableRangesChanged(seekableRanges, seekableTimeRangesLastModifiedTime, liveUpdateInterval); >+ }); > } > > if (all >@@ -171,24 +178,17 @@ void PlaybackSessionModelMediaElement::updateForEventName(const WTF::AtomicStrin > > if (all > || eventName == eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent) { >- bool enabled = externalPlaybackEnabled(); >- ExternalPlaybackTargetType targetType = externalPlaybackTargetType(); >- String localizedDeviceName = externalPlaybackLocalizedDeviceName(); >- >- bool wirelessVideoPlaybackDisabled = this->wirelessVideoPlaybackDisabled(); >- >- for (auto client : m_clients) { >- client->externalPlaybackChanged(enabled, targetType, localizedDeviceName); >- client->wirelessVideoPlaybackDisabledChanged(wirelessVideoPlaybackDisabled); >- } >+ m_clients.forEachNonNullMember([enabled = externalPlaybackEnabled(), targetType = externalPlaybackTargetType(), localizedDeviceName = externalPlaybackLocalizedDeviceName(), wirelessVideoPlaybackDisabled = wirelessVideoPlaybackDisabled()] (auto& client) { >+ client.externalPlaybackChanged(enabled, targetType, localizedDeviceName); >+ client.wirelessVideoPlaybackDisabledChanged(wirelessVideoPlaybackDisabled); >+ }); > } > > if (all > || eventName == eventNames().webkitpresentationmodechangedEvent) { >- bool isPictureInPictureActive = this->isPictureInPictureActive(); >- >- for (auto client : m_clients) >- client->pictureInPictureActiveChanged(isPictureInPictureActive); >+ m_clients.forEachNonNullMember([isPictureInPictureActive = isPictureInPictureActive()] (auto& client) { >+ client.pictureInPictureActiveChanged(isPictureInPictureActive); >+ }); > } > > >@@ -199,22 +199,20 @@ void PlaybackSessionModelMediaElement::updateForEventName(const WTF::AtomicStrin > > if (all > || eventName == eventNames().volumechangeEvent) { >- for (auto client : m_clients) { >- client->mutedChanged(isMuted()); >- client->volumeChanged(volume()); >- } >+ m_clients.forEachNonNullMember([isMuted = isMuted(), volume = volume()] (auto& client) { >+ client.mutedChanged(isMuted); >+ client.volumeChanged(volume); >+ }); > } > } >-void PlaybackSessionModelMediaElement::addClient(PlaybackSessionModelClient& client) >+void PlaybackSessionModelMediaElement::addClient(WeakPtr<PlaybackSessionModelClient>&& client) > { >- ASSERT(!m_clients.contains(&client)); >- m_clients.add(&client); >+ m_clients.add(WTFMove(client)); > } > > void PlaybackSessionModelMediaElement::removeClient(PlaybackSessionModelClient& client) > { >- ASSERT(m_clients.contains(&client)); >- m_clients.remove(&client); >+ m_clients.remove(client); > } > > void PlaybackSessionModelMediaElement::play() >@@ -346,26 +344,18 @@ void PlaybackSessionModelMediaElement::updateMediaSelectionOptions() > else > m_audioTracksForMenu.clear(); > >- auto audioOptions = audioMediaSelectionOptions(); >- auto audioIndex = audioMediaSelectedIndex(); >- auto legibleOptions = legibleMediaSelectionOptions(); >- auto legibleIndex = legibleMediaSelectedIndex(); >- >- for (auto client : m_clients) { >- client->audioMediaSelectionOptionsChanged(audioOptions, audioIndex); >- client->legibleMediaSelectionOptionsChanged(legibleOptions, legibleIndex); >- } >+ m_clients.forEachNonNullMember([audioOptions = audioMediaSelectionOptions(), audioIndex = audioMediaSelectedIndex(), legibleOptions = legibleMediaSelectionOptions(), legibleIndex = legibleMediaSelectedIndex()] (auto& client) { >+ client.audioMediaSelectionOptionsChanged(audioOptions, audioIndex); >+ client.legibleMediaSelectionOptionsChanged(legibleOptions, legibleIndex); >+ }); > } > > void PlaybackSessionModelMediaElement::updateMediaSelectionIndices() > { >- auto audioIndex = audioMediaSelectedIndex(); >- auto legibleIndex = legibleMediaSelectedIndex(); >- >- for (auto client : m_clients) { >- client->audioMediaSelectionIndexChanged(audioIndex); >- client->legibleMediaSelectionIndexChanged(legibleIndex); >- } >+ m_clients.forEachNonNullMember([audioIndex = audioMediaSelectedIndex(), legibleIndex = legibleMediaSelectedIndex()] (auto& client) { >+ client.audioMediaSelectionIndexChanged(audioIndex); >+ client.legibleMediaSelectionIndexChanged(legibleIndex); >+ }); > } > > double PlaybackSessionModelMediaElement::playbackStartedTime() const >diff --git a/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h b/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h >index 4eb0580c96139dd47e75812e619bc905d6b76ed5..4990813a3909e602cf5566a897f8707194dd6b9b 100644 >--- a/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h >+++ b/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h >@@ -32,7 +32,7 @@ namespace WebCore { > > class VideoFullscreenChangeObserver { > public: >- virtual ~VideoFullscreenChangeObserver() { }; >+ virtual ~VideoFullscreenChangeObserver() = default; > virtual void requestUpdateInlineRect() = 0; > virtual void requestVideoContentLayer() = 0; > virtual void returnVideoContentLayer() = 0; >diff --git a/Source/WebCore/platform/cocoa/VideoFullscreenModel.h b/Source/WebCore/platform/cocoa/VideoFullscreenModel.h >index ce513541642ffba32f7db6b8037b60b8007d1eed..6d1b7e98a9e35b67a2c371cba60afc388b6ab5be 100644 >--- a/Source/WebCore/platform/cocoa/VideoFullscreenModel.h >+++ b/Source/WebCore/platform/cocoa/VideoFullscreenModel.h >@@ -30,7 +30,7 @@ > > #include "FloatRect.h" > #include "HTMLMediaElementEnums.h" >-#include "PlaybackSessionModel.h" >+#include <wtf/WeakPtr.h> > > #if PLATFORM(IOS) > OBJC_CLASS AVPlayerViewController; >@@ -43,8 +43,15 @@ class VideoFullscreenModelClient; > > class VideoFullscreenModel { > public: >- virtual ~VideoFullscreenModel() { }; >- virtual void addClient(VideoFullscreenModelClient&) = 0; >+ virtual ~VideoFullscreenModel() = default; >+ >+ void ref() { refVideoFullscreenModel(); } >+ void deref() { derefVideoFullscreenModel(); } >+ >+ virtual void refVideoFullscreenModel() = 0; >+ virtual void derefVideoFullscreenModel() = 0; >+ >+ virtual void addClient(WeakPtr<VideoFullscreenModelClient>&&) = 0; > virtual void removeClient(VideoFullscreenModelClient&)= 0; > > virtual void requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia = false) = 0; >diff --git a/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.h b/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.h >index 037dd02b61d3b1a824b3f9c0ec161d599f310de7..8268da5a024371d1ddfbba182196035ad95b53e4 100644 >--- a/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.h >+++ b/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.h >@@ -28,16 +28,14 @@ > > #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) > >-#include "EventListener.h" > #include "FloatRect.h" > #include "HTMLMediaElementEnums.h" > #include "PlatformLayer.h" > #include "VideoFullscreenModel.h" > #include <wtf/Function.h> >-#include <wtf/HashSet.h> > #include <wtf/RefPtr.h> > #include <wtf/RetainPtr.h> >-#include <wtf/Vector.h> >+#include <wtf/WeakPtrContainer.h> > > namespace WebCore { > class AudioTrack; >@@ -45,7 +43,10 @@ class HTMLVideoElement; > class TextTrack; > class PlaybackSessionModelMediaElement; > >-class VideoFullscreenModelVideoElement : public VideoFullscreenModel, public EventListener { >+class VideoFullscreenModelVideoElement >+ : public RefCounted<VideoFullscreenModelVideoElement> >+ , public CanMakeWeakPtr<VideoFullscreenModelVideoElement> >+ , public VideoFullscreenModel { > public: > static RefPtr<VideoFullscreenModelVideoElement> create() > { >@@ -58,11 +59,9 @@ public: > WEBCORE_EXPORT void willExitFullscreen(); > WEBCORE_EXPORT void waitForPreparedForInlineThen(WTF::Function<void()>&& completionHandler = [] { }); > >- WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event&) override; > void updateForEventName(const WTF::AtomicString&); >- bool operator==(const EventListener& rhs) const override { return static_cast<const WebCore::EventListener*>(this) == &rhs; } > >- WEBCORE_EXPORT void addClient(VideoFullscreenModelClient&) override; >+ WEBCORE_EXPORT void addClient(WeakPtr<VideoFullscreenModelClient>&&) override; > WEBCORE_EXPORT void removeClient(VideoFullscreenModelClient&) override; > WEBCORE_EXPORT void requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia = false) override; > WEBCORE_EXPORT void setVideoLayerFrame(FloatRect) override; >@@ -72,6 +71,8 @@ public: > FloatSize videoDimensions() const override { return m_videoDimensions; } > bool hasVideo() const override { return m_hasVideo; } > >+ using RefCounted::ref; >+ using RefCounted::deref; > > protected: > WEBCORE_EXPORT VideoFullscreenModelVideoElement(); >@@ -80,6 +81,8 @@ private: > void setHasVideo(bool); > void setVideoDimensions(const FloatSize&); > >+ void refVideoFullscreenModel() final { ref(); } >+ void derefVideoFullscreenModel() final { deref(); } > void willEnterPictureInPicture() override; > void didEnterPictureInPicture() override; > void failedToEnterPictureInPicture() override; >@@ -89,15 +92,17 @@ private: > static const Vector<WTF::AtomicString>& observedEventNames(); > const WTF::AtomicString& eventNameAll(); > >+ class MediaElementEventListener; >+ > RefPtr<HTMLVideoElement> m_videoElement; > RetainPtr<PlatformLayer> m_videoFullscreenLayer; >- bool m_isListening { false }; >- HashSet<VideoFullscreenModelClient*> m_clients; >+ WeakPtrContainer<VideoFullscreenModelClient> m_clients; > bool m_hasVideo { false }; > FloatSize m_videoDimensions; > FloatRect m_videoFrame; > Vector<RefPtr<TextTrack>> m_legibleTracksForMenu; > Vector<RefPtr<AudioTrack>> m_audioTracksForMenu; >+ Ref<MediaElementEventListener> m_eventListener; > }; > > } >diff --git a/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.mm b/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.mm >index c0a4fa5f0eb5af0f87f585dcca5d65706a7f504e..a861cc7fd1bd6b7d72177b8bbe518546f574d75c 100644 >--- a/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.mm >+++ b/Source/WebCore/platform/cocoa/VideoFullscreenModelVideoElement.mm >@@ -47,8 +47,27 @@ > > using namespace WebCore; > >+ >+class VideoFullscreenModelVideoElement::MediaElementEventListener final : public EventListener { >+public: >+ MediaElementEventListener(WeakPtr<VideoFullscreenModelVideoElement>&& parent) >+ : EventListener(CPPEventListenerType) >+ , m_parent(WTFMove(parent)) >+ { >+ } >+private: >+ void handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event& event) final >+ { >+ if (m_parent) >+ m_parent->updateForEventName(event.type()); >+ } >+ bool operator==(const EventListener& rhs) const final { return static_cast<const WebCore::EventListener*>(this) == &rhs; } >+ >+ WeakPtr<VideoFullscreenModelVideoElement> m_parent; >+}; >+ > VideoFullscreenModelVideoElement::VideoFullscreenModelVideoElement() >- : EventListener(EventListener::CPPEventListenerType) >+ : m_eventListener(adoptRef(*new MediaElementEventListener(makeWeakPtr(*this)))) > { > } > >@@ -64,28 +83,21 @@ void VideoFullscreenModelVideoElement::setVideoElement(HTMLVideoElement* videoEl > if (m_videoElement && m_videoElement->videoFullscreenLayer()) > m_videoElement->setVideoFullscreenLayer(nullptr); > >- if (m_videoElement && m_isListening) { >+ if (m_videoElement) { > for (auto& eventName : observedEventNames()) >- m_videoElement->removeEventListener(eventName, *this, false); >+ m_videoElement->removeEventListener(eventName, m_eventListener.copyRef(), false); > } >- m_isListening = false; > > m_videoElement = videoElement; > > if (m_videoElement) { > for (auto& eventName : observedEventNames()) >- m_videoElement->addEventListener(eventName, *this, false); >- m_isListening = true; >+ m_videoElement->addEventListener(eventName, m_eventListener.copyRef(), false); > } > > updateForEventName(eventNameAll()); > } > >-void VideoFullscreenModelVideoElement::handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event& event) >-{ >- updateForEventName(event.type()); >-} >- > void VideoFullscreenModelVideoElement::updateForEventName(const WTF::AtomicString& eventName) > { > if (m_clients.isEmpty()) >@@ -195,16 +207,14 @@ void VideoFullscreenModelVideoElement::fullscreenModeChanged(HTMLMediaElementEnu > m_videoElement->fullscreenModeChanged(videoFullscreenMode); > } > >-void VideoFullscreenModelVideoElement::addClient(VideoFullscreenModelClient& client) >+void VideoFullscreenModelVideoElement::addClient(WeakPtr<VideoFullscreenModelClient>&& client) > { >- ASSERT(!m_clients.contains(&client)); >- m_clients.add(&client); >+ m_clients.add(WTFMove(client)); > } > > void VideoFullscreenModelVideoElement::removeClient(VideoFullscreenModelClient& client) > { >- ASSERT(m_clients.contains(&client)); >- m_clients.remove(&client); >+ m_clients.remove(client); > } > > bool VideoFullscreenModelVideoElement::isVisible() const >@@ -225,8 +235,9 @@ void VideoFullscreenModelVideoElement::setHasVideo(bool hasVideo) > > m_hasVideo = hasVideo; > >- for (auto& client : m_clients) >- client->hasVideoChanged(m_hasVideo); >+ m_clients.forEachNonNullMember([hasVideo] (auto& client) { >+ client.hasVideoChanged(hasVideo); >+ }); > } > > void VideoFullscreenModelVideoElement::setVideoDimensions(const FloatSize& videoDimensions) >@@ -236,38 +247,44 @@ void VideoFullscreenModelVideoElement::setVideoDimensions(const FloatSize& video > > m_videoDimensions = videoDimensions; > >- for (auto& client : m_clients) >- client->videoDimensionsChanged(m_videoDimensions); >+ m_clients.forEachNonNullMember([videoDimensions] (auto& client) { >+ client.videoDimensionsChanged(videoDimensions); >+ }); > } > > void VideoFullscreenModelVideoElement::willEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->willEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.willEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelVideoElement::didEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->didEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.didEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelVideoElement::failedToEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->failedToEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.failedToEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelVideoElement::willExitPictureInPicture() > { >- for (auto& client : m_clients) >- client->willExitPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.willExitPictureInPicture(); >+ }); > } > > void VideoFullscreenModelVideoElement::didExitPictureInPicture() > { >- for (auto& client : m_clients) >- client->didExitPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.didExitPictureInPicture(); >+ }); > } > > #endif >diff --git a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h >index 85801915e0f019680df47c816c0bddb5b60bc393..42230189034504e3781c97464ff16160dd1e082d 100644 >--- a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h >+++ b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h >@@ -51,18 +51,17 @@ class IntRect; > class PlaybackSessionModel; > class WebPlaybackSessionChangeObserver; > >-class WEBCORE_EXPORT PlaybackSessionInterfaceAVKit >+class PlaybackSessionInterfaceAVKit > : public PlaybackSessionInterface > , public PlaybackSessionModelClient > , public RefCounted<PlaybackSessionInterfaceAVKit> { >- > public: >- static Ref<PlaybackSessionInterfaceAVKit> create(PlaybackSessionModel& model) >+ static Ref<PlaybackSessionInterfaceAVKit> create(Ref<PlaybackSessionModel>&& model) > { >- return adoptRef(*new PlaybackSessionInterfaceAVKit(model)); >+ return adoptRef(*new PlaybackSessionInterfaceAVKit(WTFMove(model))); > } > virtual ~PlaybackSessionInterfaceAVKit(); >- PlaybackSessionModel* playbackSessionModel() const { return m_playbackSessionModel; } >+ PlaybackSessionModel& playbackSessionModel() const { return m_playbackSessionModel; } > > // PlaybackSessionInterface > WEBCORE_EXPORT void resetMediaState() override; >@@ -81,15 +80,14 @@ public: > WEBCORE_EXPORT void mutedChanged(bool) override; > WEBCORE_EXPORT void volumeChanged(double) override; > >- WEBCORE_EXPORT virtual void invalidate(); >- > WebAVPlayerController *playerController() const { return m_playerController.get(); } > > protected: >- WEBCORE_EXPORT PlaybackSessionInterfaceAVKit(PlaybackSessionModel&); >+ WEBCORE_EXPORT PlaybackSessionInterfaceAVKit(Ref<PlaybackSessionModel>&&); > > RetainPtr<WebAVPlayerController> m_playerController; >- PlaybackSessionModel* m_playbackSessionModel { nullptr }; >+ Ref<PlaybackSessionModel> m_playbackSessionModel; >+ WeakPtrFactory<PlaybackSessionModelClient> m_weakPtrFactory; > }; > > } >diff --git a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm >index 0a28548b7f5951619534432da9a0007ddb9ae864..da03ebe22d3d441ebe28f38f3cce428843fae427 100644 >--- a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm >+++ b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm >@@ -49,32 +49,30 @@ SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming) > namespace WebCore { > using namespace PAL; > >-PlaybackSessionInterfaceAVKit::PlaybackSessionInterfaceAVKit(PlaybackSessionModel& model) >+PlaybackSessionInterfaceAVKit::PlaybackSessionInterfaceAVKit(Ref<PlaybackSessionModel>&& model) > : m_playerController(adoptNS([[WebAVPlayerController alloc] init])) >- , m_playbackSessionModel(&model) >+ , m_playbackSessionModel(WTFMove(model)) > { >- model.addClient(*this); >+ m_playbackSessionModel->addClient(m_weakPtrFactory.createWeakPtr(*this)); > [m_playerController setPlaybackSessionInterface:this]; >- [m_playerController setDelegate:&model]; > >- durationChanged(model.duration()); >- currentTimeChanged(model.currentTime(), [[NSProcessInfo processInfo] systemUptime]); >- bufferedTimeChanged(model.bufferedTime()); >- rateChanged(model.isPlaying(), model.playbackRate()); >- seekableRangesChanged(model.seekableRanges(), model.seekableTimeRangesLastModifiedTime(), model.liveUpdateInterval()); >- canPlayFastReverseChanged(model.canPlayFastReverse()); >- audioMediaSelectionOptionsChanged(model.audioMediaSelectionOptions(), model.audioMediaSelectedIndex()); >- legibleMediaSelectionOptionsChanged(model.legibleMediaSelectionOptions(), model.legibleMediaSelectedIndex()); >- externalPlaybackChanged(model.externalPlaybackEnabled(), model.externalPlaybackTargetType(), model.externalPlaybackLocalizedDeviceName()); >- wirelessVideoPlaybackDisabledChanged(model.wirelessVideoPlaybackDisabled()); >+ durationChanged(m_playbackSessionModel->duration()); >+ currentTimeChanged(m_playbackSessionModel->currentTime(), [[NSProcessInfo processInfo] systemUptime]); >+ bufferedTimeChanged(m_playbackSessionModel->bufferedTime()); >+ rateChanged(m_playbackSessionModel->isPlaying(), m_playbackSessionModel->playbackRate()); >+ seekableRangesChanged(m_playbackSessionModel->seekableRanges(), m_playbackSessionModel->seekableTimeRangesLastModifiedTime(), m_playbackSessionModel->liveUpdateInterval()); >+ canPlayFastReverseChanged(m_playbackSessionModel->canPlayFastReverse()); >+ audioMediaSelectionOptionsChanged(m_playbackSessionModel->audioMediaSelectionOptions(), m_playbackSessionModel->audioMediaSelectedIndex()); >+ legibleMediaSelectionOptionsChanged(m_playbackSessionModel->legibleMediaSelectionOptions(), m_playbackSessionModel->legibleMediaSelectedIndex()); >+ externalPlaybackChanged(m_playbackSessionModel->externalPlaybackEnabled(), m_playbackSessionModel->externalPlaybackTargetType(), m_playbackSessionModel->externalPlaybackLocalizedDeviceName()); >+ wirelessVideoPlaybackDisabledChanged(m_playbackSessionModel->wirelessVideoPlaybackDisabled()); > } > > PlaybackSessionInterfaceAVKit::~PlaybackSessionInterfaceAVKit() > { >+ m_playbackSessionModel->removeClient(*this); > [m_playerController setPlaybackSessionInterface:nullptr]; > [m_playerController setExternalPlaybackActive:false]; >- >- invalidate(); > } > > void PlaybackSessionInterfaceAVKit::resetMediaState() >@@ -206,16 +204,6 @@ void PlaybackSessionInterfaceAVKit::volumeChanged(double volume) > [m_playerController volumeChanged:volume]; > } > >-void PlaybackSessionInterfaceAVKit::invalidate() >-{ >- if (!m_playbackSessionModel) >- return; >- >- [m_playerController setDelegate:nullptr]; >- m_playbackSessionModel->removeClient(*this); >- m_playbackSessionModel = nullptr; >-} >- > } > > #endif // HAVE(AVKIT) >diff --git a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h >index c6d2ead9542cf843420ce953cd3f24f9272bdec6..8ee2a9586baf2b1f938a70571539f5897cd29447 100644 >--- a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h >+++ b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h >@@ -40,6 +40,7 @@ > #include <wtf/RefPtr.h> > #include <wtf/RetainPtr.h> > #include <wtf/RunLoop.h> >+#include <wtf/WeakPtr.h> > > OBJC_CLASS UIViewController; > OBJC_CLASS UIWindow; >@@ -64,12 +65,11 @@ class VideoFullscreenInterfaceAVKit final > , public ThreadSafeRefCounted<VideoFullscreenInterfaceAVKit> { > > public: >- WEBCORE_EXPORT static Ref<VideoFullscreenInterfaceAVKit> create(PlaybackSessionInterfaceAVKit&); >+ WEBCORE_EXPORT static Ref<VideoFullscreenInterfaceAVKit> create(Ref<PlaybackSessionInterfaceAVKit>&&, Ref<VideoFullscreenModel>&&); > virtual ~VideoFullscreenInterfaceAVKit(); >- WEBCORE_EXPORT void setVideoFullscreenModel(VideoFullscreenModel*); >- WEBCORE_EXPORT void setVideoFullscreenChangeObserver(VideoFullscreenChangeObserver*); >+ WEBCORE_EXPORT void setVideoFullscreenChangeObserver(WeakPtr<VideoFullscreenChangeObserver>); > PlaybackSessionInterfaceAVKit& playbackSessionInterface() const { return m_playbackSessionInterface.get(); } >- PlaybackSessionModel* playbackSessionModel() const { return m_playbackSessionInterface->playbackSessionModel(); } >+ PlaybackSessionModel& playbackSessionModel() const { return m_playbackSessionInterface->playbackSessionModel(); } > > // VideoFullscreenModelClient > WEBCORE_EXPORT void hasVideoChanged(bool) final; >@@ -82,7 +82,6 @@ public: > WEBCORE_EXPORT void enterFullscreen(); > WEBCORE_EXPORT void exitFullscreen(const IntRect& finalRect); > WEBCORE_EXPORT void cleanupFullscreen(); >- WEBCORE_EXPORT void invalidate(); > WEBCORE_EXPORT void requestHideAndExitFullscreen(); > WEBCORE_EXPORT void preparedToReturnToInline(bool visible, const IntRect& inlineRect); > WEBCORE_EXPORT void preparedToExitFullscreen(); >@@ -131,7 +130,7 @@ public: > Mode m_targetMode; > #endif > >- VideoFullscreenModel* videoFullscreenModel() const { return m_videoFullscreenModel; } >+ VideoFullscreenModel& videoFullscreenModel() const { return m_videoFullscreenModel; } > bool shouldExitFullscreenWithReason(ExitFullScreenReason); > HTMLMediaElementEnums::VideoFullscreenMode mode() const { return m_currentMode.mode(); } > bool allowsPictureInPicturePlayback() const { return m_allowsPictureInPicturePlayback; } >@@ -164,7 +163,7 @@ public: > #endif > > protected: >- WEBCORE_EXPORT VideoFullscreenInterfaceAVKit(PlaybackSessionInterfaceAVKit&); >+ WEBCORE_EXPORT VideoFullscreenInterfaceAVKit(Ref<PlaybackSessionInterfaceAVKit>&&, Ref<VideoFullscreenModel>&&); > > #if ENABLE(FULLSCREEN_API) > void doSetup(); >@@ -180,10 +179,10 @@ protected: > WebAVPlayerController *playerController() const; > > Ref<PlaybackSessionInterfaceAVKit> m_playbackSessionInterface; >+ Ref<VideoFullscreenModel> m_videoFullscreenModel; > RetainPtr<WebAVPlayerViewControllerDelegate> m_playerViewControllerDelegate; > RetainPtr<WebAVPlayerViewController> m_playerViewController; >- VideoFullscreenModel* m_videoFullscreenModel { nullptr }; >- VideoFullscreenChangeObserver* m_fullscreenChangeObserver { nullptr }; >+ WeakPtr<VideoFullscreenChangeObserver> m_fullscreenChangeObserver; > > // These are only used when fullscreen is presented in a separate window. > RetainPtr<UIWindow> m_window; >diff --git a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm >index 5cc320e19dad39c009c73368a5871c86093e8b7d..73244eec2eb51f208f6d36e196c413161a85cf2c 100644 >--- a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm >+++ b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm >@@ -289,8 +289,7 @@ - (void)layoutSublayers > } else if ([getAVLayerVideoGravityResizeAspectFill() isEqualToString:self.videoGravity]) { > sourceVideoFrame = smallestRectWithAspectRatioAroundRect(videoAspectRatio, self.modelVideoLayerFrame); > self.modelVideoLayerFrame = CGRectMake(0, 0, sourceVideoFrame.width(), sourceVideoFrame.height()); >- if (auto* model = _fullscreenInterface->videoFullscreenModel()) >- model->setVideoLayerFrame(self.modelVideoLayerFrame); >+ _fullscreenInterface->videoFullscreenModel().setVideoLayerFrame(self.modelVideoLayerFrame); > targetVideoFrame = smallestRectWithAspectRatioAroundRect(videoAspectRatio, self.bounds); > } else > ASSERT_NOT_REACHED(); >@@ -325,8 +324,7 @@ - (void)resolveBounds > > if (!CGRectEqualToRect(self.modelVideoLayerFrame, [self bounds])) { > self.modelVideoLayerFrame = [self bounds]; >- if (auto* model = _fullscreenInterface->videoFullscreenModel()) >- model->setVideoLayerFrame(self.modelVideoLayerFrame); >+ _fullscreenInterface->videoFullscreenModel().setVideoLayerFrame(self.modelVideoLayerFrame); > } > [(UIView *)[_videoSublayer delegate] setTransform:CGAffineTransformIdentity]; > >@@ -350,8 +348,7 @@ - (void)setVideoGravity:(NSString *)videoGravity > else > ASSERT_NOT_REACHED(); > >- if (auto* model = _fullscreenInterface->videoFullscreenModel()) >- model->setVideoLayerGravity(gravity); >+ _fullscreenInterface->videoFullscreenModel().setVideoLayerGravity(gravity); > } > > - (NSString *)videoGravity >@@ -725,15 +722,16 @@ - (void)removeFromParentViewController > } > @end > >-Ref<VideoFullscreenInterfaceAVKit> VideoFullscreenInterfaceAVKit::create(PlaybackSessionInterfaceAVKit& playbackSessionInterface) >+Ref<VideoFullscreenInterfaceAVKit> VideoFullscreenInterfaceAVKit::create(Ref<PlaybackSessionInterfaceAVKit>&& playbackSessionInterface, Ref<VideoFullscreenModel>&& videoFullscreenModel) > { >- Ref<VideoFullscreenInterfaceAVKit> interface = adoptRef(*new VideoFullscreenInterfaceAVKit(playbackSessionInterface)); >+ Ref<VideoFullscreenInterfaceAVKit> interface = adoptRef(*new VideoFullscreenInterfaceAVKit(WTFMove(playbackSessionInterface), WTFMove(videoFullscreenModel))); > [interface->m_playerViewControllerDelegate setFullscreenInterface:interface.ptr()]; > return interface; > } > >-VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit(PlaybackSessionInterfaceAVKit& playbackSessionInterface) >- : m_playbackSessionInterface(playbackSessionInterface) >+VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit(Ref<PlaybackSessionInterfaceAVKit>&& playbackSessionInterface, Ref<VideoFullscreenModel>&& videoFullscreenModel) >+ : m_playbackSessionInterface(WTFMove(playbackSessionInterface)) >+ , m_videoFullscreenModel(WTFMove(videoFullscreenModel)) > , m_playerViewControllerDelegate(adoptNS([[WebAVPlayerViewControllerDelegate alloc] init])) > , m_watchdogTimer(RunLoop::main(), this, &VideoFullscreenInterfaceAVKit::watchdogTimerFired) > { >@@ -744,8 +742,7 @@ VideoFullscreenInterfaceAVKit::~VideoFullscreenInterfaceAVKit() > WebAVPlayerController* playerController = this->playerController(); > if (playerController && playerController.externalPlaybackActive) > externalPlaybackChanged(false, PlaybackSessionModel::TargetTypeNone, ""); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->removeClient(*this); >+ videoFullscreenModel().removeClient(*this); > } > > WebAVPlayerController *VideoFullscreenInterfaceAVKit::playerController() const >@@ -753,21 +750,7 @@ WebAVPlayerController *VideoFullscreenInterfaceAVKit::playerController() const > return m_playbackSessionInterface->playerController(); > } > >-void VideoFullscreenInterfaceAVKit::setVideoFullscreenModel(VideoFullscreenModel* model) >-{ >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->removeClient(*this); >- >- m_videoFullscreenModel = model; >- >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->addClient(*this); >- >- hasVideoChanged(m_videoFullscreenModel ? m_videoFullscreenModel->hasVideo() : false); >- videoDimensionsChanged(m_videoFullscreenModel ? m_videoFullscreenModel->videoDimensions() : FloatSize()); >-} >- >-void VideoFullscreenInterfaceAVKit::setVideoFullscreenChangeObserver(VideoFullscreenChangeObserver* observer) >+void VideoFullscreenInterfaceAVKit::setVideoFullscreenChangeObserver(WeakPtr<VideoFullscreenChangeObserver> observer) > { > m_fullscreenChangeObserver = observer; > } >@@ -807,7 +790,7 @@ bool VideoFullscreenInterfaceAVKit::pictureInPictureWasStartedWhenEnteringBackgr > void VideoFullscreenInterfaceAVKit::applicationDidBecomeActive() > { > LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::applicationDidBecomeActive(%p)", this); >- if (m_shouldReturnToFullscreenAfterEnteringForeground && m_videoFullscreenModel && m_videoFullscreenModel->isVisible()) { >+ if (m_shouldReturnToFullscreenAfterEnteringForeground && videoFullscreenModel().isVisible()) { > [m_playerViewController stopPictureInPicture]; > return; > } >@@ -884,7 +867,7 @@ void VideoFullscreenInterfaceAVKit::setupFullscreen(UIView& videoView, const Int > [playerController() setPictureInPicturePossible:m_allowsPictureInPicturePlayback]; > > #if PLATFORM(WATCHOS) >- m_viewController = videoFullscreenModel()->createVideoFullscreenViewController(m_playerViewController.get().avPlayerViewController); >+ m_viewController = videoFullscreenModel().createVideoFullscreenViewController(m_playerViewController.get().avPlayerViewController); > #endif > > if (m_viewController) { >@@ -949,7 +932,7 @@ static UIViewController *fallbackViewController(UIView *view) > > UIViewController *VideoFullscreenInterfaceAVKit::presentingViewController() > { >- auto *controller = videoFullscreenModel()->presentingViewController(); >+ auto *controller = videoFullscreenModel().presentingViewController(); > if (!controller) > controller = fallbackViewController(m_parentView.get()); > >@@ -1077,14 +1060,6 @@ void VideoFullscreenInterfaceAVKit::cleanupFullscreen() > m_enterRequested = false; > } > >-void VideoFullscreenInterfaceAVKit::invalidate() >-{ >- m_videoFullscreenModel = nil; >- m_fullscreenChangeObserver = nil; >- >- cleanupFullscreen(); >-} >- > void VideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen() > { > if (!m_enterRequested) >@@ -1098,9 +1073,9 @@ void VideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen() > [m_window setHidden:YES]; > [[m_playerViewController view] setHidden:YES]; > >- if (playbackSessionModel() && m_videoFullscreenModel && !m_exitRequested) { >- playbackSessionModel()->pause(); >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >+ if (!m_exitRequested) { >+ playbackSessionModel().pause(); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > } > } > >@@ -1120,7 +1095,7 @@ void VideoFullscreenInterfaceAVKit::preparedToExitFullscreen() > return; > > m_waitingForPreparedToExit = false; >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, true); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, true); > } > > bool VideoFullscreenInterfaceAVKit::mayAutomaticallyShowVideoPictureInPicture() const >@@ -1139,8 +1114,7 @@ void VideoFullscreenInterfaceAVKit::willStartPictureInPicture() > { > LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::willStartPictureInPicture(%p)", this); > setMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->willEnterPictureInPicture(); >+ videoFullscreenModel().willEnterPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::didStartPictureInPicture() >@@ -1166,8 +1140,7 @@ void VideoFullscreenInterfaceAVKit::didStartPictureInPicture() > > if (m_fullscreenChangeObserver) > m_fullscreenChangeObserver->didEnterFullscreen(); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->didEnterPictureInPicture(); >+ videoFullscreenModel().didEnterPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture() >@@ -1182,11 +1155,8 @@ void VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture() > > if (m_fullscreenChangeObserver) > m_fullscreenChangeObserver->didEnterFullscreen(); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->failedToEnterPictureInPicture(); >- >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >+ videoFullscreenModel().failedToEnterPictureInPicture(); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > } > > void VideoFullscreenInterfaceAVKit::willStopPictureInPicture() >@@ -1202,10 +1172,8 @@ void VideoFullscreenInterfaceAVKit::willStopPictureInPicture() > [m_window setHidden:NO]; > [[m_playerViewController view] setHidden:NO]; > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->willExitPictureInPicture(); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >+ videoFullscreenModel().willExitPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::didStopPictureInPicture() >@@ -1228,8 +1196,7 @@ void VideoFullscreenInterfaceAVKit::didStopPictureInPicture() > > if (m_fullscreenChangeObserver) > m_fullscreenChangeObserver->didExitFullscreen(); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->didExitPictureInPicture(); >+ videoFullscreenModel().didExitPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler(void (^completionHandler)(BOOL restored)) >@@ -1266,9 +1233,6 @@ void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletion > > bool VideoFullscreenInterfaceAVKit::shouldExitFullscreenWithReason(VideoFullscreenInterfaceAVKit::ExitFullScreenReason reason) > { >- if (!m_videoFullscreenModel) >- return true; >- > if (reason == ExitFullScreenReason::PictureInPictureStarted) { > if (pictureInPictureWasStartedWhenEnteringBackground()) > return false; >@@ -1278,8 +1242,8 @@ bool VideoFullscreenInterfaceAVKit::shouldExitFullscreenWithReason(VideoFullscre > return true; > } > >- if (playbackSessionModel() && (reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::RemoteControlStopEventReceived)) >- playbackSessionModel()->pause(); >+ if (reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::RemoteControlStopEventReceived) >+ playbackSessionModel().pause(); > > if (!m_watchdogTimer.isActive() && !ignoreWatchdogForDebugging) > m_watchdogTimer.startOneShot(defaultWatchdogTimerInterval); >@@ -1293,7 +1257,7 @@ bool VideoFullscreenInterfaceAVKit::shouldExitFullscreenWithReason(VideoFullscre > #endif > > BOOL finished = reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::PinchGestureHandled; >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, finished); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, finished); > > return false; > } >@@ -1385,14 +1349,6 @@ void VideoFullscreenInterfaceAVKit::cleanupFullscreen() > m_fullscreenChangeObserver->didCleanupFullscreen(); > } > >-void VideoFullscreenInterfaceAVKit::invalidate() >-{ >- m_videoFullscreenModel = nil; >- m_fullscreenChangeObserver = nil; >- >- cleanupFullscreen(); >-} >- > void VideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen() > { > if (m_currentMode.hasPictureInPicture()) >@@ -1403,10 +1359,8 @@ void VideoFullscreenInterfaceAVKit::requestHideAndExitFullscreen() > [m_window setHidden:YES]; > [[m_playerViewController view] setHidden:YES]; > >- if (playbackSessionModel() && m_videoFullscreenModel) { >- playbackSessionModel()->pause(); >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >- } >+ playbackSessionModel().pause(); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > } > > void VideoFullscreenInterfaceAVKit::preparedToReturnToInline(bool visible, const IntRect& inlineRect) >@@ -1445,8 +1399,7 @@ void VideoFullscreenInterfaceAVKit::willStartPictureInPicture() > > if (!m_hasVideoContentLayer) > m_fullscreenChangeObserver->requestVideoContentLayer(); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->willEnterPictureInPicture(); >+ videoFullscreenModel().willEnterPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::didStartPictureInPicture() >@@ -1466,8 +1419,7 @@ void VideoFullscreenInterfaceAVKit::didStartPictureInPicture() > [[m_playerViewController view] setHidden:YES]; > } > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->didEnterPictureInPicture(); >+ videoFullscreenModel().didEnterPictureInPicture(); > > if (m_enterFullscreenNeedsEnterPictureInPicture) > doEnterFullscreen(); >@@ -1485,11 +1437,8 @@ void VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture() > if (m_fullscreenChangeObserver) > m_fullscreenChangeObserver->didEnterFullscreen(); > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->failedToEnterPictureInPicture(); >- >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >+ videoFullscreenModel().failedToEnterPictureInPicture(); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > } > > void VideoFullscreenInterfaceAVKit::willStopPictureInPicture() >@@ -1504,8 +1453,7 @@ void VideoFullscreenInterfaceAVKit::willStopPictureInPicture() > [m_window setHidden:NO]; > [[m_playerViewController view] setHidden:NO]; > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->willExitPictureInPicture(); >+ videoFullscreenModel().willExitPictureInPicture(); > } > > void VideoFullscreenInterfaceAVKit::didStopPictureInPicture() >@@ -1525,13 +1473,11 @@ void VideoFullscreenInterfaceAVKit::didStopPictureInPicture() > [m_playerLayerView setBackgroundColor:clearUIColor()]; > [[m_playerViewController view] setBackgroundColor:clearUIColor()]; > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > > clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture); > >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->didExitPictureInPicture(); >+ videoFullscreenModel().didExitPictureInPicture(); > > if (m_enterFullscreenNeedsExitPictureInPicture) > doEnterFullscreen(); >@@ -1567,17 +1513,14 @@ void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletion > > bool VideoFullscreenInterfaceAVKit::shouldExitFullscreenWithReason(VideoFullscreenInterfaceAVKit::ExitFullScreenReason reason) > { >- if (!m_videoFullscreenModel) >- return true; >- > if (reason == ExitFullScreenReason::PictureInPictureStarted) > return false; > >- if (playbackSessionModel() && (reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::RemoteControlStopEventReceived)) >- playbackSessionModel()->pause(); >+ if (reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::RemoteControlStopEventReceived) >+ playbackSessionModel().pause(); > > BOOL finished = reason == ExitFullScreenReason::DoneButtonTapped || reason == ExitFullScreenReason::PinchGestureHandled; >- m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, finished); >+ videoFullscreenModel().requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone, finished); > > if (!m_watchdogTimer.isActive() && !ignoreWatchdogForDebugging) > m_watchdogTimer.startOneShot(defaultWatchdogTimerInterval); >@@ -1672,8 +1615,7 @@ void VideoFullscreenInterfaceAVKit::doSetup() > [playerLayer setModelVideoLayerFrame:modelVideoLayerFrame]; > [playerLayer setVideoDimensions:[playerController() contentDimensions]]; > playerLayer.fullscreenInterface = this; >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->setVideoLayerFrame(modelVideoLayerFrame); >+ videoFullscreenModel().setVideoLayerFrame(modelVideoLayerFrame); > > if (!m_playerViewController) > m_playerViewController = adoptNS([[WebAVPlayerViewController alloc] initWithFullscreenInterface:this]); >@@ -1685,7 +1627,7 @@ void VideoFullscreenInterfaceAVKit::doSetup() > [playerController() setPictureInPicturePossible:m_allowsPictureInPicturePlayback]; > > #if PLATFORM(WATCHOS) >- m_viewController = videoFullscreenModel()->createVideoFullscreenViewController(m_playerViewController.get().avPlayerViewController); >+ m_viewController = videoFullscreenModel().createVideoFullscreenViewController(m_playerViewController.get().avPlayerViewController); > #endif > > if (m_viewController) { >@@ -1892,8 +1834,7 @@ void VideoFullscreenInterfaceAVKit::setMode(HTMLMediaElementEnums::VideoFullscre > return; > > m_currentMode.setMode(mode); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->fullscreenModeChanged(m_currentMode.mode()); >+ videoFullscreenModel().fullscreenModeChanged(m_currentMode.mode()); > } > > void VideoFullscreenInterfaceAVKit::clearMode(HTMLMediaElementEnums::VideoFullscreenMode mode) >@@ -1902,8 +1843,7 @@ void VideoFullscreenInterfaceAVKit::clearMode(HTMLMediaElementEnums::VideoFullsc > return; > > m_currentMode.clearMode(mode); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->fullscreenModeChanged(m_currentMode.mode()); >+ videoFullscreenModel().fullscreenModeChanged(m_currentMode.mode()); > } > > bool VideoFullscreenInterfaceAVKit::isPlayingVideoInEnhancedFullscreen() const >diff --git a/Source/WebCore/platform/ios/WebAVPlayerController.h b/Source/WebCore/platform/ios/WebAVPlayerController.h >index a45346cddc0f475a91a3897b5aa263b7f81c7225..1e78ab06fe4b47b13d6030501a453412d2c26862 100644 >--- a/Source/WebCore/platform/ios/WebAVPlayerController.h >+++ b/Source/WebCore/platform/ios/WebAVPlayerController.h >@@ -26,6 +26,7 @@ > #if PLATFORM(IOS) && HAVE(AVKIT) > > #import <pal/spi/cocoa/AVKitSPI.h> >+#import <wtf/WeakPtr.h> > > namespace WebCore { > class PlaybackSessionModel; >@@ -39,13 +40,14 @@ class PlaybackSessionInterfaceAVKit; > @interface WebAVPlayerController : NSObject { > WebAVMediaSelectionOption *_currentAudioMediaSelectionOption; > WebAVMediaSelectionOption *_currentLegibleMediaSelectionOption; >+ RefPtr<WebCore::PlaybackSessionInterfaceAVKit> _playbackSessionInterface; > BOOL _pictureInPictureInterrupted; > BOOL _muted; > } > > @property (retain) AVPlayerController* playerControllerProxy; >-@property (assign) WebCore::PlaybackSessionModel* delegate; >-@property (assign) WebCore::PlaybackSessionInterfaceAVKit* playbackSessionInterface; >+@property (readonly) WebCore::PlaybackSessionModel* delegate; >+@property WebCore::PlaybackSessionInterfaceAVKit* playbackSessionInterface; > > @property (readonly) BOOL canScanForward; > @property BOOL canScanBackward; >diff --git a/Source/WebCore/platform/ios/WebAVPlayerController.mm b/Source/WebCore/platform/ios/WebAVPlayerController.mm >index 84814233e8d4f84e3da5374574fb1ad53e7e94bd..66e20319a1cf39038cf15d8ba4f21e0897d2308d 100644 >--- a/Source/WebCore/platform/ios/WebAVPlayerController.mm >+++ b/Source/WebCore/platform/ios/WebAVPlayerController.mm >@@ -95,6 +95,23 @@ - (void)dealloc > [super dealloc]; > } > >+@dynamic delegate; >+- (WebCore::PlaybackSessionModel*)delegate >+{ >+ return _playbackSessionInterface ? &_playbackSessionInterface->playbackSessionModel() : nullptr; >+} >+ >+@dynamic playbackSessionInterface; >+- (WebCore::PlaybackSessionInterfaceAVKit*)playbackSessionInterface >+{ >+ return _playbackSessionInterface.get(); >+} >+ >+- (void)setPlaybackSessionInterface:(WebCore::PlaybackSessionInterfaceAVKit*)playbackSessionInterface >+{ >+ _playbackSessionInterface = playbackSessionInterface; >+} >+ > - (AVPlayer *)player > { > return nil; >diff --git a/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm b/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm >index 7ff0cf574d6fd4bf57eb52cfc92c0f44e9c204c7..12dfa8e6de8c49692e10064e1c3243ef1016af35 100644 >--- a/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm >+++ b/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm >@@ -99,11 +99,11 @@ -(void)didFinishFullscreen:(VideoFullscreenControllerContext*)context; > @end > > class VideoFullscreenControllerContext final >- : private VideoFullscreenModel >- , private VideoFullscreenModelClient >- , private VideoFullscreenChangeObserver >+ : public VideoFullscreenModel >+ , public VideoFullscreenModelClient >+ , public VideoFullscreenChangeObserver > , private PlaybackSessionModel >- , private PlaybackSessionModelClient >+ , public PlaybackSessionModelClient > , public ThreadSafeRefCounted<VideoFullscreenControllerContext> { > > public: >@@ -118,6 +118,9 @@ public: > void requestHideAndExitFullscreen(); > void invalidate(); > >+ using ThreadSafeRefCounted::ref; >+ using ThreadSafeRefCounted::deref; >+ > private: > VideoFullscreenControllerContext() { } > >@@ -137,7 +140,9 @@ private: > void videoDimensionsChanged(const FloatSize&) override; > > // PlaybackSessionModel >- void addClient(PlaybackSessionModelClient&) override; >+ void refPlaybackSessionModel() final { ref(); } >+ void derefPlaybackSessionModel() final { deref(); } >+ void addClient(WeakPtr<PlaybackSessionModelClient>&&) override; > void removeClient(PlaybackSessionModelClient&) override; > void play() override; > void pause() override; >@@ -190,7 +195,9 @@ private: > void volumeChanged(double) override; > > // VideoFullscreenModel >- void addClient(VideoFullscreenModelClient&) override; >+ void refVideoFullscreenModel() final { ref(); } >+ void derefVideoFullscreenModel() final { deref(); } >+ void addClient(WeakPtr<VideoFullscreenModelClient>&&) override; > void removeClient(VideoFullscreenModelClient&) override; > void requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia = false) override; > void setVideoLayerFrame(FloatRect) override; >@@ -208,14 +215,17 @@ private: > void willExitPictureInPicture() final; > void didExitPictureInPicture() final; > >- HashSet<PlaybackSessionModelClient*> m_playbackClients; >- HashSet<VideoFullscreenModelClient*> m_fullscreenClients; >+ Vector<WeakPtr<PlaybackSessionModelClient>> m_playbackClients; >+ Vector<WeakPtr<VideoFullscreenModelClient>> m_fullscreenClients; > RefPtr<VideoFullscreenInterfaceAVKit> m_interface; > RefPtr<VideoFullscreenModelVideoElement> m_fullscreenModel; > RefPtr<PlaybackSessionModelMediaElement> m_playbackModel; > RefPtr<HTMLVideoElement> m_videoElement; > RetainPtr<UIView> m_videoFullscreenView; > RetainPtr<WebVideoFullscreenController> m_controller; >+ WeakPtrFactory<PlaybackSessionModelClient> m_playbackClientFactory; >+ WeakPtrFactory<VideoFullscreenModelClient> m_fullscreenModelClientFactory; >+ WeakPtrFactory<VideoFullscreenChangeObserver> m_fullscreenChangeObserverFactory; > }; > > #pragma mark VideoFullscreenChangeObserver >@@ -319,8 +329,6 @@ void VideoFullscreenControllerContext::didExitFullscreen() > void VideoFullscreenControllerContext::didCleanupFullscreen() > { > ASSERT(isUIThread()); >- m_interface->setVideoFullscreenModel(nullptr); >- m_interface->setVideoFullscreenChangeObserver(nullptr); > m_interface = nullptr; > m_videoFullscreenView = nil; > >@@ -329,6 +337,7 @@ void VideoFullscreenControllerContext::didCleanupFullscreen() > m_fullscreenModel->setVideoElement(nullptr); > m_playbackModel->setMediaElement(nullptr); > m_playbackModel->removeClient(*this); >+ m_playbackModel = nullptr; > m_fullscreenModel->removeClient(*this); > m_fullscreenModel = nullptr; > m_videoElement = nullptr; >@@ -543,16 +552,16 @@ void VideoFullscreenControllerContext::volumeChanged(double volume) > } > #pragma mark VideoFullscreenModel > >-void VideoFullscreenControllerContext::addClient(VideoFullscreenModelClient& client) >+void VideoFullscreenControllerContext::addClient(WeakPtr<VideoFullscreenModelClient>&& client) > { >- ASSERT(!m_fullscreenClients.contains(&client)); >- m_fullscreenClients.add(&client); >+ ASSERT(!m_fullscreenClients.contains(client)); >+ m_fullscreenClients.append(WTFMove(client)); > } > > void VideoFullscreenControllerContext::removeClient(VideoFullscreenModelClient& client) > { > ASSERT(m_fullscreenClients.contains(&client)); >- m_fullscreenClients.remove(&client); >+ m_fullscreenClients.removeAll(&client); > } > > void VideoFullscreenControllerContext::requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia) >@@ -636,35 +645,35 @@ bool VideoFullscreenControllerContext::isPictureInPictureActive() const > void VideoFullscreenControllerContext::willEnterPictureInPicture() > { > ASSERT(isUIThread()); >- for (auto* client : m_fullscreenClients) >+ for (auto& client : m_fullscreenClients) > client->willEnterPictureInPicture(); > } > > void VideoFullscreenControllerContext::didEnterPictureInPicture() > { > ASSERT(isUIThread()); >- for (auto* client : m_fullscreenClients) >+ for (auto& client : m_fullscreenClients) > client->didEnterPictureInPicture(); > } > > void VideoFullscreenControllerContext::failedToEnterPictureInPicture() > { > ASSERT(isUIThread()); >- for (auto* client : m_fullscreenClients) >+ for (auto& client : m_fullscreenClients) > client->failedToEnterPictureInPicture(); > } > > void VideoFullscreenControllerContext::willExitPictureInPicture() > { > ASSERT(isUIThread()); >- for (auto* client : m_fullscreenClients) >+ for (auto& client : m_fullscreenClients) > client->willExitPictureInPicture(); > } > > void VideoFullscreenControllerContext::didExitPictureInPicture() > { > ASSERT(isUIThread()); >- for (auto* client : m_fullscreenClients) >+ for (auto& client : m_fullscreenClients) > client->didExitPictureInPicture(); > } > >@@ -676,16 +685,16 @@ FloatSize VideoFullscreenControllerContext::videoDimensions() const > > #pragma mark - PlaybackSessionModel > >-void VideoFullscreenControllerContext::addClient(PlaybackSessionModelClient& client) >+void VideoFullscreenControllerContext::addClient(WeakPtr<PlaybackSessionModelClient>&& client) > { >- ASSERT(!m_playbackClients.contains(&client)); >- m_playbackClients.add(&client); >+ ASSERT(!m_playbackClients.contains(client)); >+ m_playbackClients.append(WTFMove(client)); > } > > void VideoFullscreenControllerContext::removeClient(PlaybackSessionModelClient& client) > { > ASSERT(m_playbackClients.contains(&client)); >- m_playbackClients.remove(&client); >+ m_playbackClients.removeAll(&client); > } > > void VideoFullscreenControllerContext::play() >@@ -937,11 +946,11 @@ void VideoFullscreenControllerContext::setUpFullscreen(HTMLVideoElement& videoEl > RetainPtr<UIView> viewRef = view; > m_videoElement = &videoElement; > m_playbackModel = PlaybackSessionModelMediaElement::create(); >- m_playbackModel->addClient(*this); >+ m_playbackModel->addClient(m_playbackClientFactory.createWeakPtr(*this)); > m_playbackModel->setMediaElement(m_videoElement.get()); > > m_fullscreenModel = VideoFullscreenModelVideoElement::create(); >- m_fullscreenModel->addClient(*this); >+ m_fullscreenModel->addClient(m_fullscreenModelClientFactory.createWeakPtr(*this)); > m_fullscreenModel->setVideoElement(m_videoElement.get()); > > bool allowsPictureInPicture = m_videoElement->webkitSupportsPresentationMode(HTMLVideoElement::VideoPresentationMode::PictureInPicture); >@@ -954,10 +963,8 @@ void VideoFullscreenControllerContext::setUpFullscreen(HTMLVideoElement& videoEl > ASSERT(isUIThread()); > > Ref<PlaybackSessionInterfaceAVKit> sessionInterface = PlaybackSessionInterfaceAVKit::create(*this); >- m_interface = VideoFullscreenInterfaceAVKit::create(sessionInterface.get()); >- m_interface->setVideoFullscreenChangeObserver(this); >- m_interface->setVideoFullscreenModel(this); >- m_interface->setVideoFullscreenChangeObserver(this); >+ m_interface = VideoFullscreenInterfaceAVKit::create(sessionInterface.get(), *this); >+ m_interface->setVideoFullscreenChangeObserver(m_fullscreenChangeObserverFactory.createWeakPtr(*this)); > > m_videoFullscreenView = adoptNS([allocUIViewInstance() init]); > >diff --git a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h >index 9aa955fc44fa4c84b9e4a0f66a943aa5b84b29e8..541951f5e2366b52f463d823c21841ad504b178f 100644 >--- a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h >+++ b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h >@@ -45,9 +45,9 @@ class WEBCORE_EXPORT PlaybackSessionInterfaceMac final > , public PlaybackSessionModelClient > , public RefCounted<PlaybackSessionInterfaceMac> { > public: >- static Ref<PlaybackSessionInterfaceMac> create(PlaybackSessionModel&); >- virtual ~PlaybackSessionInterfaceMac(); >- PlaybackSessionModel* playbackSessionModel() const; >+ static Ref<PlaybackSessionInterfaceMac> create(Ref<PlaybackSessionModel>&&); >+ virtual ~PlaybackSessionInterfaceMac() = default; >+ PlaybackSessionModel& playbackSessionModel() const; > > // PlaybackSessionInterface > void resetMediaState() final; >@@ -63,7 +63,6 @@ public: > void legibleMediaSelectionIndexChanged(uint64_t) final; > void externalPlaybackChanged(bool /* enabled */, PlaybackSessionModel::ExternalPlaybackTargetType, const String& /* localizedDeviceName */) final; > >- void invalidate(); > void ensureControlsManager(); > #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) > void setPlayBackControlsManager(WebPlaybackControlsManager *); >@@ -73,8 +72,9 @@ public: > void endScrubbing(); > > private: >- PlaybackSessionInterfaceMac(PlaybackSessionModel&); >- PlaybackSessionModel* m_playbackSessionModel { nullptr }; >+ PlaybackSessionInterfaceMac(Ref<PlaybackSessionModel>&&); >+ Ref<PlaybackSessionModel> m_playbackSessionModel; >+ WeakPtrFactory<PlaybackSessionModelClient> m_weakPtrFactory; > #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) > WebPlaybackControlsManager *m_playbackControlsManager { nullptr }; > >diff --git a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm >index 602eddba51fce11393dbce445fbb86086648c967..eeafe0074284ef4f55b06ed9a7c43d2372b2ee19 100644 >--- a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm >+++ b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm >@@ -44,24 +44,18 @@ SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming) > > namespace WebCore { > >-Ref<PlaybackSessionInterfaceMac> PlaybackSessionInterfaceMac::create(PlaybackSessionModel& model) >+Ref<PlaybackSessionInterfaceMac> PlaybackSessionInterfaceMac::create(Ref<PlaybackSessionModel>&& model) > { >- auto interface = adoptRef(*new PlaybackSessionInterfaceMac(model)); >- model.addClient(interface); >- return interface; >+ return adoptRef(*new PlaybackSessionInterfaceMac(WTFMove(model))); > } > >-PlaybackSessionInterfaceMac::PlaybackSessionInterfaceMac(PlaybackSessionModel& model) >- : m_playbackSessionModel(&model) >+PlaybackSessionInterfaceMac::PlaybackSessionInterfaceMac(Ref<PlaybackSessionModel>&& model) >+ : m_playbackSessionModel(WTFMove(model)) > { >+ playbackSessionModel().addClient(m_weakPtrFactory.createWeakPtr(*this)); > } > >-PlaybackSessionInterfaceMac::~PlaybackSessionInterfaceMac() >-{ >- invalidate(); >-} >- >-PlaybackSessionModel* PlaybackSessionInterfaceMac::playbackSessionModel() const >+PlaybackSessionModel& PlaybackSessionInterfaceMac::playbackSessionModel() const > { > return m_playbackSessionModel; > } >@@ -102,7 +96,7 @@ void PlaybackSessionInterfaceMac::rateChanged(bool isPlaying, float playbackRate > WebPlaybackControlsManager* controlsManager = playBackControlsManager(); > [controlsManager setRate:isPlaying ? playbackRate : 0.]; > [controlsManager setPlaying:isPlaying]; >- updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], playbackRate, isPlaying); >+ updatePlaybackControlsManagerTiming(playbackSessionModel().currentTime(), [[NSProcessInfo processInfo] systemUptime], playbackRate, isPlaying); > #else > UNUSED_PARAM(isPlaying); > UNUSED_PARAM(playbackRate); >@@ -112,14 +106,14 @@ void PlaybackSessionInterfaceMac::rateChanged(bool isPlaying, float playbackRate > void PlaybackSessionInterfaceMac::beginScrubbing() > { > #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) >- updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], 0, false); >+ updatePlaybackControlsManagerTiming(playbackSessionModel().currentTime(), [[NSProcessInfo processInfo] systemUptime], 0, false); > #endif >- playbackSessionModel()->beginScrubbing(); >+ playbackSessionModel().beginScrubbing(); > } > > void PlaybackSessionInterfaceMac::endScrubbing() > { >- playbackSessionModel()->endScrubbing(); >+ playbackSessionModel().endScrubbing(); > } > > #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) >@@ -193,15 +187,6 @@ void PlaybackSessionInterfaceMac::externalPlaybackChanged(bool enabled, Playback > #endif > } > >-void PlaybackSessionInterfaceMac::invalidate() >-{ >- if (!m_playbackSessionModel) >- return; >- >- m_playbackSessionModel->removeClient(*this); >- m_playbackSessionModel = nullptr; >-} >- > void PlaybackSessionInterfaceMac::ensureControlsManager() > { > #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) >@@ -220,21 +205,21 @@ void PlaybackSessionInterfaceMac::setPlayBackControlsManager(WebPlaybackControls > { > m_playbackControlsManager = manager; > >- if (!manager || !m_playbackSessionModel) >+ if (!manager) > return; > > NSTimeInterval anchorTimeStamp = ![manager rate] ? NAN : [[NSProcessInfo processInfo] systemUptime]; >- manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:m_playbackSessionModel->currentTime() anchorTimeStamp:anchorTimeStamp rate:0]; >- double duration = m_playbackSessionModel->duration(); >+ manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:playbackSessionModel().currentTime() anchorTimeStamp:anchorTimeStamp rate:0]; >+ double duration = playbackSessionModel().duration(); > manager.contentDuration = duration; > manager.hasEnabledAudio = duration > 0; > manager.hasEnabledVideo = duration > 0; >- manager.rate = m_playbackSessionModel->isPlaying() ? m_playbackSessionModel->playbackRate() : 0.; >- manager.seekableTimeRanges = timeRangesToArray(m_playbackSessionModel->seekableRanges()).get(); >+ manager.rate = playbackSessionModel().isPlaying() ? playbackSessionModel().playbackRate() : 0.; >+ manager.seekableTimeRanges = timeRangesToArray(playbackSessionModel().seekableRanges()).get(); > manager.canTogglePlayback = YES; >- manager.playing = m_playbackSessionModel->isPlaying(); >- [manager setAudioMediaSelectionOptions:m_playbackSessionModel->audioMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->audioMediaSelectedIndex())]; >- [manager setLegibleMediaSelectionOptions:m_playbackSessionModel->legibleMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(m_playbackSessionModel->legibleMediaSelectedIndex())]; >+ manager.playing = playbackSessionModel().isPlaying(); >+ [manager setAudioMediaSelectionOptions:playbackSessionModel().audioMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(playbackSessionModel().audioMediaSelectedIndex())]; >+ [manager setLegibleMediaSelectionOptions:playbackSessionModel().legibleMediaSelectionOptions() withSelectedIndex:static_cast<NSUInteger>(playbackSessionModel().legibleMediaSelectedIndex())]; > } > > void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying) >@@ -243,16 +228,14 @@ void PlaybackSessionInterfaceMac::updatePlaybackControlsManagerTiming(double cur > if (!manager) > return; > >- PlaybackSessionModel *model = playbackSessionModel(); >- if (!model) >- return; >+ auto& model = playbackSessionModel(); > > double effectiveAnchorTime = playbackRate ? anchorTime : NAN; > double effectivePlaybackRate = playbackRate; > if (!isPlaying >- || model->isScrubbing() >- || (manager.rate > 0 && model->playbackStartedTime() >= currentTime) >- || (manager.rate < 0 && model->playbackStartedTime() <= currentTime)) >+ || model.isScrubbing() >+ || (manager.rate > 0 && model.playbackStartedTime() >= currentTime) >+ || (manager.rate < 0 && model.playbackStartedTime() <= currentTime)) > effectivePlaybackRate = 0; > > manager.timing = [getAVValueTimingClass() valueTimingWithAnchorValue:currentTime anchorTimeStamp:effectiveAnchorTime rate:effectivePlaybackRate]; >diff --git a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.h b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.h >index af2c649f57e5e1585831df8b246262b2e73d6cb5..e00573a5ae6c6225737c67e87887e3bb9cfba2f6 100644 >--- a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.h >+++ b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.h >@@ -33,6 +33,7 @@ > #include "VideoFullscreenModel.h" > #include <wtf/RefCounted.h> > #include <wtf/RetainPtr.h> >+#include <wtf/WeakPtr.h> > #include <wtf/text/WTFString.h> > > OBJC_CLASS NSWindow; >@@ -46,21 +47,21 @@ class VideoFullscreenChangeObserver; > > class VideoFullscreenInterfaceMac > : public VideoFullscreenModelClient >- , private PlaybackSessionModelClient >- , public RefCounted<VideoFullscreenInterfaceMac> { >+ , public PlaybackSessionModelClient >+ , public RefCounted<VideoFullscreenInterfaceMac> >+ , public CanMakeWeakPtr<VideoFullscreenInterfaceMac> { > > public: >- static Ref<VideoFullscreenInterfaceMac> create(PlaybackSessionInterfaceMac& playbackSessionInterface) >+ static Ref<VideoFullscreenInterfaceMac> create(Ref<PlaybackSessionInterfaceMac>&& playbackSessionInterface, Ref<VideoFullscreenModel> videoFullscreenModel) > { >- return adoptRef(*new VideoFullscreenInterfaceMac(playbackSessionInterface)); >+ return adoptRef(*new VideoFullscreenInterfaceMac(WTFMove(playbackSessionInterface), WTFMove(videoFullscreenModel))); > } > virtual ~VideoFullscreenInterfaceMac(); > PlaybackSessionInterfaceMac& playbackSessionInterface() const { return m_playbackSessionInterface.get(); } >- VideoFullscreenModel* videoFullscreenModel() const { return m_videoFullscreenModel; } >- PlaybackSessionModel* playbackSessionModel() const { return m_playbackSessionInterface->playbackSessionModel(); } >- WEBCORE_EXPORT void setVideoFullscreenModel(VideoFullscreenModel*); >- VideoFullscreenChangeObserver* videoFullscreenChangeObserver() const { return m_fullscreenChangeObserver; } >- WEBCORE_EXPORT void setVideoFullscreenChangeObserver(VideoFullscreenChangeObserver*); >+ VideoFullscreenModel& videoFullscreenModel() const { return m_videoFullscreenModel; } >+ PlaybackSessionModel& playbackSessionModel() const { return m_playbackSessionInterface->playbackSessionModel(); } >+ VideoFullscreenChangeObserver* videoFullscreenChangeObserver() const { return m_fullscreenChangeObserver.get(); } >+ WEBCORE_EXPORT void setVideoFullscreenChangeObserver(WeakPtr<VideoFullscreenChangeObserver>); > > // PlaybackSessionModelClient > WEBCORE_EXPORT void rateChanged(bool isPlaying, float playbackRate) override; >@@ -97,10 +98,11 @@ public: > WEBCORE_EXPORT void requestHideAndExitPiP(); > > private: >- WEBCORE_EXPORT VideoFullscreenInterfaceMac(PlaybackSessionInterfaceMac&); >+ WEBCORE_EXPORT VideoFullscreenInterfaceMac(Ref<PlaybackSessionInterfaceMac>&&, Ref<VideoFullscreenModel>&&); > Ref<PlaybackSessionInterfaceMac> m_playbackSessionInterface; >- VideoFullscreenModel* m_videoFullscreenModel { nullptr }; >- VideoFullscreenChangeObserver* m_fullscreenChangeObserver { nullptr }; >+ Ref<VideoFullscreenModel> m_videoFullscreenModel; >+ WeakPtrFactory<PlaybackSessionModelClient> m_weakPtrFactory; >+ WeakPtr<VideoFullscreenChangeObserver> m_fullscreenChangeObserver; > HTMLMediaElementEnums::VideoFullscreenMode m_mode { HTMLMediaElementEnums::VideoFullscreenModeNone }; > RetainPtr<WebVideoFullscreenInterfaceMacObjC> m_webVideoFullscreenInterfaceObjC; > }; >diff --git a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm >index 0ae6afeade313175d2e3685cd7a2b54e8506b07b..023e765c2730447a36785f656167be64ff73b3de 100644 >--- a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm >+++ b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm >@@ -192,8 +192,8 @@ - (void)setUpPIPForVideoView:(NSView *)videoView withFrame:(NSRect)frame inWindo > [_pipViewController setUserCanResize:YES]; > [_pipViewController setPlaying:_playing]; > [self setVideoDimensions:NSEqualSizes(_videoDimensions, NSZeroSize) ? frame.size : _videoDimensions]; >- if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->videoFullscreenModel()) >- _videoFullscreenInterfaceMac->videoFullscreenModel()->setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspectFill); >+ if (_videoFullscreenInterfaceMac) >+ _videoFullscreenInterfaceMac->videoFullscreenModel().setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspectFill); > > _videoViewContainer = adoptNS([[WebVideoViewContainer alloc] initWithFrame:frame]); > [_videoViewContainer setVideoViewContainerDelegate:self]; >@@ -246,8 +246,8 @@ - (void)boundsDidChangeForVideoViewContainer:(WebVideoViewContainer *)videoViewC > > ASSERT_UNUSED(videoViewContainer, videoViewContainer == _videoViewContainer); > >- if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->videoFullscreenModel()) >- _videoFullscreenInterfaceMac->videoFullscreenModel()->setVideoLayerFrame([_videoViewContainer bounds]); >+ if (_videoFullscreenInterfaceMac) >+ _videoFullscreenInterfaceMac->videoFullscreenModel().setVideoLayerFrame([_videoViewContainer bounds]); > } > > - (void)superviewDidChangeForVideoViewContainer:(WebVideoViewContainer *)videoViewContainer >@@ -283,12 +283,12 @@ - (void)pipDidClose:(PIPViewController *)pip > { > ASSERT_UNUSED(pip, pip == _pipViewController); > >- if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->videoFullscreenModel() && _videoViewContainer && _returningWindow && !NSEqualRects(_returningRect, NSZeroRect)) { >+ if (_videoFullscreenInterfaceMac && _videoViewContainer && _returningWindow && !NSEqualRects(_returningRect, NSZeroRect)) { > [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { > context.allowsImplicitAnimation = NO; > [_videoViewContainer setFrame:_returningRect]; >- _videoFullscreenInterfaceMac->videoFullscreenModel()->setVideoLayerFrame([_videoViewContainer bounds]); >- _videoFullscreenInterfaceMac->videoFullscreenModel()->setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspect); >+ _videoFullscreenInterfaceMac->videoFullscreenModel().setVideoLayerFrame([_videoViewContainer bounds]); >+ _videoFullscreenInterfaceMac->videoFullscreenModel().setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspect); > > [[_returningWindow contentView] addSubview:_videoViewContainer.get() positioned:NSWindowAbove relativeTo:nil]; > } completionHandler:nil]; >@@ -296,10 +296,9 @@ - (void)pipDidClose:(PIPViewController *)pip > > if (_videoFullscreenInterfaceMac) { > if (!self.isExitingToStandardFullscreen) { >- if (VideoFullscreenModel* videoFullscreenModel = _videoFullscreenInterfaceMac->videoFullscreenModel()) { >- videoFullscreenModel->didExitPictureInPicture(); >- videoFullscreenModel->setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspect); >- } >+ Ref<VideoFullscreenModel> videoFullscreenModel = _videoFullscreenInterfaceMac->videoFullscreenModel(); >+ videoFullscreenModel->didExitPictureInPicture(); >+ videoFullscreenModel->setVideoLayerGravity(VideoFullscreenModel::VideoGravityResizeAspect); > } > > _videoFullscreenInterfaceMac->clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture); >@@ -313,16 +312,16 @@ - (void)pipActionPlay:(PIPViewController *)pip > { > ASSERT_UNUSED(pip, pip == _pipViewController); > >- if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->playbackSessionModel()) >- _videoFullscreenInterfaceMac->playbackSessionModel()->play(); >+ if (_videoFullscreenInterfaceMac) >+ _videoFullscreenInterfaceMac->playbackSessionModel().play(); > } > > - (void)pipActionPause:(PIPViewController *)pip > { > ASSERT_UNUSED(pip, pip == _pipViewController); > >- if (_videoFullscreenInterfaceMac && _videoFullscreenInterfaceMac->playbackSessionModel()) >- _videoFullscreenInterfaceMac->playbackSessionModel()->pause(); >+ if (_videoFullscreenInterfaceMac) >+ _videoFullscreenInterfaceMac->playbackSessionModel().pause(); > } > > - (void)pipActionStop:(PIPViewController *)pip >@@ -332,8 +331,7 @@ - (void)pipActionStop:(PIPViewController *)pip > if (!_videoFullscreenInterfaceMac) > return; > >- if (PlaybackSessionModel* playbackSessionModel = _videoFullscreenInterfaceMac->playbackSessionModel()) >- playbackSessionModel->pause(); >+ _videoFullscreenInterfaceMac->playbackSessionModel().pause(); > > _videoFullscreenInterfaceMac->requestHideAndExitPiP(); > _pipState = PIPState::ExitingPIP; >@@ -344,33 +342,23 @@ @end > namespace WebCore { > using namespace PAL; > >-VideoFullscreenInterfaceMac::VideoFullscreenInterfaceMac(PlaybackSessionInterfaceMac& playbackSessionInterface) >- : m_playbackSessionInterface(playbackSessionInterface) >+VideoFullscreenInterfaceMac::VideoFullscreenInterfaceMac(Ref<PlaybackSessionInterfaceMac>&& playbackSessionInterface, Ref<VideoFullscreenModel>&& videoFullscreenModel) >+ : m_playbackSessionInterface(WTFMove(playbackSessionInterface)) >+ , m_videoFullscreenModel(WTFMove(videoFullscreenModel)) > { >- ASSERT(m_playbackSessionInterface->playbackSessionModel()); >- auto model = m_playbackSessionInterface->playbackSessionModel(); >- model->addClient(*this); >- [videoFullscreenInterfaceObjC() updateIsPlaying:model->isPlaying() newPlaybackRate:model->playbackRate()]; >+ auto& model = playbackSessionModel(); >+ model.addClient(m_weakPtrFactory.createWeakPtr(*this)); >+ [videoFullscreenInterfaceObjC() updateIsPlaying:model.isPlaying() newPlaybackRate:model.playbackRate()]; > } > > VideoFullscreenInterfaceMac::~VideoFullscreenInterfaceMac() > { >- if (m_playbackSessionInterface->playbackSessionModel()) >- m_playbackSessionInterface->playbackSessionModel()->removeClient(*this); >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->removeClient(*this); >+ auto& model = playbackSessionModel(); >+ model.removeClient(*this); >+ m_videoFullscreenModel->removeClient(*this); > } > >-void VideoFullscreenInterfaceMac::setVideoFullscreenModel(VideoFullscreenModel* model) >-{ >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->removeClient(*this); >- m_videoFullscreenModel = model; >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->addClient(*this); >-} >- >-void VideoFullscreenInterfaceMac::setVideoFullscreenChangeObserver(VideoFullscreenChangeObserver* observer) >+void VideoFullscreenInterfaceMac::setVideoFullscreenChangeObserver(WeakPtr<VideoFullscreenChangeObserver> observer) > { > m_fullscreenChangeObserver = observer; > } >@@ -382,8 +370,7 @@ void VideoFullscreenInterfaceMac::setMode(HTMLMediaElementEnums::VideoFullscreen > return; > > m_mode = newMode; >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->fullscreenModeChanged(m_mode); >+ m_videoFullscreenModel->fullscreenModeChanged(m_mode); > } > > void VideoFullscreenInterfaceMac::clearMode(HTMLMediaElementEnums::VideoFullscreenMode mode) >@@ -393,8 +380,7 @@ void VideoFullscreenInterfaceMac::clearMode(HTMLMediaElementEnums::VideoFullscre > return; > > m_mode = newMode; >- if (m_videoFullscreenModel) >- m_videoFullscreenModel->fullscreenModeChanged(m_mode); >+ m_videoFullscreenModel->fullscreenModeChanged(m_mode); > } > > void VideoFullscreenInterfaceMac::rateChanged(bool isPlaying, float playbackRate) >@@ -499,7 +485,6 @@ void VideoFullscreenInterfaceMac::invalidate() > { > LOG(Fullscreen, "VideoFullscreenInterfaceMac::invalidate(%p)", this); > >- m_videoFullscreenModel = nil; > m_fullscreenChangeObserver = nil; > > cleanupFullscreen(); >@@ -510,9 +495,6 @@ void VideoFullscreenInterfaceMac::invalidate() > > void VideoFullscreenInterfaceMac::requestHideAndExitPiP() > { >- if (!m_videoFullscreenModel) >- return; >- > m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone); > m_videoFullscreenModel->willExitPictureInPicture(); > } >diff --git a/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm b/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm >index b6eada31806402500602bfab0d32957da6f2b451..44691c47dd9412698c9d2d0c781b321ca84be2e1 100644 >--- a/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm >+++ b/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm >@@ -94,7 +94,7 @@ - (void)seekToTime:(NSTimeInterval)time toleranceBefore:(NSTimeInterval)toleranc > { > UNUSED_PARAM(toleranceBefore); > UNUSED_PARAM(toleranceAfter); >- _playbackSessionInterfaceMac->playbackSessionModel()->seekToTime(time); >+ _playbackSessionInterfaceMac->playbackSessionModel().seekToTime(time); > } > > - (void)cancelThumbnailAndAudioAmplitudeSampleGeneration >@@ -193,7 +193,7 @@ - (void)setCurrentAudioTouchBarMediaSelectionOption:(AVTouchBarMediaSelectionOpt > if (audioMediaSelectionOption && _audioTouchBarMediaSelectionOptions) > index = [_audioTouchBarMediaSelectionOptions indexOfObject:audioMediaSelectionOption]; > >- _playbackSessionInterfaceMac->playbackSessionModel()->selectAudioMediaOption(index != NSNotFound ? index : UINT64_MAX); >+ _playbackSessionInterfaceMac->playbackSessionModel().selectAudioMediaOption(index != NSNotFound ? index : UINT64_MAX); > } > > - (NSArray<AVTouchBarMediaSelectionOption *> *)legibleTouchBarMediaSelectionOptions >@@ -223,7 +223,7 @@ - (void)setCurrentLegibleTouchBarMediaSelectionOption:(AVTouchBarMediaSelectionO > if (legibleMediaSelectionOption && _legibleTouchBarMediaSelectionOptions) > index = [_legibleTouchBarMediaSelectionOptions indexOfObject:legibleMediaSelectionOption]; > >- _playbackSessionInterfaceMac->playbackSessionModel()->selectLegibleMediaOption(index != NSNotFound ? index : UINT64_MAX); >+ _playbackSessionInterfaceMac->playbackSessionModel().selectLegibleMediaOption(index != NSNotFound ? index : UINT64_MAX); > } > > #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 >@@ -314,26 +314,26 @@ - (void)setPlaybackSessionInterfaceMac:(PlaybackSessionInterfaceMac*)playbackSes > > - (void)togglePlayback > { >- if (_playbackSessionInterfaceMac && _playbackSessionInterfaceMac->playbackSessionModel()) >- _playbackSessionInterfaceMac->playbackSessionModel()->togglePlayState(); >+ if (_playbackSessionInterfaceMac) >+ _playbackSessionInterfaceMac->playbackSessionModel().togglePlayState(); > } > > - (void)setPlaying:(BOOL)playing > { >- if (!_playbackSessionInterfaceMac || !_playbackSessionInterfaceMac->playbackSessionModel()) >+ if (!_playbackSessionInterfaceMac) > return; > > BOOL isCurrentlyPlaying = self.playing; > if (!isCurrentlyPlaying && playing) >- _playbackSessionInterfaceMac->playbackSessionModel()->play(); >+ _playbackSessionInterfaceMac->playbackSessionModel().play(); > else if (isCurrentlyPlaying && !playing) >- _playbackSessionInterfaceMac->playbackSessionModel()->pause(); >+ _playbackSessionInterfaceMac->playbackSessionModel().pause(); > } > > - (BOOL)isPlaying > { >- if (_playbackSessionInterfaceMac && _playbackSessionInterfaceMac->playbackSessionModel()) >- return _playbackSessionInterfaceMac->playbackSessionModel()->isPlaying(); >+ if (_playbackSessionInterfaceMac) >+ return _playbackSessionInterfaceMac->playbackSessionModel().isPlaying(); > > return NO; > } >@@ -341,8 +341,8 @@ - (BOOL)isPlaying > #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 > - (void)togglePictureInPicture > { >- if (_playbackSessionInterfaceMac && _playbackSessionInterfaceMac->playbackSessionModel()) >- _playbackSessionInterfaceMac->playbackSessionModel()->togglePictureInPicture(); >+ if (_playbackSessionInterfaceMac) >+ _playbackSessionInterfaceMac->playbackSessionModel().togglePictureInPicture(); > } > #endif > >diff --git a/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h b/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h >index 835bb9baf819706fdfaebece2ec0d78e53ea300b..831e431320211a89c65074ff6f67228085430307 100644 >--- a/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h >+++ b/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h >@@ -35,9 +35,10 @@ > #include <WebCore/TimeRanges.h> > #include <wtf/HashCountedSet.h> > #include <wtf/HashMap.h> >-#include <wtf/HashSet.h> > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> >+#include <wtf/Vector.h> >+#include <wtf/WeakPtrContainer.h> > > #if PLATFORM(IOS) > #include <WebCore/PlaybackSessionInterfaceAVKit.h> >@@ -56,18 +57,20 @@ namespace WebKit { > class WebPageProxy; > class PlaybackSessionManagerProxy; > >-class PlaybackSessionModelContext final: public RefCounted<PlaybackSessionModelContext>, public WebCore::PlaybackSessionModel { >+class PlaybackSessionModelContext final >+ : public WebCore::PlaybackSessionModel >+ , public RefCounted<PlaybackSessionModelContext> { > public: >- static Ref<PlaybackSessionModelContext> create(PlaybackSessionManagerProxy& manager, uint64_t contextId) >+ static Ref<PlaybackSessionModelContext> create(WeakPtr<PlaybackSessionManagerProxy>&& manager, uint64_t contextId) > { >- return adoptRef(*new PlaybackSessionModelContext(manager, contextId)); >+ return adoptRef(*new PlaybackSessionModelContext(WTFMove(manager), contextId)); > } > virtual ~PlaybackSessionModelContext() { } > > void invalidate() { m_manager = nullptr; } > > // PlaybackSessionModel >- void addClient(WebCore::PlaybackSessionModelClient&) final; >+ void addClient(WeakPtr<WebCore::PlaybackSessionModelClient>&&) final; > void removeClient(WebCore::PlaybackSessionModelClient&)final; > > void durationChanged(double); >@@ -87,16 +90,21 @@ public: > void volumeChanged(double); > void pictureInPictureActiveChanged(bool); > >+ using RefCounted::ref; >+ using RefCounted::deref; >+ > private: > friend class VideoFullscreenModelContext; > >- PlaybackSessionModelContext(PlaybackSessionManagerProxy& manager, uint64_t contextId) >- : m_manager(&manager) >+ PlaybackSessionModelContext(WeakPtr<PlaybackSessionManagerProxy>&& manager, uint64_t contextId) >+ : m_manager(WTFMove(manager)) > , m_contextId(contextId) > { > } > > // PlaybackSessionModel >+ void refPlaybackSessionModel() final { ref(); } >+ void derefPlaybackSessionModel() final { deref(); } > void play() final; > void pause() final; > void togglePlayState() final; >@@ -136,10 +144,10 @@ private: > bool isMuted() const final { return m_muted; } > double volume() const final { return m_volume; } > bool isPictureInPictureActive() const final { return m_pictureInPictureActive; } >- >- PlaybackSessionManagerProxy* m_manager; >+ >+ WeakPtr<PlaybackSessionManagerProxy> m_manager; > uint64_t m_contextId; >- HashSet<WebCore::PlaybackSessionModelClient*> m_clients; >+ WeakPtrContainer<WebCore::PlaybackSessionModelClient> m_clients; > double m_playbackStartedTime { 0 }; > bool m_playbackStartedTimeNeedsUpdate { false }; > double m_duration { 0 }; >@@ -165,7 +173,10 @@ private: > bool m_pictureInPictureActive { false }; > }; > >-class PlaybackSessionManagerProxy : public RefCounted<PlaybackSessionManagerProxy>, private IPC::MessageReceiver { >+class PlaybackSessionManagerProxy >+ : public RefCounted<PlaybackSessionManagerProxy> >+ , private IPC::MessageReceiver >+ , public CanMakeWeakPtr<PlaybackSessionManagerProxy> { > public: > static RefPtr<PlaybackSessionManagerProxy> create(WebPageProxy&); > virtual ~PlaybackSessionManagerProxy(); >diff --git a/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm b/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm >index f4c7066c1e6ead8a80fbb35331b63bc4795384e6..860e2d44be8f4bfcdd226ae0e6695856f3d31109 100644 >--- a/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm >+++ b/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm >@@ -39,16 +39,14 @@ namespace WebKit { > > #pragma mark - PlaybackSessionModelContext > >-void PlaybackSessionModelContext::addClient(PlaybackSessionModelClient& client) >+void PlaybackSessionModelContext::addClient(WeakPtr<PlaybackSessionModelClient>&& client) > { >- ASSERT(!m_clients.contains(&client)); >- m_clients.add(&client); >+ m_clients.add(WTFMove(client)); > } > > void PlaybackSessionModelContext::removeClient(PlaybackSessionModelClient& client) > { >- ASSERT(m_clients.contains(&client)); >- m_clients.remove(&client); >+ m_clients.remove(client); > } > > void PlaybackSessionModelContext::play() >@@ -161,8 +159,9 @@ void PlaybackSessionModelContext::playbackStartedTimeChanged(double playbackStar > void PlaybackSessionModelContext::durationChanged(double duration) > { > m_duration = duration; >- for (auto* client : m_clients) >- client->durationChanged(duration); >+ m_clients.forEachNonNullMember([duration] (auto& client) { >+ client.durationChanged(duration); >+ }); > } > > void PlaybackSessionModelContext::currentTimeChanged(double currentTime) >@@ -172,23 +171,26 @@ void PlaybackSessionModelContext::currentTimeChanged(double currentTime) > if (m_playbackStartedTimeNeedsUpdate) > playbackStartedTimeChanged(currentTime); > >- for (auto* client : m_clients) >- client->currentTimeChanged(currentTime, anchorTime); >+ m_clients.forEachNonNullMember([currentTime, anchorTime] (auto& client) { >+ client.currentTimeChanged(currentTime, anchorTime); >+ }); > } > > void PlaybackSessionModelContext::bufferedTimeChanged(double bufferedTime) > { > m_bufferedTime = bufferedTime; >- for (auto* client : m_clients) >- client->bufferedTimeChanged(bufferedTime); >+ m_clients.forEachNonNullMember([bufferedTime] (auto& client) { >+ client.bufferedTimeChanged(bufferedTime); >+ }); > } > > void PlaybackSessionModelContext::rateChanged(bool isPlaying, float playbackRate) > { > m_isPlaying = isPlaying; > m_playbackRate = playbackRate; >- for (auto* client : m_clients) >- client->rateChanged(isPlaying, playbackRate); >+ m_clients.forEachNonNullMember([isPlaying, playbackRate] (auto& client) { >+ client.rateChanged(isPlaying, playbackRate); >+ }); > } > > void PlaybackSessionModelContext::seekableRangesChanged(WebCore::TimeRanges& seekableRanges, double lastModifiedTime, double liveUpdateInterval) >@@ -196,23 +198,26 @@ void PlaybackSessionModelContext::seekableRangesChanged(WebCore::TimeRanges& see > m_seekableRanges = seekableRanges; > m_seekableTimeRangesLastModifiedTime = lastModifiedTime; > m_liveUpdateInterval = liveUpdateInterval; >- for (auto* client : m_clients) >- client->seekableRangesChanged(seekableRanges, lastModifiedTime, liveUpdateInterval); >+ m_clients.forEachNonNullMember([seekableRanges = makeRef(seekableRanges), lastModifiedTime, liveUpdateInterval] (auto& client) { >+ client.seekableRangesChanged(seekableRanges, lastModifiedTime, liveUpdateInterval); >+ }); > } > > void PlaybackSessionModelContext::canPlayFastReverseChanged(bool canPlayFastReverse) > { > m_canPlayFastReverse = canPlayFastReverse; >- for (auto* client : m_clients) >- client->canPlayFastReverseChanged(canPlayFastReverse); >+ m_clients.forEachNonNullMember([canPlayFastReverse] (auto& client) { >+ client.canPlayFastReverseChanged(canPlayFastReverse); >+ }); > } > > void PlaybackSessionModelContext::audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& audioMediaSelectionOptions, uint64_t audioMediaSelectedIndex) > { > m_audioMediaSelectionOptions = audioMediaSelectionOptions; > m_audioMediaSelectedIndex = audioMediaSelectedIndex; >- for (auto* client : m_clients) >- client->audioMediaSelectionOptionsChanged(audioMediaSelectionOptions, audioMediaSelectedIndex); >+ m_clients.forEachNonNullMember([audioMediaSelectionOptions, audioMediaSelectedIndex] (auto& client) { >+ client.audioMediaSelectionOptionsChanged(audioMediaSelectionOptions, audioMediaSelectedIndex); >+ }); > } > > void PlaybackSessionModelContext::legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& legibleMediaSelectionOptions, uint64_t legibleMediaSelectedIndex) >@@ -220,24 +225,27 @@ void PlaybackSessionModelContext::legibleMediaSelectionOptionsChanged(const Vect > m_legibleMediaSelectionOptions = legibleMediaSelectionOptions; > m_legibleMediaSelectedIndex = legibleMediaSelectedIndex; > >- for (auto* client : m_clients) >- client->legibleMediaSelectionOptionsChanged(legibleMediaSelectionOptions, legibleMediaSelectedIndex); >+ m_clients.forEachNonNullMember([legibleMediaSelectionOptions, legibleMediaSelectedIndex] (auto& client) { >+ client.legibleMediaSelectionOptionsChanged(legibleMediaSelectionOptions, legibleMediaSelectedIndex); >+ }); > } > > void PlaybackSessionModelContext::audioMediaSelectionIndexChanged(uint64_t selectedIndex) > { > m_audioMediaSelectedIndex = selectedIndex; > >- for (auto* client : m_clients) >- client->audioMediaSelectionIndexChanged(selectedIndex); >+ m_clients.forEachNonNullMember([selectedIndex] (auto& client) { >+ client.audioMediaSelectionIndexChanged(selectedIndex); >+ }); > } > > void PlaybackSessionModelContext::legibleMediaSelectionIndexChanged(uint64_t selectedIndex) > { > m_legibleMediaSelectedIndex = selectedIndex; > >- for (auto* client : m_clients) >- client->legibleMediaSelectionIndexChanged(selectedIndex); >+ m_clients.forEachNonNullMember([selectedIndex] (auto& client) { >+ client.legibleMediaSelectionIndexChanged(selectedIndex); >+ }); > } > > void PlaybackSessionModelContext::externalPlaybackChanged(bool enabled, PlaybackSessionModel::ExternalPlaybackTargetType type, const String& localizedName) >@@ -246,36 +254,41 @@ void PlaybackSessionModelContext::externalPlaybackChanged(bool enabled, Playback > m_externalPlaybackTargetType = type; > m_externalPlaybackLocalizedDeviceName = localizedName; > >- for (auto* client : m_clients) >- client->externalPlaybackChanged(enabled, type, localizedName); >+ m_clients.forEachNonNullMember([enabled, type, localizedName] (auto& client) { >+ client.externalPlaybackChanged(enabled, type, localizedName); >+ }); > } > > void PlaybackSessionModelContext::wirelessVideoPlaybackDisabledChanged(bool wirelessVideoPlaybackDisabled) > { > m_wirelessVideoPlaybackDisabled = wirelessVideoPlaybackDisabled; >- for (auto* client : m_clients) >- client->wirelessVideoPlaybackDisabledChanged(wirelessVideoPlaybackDisabled); >+ m_clients.forEachNonNullMember([wirelessVideoPlaybackDisabled] (auto& client) { >+ client.wirelessVideoPlaybackDisabledChanged(wirelessVideoPlaybackDisabled); >+ }); > } > > void PlaybackSessionModelContext::mutedChanged(bool muted) > { > m_muted = muted; >- for (auto* client : m_clients) >- client->mutedChanged(muted); >+ m_clients.forEachNonNullMember([muted] (auto& client) { >+ client.mutedChanged(muted); >+ }); > } > > void PlaybackSessionModelContext::volumeChanged(double volume) > { > m_volume = volume; >- for (auto* client : m_clients) >- client->volumeChanged(volume); >+ m_clients.forEachNonNullMember([volume] (auto& client) { >+ client.volumeChanged(volume); >+ }); > } > > void PlaybackSessionModelContext::pictureInPictureActiveChanged(bool active) > { > m_pictureInPictureActive = active; >- for (auto* client : m_clients) >- client->pictureInPictureActiveChanged(active); >+ m_clients.forEachNonNullMember([active] (auto& client) { >+ client.pictureInPictureActiveChanged(active); >+ }); > } > > #pragma mark - PlaybackSessionManagerProxy >@@ -303,22 +316,14 @@ void PlaybackSessionManagerProxy::invalidate() > m_page->process().removeMessageReceiver(Messages::PlaybackSessionManagerProxy::messageReceiverName(), m_page->pageID()); > m_page = nullptr; > >- auto contextMap = WTFMove(m_contextMap); >+ m_contextMap.clear(); > m_clientCounts.clear(); >- >- for (auto& tuple : contextMap.values()) { >- RefPtr<PlaybackSessionModelContext> model; >- RefPtr<PlatformPlaybackSessionInterface> interface; >- std::tie(model, interface) = tuple; >- >- interface->invalidate(); >- } > } > > PlaybackSessionManagerProxy::ModelInterfaceTuple PlaybackSessionManagerProxy::createModelAndInterface(uint64_t contextId) > { >- Ref<PlaybackSessionModelContext> model = PlaybackSessionModelContext::create(*this, contextId); >- Ref<PlatformPlaybackSessionInterface> interface = PlatformPlaybackSessionInterface::create(model); >+ Ref<PlaybackSessionModelContext> model = PlaybackSessionModelContext::create(makeWeakPtr(this), contextId); >+ Ref<PlatformPlaybackSessionInterface> interface = PlatformPlaybackSessionInterface::create(model.copyRef()); > > return std::make_tuple(WTFMove(model), WTFMove(interface)); > } >@@ -348,11 +353,8 @@ void PlaybackSessionManagerProxy::addClientForContext(uint64_t contextId) > > void PlaybackSessionManagerProxy::removeClientForContext(uint64_t contextId) > { >- if (!m_clientCounts.remove(contextId)) >- return; >- >- ensureInterface(contextId).invalidate(); >- m_contextMap.remove(contextId); >+ if (m_clientCounts.remove(contextId)) >+ m_contextMap.remove(contextId); > } > > #pragma mark Messages from PlaybackSessionManager >diff --git a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h >index 48663c252ba878bba1a191403c2ccaee31610916..b6f74f5d41b746227c96d783c230ed515862c0ab 100644 >--- a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h >+++ b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h >@@ -33,9 +33,11 @@ > #include <WebCore/VideoFullscreenChangeObserver.h> > #include <WebCore/VideoFullscreenModel.h> > #include <wtf/HashMap.h> >-#include <wtf/HashSet.h> > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> >+#include <wtf/UniqueRef.h> >+#include <wtf/Vector.h> >+#include <wtf/WeakPtrContainer.h> > > #if PLATFORM(IOS) > #include <WebCore/VideoFullscreenInterfaceAVKit.h> >@@ -59,12 +61,9 @@ class VideoFullscreenManagerProxy; > class VideoFullscreenModelContext final > : public RefCounted<VideoFullscreenModelContext> > , public WebCore::VideoFullscreenModel >- , public WebCore::VideoFullscreenChangeObserver { >+ , public WebCore::VideoFullscreenChangeObserver { > public: >- static Ref<VideoFullscreenModelContext> create(VideoFullscreenManagerProxy& manager, PlaybackSessionModelContext& playbackSessionModel, uint64_t contextId) >- { >- return adoptRef(*new VideoFullscreenModelContext(manager, playbackSessionModel, contextId)); >- } >+ static Ref<VideoFullscreenModelContext> create(WeakPtr<VideoFullscreenManagerProxy>&&, Ref<PlaybackSessionModelContext>&&, uint64_t contextId); > virtual ~VideoFullscreenModelContext(); > > void invalidate() { m_manager = nullptr; } >@@ -72,19 +71,26 @@ public: > PlatformView *layerHostView() const { return m_layerHostView.get(); } > void setLayerHostView(RetainPtr<PlatformView>&& layerHostView) { m_layerHostView = WTFMove(layerHostView); } > >+ WeakPtr<VideoFullscreenChangeObserver> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); } >+ >+ using RefCounted::ref; >+ using RefCounted::deref; >+ > private: >- VideoFullscreenModelContext(VideoFullscreenManagerProxy&, PlaybackSessionModelContext&, uint64_t); >+ VideoFullscreenModelContext(WeakPtr<VideoFullscreenManagerProxy>&&, Ref<PlaybackSessionModelContext>&&, uint64_t); > > // VideoFullscreenModel >- void addClient(WebCore::VideoFullscreenModelClient&) override; >- void removeClient(WebCore::VideoFullscreenModelClient&) override; >- void requestFullscreenMode(WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia = false) override; >- void setVideoLayerFrame(WebCore::FloatRect) override; >- void setVideoLayerGravity(VideoGravity) override; >- void fullscreenModeChanged(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) override; >- bool isVisible() const override; >- bool hasVideo() const override { return m_hasVideo; } >- WebCore::FloatSize videoDimensions() const override { return m_videoDimensions; } >+ void refVideoFullscreenModel() final { ref(); } >+ void derefVideoFullscreenModel() final { deref(); } >+ void addClient(WeakPtr<WebCore::VideoFullscreenModelClient>&&) final; >+ void removeClient(WebCore::VideoFullscreenModelClient&) final; >+ void requestFullscreenMode(WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia = false) final; >+ void setVideoLayerFrame(WebCore::FloatRect) final; >+ void setVideoLayerGravity(VideoGravity) final; >+ void fullscreenModeChanged(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) final; >+ bool isVisible() const final; >+ bool hasVideo() const final { return m_hasVideo; } >+ WebCore::FloatSize videoDimensions() const final { return m_videoDimensions; } > #if PLATFORM(IOS) > UIViewController *presentingViewController() final; > UIViewController *createVideoFullscreenViewController(AVPlayerViewController*) final; >@@ -106,16 +112,20 @@ private: > void didCleanupFullscreen() final; > void fullscreenMayReturnToInline() final; > >- VideoFullscreenManagerProxy* m_manager; >+ WeakPtr<VideoFullscreenManagerProxy> m_manager; > Ref<PlaybackSessionModelContext> m_playbackSessionModel; > uint64_t m_contextId; >+ WeakPtrFactory<VideoFullscreenChangeObserver> m_weakPtrFactory; > RetainPtr<PlatformView *> m_layerHostView; >- HashSet<WebCore::VideoFullscreenModelClient*> m_clients; >+ WeakPtrContainer<WebCore::VideoFullscreenModelClient> m_clients; > WebCore::FloatSize m_videoDimensions; > bool m_hasVideo { false }; > }; > >-class VideoFullscreenManagerProxy : public RefCounted<VideoFullscreenManagerProxy>, private IPC::MessageReceiver { >+class VideoFullscreenManagerProxy >+ : public RefCounted<VideoFullscreenManagerProxy> >+ , private IPC::MessageReceiver >+ , public CanMakeWeakPtr<VideoFullscreenManagerProxy> { > public: > static RefPtr<VideoFullscreenManagerProxy> create(WebPageProxy&, PlaybackSessionManagerProxy&); > virtual ~VideoFullscreenManagerProxy(); >diff --git a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm >index 9100afd8c41120bb5e581d230a2476f7542fed22..596c9c378f612498afdd3ce7e49ab0ae1076e9d6 100644 >--- a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm >+++ b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm >@@ -161,27 +161,28 @@ void VideoFullscreenManagerProxy::applicationDidBecomeActive() > > #pragma mark - VideoFullscreenModelContext > >-VideoFullscreenModelContext::VideoFullscreenModelContext(VideoFullscreenManagerProxy& manager, PlaybackSessionModelContext& playbackSessionModel, uint64_t contextId) >- : m_manager(&manager) >- , m_playbackSessionModel(playbackSessionModel) >- , m_contextId(contextId) >+Ref<VideoFullscreenModelContext> VideoFullscreenModelContext::create(WeakPtr<VideoFullscreenManagerProxy>&& manager, Ref<PlaybackSessionModelContext>&& playbackSessionModel, uint64_t contextId) > { >+ return adoptRef(*new VideoFullscreenModelContext(WTFMove(manager), WTFMove(playbackSessionModel), contextId)); > } > >-VideoFullscreenModelContext::~VideoFullscreenModelContext() >+VideoFullscreenModelContext::VideoFullscreenModelContext(WeakPtr<VideoFullscreenManagerProxy>&& manager, Ref<PlaybackSessionModelContext>&& playbackSessionModel, uint64_t contextId) >+ : m_manager(WTFMove(manager)) >+ , m_playbackSessionModel(WTFMove(playbackSessionModel)) >+ , m_contextId(contextId) > { > } > >-void VideoFullscreenModelContext::addClient(VideoFullscreenModelClient& client) >+VideoFullscreenModelContext::~VideoFullscreenModelContext() = default; >+ >+void VideoFullscreenModelContext::addClient(WeakPtr<VideoFullscreenModelClient>&& client) > { >- ASSERT(!m_clients.contains(&client)); >- m_clients.add(&client); >+ m_clients.add(WTFMove(client)); > } > > void VideoFullscreenModelContext::removeClient(VideoFullscreenModelClient& client) > { >- ASSERT(m_clients.contains(&client)); >- m_clients.remove(&client); >+ m_clients.remove(client); > } > > void VideoFullscreenModelContext::requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia) >@@ -284,32 +285,37 @@ void VideoFullscreenModelContext::fullscreenMayReturnToInline() > > void VideoFullscreenModelContext::willEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->willEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.willEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelContext::didEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->didEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.didEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelContext::failedToEnterPictureInPicture() > { >- for (auto& client : m_clients) >- client->failedToEnterPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.failedToEnterPictureInPicture(); >+ }); > } > > void VideoFullscreenModelContext::willExitPictureInPicture() > { >- for (auto& client : m_clients) >- client->willExitPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.willExitPictureInPicture(); >+ }); > } > > void VideoFullscreenModelContext::didExitPictureInPicture() > { >- for (auto& client : m_clients) >- client->didExitPictureInPicture(); >+ m_clients.forEachNonNullMember([] (auto& client) { >+ client.didExitPictureInPicture(); >+ }); > } > > #pragma mark - VideoFullscreenManagerProxy >@@ -346,7 +352,6 @@ void VideoFullscreenManagerProxy::invalidate() > RefPtr<PlatformVideoFullscreenInterface> interface; > std::tie(model, interface) = tuple; > >- interface->invalidate(); > [model->layerHostView() removeFromSuperview]; > model->setLayerHostView(nullptr); > } >@@ -404,13 +409,12 @@ void VideoFullscreenManagerProxy::applicationDidBecomeActive() > VideoFullscreenManagerProxy::ModelInterfaceTuple VideoFullscreenManagerProxy::createModelAndInterface(uint64_t contextId) > { > auto& playbackSessionModel = m_playbackSessionManagerProxy->ensureModel(contextId); >- Ref<VideoFullscreenModelContext> model = VideoFullscreenModelContext::create(*this, playbackSessionModel, contextId); > auto& playbackSessionInterface = m_playbackSessionManagerProxy->ensureInterface(contextId); >- Ref<PlatformVideoFullscreenInterface> interface = PlatformVideoFullscreenInterface::create(playbackSessionInterface); >+ Ref<VideoFullscreenModelContext> model = VideoFullscreenModelContext::create(makeWeakPtr(this), playbackSessionModel, contextId); >+ Ref<PlatformVideoFullscreenInterface> interface = PlatformVideoFullscreenInterface::create(makeRef(playbackSessionInterface), model.copyRef()); > m_playbackSessionManagerProxy->addClientForContext(contextId); > >- interface->setVideoFullscreenModel(&model.get()); >- interface->setVideoFullscreenChangeObserver(&model.get()); >+ interface->setVideoFullscreenChangeObserver(model->createWeakPtr()); > > return std::make_tuple(WTFMove(model), WTFMove(interface)); > } >@@ -449,7 +453,6 @@ void VideoFullscreenManagerProxy::removeClientForContext(uint64_t contextId) > clientCount--; > > if (clientCount <= 0) { >- ensureInterface(contextId).setVideoFullscreenModel(nullptr); > m_playbackSessionManagerProxy->removeClientForContext(contextId); > m_clientCounts.remove(contextId); > m_contextMap.remove(contextId); >diff --git a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >index d88d63d86e7e06eddcaaf66664eaff2af3553662..b612d0c18eabf44886b7841a68ab57f4ca970514 100644 >--- a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >+++ b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >@@ -56,7 +56,9 @@ - (void)didEnterPictureInPicture; > - (void)failedToEnterPictureInPicture; > @end > >-class WKFullScreenViewControllerPlaybackSessionModelClient : PlaybackSessionModelClient { >+class WKFullScreenViewControllerPlaybackSessionModelClient >+ : public PlaybackSessionModelClient >+ , public CanMakeWeakPtr<WKFullScreenViewControllerPlaybackSessionModelClient> { > public: > void setParent(WKFullScreenViewController *parent) { m_parent = parent; } > >@@ -75,11 +77,11 @@ public: > if (m_interface == interface) > return; > >- if (m_interface && m_interface->playbackSessionModel()) >- m_interface->playbackSessionModel()->removeClient(*this); >+ if (m_interface) >+ m_interface->playbackSessionModel().removeClient(*this); > m_interface = interface; >- if (m_interface && m_interface->playbackSessionModel()) >- m_interface->playbackSessionModel()->addClient(*this); >+ if (m_interface) >+ m_interface->playbackSessionModel().addClient(makeWeakPtr(*this)); > } > > private: >@@ -87,7 +89,9 @@ private: > RefPtr<PlaybackSessionInterfaceAVKit> m_interface; > }; > >-class WKFullScreenViewControllerVideoFullscreenModelClient : VideoFullscreenModelClient { >+class WKFullScreenViewControllerVideoFullscreenModelClient >+ : public VideoFullscreenModelClient >+ , public CanMakeWeakPtr<WKFullScreenViewControllerVideoFullscreenModelClient> { > public: > void setParent(WKFullScreenViewController *parent) { m_parent = parent; } > >@@ -96,11 +100,11 @@ public: > if (m_interface == interface) > return; > >- if (m_interface && m_interface->videoFullscreenModel()) >- m_interface->videoFullscreenModel()->removeClient(*this); >+ if (m_interface) >+ m_interface->videoFullscreenModel().removeClient(*this); > m_interface = interface; >- if (m_interface && m_interface->videoFullscreenModel()) >- m_interface->videoFullscreenModel()->addClient(*this); >+ if (m_interface) >+ m_interface->videoFullscreenModel().addClient(makeWeakPtr(*this)); > } > > VideoFullscreenInterfaceAVKit* interface() const { return m_interface.get(); } >@@ -264,9 +268,14 @@ - (void)videoControlsManagerDidChange > _playbackClient.setInterface(playbackSessionInterface); > _videoFullscreenClient.setInterface(videoFullscreenInterface); > >- PlaybackSessionModel* playbackSessionModel = playbackSessionInterface ? playbackSessionInterface->playbackSessionModel() : nullptr; >- self.playing = playbackSessionModel ? playbackSessionModel->isPlaying() : NO; >- [_pipButton setHidden:!playbackSessionModel]; >+ if (!playbackSessionInterface) { >+ self.playing = NO; >+ [_pipButton setHidden:YES]; >+ return; >+ } >+ >+ self.playing = playbackSessionInterface->playbackSessionModel().isPlaying(); >+ [_pipButton setHidden:NO]; > } > > - (void)setPrefersStatusBarHidden:(BOOL)value >@@ -512,14 +521,8 @@ - (void)_togglePiPAction:(id)sender > return; > > PlatformPlaybackSessionInterface* playbackSessionInterface = playbackSessionManager->controlsManagerInterface(); >- if (!playbackSessionInterface) >- return; >- >- PlaybackSessionModel* playbackSessionModel = playbackSessionInterface->playbackSessionModel(); >- if (!playbackSessionModel) >- return; >- >- playbackSessionModel->togglePictureInPicture(); >+ if (playbackSessionInterface) >+ playbackSessionInterface->playbackSessionModel().togglePictureInPicture(); > } > > - (void)_touchDetected:(id)sender >diff --git a/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm >index 47251d82fb33984d7f7f2a2f6c248ef857f2cc90..baabe1aacfecafa1c9becb214e84a6dee21c8136 100644 >--- a/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm >+++ b/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm >@@ -54,7 +54,9 @@ static const NSTimeInterval DefaultWatchdogTimerInterval = 1; > > namespace WebKit { > >-class WKFullScreenWindowControllerVideoFullscreenModelClient : VideoFullscreenModelClient { >+class WKFullScreenWindowControllerVideoFullscreenModelClient >+ : public CanMakeWeakPtr<WKFullScreenWindowControllerVideoFullscreenModelClient> >+ , public VideoFullscreenModelClient { > public: > void setParent(WKFullScreenWindowController *parent) { m_parent = parent; } > >@@ -63,11 +65,11 @@ public: > if (m_interface == interface) > return; > >- if (m_interface && m_interface->videoFullscreenModel()) >- m_interface->videoFullscreenModel()->removeClient(*this); >+ if (m_interface) >+ m_interface->videoFullscreenModel().removeClient(*this); > m_interface = interface; >- if (m_interface && m_interface->videoFullscreenModel()) >- m_interface->videoFullscreenModel()->addClient(*this); >+ if (m_interface) >+ m_interface->videoFullscreenModel().addClient(makeWeakPtr(this)); > } > > VideoFullscreenInterfaceMac* interface() const { return m_interface.get(); } >diff --git a/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h b/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h >index d297dac2297fff9ab88f6180b9e9d928e502812f..c8c6254ecb8d71853fcff87730b09a5ebb517b1c 100644 >--- a/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h >+++ b/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h >@@ -47,6 +47,8 @@ class MessageReceiver; > > namespace WebCore { > class Node; >+class PlaybackSessionModel; >+class PlaybackSessionModelClient; > } > > namespace WebKit { >@@ -55,17 +57,17 @@ class WebPage; > class PlaybackSessionManager; > > class PlaybackSessionInterfaceContext final >- : public RefCounted<PlaybackSessionInterfaceContext> >- , public WebCore::PlaybackSessionInterface >- , public WebCore::PlaybackSessionModelClient { >+ : public WebCore::PlaybackSessionInterface >+ , public WebCore::PlaybackSessionModelClient >+ , public RefCounted<PlaybackSessionInterfaceContext> { > public: >- static Ref<PlaybackSessionInterfaceContext> create(PlaybackSessionManager& manager, uint64_t contextId) >+ static Ref<PlaybackSessionInterfaceContext> create(WeakPtr<PlaybackSessionManager>&& manager, uint64_t contextId) > { >- return adoptRef(*new PlaybackSessionInterfaceContext(manager, contextId)); >+ return adoptRef(*new PlaybackSessionInterfaceContext(WTFMove(manager), contextId)); > } > virtual ~PlaybackSessionInterfaceContext(); > >- void invalidate() { m_manager = nullptr; } >+ WeakPtr<WebCore::PlaybackSessionModelClient> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); } > > private: > friend class VideoFullscreenInterfaceContext; >@@ -90,13 +92,17 @@ private: > void mutedChanged(bool) final; > void volumeChanged(double) final; > >- PlaybackSessionInterfaceContext(PlaybackSessionManager&, uint64_t contextId); >+ PlaybackSessionInterfaceContext(WeakPtr<PlaybackSessionManager>&&, uint64_t contextId); > >- PlaybackSessionManager* m_manager; >+ WeakPtr<PlaybackSessionManager> m_manager; >+ WeakPtrFactory<PlaybackSessionModelClient> m_weakPtrFactory; > uint64_t m_contextId; > }; > >-class PlaybackSessionManager : public RefCounted<PlaybackSessionManager>, private IPC::MessageReceiver { >+class PlaybackSessionManager >+ : public RefCounted<PlaybackSessionManager> >+ , private IPC::MessageReceiver >+ , public CanMakeWeakPtr<PlaybackSessionManager> { > public: > static Ref<PlaybackSessionManager> create(WebPage&); > virtual ~PlaybackSessionManager(); >@@ -163,6 +169,7 @@ protected: > void setMuted(uint64_t contextId, bool muted); > void setVolume(uint64_t contextId, double volume); > >+ WeakPtrFactory<WebCore::PlaybackSessionModel> m_weakPtrFactory; > WebPage* m_page; > HashMap<WebCore::HTMLMediaElement*, uint64_t> m_mediaElements; > HashMap<uint64_t, ModelInterfaceTuple> m_contextMap; >diff --git a/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm b/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm >index b010d3076b0b30c98050319091bf7093f8c027b4..465faf76aa3d85f15f5866b1da4db9e36903167d 100644 >--- a/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm >+++ b/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm >@@ -55,15 +55,13 @@ static uint64_t nextContextId() > > #pragma mark - PlaybackSessionInterfaceContext > >-PlaybackSessionInterfaceContext::PlaybackSessionInterfaceContext(PlaybackSessionManager& manager, uint64_t contextId) >- : m_manager(&manager) >+PlaybackSessionInterfaceContext::PlaybackSessionInterfaceContext(WeakPtr<PlaybackSessionManager>&& manager, uint64_t contextId) >+ : m_manager(WTFMove(manager)) > , m_contextId(contextId) > { > } > >-PlaybackSessionInterfaceContext::~PlaybackSessionInterfaceContext() >-{ >-} >+PlaybackSessionInterfaceContext::~PlaybackSessionInterfaceContext() = default; > > void PlaybackSessionInterfaceContext::resetMediaState() > { >@@ -180,10 +178,7 @@ PlaybackSessionManager::~PlaybackSessionManager() > RefPtr<PlaybackSessionModelMediaElement> model; > RefPtr<PlaybackSessionInterfaceContext> interface; > std::tie(model, interface) = tuple; >- model->removeClient(*interface); > model->setMediaElement(nullptr); >- >- interface->invalidate(); > } > > m_contextMap.clear(); >@@ -203,9 +198,9 @@ void PlaybackSessionManager::invalidate() > > PlaybackSessionManager::ModelInterfaceTuple PlaybackSessionManager::createModelAndInterface(uint64_t contextId) > { >- RefPtr<PlaybackSessionModelMediaElement> model = PlaybackSessionModelMediaElement::create(); >- RefPtr<PlaybackSessionInterfaceContext> interface = PlaybackSessionInterfaceContext::create(*this, contextId); >- model->addClient(*interface); >+ Ref<PlaybackSessionModelMediaElement> model = PlaybackSessionModelMediaElement::create(); >+ Ref<PlaybackSessionInterfaceContext> interface = PlaybackSessionInterfaceContext::create(makeWeakPtr(this), contextId); >+ model->addClient(interface->createWeakPtr()); > > return std::make_tuple(WTFMove(model), WTFMove(interface)); > } >@@ -236,8 +231,6 @@ void PlaybackSessionManager::removeContext(uint64_t contextId) > > RefPtr<HTMLMediaElement> mediaElement = model->mediaElement(); > model->setMediaElement(nullptr); >- model->removeClient(*interface); >- interface->invalidate(); > m_mediaElements.remove(mediaElement.get()); > m_contextMap.remove(contextId); > } >diff --git a/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h b/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h >index ff8c4baf463be3539830290ecd246ef9fcfb1dfa..d5e3a8f173284b4b0eb1a3cf619bb51dbd172f4b 100644 >--- a/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h >+++ b/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h >@@ -60,9 +60,9 @@ class VideoFullscreenInterfaceContext > : public RefCounted<VideoFullscreenInterfaceContext> > , public WebCore::VideoFullscreenModelClient { > public: >- static Ref<VideoFullscreenInterfaceContext> create(VideoFullscreenManager& manager, uint64_t contextId) >+ static Ref<VideoFullscreenInterfaceContext> create(WeakPtr<VideoFullscreenManager>&& manager, uint64_t contextId) > { >- return adoptRef(*new VideoFullscreenInterfaceContext(manager, contextId)); >+ return adoptRef(*new VideoFullscreenInterfaceContext(WTFMove(manager), contextId)); > } > virtual ~VideoFullscreenInterfaceContext(); > >@@ -86,14 +86,16 @@ public: > bool isFullscreen() const { return m_isFullscreen; } > void setIsFullscreen(bool flag) { m_isFullscreen = flag; } > >+ WeakPtr<WebCore::VideoFullscreenModelClient> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); } >+ > private: > // VideoFullscreenModelClient > void hasVideoChanged(bool) override; > void videoDimensionsChanged(const WebCore::FloatSize&) override; > >- VideoFullscreenInterfaceContext(VideoFullscreenManager&, uint64_t contextId); >+ VideoFullscreenInterfaceContext(WeakPtr<VideoFullscreenManager>&&, uint64_t contextId); > >- VideoFullscreenManager* m_manager; >+ WeakPtr<VideoFullscreenManager> m_manager; > uint64_t m_contextId; > std::unique_ptr<LayerHostingContext> m_layerHostingContext; > bool m_isAnimating { false }; >@@ -101,9 +103,13 @@ private: > WebCore::HTMLMediaElementEnums::VideoFullscreenMode m_fullscreenMode { WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone }; > bool m_fullscreenStandby { false }; > bool m_isFullscreen { false }; >+ WeakPtrFactory<WebCore::VideoFullscreenModelClient> m_weakPtrFactory; > }; > >-class VideoFullscreenManager : public RefCounted<VideoFullscreenManager>, private IPC::MessageReceiver { >+class VideoFullscreenManager >+ : public RefCounted<VideoFullscreenManager> >+ , public CanMakeWeakPtr<VideoFullscreenManager> >+ , private IPC::MessageReceiver { > public: > static Ref<VideoFullscreenManager> create(WebPage&, PlaybackSessionManager&); > virtual ~VideoFullscreenManager(); >diff --git a/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm b/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm >index f9fd6afea18ec398d1fc740a58de0af2ca2a3289..70f4d3a8a8ebaba8964d28a22401e10fa3eb0b4b 100644 >--- a/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm >+++ b/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm >@@ -81,8 +81,8 @@ static IntRect inlineVideoFrame(HTMLVideoElement& element) > > #pragma mark - VideoFullscreenInterfaceContext > >-VideoFullscreenInterfaceContext::VideoFullscreenInterfaceContext(VideoFullscreenManager& manager, uint64_t contextId) >- : m_manager(&manager) >+VideoFullscreenInterfaceContext::VideoFullscreenInterfaceContext(WeakPtr<VideoFullscreenManager>&& manager, uint64_t contextId) >+ : m_manager(WTFMove(manager)) > , m_contextId(contextId) > { > } >@@ -130,9 +130,6 @@ VideoFullscreenManager::~VideoFullscreenManager() > std::tie(model, interface) = tuple; > > model->setVideoElement(nullptr); >- model->removeClient(*interface); >- >- interface->invalidate(); > } > > m_contextMap.clear(); >@@ -153,11 +150,11 @@ void VideoFullscreenManager::invalidate() > VideoFullscreenManager::ModelInterfaceTuple VideoFullscreenManager::createModelAndInterface(uint64_t contextId) > { > RefPtr<VideoFullscreenModelVideoElement> model = VideoFullscreenModelVideoElement::create(); >- RefPtr<VideoFullscreenInterfaceContext> interface = VideoFullscreenInterfaceContext::create(*this, contextId); >+ RefPtr<VideoFullscreenInterfaceContext> interface = VideoFullscreenInterfaceContext::create(makeWeakPtr(*this), contextId); > m_playbackSessionManager->addClientForContext(contextId); > > interface->setLayerHostingContext(LayerHostingContext::createForExternalHostingProcess()); >- model->addClient(*interface); >+ model->addClient(interface->createWeakPtr()); > > return std::make_tuple(WTFMove(model), WTFMove(interface)); > } >@@ -190,8 +187,6 @@ void VideoFullscreenManager::removeContext(uint64_t contextId) > > RefPtr<HTMLVideoElement> videoElement = model->videoElement(); > model->setVideoElement(nullptr); >- model->removeClient(*interface); >- interface->invalidate(); > m_videoElements.remove(videoElement.get()); > m_contextMap.remove(contextId); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188747
:
347511
|
347515
|
347526
|
347531
|
347533
|
347537
|
347841
|
347847
|
347870
|
347922
|
349452
|
349486
|
349491
|
349784
|
349795
|
349838
|
351008
|
351130