1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// Copyright 2020 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 "cast/sender/cast_app_availability_tracker.h"
#include "util/osp_logging.h"
namespace openscreen {
namespace cast {
CastAppAvailabilityTracker::CastAppAvailabilityTracker() = default;
CastAppAvailabilityTracker::~CastAppAvailabilityTracker() = default;
std::vector<std::string> CastAppAvailabilityTracker::RegisterSource(
const CastMediaSource& source) {
if (registered_sources_.find(source.source_id()) !=
registered_sources_.end()) {
return {};
}
registered_sources_.emplace(source.source_id(), source);
std::vector<std::string> new_app_ids;
for (const std::string& app_id : source.app_ids()) {
if (++registration_count_by_app_id_[app_id] == 1) {
new_app_ids.push_back(app_id);
}
}
return new_app_ids;
}
void CastAppAvailabilityTracker::UnregisterSource(
const CastMediaSource& source) {
UnregisterSource(source.source_id());
}
void CastAppAvailabilityTracker::UnregisterSource(
const std::string& source_id) {
auto it = registered_sources_.find(source_id);
if (it == registered_sources_.end()) {
return;
}
for (const std::string& app_id : it->second.app_ids()) {
auto count_it = registration_count_by_app_id_.find(app_id);
OSP_DCHECK(count_it != registration_count_by_app_id_.end());
if (--(count_it->second) == 0) {
registration_count_by_app_id_.erase(count_it);
}
}
registered_sources_.erase(it);
}
std::vector<CastMediaSource> CastAppAvailabilityTracker::UpdateAppAvailability(
const std::string& receiver_id,
const std::string& app_id,
AppAvailability availability) {
auto& availabilities = app_availabilities_[receiver_id];
auto it = availabilities.find(app_id);
AppAvailabilityResult old_availability = it == availabilities.end()
? AppAvailabilityResult::kUnknown
: it->second.availability;
AppAvailabilityResult new_availability = availability.availability;
// Updated if status changes from/to kAvailable.
bool updated = (old_availability == AppAvailabilityResult::kAvailable ||
new_availability == AppAvailabilityResult::kAvailable) &&
old_availability != new_availability;
availabilities[app_id] = availability;
if (!updated) {
return {};
}
std::vector<CastMediaSource> affected_sources;
for (const auto& source : registered_sources_) {
if (source.second.ContainsAppId(app_id)) {
affected_sources.push_back(source.second);
}
}
return affected_sources;
}
std::vector<CastMediaSource>
CastAppAvailabilityTracker::RemoveResultsForReceiver(
const std::string& receiver_id) {
auto affected_sources = GetSupportedSources(receiver_id);
app_availabilities_.erase(receiver_id);
return affected_sources;
}
std::vector<CastMediaSource> CastAppAvailabilityTracker::GetSupportedSources(
const std::string& receiver_id) const {
auto it = app_availabilities_.find(receiver_id);
if (it == app_availabilities_.end()) {
return std::vector<CastMediaSource>();
}
// Find all app IDs that are available on the receiver.
std::vector<std::string> supported_app_ids;
for (const auto& availability : it->second) {
if (availability.second.availability == AppAvailabilityResult::kAvailable) {
supported_app_ids.push_back(availability.first);
}
}
// Find all registered sources whose query results contain the receiver ID.
std::vector<CastMediaSource> sources;
for (const auto& source : registered_sources_) {
if (source.second.ContainsAnyAppIdFrom(supported_app_ids)) {
sources.push_back(source.second);
}
}
return sources;
}
CastAppAvailabilityTracker::AppAvailability
CastAppAvailabilityTracker::GetAvailability(const std::string& receiver_id,
const std::string& app_id) const {
auto availabilities_it = app_availabilities_.find(receiver_id);
if (availabilities_it == app_availabilities_.end()) {
return {AppAvailabilityResult::kUnknown, Clock::time_point{}};
}
const auto& availability_map = availabilities_it->second;
auto availability_it = availability_map.find(app_id);
if (availability_it == availability_map.end()) {
return {AppAvailabilityResult::kUnknown, Clock::time_point{}};
}
return availability_it->second;
}
std::vector<std::string> CastAppAvailabilityTracker::GetRegisteredApps() const {
std::vector<std::string> registered_apps;
for (const auto& app_ids_and_count : registration_count_by_app_id_) {
registered_apps.push_back(app_ids_and_count.first);
}
return registered_apps;
}
std::vector<std::string> CastAppAvailabilityTracker::GetAvailableReceivers(
const CastMediaSource& source) const {
std::vector<std::string> receiver_ids;
// For each receiver, check if there is at least one available app in
// |source|.
for (const auto& availabilities : app_availabilities_) {
for (const std::string& app_id : source.app_ids()) {
const auto& availabilities_map = availabilities.second;
auto availability_it = availabilities_map.find(app_id);
if (availability_it != availabilities_map.end() &&
availability_it->second.availability ==
AppAvailabilityResult::kAvailable) {
receiver_ids.push_back(availabilities.first);
break;
}
}
}
return receiver_ids;
}
} // namespace cast
} // namespace openscreen
|