1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_
#define CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "components/system_media_controls/system_media_controls.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/media_session/public/mojom/media_controller.mojom.h"
namespace base {
class UnguessableToken;
}
namespace content {
// The SystemMediaControlsNotifier connects to the SystemMediaControls API and
// keeps it informed of the current media playback state and metadata. It
// observes changes to the active Media Session and updates the
// SystemMediaControls accordingly.
class CONTENT_EXPORT SystemMediaControlsNotifier
: public media_session::mojom::MediaControllerObserver,
public media_session::mojom::MediaControllerImageObserver {
public:
SystemMediaControlsNotifier(
system_media_controls::SystemMediaControls* system_media_controls,
base::UnguessableToken request_id);
SystemMediaControlsNotifier(const SystemMediaControlsNotifier&) = delete;
SystemMediaControlsNotifier& operator=(const SystemMediaControlsNotifier&) =
delete;
~SystemMediaControlsNotifier() override;
// media_session::mojom::MediaControllerObserver implementation.
void MediaSessionInfoChanged(
media_session::mojom::MediaSessionInfoPtr session_info) override;
void MediaSessionMetadataChanged(
const std::optional<media_session::MediaMetadata>& metadata) override;
void MediaSessionActionsChanged(
const std::vector<media_session::mojom::MediaSessionAction>& actions)
override;
void MediaSessionChanged(
const std::optional<base::UnguessableToken>& request_id) override;
void MediaSessionPositionChanged(
const std::optional<media_session::MediaPosition>& position) override;
// media_session::mojom::MediaControllerImageObserver implementation.
void MediaControllerImageChanged(
::media_session::mojom::MediaSessionImageType type,
const SkBitmap& bitmap) override;
// There's no chapter images in the system media tray view, so we don't need
// to implement this method.
void MediaControllerChapterImageChanged(int chapter_index,
const SkBitmap& bitmap) override {}
private:
friend class SystemMediaControlsNotifierTest;
// Updates the system media controls' metadata after a brief delay. If
// multiple calls are received during the delay, only the last one is applied.
// This prevents overloading the OS with system calls.
void DebouncePositionUpdate(media_session::MediaPosition position);
void DebounceMetadataUpdate(media_session::MediaMetadata metadata);
void DebouncePlaybackStatusUpdate(
system_media_controls::SystemMediaControls::PlaybackStatus
playback_status);
void DebounceIconUpdate(const SkBitmap& bitmap);
void DebounceSetIsSeekToEnabled(bool is_seek_to_enabled);
void MaybeScheduleMetadataUpdate();
void UpdateMetadata();
void UpdateIcon();
// Clear the system's media controls' metadata, and any pending position or
// metadata updates.
void ClearAllMetadata();
// We want to hide the controls on the lock screen on Windows in certain
// cases. We don't want this functionality on other OSes.
#if BUILDFLAG(IS_WIN)
// Polls the current idle state of the system.
void CheckLockState();
// Called when the idle state changes from unlocked to locked.
void OnScreenLocked();
// Called when the idle state changes from locked to unlocked.
void OnScreenUnlocked();
// Helper functions for dealing with the timer that hides the System Media
// Transport Controls on the lock screen 5 seconds after the user pauses.
void StartHideSmtcTimer();
void StopHideSmtcTimer();
void HideSmtcTimerFired();
bool screen_locked_ = false;
base::RepeatingTimer lock_polling_timer_;
base::OneShotTimer hide_smtc_timer_;
#endif // BUILDFLAG(IS_WIN)
// Our connection to the System Media Controls instance we should notify.
// Owned by WebAppSystemMediaControls.
const raw_ptr<system_media_controls::SystemMediaControls>
system_media_controls_;
// Timer to debounce updates.
base::OneShotTimer metadata_update_timer_;
base::OneShotTimer icon_update_timer_;
base::OneShotTimer actions_update_timer_;
// Pending metadata to be set once `metadata_update_timer_` fires.
std::optional<media_session::MediaPosition> delayed_position_update_;
std::optional<media_session::MediaMetadata> delayed_metadata_update_;
std::optional<system_media_controls::SystemMediaControls::PlaybackStatus>
delayed_playback_status_;
// Icon to use once `icon_update_timer_` fires.
std::optional<SkBitmap> delayed_icon_update_;
// Pending action to set once `actions_update_timer_` fires.
std::optional<bool> delayed_is_seek_to_enabled_;
// Tracks current media session state/metadata.
mojo::Remote<media_session::mojom::MediaController> media_controller_remote_;
media_session::mojom::MediaSessionInfoPtr session_info_ptr_;
// Used to receive updates to the active media controller.
mojo::Receiver<media_session::mojom::MediaControllerObserver>
media_controller_observer_receiver_{this};
mojo::Receiver<media_session::mojom::MediaControllerImageObserver>
media_controller_image_observer_receiver_{this};
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_
|