Commit 671d5823 authored by John Williams's avatar John Williams Committed by Commit Bot

[Cast MRP] Added logic to select an app ID based on device capabilities.

Bug: 1078435, b/155777247
Change-Id: Ic5ed0bd7766e367ca7526e9b95b461885d4bf8c7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2220909Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Commit-Queue: John Williams <jrw@chromium.org>
Auto-Submit: John Williams <jrw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775771}
parent b252c9cc
......@@ -160,9 +160,7 @@ void CastActivityManager::DoLaunchSession(DoLaunchSessionParams params) {
const MediaRoute::Id& route_id = route.media_route_id();
const MediaSinkInternal& sink = params.sink;
// TODO(crbug.com/904995): In the case of multiple app IDs (e.g. mirroring),
// we need to choose an appropriate app ID to launch based on capabilities.
std::string app_id = cast_source.GetAppIds()[0];
std::string app_id = ChooseAppId(cast_source, params.sink);
DVLOG(2) << "Launching session with route ID = " << route_id
<< ", source ID = " << cast_source.source_id()
......@@ -779,6 +777,20 @@ base::Optional<MediaSinkInternal> CastActivityManager::ConvertMirrorToCast(
return base::nullopt;
}
std::string CastActivityManager::ChooseAppId(
const CastMediaSource& source,
const MediaSinkInternal& sink) const {
const auto sink_capabilities =
BitwiseOr<cast_channel::CastDeviceCapability>::FromBits(
sink.cast_data().capabilities);
for (const auto& info : source.app_infos()) {
if (sink_capabilities.HasAll(info.required_capabilities))
return info.app_id;
}
NOTREACHED() << "Can't determine app ID from capabilities.";
return source.app_infos()[0].app_id;
}
CastActivityManager::DoLaunchSessionParams::DoLaunchSessionParams(
const MediaRoute& route,
const CastMediaSource& cast_source,
......
......@@ -270,6 +270,9 @@ class CastActivityManager : public CastActivityManagerBase,
// If no conversion should occur, returns base::nullopt.
base::Optional<MediaSinkInternal> ConvertMirrorToCast(int tab_id);
std::string ChooseAppId(const CastMediaSource& source,
const MediaSinkInternal& sink) const;
static ActivityRecordFactoryForTest* activity_record_factory_;
base::flat_set<MediaSource::Id> route_queries_;
......
......@@ -191,8 +191,8 @@ std::unique_ptr<CastMediaSource> CastMediaSourceForTabMirroring(
const MediaSource::Id& source_id) {
return std::make_unique<CastMediaSource>(
source_id,
std::vector<CastAppInfo>({CastAppInfo(kCastStreamingAppId),
CastAppInfo(kCastStreamingAudioAppId)}));
std::vector<CastAppInfo>({CastAppInfo::ForCastStreaming(),
CastAppInfo::ForCastStreamingAudio()}));
}
std::unique_ptr<CastMediaSource> CastMediaSourceForDesktopMirroring(
......@@ -200,7 +200,7 @@ std::unique_ptr<CastMediaSource> CastMediaSourceForDesktopMirroring(
// TODO(https://crbug.com/849335): Add back audio-only devices for desktop
// mirroring when proper support is implemented.
return std::make_unique<CastMediaSource>(
source_id, std::vector<CastAppInfo>({CastAppInfo(kCastStreamingAppId)}));
source_id, std::vector<CastAppInfo>({CastAppInfo::ForCastStreaming()}));
}
// The logic shared by ParseCastUrl() and ParseLegacyCastUrl().
......@@ -363,10 +363,23 @@ CastAppInfo::CastAppInfo(
const std::string& app_id,
BitwiseOr<cast_channel::CastDeviceCapability> required_capabilities)
: app_id(app_id), required_capabilities(required_capabilities) {}
CastAppInfo::~CastAppInfo() = default;
CastAppInfo::CastAppInfo(const CastAppInfo& other) = default;
// static
CastAppInfo CastAppInfo::ForCastStreaming() {
return CastAppInfo(kCastStreamingAppId, {CastDeviceCapability::VIDEO_OUT,
CastDeviceCapability::AUDIO_OUT});
}
// static
CastAppInfo CastAppInfo::ForCastStreamingAudio() {
return CastAppInfo(kCastStreamingAudioAppId,
{CastDeviceCapability::AUDIO_OUT});
}
// static
std::unique_ptr<CastMediaSource> CastMediaSource::FromMediaSource(
const MediaSource& source) {
......
......@@ -44,12 +44,20 @@ class BitwiseOr {
for (E e : values)
Add(e);
}
static constexpr BitwiseOr FromBits(T bits) { return BitwiseOr(bits); }
bool empty() const { return bits_ == 0; }
T bits() const { return bits_; }
void Add(E value) { bits_ |= Mask(value); }
bool Has(E value) const { return (bits_ & Mask(value)) != 0; }
bool HasAll(const BitwiseOr& other) const {
return (bits_ & other.bits_) == other.bits_;
}
bool operator==(const BitwiseOr& other) const { return bits_ == other.bits_; }
bool operator!=(const BitwiseOr& other) const { return *this != other; }
private:
explicit constexpr BitwiseOr(T bits) : bits_(bits) {}
static T Mask(E value) {
const T result = static_cast<T>(value);
DCHECK(static_cast<E>(result) == value);
......@@ -60,12 +68,16 @@ class BitwiseOr {
// Represents a Cast app and its capabilitity requirements.
struct CastAppInfo {
explicit CastAppInfo(const std::string& app_id,
BitwiseOr<cast_channel::CastDeviceCapability> = {});
explicit CastAppInfo(
const std::string& app_id,
BitwiseOr<cast_channel::CastDeviceCapability> required_capabilities);
~CastAppInfo();
CastAppInfo(const CastAppInfo& other);
static CastAppInfo ForCastStreaming();
static CastAppInfo ForCastStreamingAudio();
std::string app_id;
// A bitset of capabilities required by the app.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment