1/* 2 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "RemoteCommandListenerIOS.h" 28 29#if PLATFORM(IOS) 30 31#import <MediaPlayer/MPRemoteCommandCenter.h> 32#import <MediaPlayer/MPRemoteCommandEvent.h> 33#import <MediaPlayer/MPRemoteCommand.h> 34#import <WebCore/SoftLinking.h> 35 36SOFT_LINK_FRAMEWORK(MediaPlayer) 37SOFT_LINK_CLASS(MediaPlayer, MPRemoteCommandCenter) 38SOFT_LINK_CLASS(MediaPlayer, MPSeekCommandEvent) 39 40namespace WebCore { 41 42std::unique_ptr<RemoteCommandListener> RemoteCommandListener::create(RemoteCommandListenerClient& client) 43{ 44 return std::make_unique<RemoteCommandListenerIOS>(client); 45} 46 47RemoteCommandListenerIOS::RemoteCommandListenerIOS(RemoteCommandListenerClient& client) 48 : RemoteCommandListener(client) 49 , m_weakPtrFactory(this) 50{ 51 MPRemoteCommandCenter *center = [getMPRemoteCommandCenterClass() sharedCommandCenter]; 52 auto weakThis = createWeakPtr(); 53 54 m_pauseTarget = [[center pauseCommand] addTargetWithHandler:^(MPRemoteCommandEvent *) { 55 callOnMainThread([weakThis] { 56 if (!weakThis) 57 return; 58 weakThis->m_client.didReceiveRemoteControlCommand(MediaSession::PauseCommand); 59 }); 60 61 return MPRemoteCommandHandlerStatusSuccess; 62 }]; 63 64 m_playTarget = [[center playCommand] addTargetWithHandler:^(MPRemoteCommandEvent *) { 65 callOnMainThread([weakThis] { 66 if (!weakThis) 67 return; 68 weakThis->m_client.didReceiveRemoteControlCommand(MediaSession::PlayCommand); 69 }); 70 71 return MPRemoteCommandHandlerStatusSuccess; 72 }]; 73 74 m_togglePlayPauseTarget = [[center togglePlayPauseCommand] addTargetWithHandler:^(MPRemoteCommandEvent *) { 75 callOnMainThread([weakThis] { 76 if (!weakThis) 77 return; 78 weakThis->m_client.didReceiveRemoteControlCommand(MediaSession::TogglePlayPauseCommand); 79 }); 80 81 return MPRemoteCommandHandlerStatusSuccess; 82 }]; 83 84 m_seekBackwardTarget = [[center seekBackwardCommand] addTargetWithHandler:^(MPRemoteCommandEvent *event) { 85 ASSERT([event isKindOfClass:getMPSeekCommandEventClass()]); 86 87 MPSeekCommandEvent* seekEvent = static_cast<MPSeekCommandEvent *>(event); 88 MediaSession::RemoteControlCommandType command = [seekEvent type] == MPSeekCommandEventTypeBeginSeeking ? MediaSession::BeginSeekingBackwardCommand : MediaSession::EndSeekingBackwardCommand; 89 90 callOnMainThread([weakThis, command] { 91 if (!weakThis) 92 return; 93 weakThis->m_client.didReceiveRemoteControlCommand(command); 94 }); 95 96 return MPRemoteCommandHandlerStatusSuccess; 97 }]; 98 99 m_seekForwardTarget = [[center seekForwardCommand] addTargetWithHandler:^(MPRemoteCommandEvent *event) { 100 ASSERT([event isKindOfClass:getMPSeekCommandEventClass()]); 101 MPSeekCommandEvent* seekEvent = static_cast<MPSeekCommandEvent *>(event); 102 103 MediaSession::RemoteControlCommandType command = [seekEvent type] == MPSeekCommandEventTypeBeginSeeking ? MediaSession::BeginSeekingForwardCommand : MediaSession::EndSeekingForwardCommand; 104 105 callOnMainThread([weakThis, command] { 106 if (!weakThis) 107 return; 108 weakThis->m_client.didReceiveRemoteControlCommand(command); 109 }); 110 111 return MPRemoteCommandHandlerStatusSuccess; 112 }]; 113} 114 115RemoteCommandListenerIOS::~RemoteCommandListenerIOS() 116{ 117 MPRemoteCommandCenter *center = [getMPRemoteCommandCenterClass() sharedCommandCenter]; 118 [[center pauseCommand] removeTarget:m_pauseTarget.get()]; 119 [[center playCommand] removeTarget:m_playTarget.get()]; 120 [[center togglePlayPauseCommand] removeTarget:m_togglePlayPauseTarget.get()]; 121 [[center seekForwardCommand] removeTarget:m_seekForwardTarget.get()]; 122 [[center seekBackwardCommand] removeTarget:m_seekBackwardTarget.get()]; 123} 124 125} 126 127#endif 128