Bug 1671626 - part1 : remove MediaPlayerWrapper. r=spohl

As now the lowest version SDK we use for developing would be 10.12, so we don't need to this wrapper anymore and can import `MediaPlayer` directly.

Differential Revision: https://phabricator.services.mozilla.com/D97223
This commit is contained in:
Alastor Wu 2020-12-21 18:10:30 +00:00
parent fd531e4c1a
commit 0bcbe2eae9
6 changed files with 72 additions and 285 deletions

View File

@ -1,154 +1,129 @@
/* 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/. */
#import "MediaPlayerWrapper.h"
#import <MediaPlayer/MediaPlayer.h>
#include "MediaHardwareKeysEventSourceMacMediaCenter.h"
#include "MediaKeyListenerTest.h"
#include "nsCocoaFeatures.h"
extern _Nullable Class mpNowPlayingInfoCenterClass;
extern _Nullable Class mpRemoteCommandCenterClass;
extern _Nullable Class mpRemoteCommandClass;
using namespace mozilla::dom;
NS_ASSUME_NONNULL_BEGIN
TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestMediaCenterPlayPauseEvent)
{
if (nsCocoaFeatures::IsAtLeastVersion(10, 12, 2)) {
ASSERT_TRUE(MediaPlayerWrapperInit());
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
ASSERT_TRUE(source->GetListenersNum() == 0);
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
source->AddListener(listener.get());
source->AddListener(listener.get());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
MediaCenterEventHandler playPauseHandler = source->CreatePlayPauseHandler();
playPauseHandler(nil);
MediaCenterEventHandler playPauseHandler = source->CreatePlayPauseHandler();
playPauseHandler(nil);
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePaused);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Playpause));
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePaused);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Playpause));
listener->Clear(); // Reset stored media key
listener->Clear(); // Reset stored media key
playPauseHandler(nil);
playPauseHandler(nil);
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Playpause));
MediaPlayerWrapperClose();
}
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Playpause));
}
TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestMediaCenterPlayEvent)
{
if (nsCocoaFeatures::IsAtLeastVersion(10, 12, 2)) {
ASSERT_TRUE(MediaPlayerWrapperInit());
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
ASSERT_TRUE(source->GetListenersNum() == 0);
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
source->AddListener(listener.get());
source->AddListener(listener.get());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
MediaCenterEventHandler playHandler = source->CreatePlayHandler();
MediaCenterEventHandler playHandler = source->CreatePlayHandler();
center.playbackState = MPNowPlayingPlaybackStatePaused;
center.playbackState = MPNowPlayingPlaybackStatePaused;
playHandler(nil);
playHandler(nil);
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Play));
MediaPlayerWrapperClose();
}
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Play));
}
TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestMediaCenterPauseEvent)
{
if (nsCocoaFeatures::IsAtLeastVersion(10, 12, 2)) {
ASSERT_TRUE(MediaPlayerWrapperInit());
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
ASSERT_TRUE(source->GetListenersNum() == 0);
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
source->AddListener(listener.get());
source->AddListener(listener.get());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
ASSERT_TRUE(source->GetListenersNum() == 1);
ASSERT_TRUE(!listener->IsReceivedResult());
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePlaying);
MediaCenterEventHandler pauseHandler = source->CreatePauseHandler();
MediaCenterEventHandler pauseHandler = source->CreatePauseHandler();
pauseHandler(nil);
pauseHandler(nil);
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePaused);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Pause));
MediaPlayerWrapperClose();
}
ASSERT_TRUE(center.playbackState == MPNowPlayingPlaybackStatePaused);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Pause));
}
TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestMediaCenterPrevNextEvent)
{
if (nsCocoaFeatures::IsAtLeastVersion(10, 12, 2)) {
ASSERT_TRUE(MediaPlayerWrapperInit());
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
RefPtr<MediaHardwareKeysEventSourceMacMediaCenter> source =
new MediaHardwareKeysEventSourceMacMediaCenter();
ASSERT_TRUE(source->GetListenersNum() == 0);
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
source->AddListener(listener.get());
source->AddListener(listener.get());
ASSERT_TRUE(source->Open());
ASSERT_TRUE(source->Open());
MediaCenterEventHandler nextHandler = source->CreateNextTrackHandler();
MediaCenterEventHandler nextHandler = source->CreateNextTrackHandler();
nextHandler(nil);
nextHandler(nil);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Nexttrack));
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Nexttrack));
MediaCenterEventHandler previousHandler = source->CreatePreviousTrackHandler();
MediaCenterEventHandler previousHandler = source->CreatePreviousTrackHandler();
previousHandler(nil);
previousHandler(nil);
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Previoustrack));
MediaPlayerWrapperClose();
}
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Previoustrack));
}
NS_ASSUME_NONNULL_END

View File

@ -295,6 +295,7 @@ if CONFIG["OS_ARCH"] == "Darwin":
OS_LIBS += [
# Link to Metal as required by the Metal gfx-hal backend
"-weak_framework Metal",
"-weak_framework MediaPlayer",
]

View File

@ -2,7 +2,8 @@
* 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/. */
#import "MediaPlayerWrapper.h"
#import <MediaPlayer/MediaPlayer.h>
#include "MediaHardwareKeysEventSourceMacMediaCenter.h"
#include "mozilla/dom/MediaControlUtils.h"
@ -15,19 +16,12 @@ using namespace mozilla::dom;
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysEventSourceMacMediaCenter=%p, " msg, this, ##__VA_ARGS__))
extern _Nullable Class mpNowPlayingInfoCenterClass;
extern _Nullable Class mpRemoteCommandCenterClass;
extern _Nullable Class mpRemoteCommandClass;
namespace mozilla {
namespace widget {
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayPauseHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = center.playbackState == MPNowPlayingPlaybackStatePlaying
? MPNowPlayingPlaybackStatePaused
: MPNowPlayingPlaybackStatePlaying;
@ -52,8 +46,7 @@ MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePrevio
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
if (center.playbackState != MPNowPlayingPlaybackStatePlaying) {
center.playbackState = MPNowPlayingPlaybackStatePlaying;
}
@ -64,8 +57,7 @@ MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayHa
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePauseHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
if (center.playbackState != MPNowPlayingPlaybackStatePaused) {
center.playbackState = MPNowPlayingPlaybackStatePaused;
}
@ -75,9 +67,6 @@ MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePauseH
}
MediaHardwareKeysEventSourceMacMediaCenter::MediaHardwareKeysEventSourceMacMediaCenter() {
if (!MediaPlayerWrapperInit()) {
LOG("Failed to initalize MediaHardwareKeysEventSourceMacMediaCenter");
}
mPlayPauseHandler = CreatePlayPauseHandler();
mNextTrackHandler = CreateNextTrackHandler();
mPreviousTrackHandler = CreatePreviousTrackHandler();
@ -89,16 +78,14 @@ MediaHardwareKeysEventSourceMacMediaCenter::MediaHardwareKeysEventSourceMacMedia
MediaHardwareKeysEventSourceMacMediaCenter::~MediaHardwareKeysEventSourceMacMediaCenter() {
LOG("Destroy MediaHardwareKeysEventSourceMacMediaCenter");
EndListeningForEvents();
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = MPNowPlayingPlaybackStateStopped;
}
void MediaHardwareKeysEventSourceMacMediaCenter::BeginListeningForEvents() {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = MPNowPlayingPlaybackStatePlaying;
MPRemoteCommandCenter* commandCenter = [mpRemoteCommandCenterClass sharedCommandCenter];
MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
commandCenter.togglePlayPauseCommand.enabled = true;
[commandCenter.togglePlayPauseCommand addTargetWithHandler:mPlayPauseHandler];
commandCenter.nextTrackCommand.enabled = true;
@ -112,10 +99,9 @@ void MediaHardwareKeysEventSourceMacMediaCenter::BeginListeningForEvents() {
}
void MediaHardwareKeysEventSourceMacMediaCenter::EndListeningForEvents() {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = MPNowPlayingPlaybackStatePaused;
MPRemoteCommandCenter* commandCenter = [mpRemoteCommandCenterClass sharedCommandCenter];
MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
commandCenter.togglePlayPauseCommand.enabled = false;
[commandCenter.togglePlayPauseCommand removeTarget:nil];
commandCenter.nextTrackCommand.enabled = false;
@ -153,8 +139,7 @@ void MediaHardwareKeysEventSourceMacMediaCenter::HandleEvent(MediaControlKey aEv
void MediaHardwareKeysEventSourceMacMediaCenter::SetPlaybackState(
MediaSessionPlaybackState aState) {
MPNowPlayingInfoCenter* center =
(MPNowPlayingInfoCenter*)[mpNowPlayingInfoCenterClass defaultCenter];
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
if (aState == MediaSessionPlaybackState::Playing) {
center.playbackState = MPNowPlayingPlaybackStatePlaying;
} else if (aState == MediaSessionPlaybackState::Paused) {

View File

@ -1,124 +0,0 @@
/* 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 WIDGET_COCOA_MEDIAPLAYERWRAPPER_H_
#define WIDGET_COCOA_MEDIAPLAYERWRAPPER_H_
#import <Foundation/Foundation.h>
#include <dlfcn.h>
#import <Cocoa/Cocoa.h>
bool MediaPlayerWrapperInit();
void MediaPlayerWrapperClose();
typedef NS_ENUM(NSUInteger, MPNowPlayingPlaybackState) {
MPNowPlayingPlaybackStateUnknown = 0,
MPNowPlayingPlaybackStatePlaying,
MPNowPlayingPlaybackStatePaused,
MPNowPlayingPlaybackStateStopped,
MPNowPlayingPlaybackStateInterrupted
};
typedef NS_ENUM(NSInteger, MPRemoteCommandHandlerStatus) {
/// There was no error executing the requested command.
MPRemoteCommandHandlerStatusSuccess = 0,
/// The command could not be executed because the requested content does not
/// exist in the current application state.
MPRemoteCommandHandlerStatusNoSuchContent = 100,
/// The command could not be executed because there is no now playing item
/// available that is required for this command. As an example, an
/// application would return this error code if an "enable language option"
/// command is received, but nothing is currently playing.
MPRemoteCommandHandlerStatusNoActionableNowPlayingItem = 110,
/// The command could not be executed because a device required
/// is not available. For instance, if headphones are required, or if a watch
/// app realizes that it needs the companion to fulfull a request.
MPRemoteCommandHandlerStatusDeviceNotFound = 120,
/// The command could not be executed for another reason.
MPRemoteCommandHandlerStatusCommandFailed = 200
};
NS_ASSUME_NONNULL_BEGIN
@interface MPNowPlayingInfoCenter : NSObject
/// Returns the default now playing info center.
/// The default center holds now playing info about the current application.
+ (MPNowPlayingInfoCenter*)defaultCenter;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
/// The current now playing info for the center.
/// Setting the info to nil will clear it.
@property(nonatomic, copy, nullable) NSDictionary<NSString*, id>* nowPlayingInfo;
/// The current playback state of the app.
/// This only applies on macOS, where playback state cannot be determined by
/// the application's audio session. This property must be set every time
/// the app begins or halts playback, otherwise remote control functionality may
/// not work as expected.
@property(nonatomic) MPNowPlayingPlaybackState playbackState;
@end
@class MPRemoteCommand;
@interface MPRemoteCommandEvent : NSObject
/// The command that sent the event.
@property(nonatomic, readonly) MPRemoteCommand* command;
/// The time when the event occurred.
@property(nonatomic, readonly) NSTimeInterval timestamp;
@end
@interface MPRemoteCommand : NSObject
/// Whether a button (for example) should be enabled and tappable for this
/// particular command.
@property(nonatomic, assign, getter=isEnabled) BOOL enabled;
// Target-action style for adding handlers to commands.
// Actions receive an MPRemoteCommandEvent as the first parameter.
// Targets are not retained by addTarget:action:, and should be removed from the
// command when the target is deallocated.
//
// Your selector should return a MPRemoteCommandHandlerStatus value when
// possible. This allows the system to respond appropriately to commands that
// may not have been able to be executed in accordance with the application's
// current state.
- (void)addTarget:(id)target action:(SEL)action;
- (void)removeTarget:(id)target action:(nullable SEL)action;
- (void)removeTarget:(nullable id)target;
/// Returns an opaque object to act as the target.
- (id)addTargetWithHandler:(MPRemoteCommandHandlerStatus (^)(MPRemoteCommandEvent* event))handler;
@end
@interface MPRemoteCommandCenter : NSObject
// Playback Commands
@property(nonatomic, readonly) MPRemoteCommand* pauseCommand;
@property(nonatomic, readonly) MPRemoteCommand* playCommand;
@property(nonatomic, readonly) MPRemoteCommand* stopCommand;
@property(nonatomic, readonly) MPRemoteCommand* togglePlayPauseCommand;
// Previous/Next Track Commands
@property(nonatomic, readonly) MPRemoteCommand* nextTrackCommand;
@property(nonatomic, readonly) MPRemoteCommand* previousTrackCommand;
+ (MPRemoteCommandCenter*)sharedCommandCenter;
@end
NS_ASSUME_NONNULL_END
#endif // WIDGET_COCOA_MEDIAPLAYERWRAPPER_H_

View File

@ -1,48 +0,0 @@
/* 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 "MediaPlayerWrapper.h"
_Nullable Class mpNowPlayingInfoCenterClass;
_Nullable Class mpRemoteCommandCenterClass;
_Nullable Class mpRemoteCommandClass;
void* _Nullable handle;
#define MEDIAPLAYER_FRAMEWORK_PATH "/System/Library/Frameworks/MediaPlayer.framework/MediaPlayer"
bool MediaPlayerWrapperInit() {
if (handle) {
return true;
}
handle = dlopen(MEDIAPLAYER_FRAMEWORK_PATH, RTLD_LAZY | RTLD_LOCAL);
if (!handle) {
return false;
}
mpNowPlayingInfoCenterClass = (Class)dlsym(handle, "OBJC_CLASS_$_MPNowPlayingInfoCenter");
mpRemoteCommandCenterClass = (Class)dlsym(handle, "OBJC_CLASS_$_MPRemoteCommandCenter");
mpRemoteCommandClass = (Class)dlsym(handle, "OBJC_CLASS_$_MPRemoteCommand");
if (!mpNowPlayingInfoCenterClass) {
return false;
}
if (!mpRemoteCommandCenterClass) {
return false;
}
if (!mpRemoteCommandClass) {
return false;
}
return true;
}
void MediaPlayerWrapperClose() {
if (handle) {
dlclose(handle);
mpNowPlayingInfoCenterClass = nil;
mpRemoteCommandCenterClass = nil;
mpRemoteCommandClass = nil;
handle = nullptr;
}
}

View File

@ -22,7 +22,6 @@ EXPORTS += [
"DesktopBackgroundImage.h",
"MediaHardwareKeysEventSourceMac.h",
"MediaHardwareKeysEventSourceMacMediaCenter.h",
"MediaPlayerWrapper.h",
"mozView.h",
"nsBidiKeyboard.h",
"nsChangeObserver.h",
@ -87,7 +86,6 @@ SOURCES += [
"MediaHardwareKeysEventSourceMac.mm",
"MediaHardwareKeysEventSourceMacMediaCenter.mm",
"MediaKeysEventSourceFactory.cpp",
"MediaPlayerWrapper.mm",
"nsChildView.mm",
"nsClipboard.mm",
"nsCocoaDebugUtils.mm",