Release 8.0.0.15812
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / MediaController / MediaControllerManager.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Threading;
21 using Native = Interop.MediaControllerClient;
22 using NativeHandle = Interop.MediaControllerClientHandle;
23
24 namespace Tizen.Multimedia.Remoting
25 {
26     /// <summary>
27     /// Provides a means to retrieve active controllers and observe controllers added and removed.
28     /// </summary>
29     /// <since_tizen> 4 </since_tizen>
30     public partial class MediaControllerManager : IDisposable
31     {
32         private NativeHandle _handle;
33
34         private Dictionary<string, MediaController> _activated = new Dictionary<string, MediaController>();
35
36         private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
37
38         internal NativeHandle Handle
39         {
40             get
41             {
42                 if (_disposed)
43                 {
44                     throw new ObjectDisposedException(nameof(MediaControllerManager));
45                 }
46
47                 return _handle;
48             }
49         }
50
51         /// <summary>
52         /// Initializes a new instance of the <see cref="MediaControllerManager"/> class.
53         /// </summary>
54         /// <privilege>http://tizen.org/privilege/mediacontroller.client</privilege>
55         /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
56         /// <exception cref="UnauthorizedAccessException">The caller does not have required privilege.</exception>
57         /// <since_tizen> 4 </since_tizen>
58         public MediaControllerManager()
59         {
60             Native.Create(out _handle).ThrowIfError("Failed to create media controller client.");
61
62             InitializeEvents();
63
64             LoadActivatedServers();
65         }
66
67         private bool _disposed;
68
69         /// <summary>
70         /// Releases all resources used by the <see cref="MediaControllerManager"/>.
71         /// </summary>
72         /// <since_tizen> 4 </since_tizen>
73         public void Dispose()
74         {
75             Dispose(true);
76         }
77
78         /// <summary>
79         /// Releases the unmanaged resources used by the <see cref="MediaControllerManager"/>.
80         /// </summary>
81         /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
82         /// <since_tizen> 4 </since_tizen>
83         protected virtual void Dispose(bool disposing)
84         {
85             if (!_disposed)
86             {
87                 if (disposing)
88                 {
89                     // To be used if there are any other disposable objects
90                 }
91                 _handle.Dispose();
92
93                 _disposed = true;
94             }
95         }
96
97         /// <summary>
98         /// Gets the active controllers.
99         /// </summary>
100         /// <returns>An array of <see cref="MediaController"/>.</returns>
101         /// <since_tizen> 4 </since_tizen>
102         public MediaController[] GetActiveControllers()
103         {
104             if (_disposed)
105             {
106                 return new MediaController[0];
107             }
108
109             try
110             {
111                 _lock.EnterReadLock();
112                 return _activated.Values.ToArray();
113             }
114             finally
115             {
116                 _lock.ExitReadLock();
117             }
118         }
119
120         #region Controllers-related operations
121
122         #region Unlocking operations
123
124         private MediaController HandleActivation(string serverName)
125         {
126             if (_activated.ContainsKey(serverName))
127             {
128                 return null;
129             }
130
131             var controller = new MediaController(this, serverName);
132             _activated.Add(serverName, controller);
133
134             return controller;
135         }
136
137         private MediaController HandleDeactivation(string serverName)
138         {
139             if (_activated.TryGetValue(serverName, out var controller))
140             {
141                 _activated.Remove(serverName);
142             }
143
144             return controller;
145         }
146         #endregion
147
148         #region Locking operations
149
150         private MediaController HandleServerUpdated(string serverName, MediaControllerNativeServerState state)
151         {
152             try
153             {
154                 _lock.EnterWriteLock();
155
156                 if (state == MediaControllerNativeServerState.Activated)
157                 {
158                     return HandleActivation(serverName);
159                 }
160
161                 return HandleDeactivation(serverName);
162             }
163             finally
164             {
165                 _lock.ExitWriteLock();
166             }
167         }
168
169         private MediaController GetController(string serverName)
170         {
171             try
172             {
173                 _lock.EnterReadLock();
174
175                 _activated.TryGetValue(serverName, out var value);
176                 return value;
177             }
178             finally
179             {
180                 _lock.ExitReadLock();
181             }
182         }
183
184         private void LoadActivatedServers()
185         {
186             try
187             {
188                 _lock.EnterWriteLock();
189
190                 Native.ActivatedServerCallback serverCallback = (serverName, _) =>
191                 {
192                     _activated.Add(serverName, new MediaController(this, serverName));
193                     return true;
194                 };
195
196                 Native.ForeachActivatedServer(Handle, serverCallback, IntPtr.Zero).
197                     ThrowIfError("Failed to get activated servers.");
198             }
199             finally
200             {
201                 _lock.ExitWriteLock();
202             }
203         }
204
205         #endregion
206
207         #endregion
208     }
209 }