コード例 #1
0
void WebMediaSessionManager::configureWatchdogTimer()
{
    static const double watchdogTimerIntervalAfterPausing = 60 * 60;
    static const double watchdogTimerIntervalAfterPlayingToEnd = 8 * 60;

    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute()) {
        m_watchdogTimer.stop();
        return;
    }

    bool stopTimer = false;
    bool didPlayToEnd = false;
    for (auto& state : m_clientState) {
        if (flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice) && flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
            stopTimer = true;
        if (state->playedToEnd)
            didPlayToEnd = true;
        state->playedToEnd = false;
    }

    if (stopTimer) {
        m_currentWatchdogInterval = 0;
        m_watchdogTimer.stop();
        LOG(Media, "WebMediaSessionManager::configureWatchdogTimer - timer stopped");
    } else {
        double interval = didPlayToEnd ? watchdogTimerIntervalAfterPlayingToEnd : watchdogTimerIntervalAfterPausing;
        if (interval != m_currentWatchdogInterval || !m_watchdogTimer.isActive()) {
            m_watchdogTimer.startOneShot(interval);
            LOG(Media, "WebMediaSessionManager::configureWatchdogTimer - timer scheduled for %.0f", interval);
        }
        m_currentWatchdogInterval = interval;
    }
}
コード例 #2
0
void WebMediaSessionManager::configurePlaybackTargetClients()
{
    size_t indexOfClientThatRequestedPicker = notFound;
    size_t indexOfLastClientToRequestPicker = notFound;
    size_t indexOfClientWillPlayToTarget = notFound;
    bool haveActiveRoute = m_playbackTarget && m_playbackTarget->hasActiveRoute();

    for (size_t i = 0; i < m_clientState.size(); ++i) {
        auto& state = m_clientState[i];

        LOG(Media, "WebMediaSessionManager::configurePlaybackTargetClients %zu - client (%p + %llu) requestedPicker = %i, flags = %s", i, &state->client, state->contextId, state->requestedPicker, mediaProducerStateString(state->flags).utf8().data());

        if (m_targetChanged && state->requestedPicker)
            indexOfClientThatRequestedPicker = i;

        if (indexOfClientWillPlayToTarget == notFound && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
            indexOfClientWillPlayToTarget = i;

        if (indexOfClientWillPlayToTarget == notFound && haveActiveRoute && state->previouslyRequestedPicker)
            indexOfLastClientToRequestPicker = i;
    }

    if (indexOfClientThatRequestedPicker != notFound)
        indexOfClientWillPlayToTarget = indexOfClientThatRequestedPicker;
    if (indexOfClientWillPlayToTarget == notFound && indexOfLastClientToRequestPicker != notFound)
        indexOfClientWillPlayToTarget = indexOfLastClientToRequestPicker;

    LOG(Media, "WebMediaSessionManager::configurePlaybackTargetClients - indexOfClientWillPlayToTarget = %zu", indexOfClientWillPlayToTarget);

    for (size_t i = 0; i < m_clientState.size(); ++i) {
        auto& state = m_clientState[i];

        if (m_playbackTarget)
            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());

        if (i != indexOfClientWillPlayToTarget || !haveActiveRoute)
            state->client.setShouldPlayToPlaybackTarget(state->contextId, false);

        state->configurationRequired = false;
        if (m_targetChanged)
            state->requestedPicker = false;
    }

    if (haveActiveRoute && indexOfClientWillPlayToTarget != notFound) {
        auto& state = m_clientState[indexOfClientWillPlayToTarget];

        if (!flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
            state->client.setShouldPlayToPlaybackTarget(state->contextId, true);
    }

    m_targetChanged = false;
    configureWatchdogTimer();
}
コード例 #3
0
void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient& client, uint64_t contextId, MediaProducer::MediaStateFlags newFlags)
{
    size_t index = find(&client, contextId);
    ASSERT(index != notFound);
    if (index == notFound)
        return;

    auto& changedClientState = m_clientState[index];
    MediaProducer::MediaStateFlags oldFlags = changedClientState->flags;
    if (newFlags == oldFlags)
        return;

    LOG(Media, "WebMediaSessionManager::clientStateDidChange(%p + %llu) - new flags = %s, old flags = %s", &client, contextId, mediaProducerStateString(newFlags).utf8().data(), mediaProducerStateString(oldFlags).utf8().data());

    changedClientState->flags = newFlags;
    if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
        scheduleDelayedTask(TargetMonitoringConfigurationTask);

    MediaProducer::MediaStateFlags playingToTargetFlags = MediaProducer::IsPlayingToExternalDevice | MediaProducer::IsPlayingVideo;
    if ((oldFlags & playingToTargetFlags) != (newFlags & playingToTargetFlags)) {
        if (flagsAreSet(oldFlags, MediaProducer::IsPlayingVideo) && !flagsAreSet(newFlags, MediaProducer::IsPlayingVideo) && flagsAreSet(newFlags, MediaProducer::DidPlayToEnd))
            changedClientState->playedToEnd = true;
        scheduleDelayedTask(WatchdogTimerConfigurationTask);
    }

    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute() || !flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate))
        return;

    // Do not interrupt another element already playing to a device.
    for (auto& state : m_clientState) {
        if (state == changedClientState)
            continue;

        if (flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice) && flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
            return;
    }

    // Do not take begin playing to the device unless playback has just started.
    if (!flagsAreSet(newFlags, MediaProducer::IsPlayingVideo) || flagsAreSet(oldFlags, MediaProducer::IsPlayingVideo))
        return;

    for (auto& state : m_clientState) {
        if (state == changedClientState)
            continue;
        state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
    }

    changedClientState->client.setShouldPlayToPlaybackTarget(changedClientState->contextId, true);

    if (index && m_clientState.size() > 1)
        std::swap(m_clientState.at(index), m_clientState.at(0));
}
コード例 #4
0
void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient& client, uint64_t contextId, MediaProducer::MediaStateFlags newFlags)
{
    size_t index = find(&client, contextId);
    ASSERT(index != notFound);
    if (index == notFound)
        return;

    auto& changedClientState = m_clientState[index];
    MediaProducer::MediaStateFlags oldFlags = changedClientState->flags;
    if (newFlags == oldFlags)
        return;

    changedClientState->flags = newFlags;
    if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
        configurePlaybackTargetMonitoring();

    if (!flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
        return;

    // Do not interrupt another element already playing to a device.
    for (auto& state : m_clientState) {
        if (state->contextId == contextId && state->client == &client)
            continue;

        if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo) && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
            return;
    }

    if (m_playbackTarget && m_playbackTarget->hasActiveRoute()) {

        for (auto& state : m_clientState) {
            if (state->contextId == contextId && state->client == &client)
                continue;
            state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
        }

        changedClientState->client->setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
    }

    if (index && m_clientState.size() > 1)
        std::swap(m_clientState.at(index), m_clientState.at(0));
}
コード例 #5
0
void WebMediaSessionManager::configurePlaybackTargetClients()
{
    size_t indexOfClientThatRequestedPicker = notFound;
    size_t indexOfAutoPlayCandidate = notFound;
    size_t indexOfClientWillPlayToTarget = notFound;
    bool haveActiveRoute = m_playbackTarget && m_playbackTarget->hasActiveRoute();

    for (size_t i = 0; i < m_clientState.size(); ++i) {
        auto& state = m_clientState[i];

        if (state->requestedPicker)
            indexOfClientThatRequestedPicker = i;

        if (indexOfClientWillPlayToTarget == notFound && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
            indexOfClientWillPlayToTarget = i;
    }

    if (indexOfClientThatRequestedPicker != notFound)
        indexOfClientWillPlayToTarget = indexOfClientThatRequestedPicker;
    if (indexOfClientWillPlayToTarget == notFound && haveActiveRoute && indexOfAutoPlayCandidate != notFound)
        indexOfClientWillPlayToTarget = indexOfAutoPlayCandidate;

    for (size_t i = 0; i < m_clientState.size(); ++i) {
        auto& state = m_clientState[i];

        if (m_playbackTarget)
            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());

        if (i != indexOfClientWillPlayToTarget || !haveActiveRoute)
            state->client.setShouldPlayToPlaybackTarget(state->contextId, false);

        state->configurationRequired = false;
        state->requestedPicker = false;
    }

    if (haveActiveRoute && indexOfClientWillPlayToTarget != notFound) {
        auto& state = m_clientState[indexOfClientWillPlayToTarget];
        if (!flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
            state->client.setShouldPlayToPlaybackTarget(state->contextId, true);
    }
}
コード例 #6
0
void WebMediaSessionManager::showPlaybackTargetPicker(WebMediaSessionManagerClient& client, uint64_t contextId, const IntRect& rect, bool)
{
    size_t index = find(&client, contextId);
    ASSERT(index != notFound);
    if (index == notFound)
        return;

    for (auto& state : m_clientState)
        state->requestedPicker = (state->contextId == contextId && state->client == &client);

    bool hasActiveRoute = flagsAreSet(m_clientState[index]->flags, MediaProducer::IsPlayingToExternalDevice);
    targetPicker().showPlaybackTargetPicker(FloatRect(rect), hasActiveRoute);
}
コード例 #7
0
void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient& client, uint64_t contextId, MediaProducer::MediaStateFlags newFlags)
{
    size_t index = find(&client, contextId);
    ASSERT(index != notFound);
    if (index == notFound)
        return;

    auto& changedClientState = m_clientState[index];
    MediaProducer::MediaStateFlags oldFlags = changedClientState->flags;
    LOG(Media, "WebMediaSessionManager::clientStateDidChange(%p + %llu) - new flags = %s, old flags = %s", &client, contextId, mediaProducerStateString(newFlags).utf8().data(), mediaProducerStateString(oldFlags).utf8().data());
    if (newFlags == oldFlags)
        return;

    changedClientState->flags = newFlags;
    if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
        scheduleDelayedTask(TargetMonitoringConfigurationTask);

    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
        return;

    if (!flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate) || !flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
        return;

    // Do not interrupt another element already playing to a device.
    bool anotherClientHasActiveTarget = false;
    for (auto& state : m_clientState) {
        if (state == changedClientState)
            continue;

        if (flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice)) {
            if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
                return;
            anotherClientHasActiveTarget = true;
        }
    }

    // Do not take the target if another client has it and the client reporting a state change is not playing.
    if (anotherClientHasActiveTarget && !flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
        return;

    for (auto& state : m_clientState) {
        if (state == changedClientState)
            continue;
        state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
    }

    changedClientState->client.setShouldPlayToPlaybackTarget(changedClientState->contextId, true);

    if (index && m_clientState.size() > 1)
        std::swap(m_clientState.at(index), m_clientState.at(0));
}
コード例 #8
0
void WebMediaSessionManager::showPlaybackTargetPicker(WebMediaSessionManagerClient& client, uint64_t contextId, const IntRect& rect, bool)
{
    size_t index = find(&client, contextId);
    ASSERT(index != notFound);
    if (index == notFound)
        return;

    auto& clientRequestingPicker = m_clientState[index];
    for (auto& state : m_clientState) {
        state->requestedPicker = state == clientRequestingPicker;
        state->previouslyRequestedPicker = state == clientRequestingPicker;
    }

    bool hasActiveRoute = flagsAreSet(m_clientState[index]->flags, MediaProducer::IsPlayingToExternalDevice);
    LOG(Media, "WebMediaSessionManager::showPlaybackTargetPicker(%p + %llu) - hasActiveRoute = %i", &client, contextId, (int)hasActiveRoute);
    targetPicker().showPlaybackTargetPicker(FloatRect(rect), hasActiveRoute);
}