2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using Tizen.Applications;
21 namespace Tizen.Applications.Messages
24 /// The message port API provides functions to send and receive messages between applications.
27 /// 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.
28 /// If a remote application sends a message, the registered callback function of the local port is called.
29 /// The trusted message-port API allows communications between applications that are signed by the same developer(author) certificate.
31 public class MessagePort : IDisposable
33 private static readonly object s_lock = new object();
34 private static readonly HashSet<string> s_portMap = new HashSet<string>();
36 // The name of the local message port
37 private readonly string _portName = null;
39 // If true the message port is a trusted port, otherwise false it is not
40 private readonly bool _trusted = false;
42 // The local message port ID
43 private int _portId = 0;
45 // If true the message port is listening, otherwise false it is not
46 private bool _listening = false;
48 private Interop.MessagePort.message_port_message_cb _messageCallBack;
51 /// Initializes the instance of the MessagePort class.
53 /// <param name="portName">The name of the local message port.</param>
54 /// <param name="trusted">If true, it is the trusted message port of application, otherwise false.</param>
55 /// <exception cref="System.InvalidOperationException">Thrown when portName is null or empty.</exception>
57 /// MessagePort messagePort = new MessagePort("SenderPort", true);
59 public MessagePort(string portName, bool trusted)
61 if (String.IsNullOrEmpty(portName))
63 MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidParameter, "Invalid PortName", "PortName");
70 /// Destructor of the MessagePort class.
78 /// Called when a message is received.
81 /// MessagePort messagePort = new MessagePort("SenderPort", true);
82 /// messagePort.MessageReceived += MessageReceivedCallback;
83 /// static void MessageReceivedCallback(object sender, MessageReceivedEventArgs e)
85 /// Console.WriteLine("Message Received ");
86 /// if (e.Remote.AppId != null) {
87 /// Console.WriteLine("from :"+e.Remote.AppId);
91 public event EventHandler<MessageReceivedEventArgs> MessageReceived;
94 /// The name of the local message port.
96 public string PortName
104 /// If true, the message port is a trusted port, otherwise false.
115 /// If true, the message port is listening, otherwise false.
117 public bool Listening
126 /// Register the local message port.
128 /// <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>
130 /// MessagePort messagePort = new MessagePort("SenderPort", true);
131 /// messagePort.MessageReceived += MessageReceivedCallback;
132 /// messagePort.Listen();
138 if (s_portMap.Contains(_portName))
140 throw new InvalidOperationException(_portName + " is already used");
142 _messageCallBack = (int localPortId, string remoteAppId, string remotePortName, bool trusted, IntPtr message, IntPtr userData) =>
144 MessageReceivedEventArgs args = new MessageReceivedEventArgs()
146 Message = new Bundle(new SafeBundleHandle(message, false))
149 if (!String.IsNullOrEmpty(remotePortName) && !String.IsNullOrEmpty(remoteAppId))
151 args.Remote = new RemoteValues()
154 PortName = remotePortName,
158 MessageReceived?.Invoke(this, args);
162 Interop.MessagePort.RegisterTrustedPort(_portName, _messageCallBack, IntPtr.Zero) :
163 Interop.MessagePort.RegisterPort(_portName, _messageCallBack, IntPtr.Zero);
166 throw new InvalidOperationException("Can't Listening with " + _portName);
168 s_portMap.Add(_portName);
174 /// Unregisters the local message port.
176 /// <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>
178 /// MessagePort messagePort = new MessagePort("SenderPort", true);
179 /// messagePort.MessageReceived += MessageReceivedCallback;
180 /// messagePort.Listen();
181 /// using (var message = new Tizen.Application.Bundle())
183 /// message.AddItem("message", "a_string");
184 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
186 /// messageProt.StopListening();
188 public void StopListening()
192 throw new InvalidOperationException("Already stopped");
196 Interop.MessagePort.UnregisterTrustedPort(_portId) :
197 Interop.MessagePort.UnregisterPort(_portId);
199 if (ret != (int)MessagePortError.None)
201 MessagePortErrorFactory.ThrowException(ret);
206 s_portMap.Remove(_portName);
213 /// Sends an untrusted message to the message port of a remote application.
215 /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB.</param>
216 /// <param name="remoteAppId">The ID of the remote application.</param>
217 /// <param name="remotePortName">The name of the remote message port.</param>
218 /// <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>
219 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB).</exception>
221 /// MessagePort messagePort = new MessagePort("SenderPort", true);
222 /// messagePort.MessageReceived += MessageReceivedCallback;
223 /// messagePort.Listen();
224 /// using (var message = new Tizen.Application.Bundle())
226 /// message.AddItem("message", "a_string");
227 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort");
230 public void Send(Bundle message, string remoteAppId, string remotePortName)
232 Send(message, remoteAppId, remotePortName, false);
236 /// Sends a message to the message port of a remote application.
238 /// <param name="message">The message to be passed to the remote application, the recommended message size is under 4KB.</param>
239 /// <param name="remoteAppId">The ID of the remote application.</param>
240 /// <param name="remotePortName">The name of the remote message port.</param>
241 /// <param name="trusted">If true, it is the trusted message port of remote application, otherwise false.</param>
242 /// <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>
243 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when message has exceeded the maximum limit(4KB).</exception>
245 /// MessagePort messagePort = new MessagePort("SenderPort", true);
246 /// messagePort.MessageReceived += MessageReceivedCallback;
247 /// messagePort.Listen();
248 /// using (var message = new Tizen.Application.Bundle())
250 /// message.AddItem("message", "a_string");
251 /// messagePort.Send(message, "ReceiverAppID", "ReceiverPort", true);
254 public void Send(Bundle message, string remoteAppId, string remotePortName, bool trusted)
258 throw new InvalidOperationException("Should start listen before send");
262 throw new ArgumentNullException("message");
265 Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId) :
266 Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.SafeBundleHandle, _portId);
268 if (ret != (int)MessagePortError.None)
270 if (ret == (int)MessagePortError.MaxExceeded)
272 MessagePortErrorFactory.ThrowException(ret, "Message has exceeded the maximum limit(4KB)", "Message");
274 MessagePortErrorFactory.ThrowException(ret, "Can't send message");
279 /// Releases the unmanaged resource used by the MessagePort class specifying whether to perform a normal dispose operation.
281 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
282 protected virtual void Dispose(bool disposing)
292 Log.Warn(GetType().Namespace, "Exception in Dispose :" + e.Message);
298 /// Releases all resources used by the MessagePort class.
300 public void Dispose()
303 GC.SuppressFinalize(this);