Changeset 207688 in webkit
- Timestamp:
- Oct 21, 2016 11:37:47 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r207687 r207688 1 2016-10-21 Jer Noble <jer.noble@apple.com> 2 3 WebCore::PlatformMediaSession::stopSession + 13 4 https://bugs.webkit.org/show_bug.cgi?id=163799 5 6 Reviewed by Eric Carlson. 7 8 Because m_sessions can be mutated by removeSession() while iterating over m_sessions, and because 9 PlatformMediaSessions are not refcounted, it is not enough to copy m_sessions into a copied Vector 10 before iterating. Instead, wrap iteration of m_sessions in a convenience function, which sets an 11 iteration counter which, when cleared, removes all null entries from m_session. In parallel, modify 12 removeSession() to check this iteration counter, and replace the session with a null value rather 13 than mutating the m_sessions vector itself. 14 15 * platform/audio/PlatformMediaSessionManager.cpp: 16 (WebCore::PlatformMediaSessionManager::has): 17 (WebCore::PlatformMediaSessionManager::activeAudioSessionRequired): 18 (WebCore::PlatformMediaSessionManager::canProduceAudio): 19 (WebCore::PlatformMediaSessionManager::removeSession): 20 (WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback): 21 (WebCore::PlatformMediaSessionManager::sessionWillEndPlayback): 22 (WebCore::PlatformMediaSessionManager::currentSessionsMatching): 23 (WebCore::PlatformMediaSessionManager::applicationWillEnterBackground): 24 (WebCore::PlatformMediaSessionManager::applicationDidEnterForeground): 25 (WebCore::PlatformMediaSessionManager::systemWillSleep): 26 (WebCore::PlatformMediaSessionManager::systemDidWake): 27 (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForDocument): 28 (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForProcess): 29 (WebCore::PlatformMediaSessionManager::forEachSession): 30 (WebCore::PlatformMediaSessionManager::anyOfSessions): 31 * platform/audio/PlatformMediaSessionManager.h: 32 1 33 2016-10-21 Darin Adler <darin@apple.com> 2 34 -
trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
r206315 r207688 78 78 ASSERT(type >= PlatformMediaSession::None && type <= PlatformMediaSession::WebAudio); 79 79 80 for (auto* session : m_sessions) { 81 if (session->mediaType() == type) 82 return true; 83 } 84 85 return false; 80 return anyOfSessions([type] (PlatformMediaSession& session, size_t) { 81 return session.mediaType() == type; 82 }); 86 83 } 87 84 88 85 bool PlatformMediaSessionManager::activeAudioSessionRequired() const 89 86 { 90 for (auto* session : m_sessions) { 91 if (session->activeAudioSessionRequired()) 92 return true; 93 } 94 95 return false; 87 return anyOfSessions([] (PlatformMediaSession& session, size_t) { 88 return session.activeAudioSessionRequired(); 89 }); 96 90 } 97 91 98 92 bool PlatformMediaSessionManager::canProduceAudio() const 99 93 { 100 for (auto* session : m_sessions) { 101 if (session->canProduceAudio()) 102 return true; 103 } 104 105 return false; 94 return anyOfSessions([] (PlatformMediaSession& session, size_t) { 95 return session.canProduceAudio(); 96 }); 106 97 } 107 98 … … 164 155 if (index == notFound) 165 156 return; 166 167 m_sessions.remove(index); 168 169 if (m_sessions.isEmpty()) { 157 158 if (m_iteratingOverSessions) 159 m_sessions.at(index) = nullptr; 160 else 161 m_sessions.remove(index); 162 163 if (m_sessions.isEmpty() || std::all_of(m_sessions.begin(), m_sessions.end(), std::logical_not<void>())) { 170 164 m_remoteCommandListener = nullptr; 171 165 m_audioHardwareListener = nullptr; … … 212 206 endInterruption(PlatformMediaSession::NoFlags); 213 207 214 Vector<PlatformMediaSession*> sessions = m_sessions; 215 for (auto* oneSession : sessions) { 216 if (oneSession == &session) 217 continue; 218 if (oneSession->mediaType() == sessionType 208 forEachSession([&] (PlatformMediaSession& oneSession, size_t) { 209 if (&oneSession == &session) 210 return; 211 if (oneSession.mediaType() == sessionType 219 212 && restrictions & ConcurrentPlaybackNotPermitted 220 && oneSession ->state() == PlatformMediaSession::Playing)221 oneSession ->pauseSession();222 } 213 && oneSession.state() == PlatformMediaSession::Playing) 214 oneSession.pauseSession(); 215 }); 223 216 224 217 updateSessionState(); … … 235 228 size_t pausingSessionIndex = notFound; 236 229 size_t lastPlayingSessionIndex = notFound; 237 for (size_t i = 0; i < m_sessions.size(); ++i) { 238 PlatformMediaSession* oneSession = m_sessions[i]; 239 240 if (oneSession == &session) { 230 anyOfSessions([&] (PlatformMediaSession& oneSession, size_t i) { 231 if (&oneSession == &session) { 241 232 pausingSessionIndex = i; 242 continue;233 return false; 243 234 } 244 if (oneSession ->state() == PlatformMediaSession::Playing) {235 if (oneSession.state() == PlatformMediaSession::Playing) { 245 236 lastPlayingSessionIndex = i; 246 continue;237 return false; 247 238 } 248 if (oneSession->state() != PlatformMediaSession::Playing) 249 break; 250 } 239 return oneSession.state() != PlatformMediaSession::Playing; 240 }); 251 241 if (lastPlayingSessionIndex == notFound || pausingSessionIndex == notFound) 252 242 return; … … 292 282 { 293 283 Vector<PlatformMediaSession*> matchingSessions; 294 for (auto& session : m_sessions) {295 if (filter( *session))296 matchingSessions.append( session);297 } 284 forEachSession([&] (PlatformMediaSession& session, size_t) { 285 if (filter(session)) 286 matchingSessions.append(&session); 287 }); 298 288 return matchingSessions; 299 289 } … … 314 304 315 305 Vector<PlatformMediaSession*> sessions = m_sessions; 316 for (auto* session : sessions) {317 if (m_restrictions[session ->mediaType()] & BackgroundProcessPlaybackRestricted)318 session ->beginInterruption(PlatformMediaSession::EnteringBackground);319 } 306 forEachSession([&] (PlatformMediaSession& session, size_t) { 307 if (m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted) 308 session.beginInterruption(PlatformMediaSession::EnteringBackground); 309 }); 320 310 } 321 311 … … 330 320 331 321 Vector<PlatformMediaSession*> sessions = m_sessions; 332 for (auto* session : sessions) {333 if (m_restrictions[session ->mediaType()] & BackgroundProcessPlaybackRestricted)334 session ->endInterruption(PlatformMediaSession::MayResumePlaying);335 } 322 forEachSession([&] (PlatformMediaSession& session, size_t) { 323 if (m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted) 324 session.endInterruption(PlatformMediaSession::MayResumePlaying); 325 }); 336 326 } 337 327 … … 377 367 return; 378 368 379 for (auto* session : m_sessions) 380 session->beginInterruption(PlatformMediaSession::SystemSleep); 369 forEachSession([] (PlatformMediaSession& session, size_t) { 370 session.beginInterruption(PlatformMediaSession::SystemSleep); 371 }); 381 372 } 382 373 … … 386 377 return; 387 378 388 for (auto* session : m_sessions) 389 session->endInterruption(PlatformMediaSession::MayResumePlaying); 379 forEachSession([] (PlatformMediaSession& session, size_t) { 380 session.endInterruption(PlatformMediaSession::MayResumePlaying); 381 }); 390 382 } 391 383 … … 397 389 void PlatformMediaSessionManager::stopAllMediaPlaybackForDocument(const Document* document) 398 390 { 399 Vector<PlatformMediaSession*> sessions = m_sessions; 400 for (auto* session : sessions) { 401 if (session->client().hostingDocument() == document) 402 session->pauseSession(); 391 forEachSession([document] (PlatformMediaSession& session, size_t) { 392 if (session.client().hostingDocument() == document) 393 session.pauseSession(); 394 }); 395 } 396 397 void PlatformMediaSessionManager::stopAllMediaPlaybackForProcess() 398 { 399 forEachSession([] (PlatformMediaSession& session, size_t) { 400 session.stopSession(); 401 }); 402 } 403 404 void PlatformMediaSessionManager::forEachSession(std::function<void(PlatformMediaSession&, size_t)> func) const 405 { 406 ++m_iteratingOverSessions; 407 408 for (size_t i = 0, size = m_sessions.size(); i < size; ++i) { 409 auto session = m_sessions[i]; 410 if (!session) 411 continue; 412 func(*session, i); 403 413 } 404 } 405 406 void PlatformMediaSessionManager::stopAllMediaPlaybackForProcess() 407 { 408 Vector<PlatformMediaSession*> sessions = m_sessions; 409 for (auto* session : sessions) 410 session->stopSession(); 414 415 --m_iteratingOverSessions; 416 if (!m_iteratingOverSessions) 417 m_sessions.removeAll(nullptr); 418 } 419 420 bool PlatformMediaSessionManager::anyOfSessions(std::function<bool(PlatformMediaSession&, size_t)> func) const 421 { 422 ++m_iteratingOverSessions; 423 424 bool found = false; 425 for (size_t i = 0, size = m_sessions.size(); i < size; ++i) { 426 auto session = m_sessions[i]; 427 if (!session) 428 continue; 429 430 if (!func(*session, i)) 431 continue; 432 433 found = true; 434 break; 435 } 436 437 --m_iteratingOverSessions; 438 if (!m_iteratingOverSessions) 439 m_sessions.removeAll(nullptr); 440 441 return found; 411 442 } 412 443 -
trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h
r206771 r207688 121 121 122 122 void updateSessionState(); 123 void forEachSession(std::function<void(PlatformMediaSession&, size_t)>) const; 124 bool anyOfSessions(std::function<bool(PlatformMediaSession&, size_t)>) const; 123 125 124 126 // RemoteCommandListenerClient … … 136 138 137 139 SessionRestrictions m_restrictions[PlatformMediaSession::WebAudio + 1]; 138 Vector<PlatformMediaSession*> m_sessions;140 mutable Vector<PlatformMediaSession*> m_sessions; 139 141 std::unique_ptr<RemoteCommandListener> m_remoteCommandListener; 140 142 std::unique_ptr<SystemSleepListener> m_systemSleepListener; … … 149 151 mutable bool m_isApplicationInBackground { false }; 150 152 bool m_willIgnoreSystemInterruptions { false }; 153 mutable int m_iteratingOverSessions { 0 }; 151 154 }; 152 155
Note: See TracChangeset
for help on using the changeset viewer.