xref: /aosp_15_r20/external/openscreen/cast/sender/cast_app_availability_tracker.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CAST_SENDER_CAST_APP_AVAILABILITY_TRACKER_H_
6 #define CAST_SENDER_CAST_APP_AVAILABILITY_TRACKER_H_
7 
8 #include <map>
9 #include <string>
10 #include <vector>
11 
12 #include "cast/sender/channel/message_util.h"
13 #include "cast/sender/public/cast_media_source.h"
14 #include "platform/api/time.h"
15 
16 namespace openscreen {
17 namespace cast {
18 
19 // Tracks receiver queries and their extracted Cast app IDs and their
20 // availabilities on discovered receivers.
21 // Example usage:
22 ///
23 // (1) A page is interested in a Cast URL (e.g. by creating a
24 // PresentationRequest with the URL) like "cast:foo". To register the source to
25 // be tracked:
26 //   CastAppAvailabilityTracker tracker;
27 //   auto source = CastMediaSource::From("cast:foo");
28 //   auto new_app_ids = tracker.RegisterSource(source.value());
29 //
30 // (2) The set of app IDs returned by the tracker can then be used by the caller
31 // to send an app availability request to each of the discovered receivers.
32 //
33 // (3) Once the caller knows the availability value for a (receiver, app) pair,
34 // it may inform the tracker to update its results:
35 //   auto affected_sources =
36 //       tracker.UpdateAppAvailability(receiver_id, app_id, {availability,
37 //       now});
38 //
39 // (4) The tracker returns a subset of discovered sources that were affected by
40 // the update. The caller can then call |GetAvailableReceivers()| to get the
41 // updated results for each affected source.
42 //
43 // (5a): At any time, the caller may call |RemoveResultsForReceiver()| to remove
44 // cached results pertaining to the receiver, when it detects that a receiver is
45 // removed or no longer valid.
46 //
47 // (5b): At any time, the caller may call |GetAvailableReceivers()| (even before
48 // the source is registered) to determine if there are cached results available.
49 class CastAppAvailabilityTracker {
50  public:
51   // The result of an app availability request and the time when it is obtained.
52   struct AppAvailability {
53     AppAvailabilityResult availability;
54     Clock::time_point time;
55   };
56 
57   CastAppAvailabilityTracker();
58   ~CastAppAvailabilityTracker();
59 
60   CastAppAvailabilityTracker(const CastAppAvailabilityTracker&) = delete;
61   CastAppAvailabilityTracker& operator=(const CastAppAvailabilityTracker&) =
62       delete;
63 
64   // Registers |source| with the tracker. Returns a list of new app IDs that
65   // were previously not known to the tracker.
66   std::vector<std::string> RegisterSource(const CastMediaSource& source);
67 
68   // Unregisters the source given by |source| or |source_id| with the tracker.
69   void UnregisterSource(const std::string& source_id);
70   void UnregisterSource(const CastMediaSource& source);
71 
72   // Updates the availability of |app_id| on |receiver_id| to |availability|.
73   // Returns a list of registered CastMediaSources for which the set of
74   // available receivers might have been updated by this call. The caller should
75   // call |GetAvailableReceivers| with the returned CastMediaSources to get the
76   // updated lists.
77   std::vector<CastMediaSource> UpdateAppAvailability(
78       const std::string& receiver_id,
79       const std::string& app_id,
80       AppAvailability availability);
81 
82   // Removes all results associated with |receiver_id|, i.e. when the receiver
83   // becomes invalid.  Returns a list of registered CastMediaSources for which
84   // the set of available receivers might have been updated by this call. The
85   // caller should call |GetAvailableReceivers| with the returned
86   // CastMediaSources to get the updated lists.
87   std::vector<CastMediaSource> RemoveResultsForReceiver(
88       const std::string& receiver_id);
89 
90   // Returns a list of registered CastMediaSources supported by |receiver_id|.
91   std::vector<CastMediaSource> GetSupportedSources(
92       const std::string& receiver_id) const;
93 
94   // Returns the availability for |app_id| on |receiver_id| and the time at
95   // which the availability was determined. If availability is kUnknown, then
96   // the time may be null (e.g. if an availability request was never sent).
97   AppAvailability GetAvailability(const std::string& receiver_id,
98                                   const std::string& app_id) const;
99 
100   // Returns a list of registered app IDs.
101   std::vector<std::string> GetRegisteredApps() const;
102 
103   // Returns a list of receiver IDs compatible with |source|, using the current
104   // availability info.
105   std::vector<std::string> GetAvailableReceivers(
106       const CastMediaSource& source) const;
107 
108  private:
109   // App ID to availability.
110   using AppAvailabilityMap = std::map<std::string, AppAvailability>;
111 
112   // Registered sources and corresponding CastMediaSources.
113   std::map<std::string, CastMediaSource> registered_sources_;
114 
115   // App IDs tracked and the number of registered sources containing them.
116   std::map<std::string, int> registration_count_by_app_id_;
117 
118   // IDs and app availabilities of known receivers.
119   std::map<std::string, AppAvailabilityMap> app_availabilities_;
120 };
121 
122 }  // namespace cast
123 }  // namespace openscreen
124 
125 #endif  // CAST_SENDER_CAST_APP_AVAILABILITY_TRACKER_H_
126