1 // Copyright 2019 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 CONTENT_BROWSER_MEDIA_MEDIA_POWER_EXPERIMENT_MANAGER_H_ 6 #define CONTENT_BROWSER_MEDIA_MEDIA_POWER_EXPERIMENT_MANAGER_H_ 7 8 #include <map> 9 #include <set> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/macros.h" 14 #include "base/memory/scoped_refptr.h" 15 #include "base/optional.h" 16 #include "base/sequence_checker.h" 17 #include "base/sequenced_task_runner.h" 18 #include "content/common/content_export.h" 19 #include "content/public/browser/media_player_id.h" 20 #include "media/base/video_codecs.h" 21 22 namespace content { 23 24 // Keeps track of all media players across all pages, and notifies them when 25 // they enter or leave an active experiment. 26 class CONTENT_EXPORT MediaPowerExperimentManager { 27 public: 28 // Callback to notify the client when an experiment starts / stops. 29 using ExperimentCB = base::RepeatingCallback<void(bool)>; 30 31 // Flags for handling notifications of stopped players. 32 enum class NotificationMode { 33 // If the stopped player is the current experiment, then notify it that it 34 // no longer is. 35 kNotify, 36 37 // If the stopped player is the current experiment, then skip notification. 38 // This is useful if the player is being destroyed. 39 kSkip 40 }; 41 42 MediaPowerExperimentManager(); 43 virtual ~MediaPowerExperimentManager(); 44 45 // May return nullptr if experiments aren't enabled. 46 static MediaPowerExperimentManager* Instance(); 47 48 // Called when the given player begins playing. |cb| will be called if it 49 // becomes / stops being the only playing player, though never re-entrantly. 50 virtual void PlayerStarted(const MediaPlayerId& player, ExperimentCB cb); 51 52 // Called when the given player has stopped playing. It is okay if it was 53 // never started via PlayerStarted; we'll just ignore it. If 54 // |notification_mode| is kSkip, then we won't notify |player| that it's 55 // stopping, if it's the current experiment. 56 virtual void PlayerStopped( 57 const MediaPlayerId& player, 58 NotificationMode notification_mode = NotificationMode::kNotify); 59 60 private: 61 // Send start / stop notifications and update |current_experiment_player_| 62 // based on whether an experiment should be running. 63 void CheckExperimentState(); 64 65 // Set of all playing players that we know about. 66 std::map<MediaPlayerId, ExperimentCB> players_; 67 68 // If set, this is the player that has a running experiment. 69 base::Optional<MediaPlayerId> current_experiment_player_; 70 ExperimentCB current_experiment_cb_; 71 72 scoped_refptr<base::SequencedTaskRunner> task_runner_; 73 SEQUENCE_CHECKER(sequence_checker_); 74 75 DISALLOW_COPY_AND_ASSIGN(MediaPowerExperimentManager); 76 }; 77 78 } // namespace content 79 80 #endif // CONTENT_BROWSER_MEDIA_MEDIA_POWER_EXPERIMENT_MANAGER_H_ 81