47909fef2eaa3a02c61e9a6105e44747973b29a9
[framework/web/wrt-plugins-tizen.git] / src / MessagePort / MessagePortManagerProxy.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        MessagePortManagerProxy.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief
23  * ##
24  */
25
26 #include "MessagePortManagerProxy.h"
27
28 #include <unistd.h>
29 #include <app_manager.h>
30 #include <dpl/singleton_impl.h>
31
32 #include "LocalMessagePort.h"
33 #include "RemoteMessagePort.h"
34 #include "MessagePortUtility.h"
35 #include <Logger.h>
36
37 IMPLEMENT_SINGLETON(DeviceAPI::MessagePort::MessagePortManagerProxy)
38
39 namespace DeviceAPI {
40 namespace MessagePort {
41
42 using namespace std;
43 using namespace WrtDeviceApis::Commons;
44
45 MessagePortManagerProxy::MessagePortManagerProxy()
46 {
47 }
48
49 MessagePortManagerProxy::~MessagePortManagerProxy()
50 {
51         //Nothing to do
52 }
53
54 LocalMessagePortPtr MessagePortManagerProxy::requestLocalMessagePort(string &messagePortName)
55 {
56         LoggerD("request local (name : " << messagePortName << ")");
57
58         return getLocalMessagePort(messagePortName, false);
59 }
60
61 LocalMessagePortPtr MessagePortManagerProxy::requestTrustedLocalMessagePort(string &messagePortName)
62 {
63         LoggerD("request trusted local (name : " << messagePortName << ")");
64
65         return getLocalMessagePort(messagePortName, true);
66 }
67
68 RemoteMessagePortPtr MessagePortManagerProxy::requestRemoteMessagePort(string &appId, string &messagePortName)
69 {
70         LoggerD("request remote (appId : " << appId << " / name : " << messagePortName << ")");
71
72         return getRemoteMessagePort(appId, messagePortName, false);
73 }
74
75 RemoteMessagePortPtr MessagePortManagerProxy::requestTrustedRemoteMessagePort(string &appId, string &messagePortName)
76 {
77         LoggerD("request trusted remote (appId : " << appId << " / name : " << messagePortName << ")");
78
79         return getRemoteMessagePort(appId, messagePortName, true);
80 }
81
82 void MessagePortManagerProxy::sendMessage(string appId, string name, bool isTrusted,
83                 MessagePortDataItemMapPtr &data, int localPortId)
84 {
85         bundle *b = MessagePortUtilitySingleton::Instance().getBundle(data);
86
87         int err = 0;
88
89         if(!isTrusted)
90         {
91                 if(localPortId == UNDEFINED_LOCAL_PORT_ID)
92                         err = messageport_send_message(appId.c_str(), name.c_str(), b);
93                 else
94                         err = messageport_send_bidirectional_message(localPortId, appId.c_str(), name.c_str(), b);
95         }
96         else
97         {
98                 if(localPortId == UNDEFINED_LOCAL_PORT_ID)
99                         err = messageport_send_trusted_message(appId.c_str(), name.c_str(), b);
100                 else
101                         err = messageport_send_bidirectional_trusted_message(localPortId, appId.c_str(), name.c_str(), b);
102         }
103
104         if(err < 0)
105         {
106                 switch(err)
107                 {
108                 case MESSAGEPORT_ERROR_INVALID_PARAMETER:
109                         ThrowMsg(PlatformException, "The message argument is not a map of String key and String value pair.");
110                         break;
111                 case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
112                         ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (memory)");
113                         break;
114                 case MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND:
115                         ThrowMsg(NotFoundException, "The target application's port is not found.");
116                         break;
117                 case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH:
118                         ThrowMsg(PlatformWrongStateException, "The target application is not signed with the same certificate.");
119                         break;
120                 case MESSAGEPORT_ERROR_IO_ERROR:
121                         ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (I/O)");
122                         break;
123                 case MESSAGEPORT_ERROR_MAX_EXCEEDED:
124                         ThrowMsg(OutOfRangeException, "The size of message has exceeded the maximum limit.");
125                         break;
126                 default:
127                         ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error.");
128                         break;
129                 }
130         }
131 }
132
133 LocalMessagePortPtr MessagePortManagerProxy::getLocalMessagePort(string &name, bool isTrusted)
134 {
135         LoggerD("getLocalMessagePort (name:" << name << ", isTrusted:" << isTrusted << ")");
136         LocalMessagePortPtr localMessagePort = getCachedLocalMessagePort(name, isTrusted);
137
138         if(localMessagePort == NULL)
139         {
140                 int id = 0;
141                 if(isTrusted)
142                         id = messageport_register_trusted_local_port(name.c_str(), message_port_message_cb);
143                 else
144                         id = messageport_register_local_port(name.c_str(), message_port_message_cb);
145
146                 if(id < 0)
147                 {
148                         int errorCode = id;
149                         switch(errorCode)
150                         {
151                         case MESSAGEPORT_ERROR_INVALID_PARAMETER:
152                                 ThrowMsg(InvalidArgumentException, "The remote application ID or the remote message port name is empty.");
153                                 break;
154                         case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
155                                 ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (Memory)");
156                                 break;
157                         case MESSAGEPORT_ERROR_IO_ERROR:
158                                 ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (I/O)");
159                                 break;
160                         default:
161                                 ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (Unknown code)");
162                                 break;
163                         }
164                 }
165
166                 localMessagePort = LocalMessagePortPtr(new LocalMessagePort(id, name, isTrusted));
167
168                 cacheLocalMessagePort(id, name, isTrusted, localMessagePort);
169         }
170
171         return localMessagePort;
172 }
173
174 RemoteMessagePortPtr MessagePortManagerProxy::getRemoteMessagePort(string &appId, string &name, bool isTrusted)
175 {
176         LoggerD("getRemoteMessagePort (appId:" << appId << ", name:" << name << ", isTrusted:" << isTrusted << ")");
177
178         RemoteMessagePortPtr remoteMessagePort = getCachedRemoteMessagePort(appId, name, isTrusted);
179
180         if(remoteMessagePort == NULL)
181         {
182                 bool exists = false;
183                 int errorCode = 0;
184                 if(isTrusted)
185                         errorCode = messageport_check_trusted_remote_port(appId.c_str(), name.c_str(), &exists);
186                 else
187                         errorCode = messageport_check_remote_port(appId.c_str(), name.c_str(), &exists);
188
189                 if(!exists || errorCode < 0)
190                 {
191                         switch(errorCode)
192                         {
193                         case MESSAGEPORT_ERROR_INVALID_PARAMETER:
194                                 ThrowMsg(InvalidArgumentException, "The remote application ID or the remote message port name is empty.");
195                                 break;
196                         case MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND:
197                                 ThrowMsg(NotFoundException, "The target application's port is not found.");
198                                 break;
199                         case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH:
200                                 ThrowMsg(PlatformWrongStateException, "The target application is not signed with the same certificate.");
201                                 break;
202                         case MESSAGEPORT_ERROR_OUT_OF_MEMORY:
203                                 ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (Memory)");
204                                 break;
205                         case MESSAGEPORT_ERROR_IO_ERROR:
206                                 ThrowMsg(PlatformException, "The method cannot proceed due to a severe system error. (I/O)");
207                                 break;
208                         default:
209                                 ThrowMsg(NotFoundException, "The target application's port is not found. (Unknown code)");
210                                 break;
211                         }
212                 }
213
214                 remoteMessagePort = RemoteMessagePortPtr(new RemoteMessagePort(appId, name, isTrusted));
215
216                 cacheRemoteMessagePort(appId, name, isTrusted, remoteMessagePort);
217         }
218
219         return remoteMessagePort;
220 }
221
222 void MessagePortManagerProxy::cacheLocalMessagePort(int id, std::string &name, bool isTrusted, LocalMessagePortPtr &localMessagePort)
223 {
224         LocalMessagePortKey key = { name, isTrusted };
225
226         LocalMessagePortPair keyPair(key, localMessagePort);
227         m_localMessagePortMap.insert(keyPair);
228         LocalMessagePortIdPair idPair(id, localMessagePort);
229         m_localMessagePortIdMap.insert(idPair);
230 }
231
232 LocalMessagePortPtr MessagePortManagerProxy::getCachedLocalMessagePort(string &name, bool isTrusted)
233 {
234         LocalMessagePortPtr localMessagePort(NULL);
235
236         LocalMessagePortKey key = { name, isTrusted };
237         LocalMessagePortMap::iterator iter = m_localMessagePortMap.find(key);
238         if(iter != m_localMessagePortMap.end())
239         {
240                 localMessagePort = iter->second;
241                 LoggerD("Found cached LocalMessagePort");
242         }
243
244         return localMessagePort;
245 }
246
247 LocalMessagePortPtr MessagePortManagerProxy::getCachedLocalMessagePort(int id)
248 {
249         LocalMessagePortPtr localMessagePort(NULL);
250
251         LocalMessagePortIdMap::iterator iter = m_localMessagePortIdMap.find(id);
252         if(iter != m_localMessagePortIdMap.end())
253         {
254                 localMessagePort = iter->second;
255                 LoggerD("Found cached LocalMessagePort");
256         }
257
258         return localMessagePort;
259 }
260
261 void MessagePortManagerProxy::cacheRemoteMessagePort(std::string &appId, std::string &name, bool isTrusted, RemoteMessagePortPtr &remoteMessagePort)
262 {
263         RemoteMessagePortKey key = { appId, name, isTrusted };
264
265         RemoteMessagePortPair keyPair(key, remoteMessagePort);
266         m_remoteMessagePortMap.insert(keyPair);
267 }
268
269 RemoteMessagePortPtr MessagePortManagerProxy::getCachedRemoteMessagePort(string &appId, string &name, bool isTrusted)
270 {
271         RemoteMessagePortPtr remoteMessagePort(NULL);
272
273         RemoteMessagePortKey key = { appId, name, isTrusted };
274         RemoteMessagePortMap::iterator iter = m_remoteMessagePortMap.find(key);
275         if(iter != m_remoteMessagePortMap.end())
276         {
277                 remoteMessagePort = iter->second;
278                 LoggerD("Found cached RemoteMessagePort");
279         }
280
281         return remoteMessagePort;
282 }
283
284 void MessagePortManagerProxy::messagePortMessageCb(int id, const char* remote_app_id,
285                 const char* remote_port, bool trusted_message, bundle* data)
286 {
287         LoggerD("received message : (id:" << id << ", remote_appId : " << remote_app_id <<
288                         ", remote_port:" << remote_port << ", trusted:" << trusted_message << ")");
289
290         LocalMessagePortPtr localMessagePort = getCachedLocalMessagePort(id);
291         if(localMessagePort == NULL)
292         {
293                 LoggerW("There is no local message port id : " << id);
294                 return;
295         }
296
297         RemoteMessagePortPtr remoteMessagePort(NULL);
298
299         if(remote_app_id != NULL && remote_port != NULL)
300         {
301                 string remoteAppId(remote_app_id);
302                 string remotePortName(remote_port);
303                 Try
304                 {
305                         remoteMessagePort = getRemoteMessagePort(remoteAppId, remotePortName, trusted_message);
306                 }
307                 Catch(Exception)
308                 {
309                         LoggerE("Error on getRemoteMessagePort : " << _rethrown_exception.GetMessage());
310                 }
311         }
312
313         MessagePortDataItemMapPtr dataItemMap = MessagePortUtilitySingleton::Instance().getDataItemMap(data);
314
315         localMessagePort->OnMessageReceived(dataItemMap, remoteMessagePort);
316 }
317
318 // private static
319 void MessagePortManagerProxy::message_port_message_cb(int id, const char* remote_app_id,
320                 const char* remote_port, bool trusted_message, bundle* data)
321 {
322         MessagePortManagerProxySingleton::Instance().messagePortMessageCb(id, remote_app_id,
323                         remote_port, trusted_message, data);
324 }
325
326 } // MessagePort
327 } // DeviceAPI