/*
* 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.");
}
}
}