Commit 97e3ad98 authored by Michael Sun's avatar Michael Sun Committed by Commit Bot

[Media Keys] Add handling for Media Seek Forward

To support the "Fast Forward" event generated by media controller
devices (e.g. a USB HID Keyboard or a Bluetooth headset). Add handling
in media_controller_impl. One "Fast Forward" key press will fire a Seek
forward with kDefaultSeekTime=5 seconds using the media session service

BUG=1054411

Change-Id: I50b9a08c07a48143c3bf8ab516374db7a7497c68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2064749Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarBecca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Michael Sun <michaelfsun@google.com>
Cr-Commit-Position: refs/heads/master@{#743359}
parent f29b8754
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
#include "services/media_session/public/mojom/constants.mojom.h"
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
#include "services/media_session/public/mojom/media_session_service.mojom.h" #include "services/media_session/public/mojom/media_session_service.mojom.h"
#include "ui/base/accelerators/media_keys_util.h" #include "ui/base/accelerators/media_keys_util.h"
...@@ -24,6 +25,9 @@ namespace ash { ...@@ -24,6 +25,9 @@ namespace ash {
namespace { namespace {
constexpr base::TimeDelta kDefaultSeekTime =
base::TimeDelta::FromSeconds(media_session::mojom::kDefaultSeekTimeSeconds);
bool IsMediaSessionActionEligibleForKeyControl( bool IsMediaSessionActionEligibleForKeyControl(
media_session::mojom::MediaSessionAction action) { media_session::mojom::MediaSessionAction action) {
return action == media_session::mojom::MediaSessionAction::kPlay || return action == media_session::mojom::MediaSessionAction::kPlay ||
...@@ -252,6 +256,31 @@ void MediaControllerImpl::HandleMediaPrevTrack() { ...@@ -252,6 +256,31 @@ void MediaControllerImpl::HandleMediaPrevTrack() {
client_->HandleMediaPrevTrack(); client_->HandleMediaPrevTrack();
} }
void MediaControllerImpl::HandleMediaSeekForward() {
if (Shell::Get()->session_controller()->IsScreenLocked() &&
!AreLockScreenMediaKeysEnabled()) {
return;
}
ui::RecordMediaHardwareKeyAction(ui::MediaHardwareKeyAction::kSeekForward);
// If the |client_| is force handling the keys then we should forward them.
if (client_ && force_media_client_key_handling_) {
client_->HandleMediaSeekForward();
return;
}
// If media session media key handling is enabled. Seek forward with
// kDefaultSeekTime using the media session service.
if (ShouldUseMediaSession()) {
GetMediaSessionController()->Seek(kDefaultSeekTime);
return;
}
if (client_)
client_->HandleMediaSeekForward();
}
void MediaControllerImpl::RequestCaptureState() { void MediaControllerImpl::RequestCaptureState() {
if (client_) if (client_)
client_->RequestCaptureState(); client_->RequestCaptureState();
......
...@@ -65,6 +65,7 @@ class ASH_EXPORT MediaControllerImpl ...@@ -65,6 +65,7 @@ class ASH_EXPORT MediaControllerImpl
void HandleMediaStop(); void HandleMediaStop();
void HandleMediaNextTrack(); void HandleMediaNextTrack();
void HandleMediaPrevTrack(); void HandleMediaPrevTrack();
void HandleMediaSeekForward();
// Methods that forward to |client_|. // Methods that forward to |client_|.
void RequestCaptureState(); void RequestCaptureState();
......
...@@ -82,6 +82,8 @@ class MediaControllerTest : public AshTestBase { ...@@ -82,6 +82,8 @@ class MediaControllerTest : public AshTestBase {
Flush(); Flush();
Shell::Get()->media_controller()->HandleMediaNextTrack(); Shell::Get()->media_controller()->HandleMediaNextTrack();
Flush(); Flush();
Shell::Get()->media_controller()->HandleMediaSeekForward();
Flush();
} }
private: private:
...@@ -96,6 +98,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenUnlocked) { ...@@ -96,6 +98,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenUnlocked) {
EXPECT_EQ(0, controller()->stop_count()); EXPECT_EQ(0, controller()->stop_count());
EXPECT_EQ(0, controller()->previous_track_count()); EXPECT_EQ(0, controller()->previous_track_count());
EXPECT_EQ(0, controller()->next_track_count()); EXPECT_EQ(0, controller()->next_track_count());
EXPECT_EQ(0, controller()->seek_forward_count());
HandleMediaKeys(); HandleMediaKeys();
...@@ -104,6 +107,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenUnlocked) { ...@@ -104,6 +107,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenUnlocked) {
EXPECT_EQ(1, controller()->stop_count()); EXPECT_EQ(1, controller()->stop_count());
EXPECT_EQ(1, controller()->previous_track_count()); EXPECT_EQ(1, controller()->previous_track_count());
EXPECT_EQ(1, controller()->next_track_count()); EXPECT_EQ(1, controller()->next_track_count());
EXPECT_EQ(1, controller()->seek_forward_count());
} }
TEST_F(MediaControllerTest, EnableLockScreenMediaKeys) { TEST_F(MediaControllerTest, EnableLockScreenMediaKeys) {
...@@ -160,6 +164,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndControlsEnabled) { ...@@ -160,6 +164,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndControlsEnabled) {
EXPECT_EQ(0, controller()->stop_count()); EXPECT_EQ(0, controller()->stop_count());
EXPECT_EQ(0, controller()->previous_track_count()); EXPECT_EQ(0, controller()->previous_track_count());
EXPECT_EQ(0, controller()->next_track_count()); EXPECT_EQ(0, controller()->next_track_count());
EXPECT_EQ(0, controller()->seek_forward_count());
SimulateSessionLock(); SimulateSessionLock();
...@@ -170,6 +175,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndControlsEnabled) { ...@@ -170,6 +175,7 @@ TEST_F(MediaControllerTest, EnableMediaKeysWhenLockedAndControlsEnabled) {
EXPECT_EQ(1, controller()->stop_count()); EXPECT_EQ(1, controller()->stop_count());
EXPECT_EQ(1, controller()->previous_track_count()); EXPECT_EQ(1, controller()->previous_track_count());
EXPECT_EQ(1, controller()->next_track_count()); EXPECT_EQ(1, controller()->next_track_count());
EXPECT_EQ(1, controller()->seek_forward_count());
} }
TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) { TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) {
...@@ -182,6 +188,7 @@ TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) { ...@@ -182,6 +188,7 @@ TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) {
EXPECT_EQ(0, controller()->stop_count()); EXPECT_EQ(0, controller()->stop_count());
EXPECT_EQ(0, controller()->previous_track_count()); EXPECT_EQ(0, controller()->previous_track_count());
EXPECT_EQ(0, controller()->next_track_count()); EXPECT_EQ(0, controller()->next_track_count());
EXPECT_EQ(0, controller()->seek_forward_count());
SimulateSessionLock(); SimulateSessionLock();
...@@ -192,6 +199,7 @@ TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) { ...@@ -192,6 +199,7 @@ TEST_F(MediaControllerTest, DisableMediaKeysWhenLockedAndControlsDisabled) {
EXPECT_EQ(0, controller()->stop_count()); EXPECT_EQ(0, controller()->stop_count());
EXPECT_EQ(0, controller()->previous_track_count()); EXPECT_EQ(0, controller()->previous_track_count());
EXPECT_EQ(0, controller()->next_track_count()); EXPECT_EQ(0, controller()->next_track_count());
EXPECT_EQ(0, controller()->seek_forward_count());
} }
} // namespace ash } // namespace ash
...@@ -30,6 +30,9 @@ class ASH_PUBLIC_EXPORT MediaClient { ...@@ -30,6 +30,9 @@ class ASH_PUBLIC_EXPORT MediaClient {
// Handles the Previous Track Media shortcut key. // Handles the Previous Track Media shortcut key.
virtual void HandleMediaPrevTrack() = 0; virtual void HandleMediaPrevTrack() = 0;
// Handles the Seek Forward Media shortcut key.
virtual void HandleMediaSeekForward() = 0;
// Requests that the client resends the NotifyMediaCaptureChanged() message. // Requests that the client resends the NotifyMediaCaptureChanged() message.
virtual void RequestCaptureState() = 0; virtual void RequestCaptureState() = 0;
......
...@@ -33,6 +33,10 @@ void TestMediaClient::HandleMediaPrevTrack() { ...@@ -33,6 +33,10 @@ void TestMediaClient::HandleMediaPrevTrack() {
++handle_media_prev_track_count_; ++handle_media_prev_track_count_;
} }
void TestMediaClient::HandleMediaSeekForward() {
++handle_media_seek_forward_count_;
}
void TestMediaClient::RequestCaptureState() {} void TestMediaClient::RequestCaptureState() {}
void TestMediaClient::SuspendMediaSessions() { void TestMediaClient::SuspendMediaSessions() {
......
...@@ -24,6 +24,7 @@ class TestMediaClient : public MediaClient { ...@@ -24,6 +24,7 @@ class TestMediaClient : public MediaClient {
void HandleMediaPause() override; void HandleMediaPause() override;
void HandleMediaStop() override; void HandleMediaStop() override;
void HandleMediaPrevTrack() override; void HandleMediaPrevTrack() override;
void HandleMediaSeekForward() override;
void RequestCaptureState() override; void RequestCaptureState() override;
void SuspendMediaSessions() override; void SuspendMediaSessions() override;
...@@ -39,6 +40,9 @@ class TestMediaClient : public MediaClient { ...@@ -39,6 +40,9 @@ class TestMediaClient : public MediaClient {
int handle_media_prev_track_count() const { int handle_media_prev_track_count() const {
return handle_media_prev_track_count_; return handle_media_prev_track_count_;
} }
int handle_media_seek_forward_count() const {
return handle_media_seek_forward_count_;
}
bool media_sessions_suspended() const { return media_sessions_suspended_; } bool media_sessions_suspended() const { return media_sessions_suspended_; }
private: private:
...@@ -48,6 +52,7 @@ class TestMediaClient : public MediaClient { ...@@ -48,6 +52,7 @@ class TestMediaClient : public MediaClient {
int handle_media_pause_count_ = 0; int handle_media_pause_count_ = 0;
int handle_media_stop_count_ = 0; int handle_media_stop_count_ = 0;
int handle_media_prev_track_count_ = 0; int handle_media_prev_track_count_ = 0;
int handle_media_seek_forward_count_ = 0;
bool media_sessions_suspended_ = false; bool media_sessions_suspended_ = false;
DISALLOW_COPY_AND_ASSIGN(TestMediaClient); DISALLOW_COPY_AND_ASSIGN(TestMediaClient);
......
...@@ -197,6 +197,10 @@ void MediaClientImpl::HandleMediaPrevTrack() { ...@@ -197,6 +197,10 @@ void MediaClientImpl::HandleMediaPrevTrack() {
HandleMediaAction(ui::VKEY_MEDIA_PREV_TRACK); HandleMediaAction(ui::VKEY_MEDIA_PREV_TRACK);
} }
void MediaClientImpl::HandleMediaSeekForward() {
HandleMediaAction(ui::VKEY_OEM_104);
}
void MediaClientImpl::RequestCaptureState() { void MediaClientImpl::RequestCaptureState() {
base::flat_map<AccountId, MediaCaptureState> capture_states; base::flat_map<AccountId, MediaCaptureState> capture_states;
for (user_manager::User* user : for (user_manager::User* user :
...@@ -308,10 +312,11 @@ void MediaClientImpl::HandleMediaAction(ui::KeyboardCode keycode) { ...@@ -308,10 +312,11 @@ void MediaClientImpl::HandleMediaAction(ui::KeyboardCode keycode) {
router->NotifyTogglePlayState(); router->NotifyTogglePlayState();
break; break;
// TODO(https://crbug.com/1053777): Handle media action for VKEY_MEDIA_PLAY, // TODO(https://crbug.com/1053777): Handle media action for VKEY_MEDIA_PLAY,
// VKEY_MEDIA_PAUSE, and VKEY_MEDIA_STOP. // VKEY_MEDIA_PAUSE, VKEY_MEDIA_STOP, and VKEY_OEM_104.
case ui::VKEY_MEDIA_PLAY: case ui::VKEY_MEDIA_PLAY:
case ui::VKEY_MEDIA_PAUSE: case ui::VKEY_MEDIA_PAUSE:
case ui::VKEY_MEDIA_STOP: case ui::VKEY_MEDIA_STOP:
case ui::VKEY_OEM_104: // KEYCODE_MEDIA_FAST_FORWARD
break; break;
default: default:
break; break;
......
...@@ -41,6 +41,7 @@ class MediaClientImpl : public ash::MediaClient, ...@@ -41,6 +41,7 @@ class MediaClientImpl : public ash::MediaClient,
void HandleMediaPause() override; void HandleMediaPause() override;
void HandleMediaStop() override; void HandleMediaStop() override;
void HandleMediaPrevTrack() override; void HandleMediaPrevTrack() override;
void HandleMediaSeekForward() override;
void RequestCaptureState() override; void RequestCaptureState() override;
void SuspendMediaSessions() override; void SuspendMediaSessions() override;
......
...@@ -18,7 +18,8 @@ enum class MediaHardwareKeyAction { ...@@ -18,7 +18,8 @@ enum class MediaHardwareKeyAction {
kNextTrack, kNextTrack,
kPreviousTrack, kPreviousTrack,
kPlayPause, kPlayPause,
kMaxValue = kPlayPause kSeekForward,
kMaxValue = kSeekForward
}; };
// The name of the histogram that records |MediaHardwareKeyAction|. // The name of the histogram that records |MediaHardwareKeyAction|.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment