summaryrefslogtreecommitdiff
path: root/chromium/chrome/common/media_router/discovery/media_sink_service_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/common/media_router/discovery/media_sink_service_base.h')
-rw-r--r--chromium/chrome/common/media_router/discovery/media_sink_service_base.h135
1 files changed, 135 insertions, 0 deletions
diff --git a/chromium/chrome/common/media_router/discovery/media_sink_service_base.h b/chromium/chrome/common/media_router/discovery/media_sink_service_base.h
new file mode 100644
index 00000000000..df9547f1e28
--- /dev/null
+++ b/chromium/chrome/common/media_router/discovery/media_sink_service_base.h
@@ -0,0 +1,135 @@
+// Copyright 2017 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.
+
+#ifndef CHROME_COMMON_MEDIA_ROUTER_DISCOVERY_MEDIA_SINK_SERVICE_BASE_H_
+#define CHROME_COMMON_MEDIA_ROUTER_DISCOVERY_MEDIA_SINK_SERVICE_BASE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/gtest_prod_util.h"
+#include "base/observer_list.h"
+#include "base/sequence_checker.h"
+#include "base/timer/timer.h"
+#include "chrome/common/media_router/discovery/media_sink_internal.h"
+#include "chrome/common/media_router/discovery/media_sink_service_util.h"
+
+namespace media_router {
+
+class MediaRoute;
+
+// Base class for discovering MediaSinks. Responsible for bookkeeping of
+// current set of discovered sinks, and notifying observers when there are
+// updates.
+// In addition, this class maintains a "discovery timer", used for batching
+// updates in quick succession. The timer fires when it is assumed that
+// discovery has reached a relatively steady state. When the timer fires:
+// - The batched updated sink list will be sent back to the Media Router
+// extension via |callback|. This back-channel is necessary until all logic
+// dependent on MediaSinks are moved out of the extension.
+// - Subclasses may record discovered related metrics.
+// This class may be created on any thread, but all subsequent methods must be
+// invoked on the same thread.
+class MediaSinkServiceBase {
+ public:
+ // Listens for sink updates in MediaSinkServiceBase.
+ class Observer {
+ public:
+ virtual ~Observer() = default;
+
+ // Invoked when the list of discovered sinks changes.
+ virtual void OnSinksDiscovered(
+ const std::vector<MediaSinkInternal>& sinks) {}
+
+ // Invoked when |sink| is added or updated.
+ virtual void OnSinkAddedOrUpdated(const MediaSinkInternal& sink) {}
+
+ // Invoked when |sink| is removed.
+ virtual void OnSinkRemoved(const MediaSinkInternal& sink) {}
+ };
+
+ // |callback|: Callback to inform the MediaRouter extension of discovered
+ // sinks updates. Other uses should implement Observer::OnSinksDiscovered().
+ explicit MediaSinkServiceBase(const OnSinksDiscoveredCallback& callback);
+ virtual ~MediaSinkServiceBase();
+
+ // Adds |observer| to observe |this| for sink updates.
+ // Caller is responsible for calling |RemoveObserver| before it is destroyed.
+ // Both methods are safe to call on any thread.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ // Overridden by subclass to initiate action triggered by user gesture, e.g.
+ // start one-off round of discovery.
+ virtual void OnUserGesture() {}
+
+ // Adds or updates, or removes a sink.
+ // Notifies |observers_| that the sink has been added, updated, or removed.
+ // Also invokes |StartTimer()|.
+ void AddOrUpdateSink(const MediaSinkInternal& sink);
+ void RemoveSink(const MediaSinkInternal& sink);
+ void RemoveSinkById(const MediaSink::Id& sink_id);
+
+ const base::flat_map<MediaSink::Id, MediaSinkInternal>& GetSinks() const;
+
+ // These methods return nullptr when no sink is found.
+ const MediaSinkInternal* GetSinkById(const MediaSink::Id& sink_id) const;
+ const MediaSinkInternal* GetSinkByRoute(const MediaRoute& route) const;
+
+ void SetTimerForTest(std::unique_ptr<base::OneShotTimer> timer);
+
+ protected:
+ // Called when |discovery_timer_| expires. Informs subclass to report device
+ // counts. Also informs Media Router of updated list of discovered sinks.
+ // May be overridden by subclass to perform additional operations, such as
+ // pruning old sinks.
+ virtual void OnDiscoveryComplete();
+
+ // Starts |discovery_timer_| to invoke |OnDiscoveryComplete()|. Subclasses
+ // may call this at the start of a round of discovery.
+ void StartTimer();
+
+ private:
+ friend class MediaSinkServiceBaseTest;
+ FRIEND_TEST_ALL_PREFIXES(MediaSinkServiceBaseTest,
+ TestOnDiscoveryComplete_SameSink);
+ FRIEND_TEST_ALL_PREFIXES(MediaSinkServiceBaseTest,
+ TestOnDiscoveryComplete_SameSinkDifferentOrders);
+
+ // Overriden by subclass to report device counts.
+ virtual void RecordDeviceCounts() {}
+
+ // The current set of discovered sinks keyed by MediaSink ID.
+ base::flat_map<MediaSink::Id, MediaSinkInternal> sinks_;
+
+ // Observers to notify when a sink is added, updated, or removed.
+ base::ObserverList<Observer>::Unchecked observers_;
+
+ // Timer for recording device counts after a sink list has changed. To ensure
+ // the metrics are recorded accurately, a small delay is introduced after a
+ // sink list change in order for the discovery process to reach a steady
+ // state before the metrics are recorded.
+ std::unique_ptr<base::OneShotTimer> discovery_timer_;
+
+ // The following fields exist temporarily for sending back discovered sinks to
+ // the Media Router extension.
+ // TODO(https://crbug.com/809249): Remove once the extension no longer need
+ // the sinks.
+
+ // Callback to MediaRouter to provide sinks to the MR extension.
+ OnSinksDiscoveredCallback on_sinks_discovered_cb_;
+
+ // Sinks saved in the previous |OnDiscoveryComplete()| invocation. Checked
+ // against |sinks_| during |OnDiscoveryComplete()| before invoking
+ // |on_sinks_discovered_cb_|.
+ base::flat_map<MediaSink::Id, MediaSinkInternal> previous_sinks_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ DISALLOW_COPY_AND_ASSIGN(MediaSinkServiceBase);
+};
+
+} // namespace media_router
+
+#endif // CHROME_COMMON_MEDIA_ROUTER_DISCOVERY_MEDIA_SINK_SERVICE_BASE_H_