/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Diagnostics; using Native = Interop.MediaControllerClient; namespace Tizen.Multimedia.Remoting { /// /// Provides a means to to send commands to and handle events from media control server. /// public class MediaController { internal MediaController(MediaControllerManager manager, string serverAppId) { Debug.Assert(manager != null); Debug.Assert(serverAppId != null); Manager = manager; ServerAppId = serverAppId; } private MediaControllerManager Manager { get; } /// /// Gets the application id of the server. /// /// The server application id. public string ServerAppId { get; } /// /// Gets a value indicating whether the sever has been stopped. /// /// true if the server has been stopped; otherwise, false. public bool IsStopped { get; private set; } private void ThrowIfStopped() { if (IsStopped) { throw new InvalidOperationException("The server has already been stopped."); } } /// /// Occurs when the server is stopped. /// public event EventHandler ServerStopped; internal void RaiseStoppedEvent() { IsStopped = true; ServerStopped?.Invoke(this, EventArgs.Empty); } /// /// Occurs when the playback state is updated. /// public event EventHandler PlaybackStateUpdated; private PlaybackStateUpdatedEventArgs CreatePlaybackUpdatedEventArgs(IntPtr playbackHandle) { try { Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state."); Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position."); return new PlaybackStateUpdatedEventArgs(playbackCode.ToState(), (long)position); } catch (Exception e) { Log.Error(GetType().FullName, e.ToString()); } return null; } internal void RaisePlaybackUpdatedEvent(IntPtr playbackHandle) { var eventHandler = PlaybackStateUpdated; if (eventHandler == null) { return; } var args = CreatePlaybackUpdatedEventArgs(playbackHandle); if (args != null) { eventHandler.Invoke(this, args); } } /// /// Occurs when the metadata is updated. /// public event EventHandler MetadataUpdated; private MetadataUpdatedEventArgs CreateMetadataUpdatedEventArgs(IntPtr metadataHandle) { try { return new MetadataUpdatedEventArgs(new MediaControlMetadata(metadataHandle)); } catch (Exception e) { Log.Error(GetType().FullName, e.ToString()); } return null; } internal void RaiseMetadataUpdatedEvent(IntPtr metadataHandle) { var eventHandler = MetadataUpdated; if (eventHandler == null) { return; } var args = CreateMetadataUpdatedEventArgs(metadataHandle); if (args != null) { eventHandler.Invoke(this, args); } } /// /// Occurs when the shuffle mode is updated. /// public event EventHandler ShuffleModeUpdated; internal void RaiseShuffleModeUpdatedEvent(MediaControllerShuffleMode mode) { ShuffleModeUpdated?.Invoke(this, new ShuffleModeUpdatedEventArgs(mode == MediaControllerShuffleMode.On)); } /// /// Occurs when the repeat mode is updated. /// public event EventHandler RepeatModeUpdated; internal void RaiseRepeatModeUpdatedEvent(MediaControlRepeatMode mode) { RepeatModeUpdated?.Invoke(this, new RepeatModeUpdatedEventArgs(mode)); } /// /// Returns the playback state set by the server. /// /// The playback state. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// The has already been disposed of. /// public MediaControlPlaybackState GetPlaybackState() { ThrowIfStopped(); IntPtr playbackHandle = IntPtr.Zero; try { Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback."); Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state."); return playbackCode.ToState(); } finally { if (playbackHandle != IntPtr.Zero) { Native.DestroyPlayback(playbackHandle); } } } /// /// Returns the playback position set by the server. /// /// The playback position in milliseconds. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// The has already been disposed of. /// public long GetPlaybackPosition() { ThrowIfStopped(); IntPtr playbackHandle = IntPtr.Zero; try { Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback."); Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position."); return (long)position; } finally { if (playbackHandle != IntPtr.Zero) { Native.DestroyPlayback(playbackHandle); } } } /// /// Returns the metadata set by the server. /// /// The metadata. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// The has already been disposed of. /// public MediaControlMetadata GetMetadata() { ThrowIfStopped(); IntPtr metadataHandle = IntPtr.Zero; try { Native.GetServerMetadata(Manager.Handle, ServerAppId, out metadataHandle). ThrowIfError("Failed to get metadata."); return new MediaControlMetadata(metadataHandle); } finally { if (metadataHandle != IntPtr.Zero) { Native.DestroyMetadata(metadataHandle); } } } /// /// Returns whether the shuffle mode is enabled. /// /// A value indicating whether the shuffle mode is enabled. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// The has already been disposed of. /// public bool IsShuffleModeEnabled() { ThrowIfStopped(); Native.GetServerShuffleMode(Manager.Handle, ServerAppId, out var shuffleMode). ThrowIfError("Failed to get shuffle mode state."); return shuffleMode == MediaControllerShuffleMode.On; } /// /// Returns the repeat mode. /// /// A set by the server. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// The has already been disposed of. /// public MediaControlRepeatMode GetRepeatMode() { ThrowIfStopped(); Native.GetServerRepeatMode(Manager.Handle, ServerAppId, out var repeatMode). ThrowIfError("Failed to get repeat mode state."); return repeatMode.ToPublic(); } /// /// Sends playback command to the server. /// A playback command. /// /// The server has already been stopped. /// -or-\n /// An internal error occurs. /// /// is not valid. /// The has already been disposed of. /// public void SendPlaybackCommand(MediaControlPlaybackCommand command) { ThrowIfStopped(); ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), command, nameof(command)); Native.SendPlaybackStateCommand(Manager.Handle, ServerAppId, command.ToCode()). ThrowIfError("Failed to send command."); } } }