/* * 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.Collections.Generic; using System.Linq; using System.Threading; using Native = Interop.MediaControllerClient; using NativeHandle = Interop.MediaControllerClientHandle; namespace Tizen.Multimedia.Remoting { /// /// Provides a means to retrieve active controllers and observe controllers added and removed. /// /// 4 public partial class MediaControllerManager : IDisposable { private NativeHandle _handle; private Dictionary _activated = new Dictionary(); private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); internal NativeHandle Handle { get { if (_disposed) { throw new ObjectDisposedException(nameof(MediaControllerManager)); } return _handle; } } /// /// Initializes a new instance of the class. /// /// http://tizen.org/privilege/mediacontroller.client /// An internal error occurs. /// The caller does not have required privilege. /// 4 public MediaControllerManager() { Native.Create(out _handle).ThrowIfError("Failed to create media controller client."); InitializeEvents(); LoadActivatedServers(); } private bool _disposed; /// /// Releases all resources used by the . /// /// 4 public void Dispose() { Dispose(true); } /// /// Releases the unmanaged resources used by the . /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. /// 4 protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // To be used if there are any other disposable objects } _handle.Dispose(); _disposed = true; } } /// /// Gets the active controllers. /// /// An array of . /// 4 public MediaController[] GetActiveControllers() { if (_disposed) { return new MediaController[0]; } try { _lock.EnterReadLock(); return _activated.Values.ToArray(); } finally { _lock.ExitReadLock(); } } #region Controllers-related operations #region Unlocking operations private MediaController HandleActivation(string serverName) { if (_activated.ContainsKey(serverName)) { return null; } var controller = new MediaController(this, serverName); _activated.Add(serverName, controller); return controller; } private MediaController HandleDeactivation(string serverName) { if (_activated.TryGetValue(serverName, out var controller)) { _activated.Remove(serverName); } return controller; } #endregion #region Locking operations private MediaController HandleServerUpdated(string serverName, MediaControllerNativeServerState state) { try { _lock.EnterWriteLock(); if (state == MediaControllerNativeServerState.Activated) { return HandleActivation(serverName); } return HandleDeactivation(serverName); } finally { _lock.ExitWriteLock(); } } private MediaController GetController(string serverName) { try { _lock.EnterReadLock(); _activated.TryGetValue(serverName, out var value); return value; } finally { _lock.ExitReadLock(); } } private void LoadActivatedServers() { try { _lock.EnterWriteLock(); Native.ActivatedServerCallback serverCallback = (serverName, _) => { _activated.Add(serverName, new MediaController(this, serverName)); return true; }; Native.ForeachActivatedServer(Handle, serverCallback, IntPtr.Zero). ThrowIfError("Failed to get activated servers."); } finally { _lock.ExitWriteLock(); } } #endregion #endregion } }