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 device queries and their extracted Cast app IDs and their 20 // availabilities on discovered devices. 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 devices. 32 // 33 // (3) Once the caller knows the availability value for a (device, app) pair, it 34 // may inform the tracker to update its results: 35 // auto affected_sources = 36 // tracker.UpdateAppAvailability(device_id, app_id, {availability, now}); 37 // 38 // (4) The tracker returns a subset of discovered sources that were affected by 39 // the update. The caller can then call |GetAvailableDevices()| to get the 40 // updated results for each affected source. 41 // 42 // (5a): At any time, the caller may call |RemoveResultsForDevice()| to remove 43 // cached results pertaining to the device, when it detects that a device is 44 // removed or no longer valid. 45 // 46 // (5b): At any time, the caller may call |GetAvailableDevices()| (even before 47 // the source is registered) to determine if there are cached results available. 48 // TODO(crbug.com/openscreen/112): Device -> Receiver renaming. 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 |device_id| to |availability|. 73 // Returns a list of registered CastMediaSources for which the set of 74 // available devices might have been updated by this call. The caller should 75 // call |GetAvailableDevices| with the returned CastMediaSources to get the 76 // updated lists. 77 std::vector<CastMediaSource> UpdateAppAvailability( 78 const std::string& device_id, 79 const std::string& app_id, 80 AppAvailability availability); 81 82 // Removes all results associated with |device_id|, i.e. when the device 83 // becomes invalid. Returns a list of registered CastMediaSources for which 84 // the set of available devices might have been updated by this call. The 85 // caller should call |GetAvailableDevices| with the returned CastMediaSources 86 // to get the updated lists. 87 std::vector<CastMediaSource> RemoveResultsForDevice( 88 const std::string& device_id); 89 90 // Returns a list of registered CastMediaSources supported by |device_id|. 91 std::vector<CastMediaSource> GetSupportedSources( 92 const std::string& device_id) const; 93 94 // Returns the availability for |app_id| on |device_id| and the time at which 95 // the availability was determined. If availability is kUnknown, then the time 96 // may be null (e.g. if an availability request was never sent). 97 AppAvailability GetAvailability(const std::string& device_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 device IDs compatible with |source|, using the current 104 // availability info. 105 std::vector<std::string> GetAvailableDevices( 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 devices. 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