Bug 1575995 - part1 : implement basic classes for handling media hardware keys. r=baku

In order to receive platform level media hardward keys event, we create a `MediaHardwareKeysEventSource` which is used to implement intercepting those events according to different platforms.

We can add a `MediaHardwareKeysEventListener` onto `MediaHardwareKeysEventSource`, so that we can get notification whenever hardware media keys are being pressed.

`MediaHardwareKeysManager` is used to encapsulate all these details, it would create a source and corresponding listener.

Differential Revision: https://phabricator.services.mozilla.com/D43313

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alastor Wu 2019-09-13 00:08:57 +00:00
Родитель 140dc3f765
Коммит d7506cd7d5
6 изменённых файлов: 229 добавлений и 0 удалений

Просмотреть файл

@ -9,6 +9,7 @@
#include "AudioFocusManager.h"
#include "MediaController.h"
#include "MediaHardwareKeysManager.h"
#include "nsDataHashtable.h"
#include "nsIObserver.h"
#include "nsTArray.h"
@ -55,6 +56,7 @@ class MediaControlService final : public nsIObserver {
nsDataHashtable<nsUint64HashKey, RefPtr<MediaController>> mControllers;
AudioFocusManager mAudioFocusManager;
MediaHardwareKeysManager mHardwareKeysManager;
};
} // namespace dom

Просмотреть файл

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaHardwareKeysEvent.h"
#include "MediaControlService.h"
#include "mozilla/Logging.h"
extern mozilla::LazyLogModule gMediaControlLog;
// avoid redefined macro in unified build
#undef LOG
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysEventListener=%p, " msg, this, ##__VA_ARGS__))
namespace mozilla {
namespace dom {
static const char* ToMediaControlKeysEventStr(MediaControlKeysEvent aKeyEvent) {
switch (aKeyEvent) {
case MediaControlKeysEvent::ePlayPause:
return "PlayPause";
case MediaControlKeysEvent::eNext:
return "Next";
case MediaControlKeysEvent::ePrev:
return "Prev";
default:
MOZ_ASSERT_UNREACHABLE("Invalid action.");
}
return "Unknown";
}
#undef LOG_KEY
#define LOG_KEY(msg, key, ...) \
if (MOZ_LOG_TEST(gMediaControlLog, mozilla::LogLevel::Debug)) { \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysEventListener=%p, " msg, this, \
ToMediaControlKeysEventStr(key), ##__VA_ARGS__)); \
}
void MediaHardwareKeysEventListener::OnKeyPressed(
MediaControlKeysEvent aKeyEvent) {
LOG_KEY("OnKeyPressed '%s'", aKeyEvent);
switch (aKeyEvent) {
case MediaControlKeysEvent::ePlayPause:
// TODO : implement playing/pausing controller in following patch.
return;
case MediaControlKeysEvent::eNext:
case MediaControlKeysEvent::ePrev:
// TODO : implement related controller functions.
return;
default:
LOG("Error : undefined event!");
return;
}
}
void MediaHardwareKeysEventSource::AddListener(
MediaHardwareKeysEventListener* aListener) {
MOZ_ASSERT(aListener);
LOG("Add listener %p", aListener);
mListeners.AppendElement(aListener);
}
void MediaHardwareKeysEventSource::RemoveListener(
MediaHardwareKeysEventListener* aListener) {
MOZ_ASSERT(aListener);
LOG("Remove listener %p", aListener);
mListeners.RemoveElement(aListener);
}
size_t MediaHardwareKeysEventSource::GetListenersNum() const {
return mListeners.Length();
}
void MediaHardwareKeysEventSource::Close() { mListeners.Clear(); }
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,57 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_mediahardwarekeysevent_h__
#define mozilla_dom_mediahardwarekeysevent_h__
#include "nsISupportsImpl.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
enum class MediaControlKeysEvent { ePlayPause, ePrev, eNext, eNone };
/**
* MediaHardwareKeysEventListener is used to monitor MediaControlKeysEvent, we
* can add it onto the MediaHardwareKeysEventSource, and then everytime when
* the media key events occur, `OnKeyPressed` will be called so that we can do
* related handling.
*/
class MediaHardwareKeysEventListener {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaHardwareKeysEventListener);
MediaHardwareKeysEventListener() = default;
virtual void OnKeyPressed(MediaControlKeysEvent aKeyEvent);
protected:
virtual ~MediaHardwareKeysEventListener() = default;
};
/**
* MediaHardwareKeysEventSource is a base class which is used to implement
* intercepting media hardware keys event per plaftform. When receiving media
* key events, it would notify all listeners which have been added onto the
* source.
*/
class MediaHardwareKeysEventSource {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaHardwareKeysEventSource);
MediaHardwareKeysEventSource() = default;
virtual void AddListener(MediaHardwareKeysEventListener* aListener);
virtual void RemoveListener(MediaHardwareKeysEventListener* aListener);
size_t GetListenersNum() const;
void Close();
protected:
virtual ~MediaHardwareKeysEventSource() = default;
nsTArray<RefPtr<MediaHardwareKeysEventListener>> mListeners;
};
} // namespace dom
} // namespace mozilla
#endif

Просмотреть файл

@ -0,0 +1,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaHardwareKeysManager.h"
#include "mozilla/Assertions.h"
#include "mozilla/Logging.h"
extern mozilla::LazyLogModule gMediaControlLog;
#undef LOG
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysManager=%p, " msg, this, ##__VA_ARGS__))
namespace mozilla {
namespace dom {
MediaHardwareKeysManager::MediaHardwareKeysManager() {
StartMonitoringHardwareKeys();
}
MediaHardwareKeysManager::~MediaHardwareKeysManager() {
StopMonitoringHardwareKeys();
}
void MediaHardwareKeysManager::StartMonitoringHardwareKeys() {
LOG("StartMonitoringHardwareKeys");
CreateEventSource();
if (mEventSource) {
mEventSource->AddListener(new MediaHardwareKeysEventListener());
}
}
void MediaHardwareKeysManager::CreateEventSource() {
// TODO : create source per platform.
}
void MediaHardwareKeysManager::StopMonitoringHardwareKeys() {
LOG("StopMonitoringHardwareKeys");
if (mEventSource) {
mEventSource->Close();
mEventSource = nullptr;
}
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_mediahardwarekeysobservice_h__
#define mozilla_dom_mediahardwarekeysobservice_h__
#include "MediaHardwareKeysEvent.h"
namespace mozilla {
namespace dom {
/**
* MediaHardwareKeysManager is used to create a source to intercept platform
* level media keys event and assign a proper event listener to handle those
* events.
*/
class MediaHardwareKeysManager final {
public:
MediaHardwareKeysManager();
~MediaHardwareKeysManager();
void StartMonitoringHardwareKeys();
void StopMonitoringHardwareKeys();
private:
void CreateEventSource();
RefPtr<MediaHardwareKeysEventSource> mEventSource;
};
} // namespace dom
} // namespace mozilla
#endif

Просмотреть файл

@ -8,6 +8,8 @@ EXPORTS.mozilla.dom += [
'MediaController.h',
'MediaControlService.h',
'MediaControlUtils.h',
'MediaHardwareKeysEvent.h',
'MediaHardwareKeysManager.h',
]
EXPORTS.ipc += [
@ -18,6 +20,8 @@ UNIFIED_SOURCES += [
'AudioFocusManager.cpp',
'MediaController.cpp',
'MediaControlService.cpp',
'MediaHardwareKeysEvent.cpp',
'MediaHardwareKeysManager.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')