blob: 97d91b885891ac8bd88395484cc49aea40c3ce5d [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/media/media_experiment_manager.h"
#include <utility>
#include "base/bind_helpers.h"
namespace content {
MediaExperimentManager::ScopedPlayerState::ScopedPlayerState(
base::OnceClosure destruction_cb,
PlayerState* state)
: state_(state), destruction_cb_(std::move(destruction_cb)) {}
MediaExperimentManager::ScopedPlayerState::ScopedPlayerState(
ScopedPlayerState&& rhs) {
destruction_cb_ = std::move(rhs.destruction_cb_);
state_ = rhs.state_;
}
MediaExperimentManager::ScopedPlayerState::~ScopedPlayerState() {
if (destruction_cb_)
std::move(destruction_cb_).Run();
}
MediaExperimentManager::MediaExperimentManager() = default;
MediaExperimentManager::~MediaExperimentManager() = default;
// Keeps track of all media players across all pages, and notifies them when
// they enter or leave an active experiment.
void MediaExperimentManager::PlayerCreated(const MediaPlayerId& player_id,
Client* client) {
// TODO: check that we don't know about it already.
player_ids_by_client_[client].insert(player_id);
players_[player_id].client = client;
}
void MediaExperimentManager::PlayerDestroyed(const MediaPlayerId& player_id) {
ErasePlayersInternal({player_id});
}
MediaExperimentManager::ScopedPlayerState
MediaExperimentManager::GetPlayerState(const MediaPlayerId& player_id) {
auto iter = players_.find(player_id);
DCHECK(iter != players_.end());
// TODO(liberato): Replace this callback with something that checks the
// experiment state, to see if an experiment has started / stopped.
return ScopedPlayerState(base::DoNothing(), &iter->second);
}
void MediaExperimentManager::ClientDestroyed(Client* client) {
auto by_client = player_ids_by_client_.find(client);
// Make a copy, since ErasePlayers will modify the original.
ErasePlayersInternal(std::set<MediaPlayerId>(by_client->second));
}
void MediaExperimentManager::ErasePlayersInternal(
const std::set<MediaPlayerId>& player_ids) {
for (auto player_id : player_ids) {
auto player_iter = players_.find(player_id);
DCHECK(player_iter != players_.end());
// Erase this player from the client, and maybe the client if it's the
// only player owned by it.
auto by_client_iter =
player_ids_by_client_.find(player_iter->second.client);
DCHECK(by_client_iter != player_ids_by_client_.end());
by_client_iter->second.erase(player_id);
if (by_client_iter->second.size() == 0)
player_ids_by_client_.erase(by_client_iter);
players_.erase(player_iter);
}
}
size_t MediaExperimentManager::GetPlayerCountForTesting() const {
return players_.size();
}
// static
MediaExperimentManager* MediaExperimentManager::Instance() {
return nullptr;
}
} // namespace content