| // Copyright 2019 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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ |
| #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ |
| |
| #include "base/callback.h" |
| #include "base/sequence_checker.h" |
| #include "base/time/time.h" |
| #include "media/base/video_codecs.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| #include "services/device/public/mojom/battery_monitor.mojom.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "third_party/blink/public/platform/web_common.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace media { |
| struct PipelineMetadata; |
| |
| // Class to monitor for power events during playback and record them to UMA/UKM. |
| class BLINK_PLATFORM_EXPORT PowerStatusHelper { |
| public: |
| using CreateBatteryMonitorCB = base::RepeatingCallback< |
| mojo::PendingRemote<device::mojom::BatteryMonitor>()>; |
| |
| // Bits used to construct UMA buckets. |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum /* not class */ Bits { |
| // Bit layout is: [msb] xx f F RR CC [lsb] |
| // R == resolution |
| // C == codec |
| // F == frame rate |
| // f == full screen |
| // x == unused |
| // Remember that we can't use more than 6 bits, since we shouldn't go over |
| // 100 UMA buckets. |
| |
| // Codec bits, values 0x00 to 0x03 |
| // Named "CodecBits" to prevent a name collision with media::VideoCodec. |
| kCodecBitsH264 = (0x00) << 0, |
| kCodecBitsVP9Profile0 = (0x01) << 0, |
| // Ignore Profile1 |
| kCodecBitsVP9Profile2 = (0x02) << 0, |
| // TODO(liberato): add AV1 |
| |
| // Resolution bits, values 0x00 to 0x03 |
| kResolution360p = (0x00) << 2, |
| kResolution720p = (0x01) << 2, |
| kResolution1080p = (0x02) << 2, |
| |
| // Frame rate bits, values 0x00 to 0x01 |
| kFrameRate30 = (0x00) << 4, |
| kFrameRate60 = (0x01) << 4, |
| |
| // Fullscreen bits, values 0x00 to 0x01 |
| kFullScreenNo = (0x00) << 5, |
| kFullScreenYes = (0x01) << 5, |
| |
| // This is not a valid bit for, you know, testing. |
| kNotAValidBitForTesting = (0x01) << 10, |
| }; |
| |
| // If |stats_cb| is not provided, then we'll record to UMA. It's just for |
| // the tests. |
| explicit PowerStatusHelper(CreateBatteryMonitorCB create_battery_monitor_cb); |
| PowerStatusHelper(const PowerStatusHelper&) = delete; |
| PowerStatusHelper& operator=(const PowerStatusHelper&) = delete; |
| ~PowerStatusHelper(); |
| |
| // Notify us about changes to the player. |
| void SetIsPlaying(bool is_playing); |
| void SetMetadata(const media::PipelineMetadata& metadata); |
| void SetIsFullscreen(bool is_fullscreen); |
| void SetAverageFrameRate(absl::optional<int> average_fps); |
| |
| // Handle notifications about the experiment state from the power experiment. |
| // manager. |state| indicates whether our player is eligible to record power |
| // experiments readings. |
| void UpdatePowerExperimentState(bool state); |
| |
| private: |
| friend class PowerStatusHelperTest; |
| friend class PowerStatusHelperBucketTest; |
| |
| // Return the UMA bucket for the given video configuration, or nullopt if we |
| // don't want to record it. |
| static absl::optional<int> BucketFor(bool is_playing, |
| bool has_video, |
| media::VideoCodec codec, |
| media::VideoCodecProfile profile, |
| gfx::Size natural_size, |
| bool is_fullscreen, |
| absl::optional<int> average_fps); |
| |
| // Return the histogram names. Here so that tests can find them too. |
| static const char* BatteryDeltaHistogram(); |
| static const char* ElapsedTimeHistogram(); |
| |
| // Recompute everything when playback state or power experiment state changes. |
| void OnAnyStateChange(); |
| |
| // Handle updates about the current battery status. |
| void OnBatteryStatus(device::mojom::BatteryStatusPtr battery_status); |
| |
| // Start monitoring if we haven't already. Any outstanding callbacks will be |
| // cancelled if monitoring was already in progress. |
| void StartMonitoring(); |
| void StopMonitoring(); |
| |
| // Register to receive a power update the next time it changes. |
| void QueryNextStatus(); |
| |
| CreateBatteryMonitorCB create_battery_monitor_cb_; |
| |
| // Most recent parameters we were given. |
| bool is_playing_ = false; |
| bool has_video_ = false; |
| media::VideoCodec codec_ = media::VideoCodec::kUnknownVideoCodec; |
| media::VideoCodecProfile profile_ = |
| media::VideoCodecProfile::VIDEO_CODEC_PROFILE_UNKNOWN; |
| gfx::Size natural_size_; |
| bool is_fullscreen_ = false; |
| // For estimating fps. Can be unset if we don't know. |
| absl::optional<int> average_fps_; |
| |
| // Current UMA bucket, if any. |
| absl::optional<int> current_bucket_; |
| |
| // If set, our previous battery level, from 0-100. |
| absl::optional<float> battery_level_baseline_; |
| // The time at which we last got an update from |battery_monitor_|. |
| base::TimeTicks last_update_; |
| |
| // Are we currently the player that should be recording power for the power |
| // experiment, according to the MediaPowerExperimentManager? |
| bool experiment_state_ = false; |
| |
| mojo::Remote<device::mojom::BatteryMonitor> battery_monitor_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| }; |
| |
| } // namespace media |
| |
| #endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ |