Release 4.0.0-preview1-00201
[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     public partial class MediaControllerManager : IDisposable
30     {
31         private NativeHandle _handle;
32
33         private Dictionary<string, MediaController> _activated = new Dictionary<string, MediaController>();
34
35         private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
36
37         internal NativeHandle Handle
38         {
39             get
40             {
41                 if (_disposed)
42                 {
43                     throw new ObjectDisposedException(nameof(MediaControllerManager));
44                 }
45
46                 return _handle;
47             }
48         }
49
50         /// <summary>
51         /// Initializes a new instance of the <see cref="MediaControllerManager"/> class.
52         /// </summary>
53         /// <privilege>http://tizen.org/privilege/mediacontroller.client</privilege>
54         /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
55         /// <exception cref="UnauthorizedAccessException">The caller does not have required privilege.</exception>
56         public MediaControllerManager()
57         {
58             Native.Create(out _handle).ThrowIfError("Failed to create media controller client.");
59
60             InitializeEvents();
61
62             LoadActivatedServers();
63         }
64
65         private bool _disposed;
66
67         /// <summary>
68         /// Releases all resources used by the <see cref="MediaControllerManager"/>.
69         /// </summary>
70         public void Dispose()
71         {
72             Dispose(true);
73         }
74
75         /// <summary>
76         /// Releases the unmanaged resources used by the <see cref="MediaControllerManager"/>.
77         /// </summary>
78         /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
79         protected virtual void Dispose(bool disposing)
80         {
81             if (!_disposed)
82             {
83                 if (disposing)
84                 {
85                     // To be used if there are any other disposable objects
86                 }
87                 _handle.Dispose();
88
89                 _disposed = true;
90             }
91         }
92
93         /// <summary>
94         /// Gets the active controllers.
95         /// </summary>
96         /// <returns>An array of <see cref="MediaController"/>.</returns>
97         public MediaController[] GetActiveControllers()
98         {
99             if (_disposed)
100             {
101                 return new MediaController[0];
102             }
103
104             try
105             {
106                 _lock.EnterReadLock();
107                 return _activated.Values.ToArray();
108             }
109             finally
110             {
111                 _lock.ExitReadLock();
112             }
113         }
114
115         #region Controllers-related operations
116
117         #region Unlocking operations
118
119         private MediaController HandleActivation(string serverName)
120         {
121             if (_activated.ContainsKey(serverName))
122             {
123                 return null;
124             }
125
126             var controller = new MediaController(this, serverName);
127             _activated.Add(serverName, controller);
128
129             return controller;
130         }
131
132         private MediaController HandleDeactivation(string serverName)
133         {
134             if (_activated.TryGetValue(serverName, out var controller))
135             {
136                 _activated.Remove(serverName);
137             }
138
139             return controller;
140         }
141         #endregion
142
143         #region Locking operations
144
145         private MediaController HandleServerUpdated(string serverName, MediaControllerServerState state)
146         {
147             try
148             {
149                 _lock.EnterWriteLock();
150
151                 if (state == MediaControllerServerState.Activated)
152                 {
153                     return HandleActivation(serverName);
154                 }
155
156                 return HandleDeactivation(serverName);
157             }
158             finally
159             {
160                 _lock.ExitWriteLock();
161             }
162         }
163
164         private MediaController GetController(string serverName)
165         {
166             try
167             {
168                 _lock.EnterReadLock();
169
170                 _activated.TryGetValue(serverName, out var value);
171                 return value;
172             }
173             finally
174             {
175                 _lock.ExitReadLock();
176             }
177         }
178
179         private void LoadActivatedServers()
180         {
181             try
182             {
183                 _lock.EnterWriteLock();
184
185                 Native.ActivatedServerCallback serverCallback = (serverName, _) =>
186                 {
187                     _activated.Add(serverName, new MediaController(this, serverName));
188                     return true;
189                 };
190
191                 Native.ForeachActivatedServer(Handle, serverCallback, IntPtr.Zero).
192                     ThrowIfError("Failed to get activated servers.");
193             }
194             finally
195             {
196                 _lock.ExitWriteLock();
197             }
198         }
199
200         #endregion
201
202         #endregion
203     }
204 }