#include "chrome/browser/media/router/providers/cast/cast_activity_manager.h"
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/types/expected_macros.h"
#include "chrome/browser/media/router/data_decoder_util.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/media/router/providers/cast/app_activity.h"
#include "chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h"
#include "chrome/browser/media/router/providers/cast/cast_session_client.h"
#include "chrome/browser/media/router/providers/cast/mirroring_activity.h"
#include "chrome/grit/generated_resources.h"
#include "components/access_code_cast/common/access_code_cast_metrics.h"
#include "components/media_router/browser/logger_impl.h"
#include "components/media_router/browser/media_router_metrics.h"
#include "components/media_router/common/media_source.h"
#include "components/media_router/common/mojom/media_router.mojom.h"
#include "components/media_router/common/providers/cast/channel/cast_device_capability.h"
#include "components/media_router/common/providers/cast/channel/cast_message_util.h"
#include "components/media_router/common/providers/cast/channel/enum_table.h"
#include "components/media_router/common/route_request_result.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/origin.h"
PresentationConnectionCloseReason;
PresentationConnectionState;
namespace media_router {
namespace {
constexpr char kLoggerComponent[] = …;
void RecordSavedDeviceConnectDurationMetric(
base::Time route_request_creation_timestamp) { … }
}
CastActivityManager::CastActivityManager(
MediaSinkServiceBase* media_sink_service,
CastSessionTracker* session_tracker,
cast_channel::CastMessageHandler* message_handler,
mojom::MediaRouter* media_router,
mojom::Logger* logger,
const std::string& hash_token)
: … { … }
CastActivityManager::~CastActivityManager() { … }
void CastActivityManager::LaunchSession(
const CastMediaSource& cast_source,
const MediaSinkInternal& sink,
const std::string& presentation_id,
const url::Origin& origin,
int frame_tree_node_id,
mojom::MediaRouteProvider::CreateRouteCallback callback) { … }
void CastActivityManager::LaunchSessionParsed(
const CastMediaSource& cast_source,
const MediaSinkInternal& sink,
const std::string& presentation_id,
const url::Origin& origin,
int frame_tree_node_id,
mojom::MediaRouteProvider::CreateRouteCallback callback,
data_decoder::DataDecoder::ValueOrError result) { … }
void CastActivityManager::DoLaunchSession(DoLaunchSessionParams params) { … }
AppActivity* CastActivityManager::FindActivityForSessionJoin(
const CastMediaSource& cast_source,
const std::string& presentation_id) { … }
AppActivity* CastActivityManager::FindActivityForAutoJoin(
const CastMediaSource& cast_source,
const url::Origin& origin,
int frame_tree_node_id) { … }
void CastActivityManager::JoinSession(
const CastMediaSource& cast_source,
const std::string& presentation_id,
const url::Origin& origin,
int frame_tree_node_id,
mojom::MediaRouteProvider::JoinRouteCallback callback) { … }
void CastActivityManager::OnActivityStopped(const std::string& route_id) { … }
void CastActivityManager::RemoveActivity(
ActivityMap::iterator activity_it,
PresentationConnectionState state,
PresentationConnectionCloseReason close_reason) { … }
void CastActivityManager::RemoveActivityWithoutNotification(
ActivityMap::iterator activity_it,
PresentationConnectionState state,
PresentationConnectionCloseReason close_reason) { … }
void CastActivityManager::TerminateSession(
const MediaRoute::Id& route_id,
mojom::MediaRouteProvider::TerminateRouteCallback callback) { … }
bool CastActivityManager::BindMediaController(
const std::string& route_id,
mojo::PendingReceiver<mojom::MediaController> media_controller,
mojo::PendingRemote<mojom::MediaStatusObserver> observer) { … }
CastActivityManager::ActivityMap::iterator
CastActivityManager::FindActivityByChannelId(int channel_id) { … }
CastActivityManager::ActivityMap::iterator
CastActivityManager::FindActivityBySink(const MediaSinkInternal& sink) { … }
MirroringActivity* CastActivityManager::FindMirroringActivityByRouteId(
const MediaRoute::Id& route_id) { … }
AppActivity* CastActivityManager::AddAppActivity(const MediaRoute& route,
const std::string& app_id) { … }
CastActivity* CastActivityManager::AddMirroringActivity(
const MediaRoute& route,
const std::string& app_id,
const int frame_tree_node_id,
const CastSinkExtraData& cast_data) { … }
void CastActivityManager::OnAppMessage(
int channel_id,
const openscreen::cast::proto::CastMessage& message) { … }
void CastActivityManager::OnInternalMessage(
int channel_id,
const cast_channel::InternalMessage& message) { … }
void CastActivityManager::OnSessionAddedOrUpdated(const MediaSinkInternal& sink,
const CastSession& session) { … }
void CastActivityManager::OnSessionRemoved(const MediaSinkInternal& sink) { … }
void CastActivityManager::OnMediaStatusUpdated(
const MediaSinkInternal& sink,
const base::Value::Dict& media_status,
std::optional<int> request_id) { … }
void CastActivityManager::OnSourceChanged(const std::string& media_route_id,
int old_frame_tree_node_id,
int frame_tree_node_id) { … }
cast_channel::ResultCallback CastActivityManager::MakeResultCallbackForRoute(
const std::string& route_id,
mojom::MediaRouteProvider::TerminateRouteCallback callback) { … }
void CastActivityManager::SendRouteMessage(const std::string& media_route_id,
const std::string& message) { … }
void CastActivityManager::SendRouteJsonMessage(
const std::string& media_route_id,
const std::string& message,
data_decoder::DataDecoder::ValueOrError result) { … }
void CastActivityManager::AddNonLocalActivity(const MediaSinkInternal& sink,
const CastSession& session) { … }
const MediaRoute* CastActivityManager::GetRoute(
const MediaRoute::Id& route_id) const { … }
std::vector<MediaRoute> CastActivityManager::GetRoutes() const { … }
void CastActivityManager::NotifyAllOnRoutesUpdated() { … }
void CastActivityManager::HandleLaunchSessionResponse(
DoLaunchSessionParams params,
cast_channel::LaunchSessionResponse response,
cast_channel::LaunchSessionCallbackWrapper* out_callback) { … }
void CastActivityManager::HandleStopSessionResponse(
const MediaRoute::Id& route_id,
mojom::MediaRouteProvider::TerminateRouteCallback callback,
cast_channel::Result result) { … }
void CastActivityManager::HandleLaunchSessionResponseFailures(
ActivityMap::iterator activity_it,
DoLaunchSessionParams params,
const std::string& message,
mojom::RouteRequestResultCode result_code) { … }
void CastActivityManager::HandleLaunchSessionResponseMiddleStages(
DoLaunchSessionParams params,
const std::string& message,
cast_channel::LaunchSessionCallbackWrapper* out_callback) { … }
void CastActivityManager::EnsureConnection(const std::string& client_id,
int channel_id,
const std::string& destination_id,
const CastMediaSource& cast_source) { … }
void CastActivityManager::SendFailedToCastIssue(
const MediaSink::Id& sink_id,
const MediaRoute::Id& route_id) { … }
void CastActivityManager::SendPendingUserAuthNotification(
const std::string& sink_name,
const MediaSink::Id& sink_id) { … }
std::optional<MediaSinkInternal>
CastActivityManager::GetSinkForMirroringActivity(int frame_tree_node_id) const { … }
std::string CastActivityManager::ChooseAppId(
const CastMediaSource& source,
const MediaSinkInternal& sink) const { … }
void CastActivityManager::TerminateAllLocalMirroringActivities() { … }
void CastActivityManager::MaybeShowIssueAtLaunch(
const MediaSource& media_source,
const MediaSink::Id& sink_id) { … }
CastActivityManager::DoLaunchSessionParams::DoLaunchSessionParams(
const MediaRoute& route,
const CastMediaSource& cast_source,
const MediaSinkInternal& sink,
const url::Origin& origin,
int frame_tree_node_id,
const std::optional<base::Value> app_params,
mojom::MediaRouteProvider::CreateRouteCallback callback)
: … { … }
void CastActivityManager::AddMirroringActivityForTest(
const MediaRoute::Id& route_id,
std::unique_ptr<MirroringActivity> mirroring_activity) { … }
void CastActivityManager::HandleMissingSinkOnJoin(
mojom::MediaRouteProvider::JoinRouteCallback callback,
const std::string& sink_id,
const std::string& source_id,
const std::string& session_id) { … }
void CastActivityManager::HandleMissingSessionIdOnJoin(
mojom::MediaRouteProvider::JoinRouteCallback callback) { … }
void CastActivityManager::HandleMissingSessionOnJoin(
mojom::MediaRouteProvider::JoinRouteCallback callback,
const std::string& sink_id,
const std::string& source_id,
const std::string& session_id) { … }
CastActivityManager::DoLaunchSessionParams::DoLaunchSessionParams(
DoLaunchSessionParams&& other) = default;
CastActivityManager::DoLaunchSessionParams::~DoLaunchSessionParams() = default;
CastActivityFactoryForTest*
CastActivityManager::cast_activity_factory_for_test_ = …;
}