1 // Copyright 2016 by Samsung Electronics, Inc.,
3 // This software is the confidential and proprietary information
4 // of Samsung Electronics, Inc. ("Confidential Information"). You
5 // shall not disclose such Confidential Information and shall use
6 // it only in accordance with the terms of the license agreement
7 // you entered into with Samsung.
10 using System.Collections.Generic;
12 namespace Tizen.Applications.Messages
15 /// The Message Port API provides functions to send and receive messages between applications.
18 /// The Message Port API provides functions for passing messages between applications. An application should register its own local port to receive messages from remote applications.
19 /// If a remote application sends a message, the registered callback function of the local port is called.
20 /// The trusted message-port API allows communications between applications that are signed by the same developer(author) certificate.
22 public class MessagePort : IDisposable
24 private static readonly object s_lock = new object();
25 private static readonly HashSet<string> s_portMap = new HashSet<string>();
27 // The name of the local message port
28 private readonly string _portName = null;
30 // If true the message port is a trusted port, otherwise false it is not
31 private readonly bool _trusted = false;
33 // The local message port ID
34 private int _portId = 0;
36 // If true the message port is listening, otherwise false it is not
37 private bool _listening = false;
39 private Interop.MessagePort.message_port_message_cb _messageCallBack;
42 /// Initializes the instance of the MessagePort class.
44 /// <param name="portName">The name of the local message port</param>
45 /// <param name="trusted">If true is the trusted message port of application, otherwise false</param>
46 /// <exception cref="System.InvalidOperationException">Thrown when portName is null or empty</exception>
48 /// MessagePort messagePort = new MessagePort("SenderPort", true);
50 public MessagePort(string portName, bool trusted)
52 if (String.IsNullOrEmpty(portName))
54 MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidParameter, "Invalid PortName", "PortName");
61 /// Destructor of the MessagePort class.
69 /// Called when a message is received.
72 /// MessagePort messagePort = new MessagePort("SenderPort", true);
73 /// messagePort.MessageReceived += MessageReceivedCallback;
74 /// static void MessageReceivedCallback(object sender, MessageReceivedEventArgs e)
76 /// Console.WriteLine("Message Received ");
77 /// if (e.Remote.AppId != null) {
78 /// Console.WriteLine("from :"+e.Remote.AppId);
82 public event EventHandler<MessageReceivedEventArgs> MessageReceived;
85 /// The name of the local message port
87 public string PortName
95 /// If true the message port is a trusted port, otherwise false it is not
106 /// If true the message port is listening, otherwise false it is not
108 public bool Listening
117 /// Register the local message port.
119 /// <exception cref="System.InvalidOperationException">Thrown when portName is already used, when there is an invalid parameter, when out of memory, when there is an I/O error</exception>
121 /// MessagePort messagePort = new MessagePort("SenderPort", true);
122 /// messagePort.MessageReceived += MessageReceivedCallback;
123 /// messagePort.Listen();
129 if (s_portMap.Contains(_portName))
131 throw new InvalidOperationException(_portName + " is already used");
133 _messageCallBack = (int localPortId, string remoteAppId, string remotePortName, bool trusted, IntPtr message, IntPtr userData) =>
135 MessageReceivedEventArgs args = new MessageReceivedEventArgs()
137 Message = Bundle.MakeRetainedBundle(message)
140 if (!String.IsNullOrEmpty(remotePortName) && !String.IsNullOrEmpty(remoteAppId))
142 args.Remote = new RemoteValues()
145 PortName = remotePortName,
149 MessageReceived?.Invoke(this, args);
153 Interop.MessagePort.RegisterTrustedPort(_portName, _messageCallBack, IntPtr.Zero) :
154 Interop.MessagePort.RegisterPort(_portName, _messageCallBack, IntPtr.Zero);
157 throw new InvalidOperationException("Can't Listening with " + _portName);
159 s_portMap.Add(_portName);
165 /// Unregisters the local message port.
167 /// <exception cref="System.InvalidOperationException">Thrown when messageport is already stopped, when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
169 /// MessagePort messagePort = new MessagePort("SenderPort", true);
170 /// messagePort.MessageReceived += MessageReceivedCallback;
171 /// messagePort.Listen();
172 /// using (var message = new Tizen.Application.Bundle())
174 /// message.AddItem("message", "a_string");
175 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
177 /// messageProt.StopListening();
179 public void StopListening()
183 throw new InvalidOperationException("Already stopped");
187 Interop.MessagePort.UnregisterTrustedPort(_portId) :
188 Interop.MessagePort.UnregisterPort(_portId);
190 if (ret != (int)MessagePortError.None)
192 MessagePortErrorFactory.ThrowException(ret);
197 s_portMap.Remove(_portName);
204 /// Sends a untrusted message to the message port of a remote application.
206 /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB</param>
207 /// <param name="remoteAppId">The ID of the remote application</param>
208 /// <param name="remotePortName">The name of the remote message port</param>
209 /// <exception cref="System.InvalidOperationException">Thrown when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
210 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB)</exception>
212 /// MessagePort messagePort = new MessagePort("SenderPort", true);
213 /// messagePort.MessageReceived += MessageReceivedCallback;
214 /// messagePort.Listen();
215 /// using (var message = new Tizen.Application.Bundle())
217 /// message.AddItem("message", "a_string");
218 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
221 public void Send(Bundle message, string remoteAppId, string remotePortName)
223 Send(message, remoteAppId, remotePortName, false);
227 /// Sends a message to the message port of a remote application.
229 /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB</param>
230 /// <param name="remoteAppId">The ID of the remote application</param>
231 /// <param name="remotePortName">The name of the remote message port</param>
232 /// <param name="trusted">If true the trusted message port of remote application otherwise false</param>
233 /// <exception cref="System.InvalidOperationException">Thrown when there is an invalid parameter, when the port is not found, when out of memory, when there is an I/O error</exception>
234 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB)</exception>
236 /// MessagePort messagePort = new MessagePort("SenderPort", true);
237 /// messagePort.MessageReceived += MessageReceivedCallback;
238 /// messagePort.Listen();
239 /// using (var message = new Tizen.Application.Bundle())
241 /// message.AddItem("message", "a_string");
242 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort", true);
245 public void Send(Bundle message, string remoteAppId, string remotePortName, bool trusted)
249 throw new InvalidOperationException("Should start listen before send");
253 throw new ArgumentNullException("message");
256 Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId) :
257 Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId);
259 if (ret != (int)MessagePortError.None)
261 if (ret == (int)MessagePortError.MaxExceeded)
263 MessagePortErrorFactory.ThrowException(ret, "Message has exceeded the maximum limit(4KB)", "Message");
265 MessagePortErrorFactory.ThrowException(ret, "Can't send message");
270 /// Releases the unmanaged resourced used by the MessagePort class specifying whether to perform a normal dispose operation.
272 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
273 protected virtual void Dispose(bool disposing)
283 Log.Warn(GetType().Namespace, "Exception in Dispose :" + e.Message);
289 /// Releases all resources used by the MessagePort class.
291 public void Dispose()
294 GC.SuppressFinalize(this);