Name: csapi-multimedia
Summary: Tizen Multimedia API for C#
-Version: 1.1.1
+Version: 1.1.2
Release: 0
Group: Development/Libraries
License: Apache-2.0
Tizen.Multimedia.MediaCodec 1.0.0 \
Tizen.Multimedia.MediaPlayer 1.0.0 \
Tizen.Multimedia.Metadata 1.0.0 \
- Tizen.Multimedia.Radio 1.0.0 \
+ Tizen.Multimedia.Radio 1.0.1 \
Tizen.Multimedia.Recorder 1.0.0 \
Tizen.Multimedia.StreamRecorder 1.0.0 \
Tizen.Multimedia.Remoting 1.0.0 \
+++ /dev/null
-/*
- * 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.IO;
-using System.Runtime.CompilerServices;
-using Tizen;
-
-namespace Tizen.Multimedia
-{
- internal static partial class Interop
- {
- internal enum ErrorCode
- {
- None = Tizen.Internals.Errors.ErrorCode.None,
- OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
- InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
- InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
- PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
- NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
- ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
- NoSuchFile = Tizen.Internals.Errors.ErrorCode.NoSuchFile,
-
- // Radio
- InvalidState = -0x019A0000 | 0x01, // RADIO_ERROR_INVALID_STATE
- SoundPolicy = -0x019A0000 | 0x02, // RADIO_ERROR_SOUND_POLICY
- NoAntenna = -0x019A0000 | 0x03, // RADIO_ERROR_NO_ANTENNA
-
- // Image/ Video Utility
- NotSupportedFormat = -0x01980000 | 0x01, // VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT
- }
- }
-
- internal static class ErrorCodeExtensions
- {
- private const string LogTag = "Tizen.Multimedia";
-
- internal static bool IsSuccess(this Interop.ErrorCode err)
- {
- return err == Interop.ErrorCode.None;
- }
-
- internal static bool IsFailed(this Interop.ErrorCode err)
- {
- return !err.IsSuccess();
- }
-
- /// <summary>
- /// Utility method to check for error, returns false if failed and print warning messages
- /// </summary>
- /// <returns>true in case of no error, false otherwise</returns>
- internal static bool WarnIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
- {
- if (err.IsFailed())
- {
- Log.Debug(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
- return false;
- }
- return true;
- }
-
- /// <summary>
- /// Utility method to check for error, returns false if failed and throw exception
- /// </summary>
- /// <returns>true in case of no error</returns>
- internal static bool ThrowIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
- {
- if (err.IsFailed())
- {
- Log.Error(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
- throw err.GetException(msg);
- }
- return true;
- }
-
- internal static Exception GetException(this Interop.ErrorCode err, string message)
- {
- string errMessage = $"{message}, err: {err.ToString()}";
- switch (err)
- {
- //case ErrorCode.None:
- case Interop.ErrorCode.PermissionDenied: return new UnauthorizedAccessException(errMessage);
- case Interop.ErrorCode.InvalidParameter: return new ArgumentException(errMessage);
- case Interop.ErrorCode.NoSuchFile: return new FileNotFoundException(errMessage);
- case Interop.ErrorCode.OutOfMemory: return new OutOfMemoryException(errMessage);
- case Interop.ErrorCode.NoAntenna:
- case Interop.ErrorCode.NotSupported: return new NotSupportedException(errMessage);
- case Interop.ErrorCode.InvalidOperation:
- case Interop.ErrorCode.InvalidState:
- case Interop.ErrorCode.SoundPolicy:
- case Interop.ErrorCode.ResourceBusy:
- default: return new InvalidOperationException(errMessage);
- }
- }
- }
-}
\ No newline at end of file
{
internal static partial class Interop
{
- internal enum RadioState
- {
- Ready, // RADIO_STATE_READY
- Playing, // RADIO_STATE_PLAYING
- Scanning, // RADIO_STATE_SCANNING
- }
-
- internal enum RadioInterruptedReason
- {
- Completed, // RADIO_INTERRUPTED_COMPLETED
- Media, // RADIO_INTERRUPTED_BY_MEDIA
- Call, // RADIO_INTERRUPTED_BY_CALL
- EarjackUnplug, // RADIO_INTERRUPTED_BY_EARJACK_UNPLUG
- ResourceConflict, // RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT
- Alarm, // RADIO_INTERRUPTED_BY_ALARM
- Emergency, // RADIO_INTERRUPTED_BY_EMERGENCY
- ResumableMedia, // RADIO_INTERRUPTED_BY_RESUMABLE_MEDIA
- Notification, // RADIO_INTERRUPTED_BY_NOTIFICATION
- }
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_state")]
- internal static extern ErrorCode GetState(this RadioHandle /* radio_h */ radio, out RadioState /* radio_state_e */ state);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_start")]
- internal static extern ErrorCode Start(this RadioHandle /* radio_h */ radio);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_stop")]
- internal static extern ErrorCode Stop(this RadioHandle /* radio_h */ radio);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_seek_up")]
- internal static extern ErrorCode SeekUp(this RadioHandle /* radio_h */ radio, RadioHandle.SeekCompletedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_seek_down")]
- internal static extern ErrorCode SeekDown(this RadioHandle /* radio_h */ radio, RadioHandle.SeekCompletedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_set_frequency")]
- internal static extern ErrorCode SetFrequency(this RadioHandle /* radio_h */ radio, int frequency);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency")]
- internal static extern ErrorCode GetFrequency(this RadioHandle /* radio_h */ radio, out int frequency);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_signal_strength")]
- internal static extern ErrorCode GetSignalStrength(this RadioHandle /* radio_h */ radio, out int strength);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_scan_start")]
- internal static extern ErrorCode ScanStart(this RadioHandle /* radio_h */ radio, RadioHandle.ScanUpdatedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_scan_stop")]
- internal static extern ErrorCode ScanStop(this RadioHandle /* radio_h */ radio, RadioHandle.ScanStoppedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_set_mute")]
- internal static extern ErrorCode SetMute(this RadioHandle /* radio_h */ radio, bool muted);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_is_muted")]
- internal static extern ErrorCode GetMuted(this RadioHandle /* radio_h */ radio, out bool muted);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_set_scan_completed_cb")]
- internal static extern ErrorCode SetScanCompletedCb(this RadioHandle /* radio_h */ radio, RadioHandle.ScanCompletedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_unset_scan_completed_cb")]
- internal static extern ErrorCode UnsetScanCompletedCb(this RadioHandle /* radio_h */ radio);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_set_interrupted_cb")]
- internal static extern ErrorCode SetInterruptedCb(this RadioHandle /* radio_h */ radio, RadioHandle.InterruptedCallback callback, IntPtr /* void */ userData);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_unset_interrupted_cb")]
- internal static extern ErrorCode UnsetInterruptedCb(this RadioHandle /* radio_h */ radio);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency_range")]
- internal static extern ErrorCode GetFrequencyRange(this RadioHandle /* radio_h */ radio, out int minFreq, out int maxFreq);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_channel_spacing")]
- internal static extern ErrorCode GetChannelSpacing(this RadioHandle /* radio_h */ radio, out int channelSpacing);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_set_volume")]
- internal static extern ErrorCode SetVolume(this RadioHandle /* radio_h */ radio, float volume);
-
- [DllImport(Libraries.Radio, EntryPoint = "radio_get_volume")]
- internal static extern ErrorCode GetVolume(this RadioHandle /* radio_h */ radio, out float volume);
-
- internal struct RadioFrequencyRange
- {
- public int minFreq;
- public int maxFreq;
- }
-
- internal class RadioHandle : SafeMultimediaHandle
+ internal static class Radio
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate void SeekCompletedCallback(int frequency, IntPtr /* void */ userData);
+ internal delegate void SeekCompletedCallback(int frequency, IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate void ScanUpdatedCallback(int frequency, IntPtr /* void */ userData);
+ internal delegate void ScanUpdatedCallback(int frequency, IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate void ScanStoppedCallback(IntPtr /* void */ userData);
+ internal delegate void ScanStoppedCallback(IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate void ScanCompletedCallback(IntPtr /* void */ userData);
+ internal delegate void ScanCompletedCallback(IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate void InterruptedCallback(RadioInterruptedReason /* radio_interrupted_code_e */ code, IntPtr /* void */ userData);
+ internal delegate void InterruptedCallback(RadioInterruptedReason reason, IntPtr userData);
+
[DllImport(Libraries.Radio, EntryPoint = "radio_create")]
- internal static extern ErrorCode Create(out IntPtr /* radio_h */ radio);
+ internal static extern RadioError Create(out RadioHandle radio);
[DllImport(Libraries.Radio, EntryPoint = "radio_destroy")]
- internal static extern ErrorCode Destroy(IntPtr /* radio_h */ radio);
+ internal static extern RadioError Destroy(IntPtr radio);
- internal RadioHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease)
- {
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_state")]
+ internal static extern RadioError GetState(RadioHandle radio, out RadioState state);
- internal RadioHandle() : this(CreateNativeHandle(), true)
- {
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_start")]
+ internal static extern RadioError Start(RadioHandle radio);
- internal static IntPtr CreateNativeHandle()
- {
- IntPtr handle;
- Create(out handle).ThrowIfFailed("Failed to create native handle");
- return handle;
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_stop")]
+ internal static extern RadioError Stop(RadioHandle radio);
- internal override ErrorCode DisposeNativeHandle()
- {
- return Destroy(handle);
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_seek_up")]
+ internal static extern RadioError SeekUp(RadioHandle radio, SeekCompletedCallback callback,
+ IntPtr userData = default(IntPtr));
- internal RadioState State
- {
- get { return NativeGet<RadioState>(this.GetState); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_seek_down")]
+ internal static extern RadioError SeekDown(RadioHandle radio, SeekCompletedCallback callback,
+ IntPtr userData = default(IntPtr));
- internal int Frequency
- {
- get { return NativeGet<int>(this.GetFrequency); }
- set { NativeSet(this.SetFrequency, value); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_frequency")]
+ internal static extern RadioError SetFrequency(RadioHandle radio, int frequency);
- internal int SignalStrength
- {
- get { return NativeGet<int>(this.GetSignalStrength); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency")]
+ internal static extern RadioError GetFrequency(RadioHandle radio, out int frequency);
- internal bool IsMuted
- {
- get { return NativeGet<bool>(this.GetMuted); }
- set { NativeSet(this.SetMute, value); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_signal_strength")]
+ internal static extern RadioError GetSignalStrength(RadioHandle radio, out int strength);
- internal int ChannelSpacing
- {
- get { return NativeGet<int>(this.GetChannelSpacing); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_scan_start")]
+ internal static extern RadioError ScanStart(RadioHandle radio, ScanUpdatedCallback callback,
+ IntPtr userData = default(IntPtr));
- internal float Volume
- {
- get { return NativeGet<float>(this.GetVolume); }
- set { NativeSet(this.SetVolume, value); }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_scan_stop")]
+ internal static extern RadioError ScanStop(RadioHandle radio, ScanStoppedCallback callback,
+ IntPtr userData = default(IntPtr));
- internal int MinimumFrequency
- {
- get
- {
- RadioFrequencyRange range;
- this.GetFrequencyRange(out range.minFreq, out range.maxFreq);
- return range.minFreq;
- }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_mute")]
+ internal static extern RadioError SetMute(RadioHandle radio, bool muted);
- internal int MaximumFrequency
- {
- get
- {
- RadioFrequencyRange range;
- this.GetFrequencyRange(out range.minFreq, out range.maxFreq);
- return range.maxFreq;
- }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_is_muted")]
+ internal static extern RadioError GetMuted(RadioHandle radio, out bool muted);
- internal ScanCompletedCallback ScanCompleteCb
- {
- set
- {
- var err = (value != null) ? this.SetScanCompletedCb(value, IntPtr.Zero) : this.UnsetScanCompletedCb();
- err.ThrowIfFailed("Failed to set/ unset scan complete callback");
- }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_scan_completed_cb")]
+ internal static extern RadioError SetScanCompletedCb(RadioHandle radio,
+ ScanCompletedCallback callback, IntPtr userData = default(IntPtr));
- internal InterruptedCallback InteruptedCb
- {
- set
- {
- var err = (value != null) ? this.SetInterruptedCb(value, IntPtr.Zero) : this.UnsetInterruptedCb();
- err.ThrowIfFailed("Failed to set/ unset interrupted callback");
- }
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_unset_scan_completed_cb")]
+ internal static extern RadioError UnsetScanCompletedCb(RadioHandle radio);
- internal void StartPlayback()
- {
- this.Start().ThrowIfFailed("Failed to start radio");
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_interrupted_cb")]
+ internal static extern RadioError SetInterruptedCb(RadioHandle radio,
+ InterruptedCallback callback, IntPtr userData = default(IntPtr));
- internal void StopPlayback()
- {
- this.Stop().ThrowIfFailed("Failed to stop radio");
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_unset_interrupted_cb")]
+ internal static extern RadioError UnsetInterruptedCb(RadioHandle radio);
- internal void StartScan(ScanUpdatedCallback callback)
- {
- this.ScanStart(callback, IntPtr.Zero).ThrowIfFailed("Failed to start radio");
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_frequency_range")]
+ internal static extern RadioError GetFrequencyRange(RadioHandle radio, out int minFreq, out int maxFreq);
- internal void StopScan(ScanStoppedCallback callback)
- {
- this.ScanStop(callback, IntPtr.Zero).ThrowIfFailed("Failed to stop radio");
- }
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_channel_spacing")]
+ internal static extern RadioError GetChannelSpacing(RadioHandle radio, out int channelSpacing);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_set_volume")]
+ internal static extern RadioError SetVolume(RadioHandle radio, float volume);
+
+ [DllImport(Libraries.Radio, EntryPoint = "radio_get_volume")]
+ internal static extern RadioError GetVolume(RadioHandle radio, out float volume);
+ }
- internal void SeekUp(SeekCompletedCallback callback)
+ internal class RadioHandle : SafeHandle
+ {
+ protected RadioHandle() : base(IntPtr.Zero, true)
{
- this.SeekUp(callback, IntPtr.Zero).ThrowIfFailed("Failed to start radio");
}
- internal void SeekDown(SeekCompletedCallback callback)
+ public override bool IsInvalid => handle == IntPtr.Zero;
+
+ protected override bool ReleaseHandle()
{
- this.SeekDown(callback, IntPtr.Zero).ThrowIfFailed("Failed to stop radio");
+ var ret = Radio.Destroy(handle);
+ if (ret != RadioError.None)
+ {
+ Log.Debug(GetType().FullName, $"Failed to release native handle.");
+ return false;
+ }
+
+ return true;
}
}
}
+++ /dev/null
-/*
- * 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 System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace Tizen.Multimedia
-{
- internal static partial class Interop
- {
- internal static Task<T> PinnedTask<T>(TaskCompletionSource<T> tcs)
- {
- var gch = GCHandle.Alloc(tcs);
- return tcs.Task.ContinueWith(
- t => { gch.Free(); return t; },
- TaskContinuationOptions.ExecuteSynchronously).Unwrap();
- }
-
- internal abstract class SafeMultimediaHandle : SafeHandle
- {
- internal delegate ErrorCode GetterMethod<TProp>(out TProp value);
- internal delegate ErrorCode SetterMethod<TProp>(TProp value);
-
- protected SafeMultimediaHandle(IntPtr handle, bool needToRelease) : base(handle, true)
- {
- Debug.Assert(handle != IntPtr.Zero);
- HasOwnership = needToRelease;
- }
-
- internal bool HasOwnership { get; set; }
- public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
-
- internal abstract ErrorCode DisposeNativeHandle();
-
- internal TProp NativeGet<TProp>(GetterMethod<TProp> getter, [CallerMemberName] string propertyName = "")
- {
- TProp value; getter(out value).ThrowIfFailed($"Failed to get {propertyName}");
- return value;
- }
-
- internal string NativeGet(GetterMethod<string> getter, [CallerMemberName] string propertyName = "")
- {
- string value; getter(out value).ThrowIfFailed($"Failed to get {propertyName}");
- return value;
- }
-
- internal void NativeSet<TProp>(SetterMethod<TProp> setter, TProp value, [CallerMemberName] string propertyName = "")
- {
- setter(value).ThrowIfFailed($"Failed to set {propertyName}");
- }
-
- protected override bool ReleaseHandle()
- {
- var err = ErrorCode.None;
- if (HasOwnership)
- {
- err = DisposeNativeHandle();
- err.WarnIfFailed($"Failed to delete native {GetType()} handle");
- }
-
- SetHandle(IntPtr.Zero);
- return err.IsSuccess();
- }
- }
- }
-}
\ No newline at end of file
*/
using System;
-using System.Runtime.CompilerServices;
+using System.Linq;
using System.Threading.Tasks;
using Tizen.System;
+using static Tizen.Multimedia.Interop.Radio;
namespace Tizen.Multimedia
{
/// <summary>
- /// Radio class, provides support for using the Radio feature
+ /// Provides means for using the radio feature.
/// </summary>
public class Radio : IDisposable
{
- internal Interop.RadioHandle _handle;
+ private Interop.RadioHandle _handle;
private const string FeatureFmRadio = "http://tizen.org/feature/fmradio";
/// <summary>
- /// Radio constructor
+ /// Initialize a new instance of the Radio class.
/// </summary>
- /// <Feature> http://tizen.org/feature/fmradio </Feature>
- /// <exception cref="OutOfMemoryException"></exception>
- /// <exception cref="NotSupportedException">This is thrown if Radio feature is not supported</exception>
- /// <exception cref="InvalidOperationException"></exception>
+ /// <exception cref="NotSupportedException">Radio feature is not supported</exception>
public Radio()
{
ValidateFeatureSupported(FeatureFmRadio);
- _handle = new Interop.RadioHandle();
- _handle.ScanCompleteCb = ScanCompleteCallback;
- _handle.InteruptedCb = PlaybackIntruptedCallback;
+
+ Create(out _handle);
+
+ try
+ {
+ SetScanCompletedCb(_handle, ScanCompleteCallback).ThrowIfFailed("Failed to initialize radio");
+ SetInterruptedCb(_handle, IntruptedCallback).ThrowIfFailed("Failed to initialize radio");
+ }
+ catch (Exception)
+ {
+ _handle.Dispose();
+ throw;
+ }
+ }
+
+ private Interop.RadioHandle Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ return _handle;
+ }
}
/// <summary>
- /// Scan update event, to be triggered when radio scan information is updated
+ /// Occurs when radio scan information is updated.
/// </summary>
- public event EventHandler<ScanUpdatedEventArgs> ScanInformationUpdated;
+ public event EventHandler<ScanUpdatedEventArgs> ScanUpdated;
/// <summary>
- /// Scan stopped event, to be triggered when radio scanning stops
+ /// Occurs when radio scanning stops.
/// </summary>
public event EventHandler ScanStopped;
/// <summary>
- /// Scan complete event, to be triggered when radio scan is completed
+ /// Occurs when radio scan is completed.
/// </summary>
public event EventHandler ScanCompleted;
/// <summary>
- /// Playback interrupted event, to be triggered when radio playback is interrupted
+ /// Occurs when radio is interrupted
/// </summary>
- public event EventHandler<RadioInterruptedEventArgs> PlaybackInterrupted;
+ public event EventHandler<RadioInterruptedEventArgs> Interrupted;
/// <summary>
- /// Current state for the radio
+ /// Gets the current state of the radio.
/// </summary>
public RadioState State
{
get
{
- ValidateObjectNotDisposed();
- return (RadioState)_handle.State;
+ RadioState state;
+ GetState(Handle, out state);
+ return state;
}
}
/// <summary>
- /// Current radio frequency, in [87500 ~ 108000] (kHz) range
+ /// Gets or sets the radio frequency, in [87500 ~ 108000] (kHz).
/// </summary>
- /// <exception cref="ArgumentOutOfRangeException">This is thrown if value passed to setter in not in valid range</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than <see cref="Range.Min"/> of <see cref="FrequencyRange"/>.\n
+ /// - or - \n
+ /// <paramref name="value"/> is greater than <see cref="Range.Max"/> of <see cref="FrequencyRange"/>.\n
+ /// </exception>
public int Frequency
{
get
{
- ValidateObjectNotDisposed();
- return _handle.Frequency;
+ int value = 0;
+ GetFrequency(Handle, out value).ThrowIfFailed("Failed to get frequency");
+ return value;
}
set
{
- ValidateObjectNotDisposed();
- ValidateInputRangeForPropertySetter(value, 87500, 108000);
- _handle.Frequency = value;
+ if (value < FrequencyRange.Min || value > FrequencyRange.Max)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Frequency), value, "Frequency must be within FrequencyRange.");
+ }
+
+ SetFrequency(Handle, value).ThrowIfFailed("Failed to set frequency");
}
}
/// <summary>
- /// Current signal strength, in [-128 ~ 128] (dBm) range
+ /// Gets the current signal strength, in [-128 ~ 128] (dBm).
/// </summary>
public int SignalStrength
{
get
{
- ValidateObjectNotDisposed();
- return _handle.SignalStrength;
+ int value = 0;
+ GetSignalStrength(Handle, out value).ThrowIfFailed("Failed to get signal strength");
+ return value;
}
}
/// <summary>
- /// Indicates if radio is muted. By default radio is not muted.
+ /// Gets the value indicating if radio is muted.
/// </summary>
+ /// <value>
+ /// true if the radio is muted; otherwise, false.
+ /// The default is false.
+ /// </value>
public bool IsMuted
{
get
{
- ValidateObjectNotDisposed();
- return _handle.IsMuted;
+ bool value;
+ GetMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state");
+ return value;
}
set
{
- ValidateObjectNotDisposed();
- _handle.IsMuted = value;
+ SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state");
}
}
/// <summary>
- /// Channel spacing for current region
+ /// Gets the channel spacing for current region.
/// </summary>
public int ChannelSpacing
{
get
{
- ValidateObjectNotDisposed();
- return _handle.ChannelSpacing;
+ int value;
+ GetChannelSpacing(Handle, out value).ThrowIfFailed("Failed to get channel spacing");
+ return value;
}
}
/// <summary>
- /// Current radio volume level, in [0.0 ~ 1.0](1.0 = 100%) range.
- /// Default value for volume is 1.0.
+ /// Gets or sets the radio volume level.
/// </summary>
- /// <exception cref="ArgumentOutOfRangeException">This is thrown if value passed to setter in not in valid range</exception>
+ /// <remarks>Valid volume range is from 0 to 1.0(100%), inclusive.</remarks>
+ /// <value>The default is 1.0.</value>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// <paramref name="value"/> is less than zero.\n
+ /// - or -\n
+ /// <paramref name="value"/> is greater than 1.0.
+ /// </exception>
public float Volume
{
get
{
- ValidateObjectNotDisposed();
- return _handle.Volume;
+ float value;
+ GetVolume(Handle, out value).ThrowIfFailed("Failed to get volume level.");
+ return value;
}
set
{
- ValidateObjectNotDisposed();
- ValidateInputRangeForPropertySetter(value, 0.0, 1.0);
- _handle.Volume = value;
- }
- }
+ if (value < 0F || 1.0F < value)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), value,
+ $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
+ }
- /// <summary>
- /// Minimum frequency for the region, in [87500 ~ 108000] (kHz) range
- /// </summary>
- public int MinimumFrequency
- {
- get
- {
- ValidateObjectNotDisposed();
- return _handle.MinimumFrequency;
+ SetVolume(Handle, value).ThrowIfFailed("Failed to set volume level");
}
}
/// <summary>
- /// Maximum frequency for the region, in [87500 ~ 108000] (kHz) range
+ /// Gets the frequency for the region, in [87500 ~ 108000] (kHz).
/// </summary>
- public int MaximumFrequency
+ public Range FrequencyRange
{
get
{
- ValidateObjectNotDisposed();
- return _handle.MaximumFrequency;
+ int min, max;
+
+ GetFrequencyRange(Handle, out min, out max).ThrowIfFailed("Failed to get frequency range");
+
+ return new Range(min, max);
}
}
/// <summary>
- /// Starts radio playback
+ /// Starts the radio.
/// </summary>
- /// <remarks>This method can be called if Radio is in Ready state. This method will move Radio to Playing state</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is not in Ready state</exception>
- public void StartPlayback()
+ /// <remarks>The radio must be in the <see cref="RadioState.Ready"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public void Start()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State == RadioState.Ready);
- _handle.StartPlayback();
+ ValidateRadioState(RadioState.Ready);
+
+ Interop.Radio.Start(Handle).ThrowIfFailed("Failed to start radio");
}
/// <summary>
- /// Stops radio playback
+ /// Stops the radio.
/// </summary>
- /// <remarks>This method can be called if Radio is in Playing state. This method will move Radio to Ready state</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is not in Playing state</exception>
- public void StopPlayback()
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public void Stop()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State == RadioState.Playing);
- _handle.StopPlayback();
+ ValidateRadioState(RadioState.Playing);
+
+ Interop.Radio.Stop(Handle).ThrowIfFailed("Failed to stop radio");
}
/// <summary>
/// Starts radio scan, will trigger ScanInformationUpdated event, when scan information is updated
/// </summary>
- /// <remarks>This method should not be called if Radio is in Scanning state. This method will move Radio to Scanning state</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is already in Scanning state</exception>
+ /// <remarks>The radio must be in the <see cref="RadioState.Ready"/> or <see cref="RadioState.Playing"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ /// <seealso cref="ScanUpdated"/>
+ /// <seealso cref="ScanCompleted"/>
public void StartScan()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State != RadioState.Scanning);
- _handle.StartScan(ScanUpdateCallback);
+ ValidateRadioState(RadioState.Ready, RadioState.Playing);
+
+ ScanStart(Handle, ScanUpdatedCallback);
}
/// <summary>
- /// Stops radio scan, will trigger ScanStopped event, once complete
+ /// Stops radio scan.
/// </summary>
- /// <remarks>This method should be called only if Radio is in Scanning state</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is not in Scanning state</exception>
+ /// <remarks>The radio must be in the <see cref="RadioState.Scanning"/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ /// <seealso cref="ScanStopped"/>
public void StopScan()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State == RadioState.Scanning);
- _handle.StopScan(ScanStoppedCallback);
+ ValidateRadioState(RadioState.Scanning);
+
+ ScanStop(Handle, ScanStoppedCallback);
}
/// <summary>
- /// Seeks up the effective frequency of the radio
+ /// Seeks up the effective frequency of the radio.
/// </summary>
- /// <returns>Current frequency, in range [87500 ~ 108000] (kHz)</returns>
- /// <remarks>Radio must be in Playing state to use this API</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is not in Playing state</exception>
- public Task<int> SeekUpAsync()
+ /// <returns>
+ /// A task that represents the asynchronous seeking operation.
+ /// The result value is the current frequency, in range [87500 ~ 108000] (kHz).
+ /// It can be -1 if the seeking operation has failed.
+ /// </returns>
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public async Task<int> SeekUpAsync()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State == RadioState.Playing);
+ ValidateRadioState(RadioState.Playing);
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
- Interop.RadioHandle.SeekCompletedCallback callback = (currentFrequency, userData) =>
+ SeekCompletedCallback callback = (currentFrequency, _) =>
{
tcs.TrySetResult(currentFrequency);
};
- _handle.SeekUp(callback);
- return Interop.PinnedTask(tcs);
+ SeekUp(Handle, callback);
+ return await tcs.Task;
}
/// <summary>
- /// Seeks down the effective frequency of the radio
+ /// Seeks down the effective frequency of the radio.
/// </summary>
- /// <returns>Current frequency, in range [87500 ~ 108000] (kHz)</returns>
- /// <remarks>Radio must be in Playing state to use this API</remarks>
- /// <exception cref="InvalidOperationException">This is thrown if Radio is not in Playing state</exception>
- public Task<int> SeekDownAsync()
+ /// <returns>
+ /// A task that represents the asynchronous seeking operation.
+ /// The result value is the current frequency, in range [87500 ~ 108000] (kHz).
+ /// It can be -1 if the seeking operation has failed.
+ /// </returns>
+ /// <remarks>The radio must be in the <see cref="RadioState.Playing/> state.</remarks>
+ /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
+ public async Task<int> SeekDownAsync()
{
- ValidateObjectNotDisposed();
- ValidateRadioState(() => State == RadioState.Playing);
+ ValidateRadioState(RadioState.Playing);
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
- Interop.RadioHandle.SeekCompletedCallback callback = (currentFrequency, userData) =>
+ SeekCompletedCallback callback = (currentFrequency, _) =>
{
tcs.TrySetResult(currentFrequency);
};
- _handle.SeekDown(callback);
- return Interop.PinnedTask(tcs);
+ SeekDown(Handle, callback);
+ return await tcs.Task;
}
private void ValidateFeatureSupported(string featurePath)
}
- private void ScanUpdateCallback(int frequency, IntPtr data)
+ private void ScanUpdatedCallback(int frequency, IntPtr data)
{
- ScanInformationUpdated?.Invoke(this, new ScanUpdatedEventArgs(frequency));
+ ScanUpdated?.Invoke(this, new ScanUpdatedEventArgs(frequency));
}
private void ScanStoppedCallback(IntPtr data)
ScanCompleted?.Invoke(this, EventArgs.Empty);
}
- private void PlaybackIntruptedCallback(Interop.RadioInterruptedReason reason, IntPtr data)
+ private void IntruptedCallback(RadioInterruptedReason reason, IntPtr data)
{
- PlaybackInterrupted?.Invoke(this, new RadioInterruptedEventArgs((RadioInterruptedReason)reason));
+ Interrupted?.Invoke(this, new RadioInterruptedEventArgs(reason));
}
- private void ValidateInputRangeForPropertySetter<T>(T input, T min, T max, [CallerMemberName] string member = "") where T : IComparable<T>
+ private void ValidateRadioState(params RadioState[] reqiured)
{
- if (min.CompareTo(input) == 1 || max.CompareTo(input) == -1)
- {
- throw new ArgumentOutOfRangeException(member, input, $"Valid Range [{min} - {max}]");
- }
- }
+ RadioState curState = State;
- private void ValidateRadioState(Func<bool> stateVerifier, [CallerMemberName] string member = "")
- {
- if (stateVerifier() == false)
+ if (reqiured.Contains(curState) == false)
{
- throw new InvalidOperationException($"{State} is not valid state to call {member}. Please check API documentation");
+ throw new InvalidOperationException($"{curState} is not valid state.");
}
}
- private void ValidateObjectNotDisposed()
+ #region IDisposable Support
+ private bool _disposed = false;
+
+ protected virtual void Dispose(bool disposing)
{
- if (_disposedValue)
+ if (!_disposed)
{
- throw new ObjectDisposedException(GetType().Name);
+ if (_handle != null)
+ {
+ _handle.Dispose();
+ }
+ _disposed = true;
}
}
- private bool _disposedValue = false;
-
+ /// <summary>
+ /// Releases all resources used by the <see cref="Radio"/> object.
+ /// </summary>
public void Dispose()
{
- _handle.ScanCompleteCb = null;
- _handle.InteruptedCb = null;
- _handle.Dispose();
- _disposedValue = true;
+ Dispose(true);
}
+ #endregion
}
}
--- /dev/null
+/*
+ * 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 Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia
+{
+
+ internal enum RadioError
+ {
+ None = ErrorCode.None,
+ OutOfMemory = ErrorCode.OutOfMemory,
+ InvalidParameter = ErrorCode.InvalidParameter,
+ InvalidOperation = ErrorCode.InvalidOperation,
+ PermissionDenied = ErrorCode.PermissionDenied,
+ NotSupported = ErrorCode.NotSupported,
+
+ InvalidState = -0x019A0000 | 0x01,
+ SoundPolicy = -0x019A0000 | 0x02,
+ NoAntenna = -0x019A0000 | 0x03,
+ }
+
+ internal static class RadioErrorExtesions
+ {
+ internal static void ThrowIfFailed(this RadioError err, string message)
+ {
+ if (err == RadioError.None)
+ {
+ return;
+ }
+
+ string errMessage = $"{message}; {err}.";
+ switch (err)
+ {
+ case RadioError.PermissionDenied:
+ throw new UnauthorizedAccessException(errMessage);
+
+ case RadioError.InvalidParameter:
+ throw new ArgumentException(errMessage);
+
+ case RadioError.OutOfMemory:
+ throw new OutOfMemoryException(errMessage);
+
+ case RadioError.NotSupported:
+ case RadioError.NoAntenna:
+ throw new NotSupportedException(errMessage);
+
+ default:
+ throw new InvalidOperationException(errMessage);
+ }
+ }
+
+ }
+
+}
namespace Tizen.Multimedia
{
/// <summary>
- /// Arguments for radio Playback Interrupted events
+ /// Provides data for the <see cref="Radio.Interrupted"/> event.
/// </summary>
public class RadioInterruptedEventArgs : EventArgs
{
}
/// <summary>
- /// Tuned radio frequency, in range [87500 ~ 108000] (kHz)
- /// </summary>
+ /// Gets the reason.
+ /// </summary
public RadioInterruptedReason Reason { get; }
+
+ public override string ToString()
+ {
+ return $"Reason={ Reason.ToString() }";
+ }
}
-}
\ No newline at end of file
+}
namespace Tizen.Multimedia
{
/// <summary>
- /// Radio Interrupted Reason
+ /// Specifies <see cref="Radio"/> interrupted reasons.
/// </summary>
public enum RadioInterruptedReason
{
/// <summary>
- /// Playback interrupted by a resource conflict
+ /// By a resource conflict.
/// </summary>
- ResourceConflict = Interop.RadioInterruptedReason.ResourceConflict,
-
+ ResourceConflict = 4,
}
-}
\ No newline at end of file
+}
namespace Tizen.Multimedia
{
/// <summary>
- /// Radio State
+ /// Specifies states of the <see cref="Radio"/>.
/// </summary>
public enum RadioState
{
/// <summary>
- /// Ready to play or scan
+ /// Ready to play or scan.
/// </summary>
- Ready = Interop.RadioState.Ready,
+ Ready,
/// <summary>
- /// Playing audio from the tuner
+ /// Playing audio from the tuner.
/// </summary>
- Playing = Interop.RadioState.Playing,
+ Playing,
/// <summary>
- /// Scanning/ searching for the next station for signal
+ /// Scanning; searching for the next station for signal.
/// </summary>
- Scanning = Interop.RadioState.Scanning,
+ Scanning,
}
-}
\ No newline at end of file
+}
namespace Tizen.Multimedia
{
/// <summary>
- /// Arguments for radio scan update events
+ /// Provides data for the <see cref="Radio.ScanUpdated"/> event.
/// </summary>
public class ScanUpdatedEventArgs : EventArgs
{
}
/// <summary>
- /// Tuned radio frequency, in range [87500 ~ 108000] (kHz)
+ /// Gets the tuned radio frequency that is scanned, in range [87500 ~ 108000] (kHz).
/// </summary>
public int Frequency { get; }
+
+
+ public override string ToString()
+ {
+ return $"Frequency={ Frequency.ToString() }";
+ }
}
-}
\ No newline at end of file
+}
<PackageReference Include="Tizen.System.Information" Version="1.0.2" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen.Multimedia\Tizen.Multimedia.csproj" />
+ </ItemGroup>
+
</Project>
<description>Provides the Multimedia Radio API for Tizen.Net</description>
<dependencies>
<dependency id="Tizen" version="1.0.2" />
+ <dependency id="Tizen.Multimedia" version="1.2.0" />
</dependencies>
</metadata>
</package>
<PackageReference Include="ElmSharp" Version="1.1.0-*" />
<PackageReference Include="Tizen" Version="1.0.3" />
<PackageReference Include="Tizen.Applications.Common" Version="1.4.2" />
- <PackageReference Include="Tizen.System.Information" Version="1.0.3" />
+ <PackageReference Include="Tizen.System.Information" Version="1.0.2" />
</ItemGroup>
</Project>