5e9f54151e817c16778db330cc969eae2b2661e2
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.MessagePort / Tizen.Applications.Messages / RemotePort.cs
1 /*
2  * Copyright (c) 2017 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 namespace Tizen.Applications.Messages
18 {
19     using System;
20
21     /// <summary>
22     /// The RemotePort Class provides functions to get if the remote port is running and to get whether the remote port is registered or unregistered.
23     /// </summary>
24     /// <since_tizen> 4 </since_tizen>
25     public class RemotePort : IDisposable
26     {
27         private int _watcherIdForRegistered = -1;
28         private int _watcherIdForUnRegistered = -1;
29         private bool _disposed = false;
30
31         private Interop.MessagePort.message_port_registration_event_cb _registeredCallBack;
32         private Interop.MessagePort.message_port_registration_event_cb _unregisteredCallBack;
33
34         private EventHandler<RemotePortStateChangedEventArgs> _remotePortRegistered;
35         private EventHandler<RemotePortStateChangedEventArgs> _remotePortUnregistered;
36
37         private readonly string _portName = null;
38         private readonly string _appId = null;
39         private readonly bool _trusted = false;
40
41         private bool _isRunning = false;
42
43         /// <summary>
44         /// Constructor of the RemotePort class.
45         /// </summary>
46         /// <since_tizen> 4 </since_tizen>
47         /// <param name="appId">The Id of the remote application</param>
48         /// <param name="portName">The name of the remote message port</param>
49         /// <param name="trusted">If true is the trusted message port of application, otherwise false</param>
50         /// <exception cref="System.ArgumentException">Thrown when appId is null or empty, when portName is null or empty</exception>
51         /// <code>
52         /// RemotePort remotePort = new RemotePort("org.tizen.example.messageport", "SenderPort", false);
53         /// </code>
54         public RemotePort(String appId, string portName, bool trusted)
55         {
56             if (String.IsNullOrEmpty(appId) || String.IsNullOrEmpty(portName))
57             {
58                 MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidParameter, "Remote Port", "AppId or PortName");
59             }
60
61             _appId = appId;
62             _portName = portName;
63             _trusted = trusted;
64
65             _registeredCallBack = (string remoteAppId, string remotePortName, bool remoteTrusted, IntPtr userData) =>
66             {
67                 RemotePortStateChangedEventArgs args = new RemotePortStateChangedEventArgs()
68                 {
69                     Status = State.Registered
70                 };
71
72                 _remotePortRegistered?.Invoke(this, args);
73             };
74
75             _unregisteredCallBack = (string remoteAppId, string remotePortName, bool remoteTrusted, IntPtr userData) =>
76             {
77                 RemotePortStateChangedEventArgs args = new RemotePortStateChangedEventArgs()
78                 {
79                     Status = State.Unregistered
80                 };
81
82                 _remotePortUnregistered?.Invoke(this, args);
83             };
84         }
85
86         /// <summary>
87         /// Destructor of the RemotePort class.
88         /// </summary>
89         /// <since_tizen> 4 </since_tizen>
90         ~RemotePort()
91         {
92             Dispose(false);
93         }
94
95         /// <summary>
96         /// The AppId of the remote port
97         /// </summary>
98         /// <since_tizen> 4 </since_tizen>
99         /// <returns> Return appid of RemotePort </returns>
100         public string AppId
101         {
102             get
103             {
104                 return _appId;
105             }
106         }
107
108         /// <summary>
109         /// The name of the remote message port
110         /// </summary>
111         /// <since_tizen> 4 </since_tizen>
112         /// <returns> Return name of RemotePort </returns>
113         public string PortName
114         {
115             get
116             {
117                 return _portName;
118             }
119         }
120
121         /// <summary>
122         /// If true the remote port is a trusted port, otherwise if false it is not
123         /// </summary>
124         /// <since_tizen> 4 </since_tizen>
125         ///  <returns> Return true if RemotePort is trusted </returns>
126         public bool Trusted
127         {
128             get
129             {
130                 return _trusted;
131             }
132         }
133
134         /// <summary>
135         /// Check if the remote message port is running.
136         /// </summary>
137         /// <since_tizen> 4 </since_tizen>
138         /// <exception cref="System.InvalidOperationException">Thrown when there is an I/O error</exception>
139         /// <exception cref="System.OutOfMemoryException">Thrown when out of memory.</exception>
140         /// <code>
141         /// Remote remotePort = new RemotePort("org.tizen.example", "SenderPort", true);
142         /// bool isRunning = remotePort.isRunning();
143         /// </code>
144         /// <returns> Return true if Remote Port is running </returns>
145         public bool IsRunning()
146         {
147             int ret;
148
149             ret = _trusted ?
150                 Interop.MessagePort.CheckTrustedRemotePort(_appId, _portName, out _isRunning) :
151                 Interop.MessagePort.CheckRemotePort(_appId, _portName, out _isRunning);
152
153             if (ret != (int)MessagePortError.None)
154             {
155                 MessagePortErrorFactory.ThrowException(ret);
156             }
157
158             return _isRunning;
159         }
160
161         /// <summary>
162         /// Called when the remote port is registered or unregistered.
163         /// </summary>
164         /// <since_tizen> 4 </since_tizen>
165         /// <exception cref="System.InvalidOperationException">Thrown when there is an I/O error</exception>
166         /// <exception cref="System.OutOfMemoryException">Thrown when out of memory.</exception>
167         /// <code>
168         /// Remote remotePort = new RemotePort("org.tizen.example", "SenderPort", true);
169         /// remotePort.RemotePortStateChanged += RemotePortStateChangedCallback;
170         /// static void RemotePortStateChangedCallback(object sender, MessageReceivedEventArgs e)
171         /// {
172         ///     switch (e.Status)
173         ///     {
174         ///     case State.Registered :
175         ///         Console.WriteLine("Remote Port Registered ");
176         ///         break;
177         ///     case State.Unregistered :
178         ///         Console.WriteLine("Remote Port Unregistered ");
179         ///         break;
180         ///     default :
181         ///         break;
182         ///     }
183         /// }
184         /// </code>
185         public event EventHandler<RemotePortStateChangedEventArgs> RemotePortStateChanged
186         {
187             add
188             {
189                 if (_remotePortRegistered == null)
190                 {
191                     int ret = AddRegistrationCallback();
192
193                     if (ret != (int)MessagePortError.None)
194                     {
195                         MessagePortErrorFactory.ThrowException(ret);
196                     }
197                 }
198
199                 _remotePortRegistered += value;
200                 _remotePortUnregistered += value;
201             }
202
203             remove
204             {
205                 if (_remotePortRegistered?.GetInvocationList()?.Length > 0)
206                 {
207                     _remotePortRegistered -= value;
208                     _remotePortUnregistered -= value;
209
210                     if (_remotePortRegistered == null)
211                     {
212                         RemoveRegistrationCallback();
213                     }
214                 }
215             }
216         }
217
218         private int AddRegistrationCallback()
219         {
220             if (_watcherIdForRegistered != -1)
221             {
222                 Interop.MessagePort.RemoveRegistrationCallback(_watcherIdForRegistered);
223                 _watcherIdForRegistered = -1;
224             }
225
226             int ret = Interop.MessagePort.AddRegisteredCallback(_appId, _portName, _trusted, _registeredCallBack, IntPtr.Zero, out _watcherIdForRegistered);
227
228             if (ret != (int)MessagePortError.None)
229             {
230                 return ret;
231             }
232
233             if (_watcherIdForUnRegistered != -1)
234             {
235                 Interop.MessagePort.RemoveRegistrationCallback(_watcherIdForUnRegistered);
236                 _watcherIdForUnRegistered = -1;
237             }
238
239             ret = Interop.MessagePort.AddUnregisteredCallback(_appId, _portName, _trusted, _unregisteredCallBack, IntPtr.Zero, out _watcherIdForUnRegistered);
240
241             if (ret != (int)MessagePortError.None)
242             {
243                 return ret;
244             }
245
246             return ret;
247         }
248
249         private void RemoveRegistrationCallback()
250         {
251             if (_watcherIdForRegistered != -1 && _watcherIdForUnRegistered != -1)
252             {
253                 int ret = Interop.MessagePort.RemoveRegistrationCallback(_watcherIdForRegistered);
254
255                 if (ret != (int)MessagePortError.None)
256                 {
257                     MessagePortErrorFactory.ThrowException(ret);
258                 }
259
260                 _watcherIdForRegistered = -1;
261
262                 ret = Interop.MessagePort.RemoveRegistrationCallback(_watcherIdForUnRegistered);
263
264                 if (ret != (int)MessagePortError.None)
265                 {
266                     MessagePortErrorFactory.ThrowException(ret);
267                 }
268
269                 _watcherIdForUnRegistered = -1;
270             }
271         }
272
273         /// <summary>
274         /// Releases the unmanaged resources used by the RemotePort class specifying whether to perform a normal dispose operation.
275         /// </summary>
276         /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
277         protected virtual void Dispose(bool disposing)
278         {
279             if (_disposed)
280             {
281                 return;
282             }
283
284             RemoveRegistrationCallback();
285
286             _disposed = true;
287         }
288
289         /// <summary>
290         /// Releases all resources used by the RemotePort class.
291         /// </summary>
292         /// <since_tizen> 4 </since_tizen>
293         public void Dispose()
294         {
295             Dispose(true);
296             GC.SuppressFinalize(this);
297         }
298     }
299
300     /// <summary>
301     /// Enumeration for Remote Message Port state type
302     /// </summary>
303     /// <since_tizen> 4 </since_tizen>
304     public enum State : Byte
305     {
306         /// <summary>
307         /// Value representing Remote Port state is unregistered
308         /// </summary>
309         Unregistered = 0,
310         /// <summary>
311         /// Value representing Remote Port state is registered
312         /// </summary>
313         Registered = 1
314     }
315 }