Merge "Change langlist.xml path" into tizen_2.2
[platform/framework/native/appfw.git] / src / app / FApp_AppArg.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18 * @file     FApp_AppArg.cpp
19 * @brief        This is the implementation for the _AppArg.cpp class.
20 */
21
22 #include <cstdio>
23 #include <cstdlib>
24 #include <vector>
25 #include <new>
26 #include <typeinfo>
27 #include <unique_ptr.h>
28
29 #include <aul.h>
30 #include <app.h>
31 #include <appsvc/appsvc.h>
32 #include <Ecore_X.h>
33
34 #include <FBaseInteger.h>
35 #include <FBaseColArrayList.h>
36 #include <FBaseColHashMap.h>
37 #include <FBaseUtilStringTokenizer.h>
38
39 #include <FBaseSysLog.h>
40 #include <FBase_StringConverter.h>
41
42 #include "FApp_MapDataControlImpl.h"
43 #include "FApp_AppControlImpl.h"
44 #include "FApp_SqlDataControlImpl.h"
45 #include "FApp_AppControlEventArg.h"
46 #include "FApp_AppArg.h"
47 #include "FApp_AppMessageImpl.h"
48 #include "FApp_Aul.h"
49 #include "FAppPkg_PackageManagerImpl.h"
50
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::Base::Utility;
54 using namespace Tizen::App::Package;
55
56
57 extern "C" int appsvc_allow_transient_app(bundle*, Ecore_X_Window);
58
59 namespace Tizen { namespace App
60 {
61
62 static const char OSP_V_LAUNCH_TYPE_LAUNCH[] = "launch";
63 static const char OSP_V_LAUNCH_TYPE_APPCONTROL[] = "appcontrol";
64 static const char OSP_V_LAUNCH_TYPE_DATACONTROL[] = "datacontrol";
65 static const char OSP_V_LAUNCH_TYPE_CONDTION[] = "condition";
66 static const char OSP_V_REQUEST_TYPE_SQL_QUERY[] = "sql_query";
67 static const char OSP_V_REQUEST_TYPE_SQL_INSERT[] = "sql_insert";
68 static const char OSP_V_REQUEST_TYPE_SQL_UPDATE[] = "sql_update";
69 static const char OSP_V_REQUEST_TYPE_SQL_DELETE[] = "sql_delete";
70 static const char OSP_V_REQUEST_TYPE_MAP_QEURY[] = "map_query";
71 static const char OSP_V_REQUEST_TYPE_MAP_INSERT[] = "map_insert";
72 static const char OSP_V_REQUEST_TYPE_MAP_UPDATE[] = "map_update";
73 static const char OSP_V_REQUEST_TYPE_MAP_DELETE[] = "map_delete";
74 static const char OSP_V_VERSION_2_1_0_3[] = "ver_2.1.0.3";
75 static const char BUNDLE_KEY_PREFIX_AUL[] = "__AUL_";
76 static const char BUNDLE_KEY_PREFIX_SERVICE[] = "__APP_SVC_";
77 static const char BUNDLE_KEY_PREFIX_OSP[] = "__OSP_";
78 const char TIZEN_NOTIFICATION_DATA[] = "http://tizen.org/appcontrol/data/notification";
79
80 static const char SAMSUNG_ACCOUNT_KEY_CLIENT_ID[] = "client_id";
81 static const char SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET[] = "client_secret";
82 static const char SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY[] = "service_category";
83
84 static const char SMS_KEY_SERVICE_CALLER[] = "service_caller";
85 static const char SMS_KEY_SERVICE_DATA[] = "service_data";
86
87
88 _AppArg::_AppArg(void)
89         : __pBundle(null)
90 {
91 }
92
93
94 _AppArg::~_AppArg(void)
95 {
96         if (__pBundle)
97         {
98                 bundle_free(__pBundle);
99         }
100 }
101
102
103 result
104 _AppArg::Construct(const String& argText)
105 {
106         __pBundle = bundle_create();
107         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
108
109         return CreateLaunchArg(__pBundle, argText);
110 }
111
112
113 result
114 _AppArg::Construct(const IList* pList)
115 {
116         __pBundle = bundle_create();
117         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
118
119         return CreateLaunchArg(__pBundle, pList);
120 }
121
122
123 result
124 _AppArg::Construct(const _AppControlImpl& ac, const IList* pList)
125 {
126         __pBundle = bundle_create();
127         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
128
129         return CreateAppControlArg(__pBundle, ac, pList);
130 }
131
132
133 result
134 _AppArg::Construct(const _AppControlImpl& ac, const String* pUri, const String* pMime, const IMap* pList)
135 {
136         __pBundle = bundle_create();
137         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
138
139         return CreateAppControlArg(__pBundle, ac, pUri, pMime, pList);
140 }
141
142
143 result
144 _AppArg::Construct(const _AppMessageImpl& msg, const String& oId, const String* pUri, const String* pMime)
145 {
146         __pBundle = bundle_dup(const_cast<bundle*>(msg.GetBundle()));
147         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
148
149         return CreateAppControlArg(__pBundle, oId, pUri, pMime, null);
150 }
151
152
153 result
154 _AppArg::Construct(const _SqlDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
155 {
156         __pBundle = bundle_create();
157         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
158
159         return CreateSqlDataControlArg(__pBundle, dc, requestType, pList);
160 }
161
162
163 result
164 _AppArg::Construct(const _MapDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
165 {
166         __pBundle = bundle_create();
167         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
168
169         return CreateMapDataControlArg(__pBundle, dc, requestType, pList);
170 }
171
172
173 result
174 _AppArg::ConstructResult(const _AppArg& arg, const IList* pList)
175 {
176         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
177         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
178
179         return CreateResultArg(__pBundle, pList);
180 }
181
182
183 result
184 _AppArg::ConstructResult(const _AppArg& arg, const IMap* pMap)
185 {
186         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
187         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
188
189         return CreateResultArg(__pBundle, pMap);
190 }
191
192
193 result
194 _AppArg::Construct(bundle* b)
195 {
196         __pBundle = bundle_dup(b);
197         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure.");
198
199         return E_SUCCESS;
200 }
201
202
203 result
204 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList)
205 {
206         __pBundle = bundle_create();
207         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
208
209         return CreateAppLaunchConditionArg(__pBundle, condition, pList);
210 }
211
212 result
213 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList, const IMap* pMap)
214 {
215         __pBundle = bundle_create();
216         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
217
218         CreateAppLaunchConditionArg(__pBundle, condition, pList);
219
220         return CreateResultArg(__pBundle, pMap);
221 }
222
223 ArrayList*
224 _AppArg::GetArgListN(int num) const
225 {
226         bundle* pBundle = __pBundle;
227         SysTryReturn(NID_APP, pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
228
229         ArrayList* pList = new (std::nothrow) ArrayList();
230         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
231
232         pList->Construct();
233
234         const char* p = NULL;
235         _AppHandler launch_type = GetHandler(pBundle);
236
237         switch (launch_type)
238         {
239         case _APP_HANDLER_APPCONTROL:
240                 // request Id
241                 // [FIXME] proper request Id required
242                 pList->Add(*new (std::nothrow) String(GetRequestId(num)));
243
244                 // category
245                 p = appsvc_get_category(pBundle);
246                 if (p)
247                 {
248                         pList->Add(*new (std::nothrow) String(p));
249                 }
250                 else
251                 {
252                         pList->Add(*new (std::nothrow) String(L""));
253                 }
254
255                 // MIME type
256                 p = appsvc_get_mime(pBundle);
257                 if (p)
258                 {
259                         pList->Add(*new (std::nothrow) String(p));
260                 }
261                 else
262                 {
263                         pList->Add(*new (std::nothrow) String(L""));
264                 }
265
266                 // URI scheme
267                 p = appsvc_get_uri(pBundle);
268                 if (p)
269                 {
270                         pList->Add(*new (std::nothrow) String(p));
271                 }
272                 else
273                 {
274                         pList->Add(*new (std::nothrow) String(L""));
275                 }
276
277                 break;
278
279         case _APP_HANDLER_DATACONTROL:
280                 // appId
281                 AddListFromBundle(pList, pBundle, OSP_K_APPID);
282                 // request type
283                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
284                 // reqId
285                 AddListFromBundle(pList, pBundle, OSP_K_REQUEST_ID);
286                 // providerId
287                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_PROVIDER);
288                 break;
289
290         case _APP_HANDLER_LAUNCH_COND:
291                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_CONDITIONAL));
292                 AddListFromBundle(pList, pBundle, OSP_K_COND);
293                 break;
294
295         case _APP_HANDLER_LAUNCH_NORMAL:
296                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_NORMAL));
297                 pList->Add(*new (std::nothrow) String(L"osp.operation.MAIN"));
298                 break;
299
300         default:
301                 SysLog(NID_APP, "Invalid handler type");
302                 break;
303         }
304
305         SetArgList(__pBundle, pList);
306
307         return pList;
308 }
309
310
311 ArrayList*
312 _AppArg::GetArgListN(void) const
313 {
314         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
315
316         ArrayList* pList = new (std::nothrow) ArrayList();
317         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
318
319         pList->Construct();
320
321         SetArgList(__pBundle, pList);
322
323         return pList;
324 }
325
326 // the returned map is allocated using SingleObjectDeleter
327 HashMap*
328 _AppArg::GetArgMapN(void) const
329 {
330         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
331
332         //Print();
333
334         HashMap* pHashMap = new (std::nothrow) HashMap(SingleObjectDeleter);
335         SysTryReturn(NID_APP, pHashMap != null, null, E_OUT_OF_MEMORY, "HashMap creation failure.");
336
337         pHashMap->Construct();
338
339         SetArgMap(__pBundle, pHashMap);
340
341         if (pHashMap->GetCount() == 0)
342         {
343                 delete pHashMap;
344                 return null;
345         }
346
347         return pHashMap;
348 }
349
350 static bool
351 IsInternalKey(const char* pKey)
352 {
353         if (strncmp(BUNDLE_KEY_PREFIX_AUL, pKey, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
354         {
355                 return true;
356         }
357
358         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, pKey, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
359         {
360                 return true;
361         }
362
363         if (strncmp(BUNDLE_KEY_PREFIX_OSP, pKey, strlen(BUNDLE_KEY_PREFIX_OSP)) == 0)
364         {
365                 return true;
366         }
367
368         return false;
369 }
370
371 static void
372 BundleIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
373 {
374         HashMap* pMap = static_cast<HashMap*>(pData);
375
376         if (pKey && pVal && pMap)
377         {
378                 if (IsInternalKey(pKey))
379                 {
380                         //SysLog(NID_APP, "(%s)", pKey);
381                         return;
382                 }
383
384                 size_t size = 0;
385                 char* pStr = NULL;
386                 switch (type)
387                 {
388                 case BUNDLE_TYPE_STR:
389                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
390                         if (pStr)
391                         {
392                                 pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(pStr));
393                         }
394                         break;
395                 case BUNDLE_TYPE_STR_ARRAY:
396                         {
397                                 void** pArr = NULL;
398                                 bundle_keyval_get_array_val(const_cast<bundle_keyval_t*>(pVal), &pArr, &size, NULL);
399                                 if (pArr && size > 0)
400                                 {
401                                         ArrayList* pList = new (std::nothrow) ArrayList(SingleObjectDeleter);
402                                         if (pList)
403                                         {
404                                                 pList->Construct();
405
406                                                 for (size_t i = 0; i < size; i++)
407                                                 {
408                                                         // type unsafe ugly static casting required
409                                                         pList->Add(new (std::nothrow) String(static_cast<char*>(*(pArr + i))));
410                                                 }
411
412                                                 const int count = pList->GetCount();
413                                                 if (count != 0)
414                                                 {
415                                                         SysLog(NID_APP, "Adding %d elements for %s", count, pKey);
416                                                         pMap->Add(new (std::nothrow) String(pKey), pList);
417                                                 }
418                                                 else
419                                                 {
420                                                         SysLog(NID_APP, "No object for %s", pKey);
421                                                         delete pList;
422                                                 }
423                                         }
424                                 }
425                                 else
426                                 {
427                                         SysLog(NID_APP, "No entry for str array %s(%d)", pKey, size);
428                                 }
429                         }
430                         break;
431                 case BUNDLE_TYPE_BYTE:
432                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
433
434                         SysLog(NID_IO, "Bundle byte value = %s, size = %d", pStr, size);
435
436                         if (pStr)
437                         {
438                                 ByteBuffer* pBuffer = new (std::nothrow) ByteBuffer();
439                                 SysTryLog(NID_IO, pBuffer != null, "The memory is insufficient.");
440                                 result r = pBuffer->Construct(size);
441                                 SysTryLog(NID_IO, r == E_SUCCESS, "Constructing pBuffer is failed.");
442
443                                 r = pBuffer->SetArray((const byte*)pStr, 0, size);
444                                 SysTryLog(NID_IO, r == E_SUCCESS, "SetArray()for ByteBuffer is failed.");
445
446                                 pBuffer->Flip();
447
448                                 pMap->Add(new (std::nothrow) String(pKey), pBuffer);
449                         }
450                         break;
451                 default:
452                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
453                         break;
454                 }
455         }
456 }
457
458 result
459 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
460 {
461         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
462
463         return E_SUCCESS;
464 }
465
466 result
467 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
468 {
469         // actual argument below
470         int len = 0;
471         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
472         if (pa)
473         {
474                 for (int i = 0; i < len; i++)
475                 {
476                         if (pa[i])
477                         {
478                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
479                                 pList->Add(*new (std::nothrow) String(pa[i]));
480                         }
481                 }
482         }
483
484         const char* p = appsvc_get_uri(pBundle);
485         if (p)
486         {
487                 pList->Add(*new (std::nothrow) String(p));
488                 SysLog(NID_APP, "argument is %s", p);
489         }
490
491         String tmp;
492         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_CALLER);
493         if (p)
494         {
495                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_CALLER, p);
496                 pList->Add(*new (std::nothrow) String(tmp));
497                 SysLog(NID_APP, "service_caller is %s", p);
498         }
499         
500         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_DATA);
501         if (p)
502         {
503                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_DATA, p);
504                 pList->Add(*new (std::nothrow) String(tmp));
505                 SysLog(NID_APP, "service_data is set");
506         }
507         
508         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_ID);
509         if (p)
510         {
511                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_ID, p);
512                 pList->Add(*new (std::nothrow) String(tmp));
513                 SysLog(NID_APP, "client_id is %s", p);
514         }
515         
516         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET);
517         if (p)
518         {
519                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET, p);
520                 pList->Add(*new (std::nothrow) String(tmp));
521                 SysLog(NID_APP, "client_secret is %s", p);
522         }
523
524         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY);
525         if (p)
526         {
527                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY, p);
528                 pList->Add(*new (std::nothrow) String(tmp));
529                 SysLog(NID_APP, "service_category is %s", p);
530         }
531
532         return E_SUCCESS;
533 }
534
535
536 String
537 _AppArg::GetValue(const char* key) const
538 {
539         const char* p = appsvc_get_data(__pBundle, key);
540         return String(p);
541 }
542
543
544 _AppHandler
545 _AppArg::GetHandler(bundle* b)
546 {
547         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
548
549         const char* p = null;
550
551         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
552
553         if (p)
554         {
555                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
556                 {
557                         return _APP_HANDLER_DATACONTROL;
558                 }
559
560                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
561                 {
562                         SysLog(NID_APP, "Building AppControl arguments.");
563
564                         return _APP_HANDLER_APPCONTROL;
565                 }
566                 else
567                 {
568                         // not appcontrol nor datacontrol => normal launch or condlaunch
569                         p = appsvc_get_data(b, OSP_K_COND);
570                         if (p)
571                         {
572                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
573                                 return _APP_HANDLER_LAUNCH_COND;
574                         }
575                         else
576                         {
577                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
578                                 return _APP_HANDLER_LAUNCH_NORMAL;
579                         }
580                 }
581         }
582
583         // fallback
584         return _APP_HANDLER_APPCONTROL;
585 }
586
587
588 int
589 _AppArg::GetCallerPid(bundle* pBundle)
590 {
591         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
592         if (pBundleValue == NULL)
593         {
594                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
595         }
596
597         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
598
599         return atoi(pBundleValue);
600 }
601
602
603 AppId
604 _AppArg::GetCallerAppId(void) const
605 {
606         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLER_APPID);
607
608         return String(pBundleValue);
609 }
610
611
612 AppId
613 _AppArg::GetCalleeAppId(void) const
614 {
615         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLEE_APPID);
616
617         const AppId retVal = pBundleValue;
618
619         return _Aul::GetRealAppId(retVal);
620 }
621
622
623 void
624 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
625 {
626         bundle* pBundle = bk;
627
628         const char* p = appsvc_get_data(pBundle, key);
629         if (p)
630         {
631                 pList->Add(*new (std::nothrow) String(p));
632         }
633         else
634         {
635                 pList->Add(*new (std::nothrow) String(L""));
636         }
637 }
638
639
640 result
641 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
642 {
643         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
644
645         return AddStrArray(b, pKey.get(), pList);
646 }
647
648
649 result
650 _AppArg::AddStrArray(bundle* pb, const char* key, const IList* pList)
651 {
652         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
653
654         if (pList == null || pList->GetCount() == 0)
655         {
656                 SysLog(NID_APP, "No element added for bundle.");
657                 return E_SUCCESS;
658         }
659
660         _AppMessageImpl::AddValueArray(pb, key, pList);
661
662         _AppMessageImpl::AddData(pb, pList);
663
664         return E_SUCCESS;
665 }
666
667
668 result
669 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
670 {
671         bundle* pb = b;
672         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
673
674         if (pMap == null || pMap->GetCount() == 0)
675         {
676                 SysLog(NID_APP, "No element added for bundle.");
677                 return E_SUCCESS;
678         }
679
680         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
681         while(pEnum->MoveNext() == E_SUCCESS)
682         {
683                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
684                 const Object* pObj = pEnum->GetValue();
685
686                 if (pKey && pObj)
687                 {
688                         if (typeid(*pObj) == typeid(const String))
689                         {
690                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
691                                 if (pVal)
692                                 {
693                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
694                                 }
695                         }
696                         else if (typeid(*pObj) == typeid(const ArrayList))
697                         {
698                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
699                                 if (pList)
700                                 {
701                                         SysLog(NID_APP, "ArrayList type");
702
703                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
704                                 }
705                         }
706                         else if (typeid(*pObj) == typeid(const ByteBuffer))
707                         {
708                                 SysLog(NID_APP, "ByteBuffer type");
709                                 const ByteBuffer* pBuffer = static_cast<const ByteBuffer*>(pObj);
710
711                                 std::unique_ptr<char[]> pBundleKey(_StringConverter::CopyToCharArrayN(*pKey));
712                                 bundle_add_byte(b, pBundleKey.get(), pBuffer->GetPointer(), pBuffer->GetLimit());
713                         }
714                 }
715         }
716
717         return E_SUCCESS;
718 }
719
720
721 result
722 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
723 {
724         if (pMap == null || pList == null)
725         {
726                 return E_SUCCESS;
727         }
728
729         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
730         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
731
732         String key;
733         String value;
734         while (pEnum->MoveNext() == E_SUCCESS)
735         {
736                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
737
738                 int index = -1;
739                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
740                 {
741                         continue;
742                 }
743                 pStr->SubString(0, index, key);
744                 if (key.IsEmpty())
745                 {
746                         continue;
747                 }
748
749                 pStr->SubString(index + 1, value);
750
751                 pMap->Add(new String(key), new String(value));
752
753                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
754         }
755
756         return E_SUCCESS;
757 }
758
759
760 result
761 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
762 {
763         switch (res)
764         {
765         case APP_CTRL_RESULT_SUCCEEDED:
766                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
767                 break;
768         case APP_CTRL_RESULT_CANCELED:
769                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
770                 return E_SUCCESS;
771         case APP_CTRL_RESULT_TERMINATED:
772                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
773                 return E_SUCCESS;
774         case APP_CTRL_RESULT_ABORTED:
775                 list.Add(* new (std::nothrow) String("aborted"));
776                 return E_SUCCESS;
777                 //case APP_CTRL_RESULT_FAILED:
778         default:
779                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
780                 return E_SUCCESS;
781         }
782
783         if (pArgs == null)
784         {
785                 return E_SUCCESS;
786         }
787
788         bool isPathRegistered = false;
789         // handle APP_CTRL_RESULT_SUCCEEDED only
790         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
791
792         while(pMapEnum->MoveNext() == E_SUCCESS)
793         {
794                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
795                 if (pKey == null)
796                 {
797                         SysLog(NID_APP, "Invalid entry.");
798                         continue;
799                 }
800
801                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
802                 {
803                         if (!isPathRegistered)
804                         {
805                                 isPathRegistered = true;
806                         }
807                         else
808                         {
809                                 SysLog(NID_APP, "Selected path key is already registered.");
810                                 continue;
811                         }
812                 }
813
814                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
815                 if (pVal)
816                 {
817                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
818
819                         StringTokenizer strTok(*pVal, L';');
820                         if (strTok.GetTokenCount() == 0)
821                         {
822                                 list.Add(* new (std::nothrow) String(*pVal));
823                         }
824                         else
825                         {
826                                 String token;
827                                 while(strTok.HasMoreTokens())
828                                 {
829                                         strTok.GetNextToken(token);
830                                         list.Add(* new (std::nothrow) String(token));
831                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
832                                 }
833                         }
834                 }
835         }
836
837         return E_SUCCESS;
838 }
839
840
841 ArrayList*
842 _AppArg::GetListN(bundle* b, const char* key)
843 {
844         bundle* pb = b;
845         if (pb == null)
846         {
847                 return null;
848         }
849
850         const char** pValArray = null;
851         int len = 0;
852
853         pValArray = appsvc_get_data_array(b, key, &len);
854         if (len == 0 || pValArray == null)
855         {
856                 return null;
857         }
858
859         ArrayList* pList = new (std::nothrow) ArrayList;
860         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
861
862         pList->Construct();
863
864         for (int i = 0; i < len; i++)
865         {
866                 pList->Add(*new (std::nothrow) String(pValArray[i]));
867         }
868
869         return pList;
870 }
871
872
873 result
874 _AppArg::CreateLaunchArg(bundle* b, const String& arg)
875 {
876         SysAssertf(b != null, "Valid bundle should be supplied");
877
878         bundle* pb = b;
879
880         if (!arg.IsEmpty())
881         {
882                 const char** pSa = new (std::nothrow) const char*[1];
883                 SysTryReturnResult(NID_APP, pSa != null, E_OUT_OF_MEMORY, "Insufficient memory.");
884                 pSa[0] = _StringConverter::CopyToCharArrayN(arg);
885                 bundle_add_str_array(pb, OSP_K_ARG, pSa, 1);
886
887                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pSa[0]);
888
889                 delete[] pSa[0];
890                 delete[] pSa;
891         }
892
893         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
894
895         return E_SUCCESS;
896 }
897
898
899 result
900 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
901 {
902         SysAssertf(b != null, "Valid bundle should be supplied");
903
904         bundle* pb = b;
905
906         AddStrArray(pb, OSP_K_ARG, pList);
907
908         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
909
910         return E_SUCCESS;
911 }
912
913
914 result
915 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
916 {
917         SysAssertf(b != null, "Valid bundle should be supplied");
918         SysLog(NID_APP, "");
919
920         bundle* pb = b;
921
922         AddStrArray(pb, OSP_K_ARG, pList);
923
924         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
925         if (p)
926         {
927                 bundle_add(pb, OSP_K_COND, p.get());
928         }
929
930         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
931
932         return E_SUCCESS;
933 }
934
935
936 result
937 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const IList* pList)
938 {
939         SysAssertf(b != null, "Valid bundle should be supplied");
940
941         bundle* pb = b;
942
943         AddStrArray(pb, OSP_K_ARG, pList);
944
945         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
946         if (pOperation)
947         {
948                 appsvc_set_operation(pb, pOperation.get());
949         }
950
951         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
952
953         return E_SUCCESS;
954 }
955
956
957 result
958 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const String* pUriData, const String* pMimeType, const IMap* pMap)
959 {
960         return CreateAppControlArg(b, ac._opId, pUriData, pMimeType, pMap);
961 }
962
963
964 result
965 _AppArg::CreateAppControlArg(bundle* b, const String& oId, const String* pUriData, const String* pMimeType, const IMap* pMap)
966 {
967         SysAssertf(b != null, "Valid bundle should be supplied");
968
969         bundle* pb = b;
970
971         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(oId));
972         if (pOperation.get())
973         {
974                 appsvc_set_operation(pb, pOperation.get());
975         }
976
977         if (pUriData)
978         {
979                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
980                 if (pUri.get())
981                 {
982                         appsvc_set_uri(pb, pUri.get());
983                 }
984         }
985
986         if (pMimeType)
987         {
988                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
989                 if (pMime.get())
990                 {
991                         appsvc_set_mime(pb, pMime.get());
992                 }
993         }
994
995         AddStrMap(pb, pMap);
996
997         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
998
999         return E_SUCCESS;
1000 }
1001
1002
1003 namespace
1004 {
1005 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
1006 }
1007 result
1008 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
1009                                                                  const IList* pArgList)
1010 {
1011         SysAssertf(b != null, "Valid bundle should be supplied");
1012
1013         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1014
1015         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1016         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
1017         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1018         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
1019         bundle_add(b, AUL_K_NO_CANCEL, "1");
1020
1021         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1022         if (pProvider)
1023         {
1024                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1025         }
1026
1027         AddStrArray(b, OSP_K_ARG, pArgList);
1028
1029         return E_SUCCESS;
1030 }
1031
1032
1033 result
1034 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
1035                                                                  const IList* pArgList)
1036 {
1037         SysAssertf(b != null, "Valid bundle should be supplied");
1038
1039         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1040
1041         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1042         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
1043         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1044         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
1045         bundle_add(b, AUL_K_NO_CANCEL, "1");
1046
1047         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1048         if (pProvider)
1049         {
1050                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1051         }
1052
1053         AddStrArray(b, OSP_K_ARG, pArgList);
1054
1055         return E_SUCCESS;
1056 }
1057
1058
1059 result
1060 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1061 {
1062         SysAssertf(b != null, "Valid bundle should be supplied");
1063
1064         bundle* pb = b;
1065
1066         AddStrArray(pb, OSP_K_ARG, pList);
1067
1068         _AppMessageImpl::AddData(pb, pList);
1069
1070         return E_SUCCESS;
1071 }
1072
1073
1074 result
1075 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1076 {
1077         SysAssertf(b != null, "Valid bundle should be supplied");
1078
1079         bundle* pb = b;
1080
1081         AddStrMap(pb, pMap);
1082
1083         return E_SUCCESS;
1084 }
1085
1086
1087 bundle*
1088 _AppArg::CreateBundleFromSvc(void* svc)
1089 {
1090         bundle* pBundle = GetBundleFromSvc(svc);
1091         if (pBundle)
1092         {
1093                 return bundle_dup(pBundle);
1094         }
1095
1096         return null;
1097 }
1098
1099
1100 bundle*
1101 _AppArg::GetBundleFromSvc(void* svc)
1102 {
1103         struct DummyS
1104         {
1105                 int dummy1;
1106                 int dummy2;
1107                 bundle* pData;
1108         };
1109
1110         DummyS* pDummy = static_cast<DummyS*>(svc);
1111
1112         if (pDummy && pDummy->pData)
1113         {
1114                 return pDummy->pData;
1115         }
1116
1117         return NULL;
1118 }
1119
1120
1121 String
1122 _AppArg::GetRequestId(int num)
1123 {
1124         String str;
1125         str.Format(10, L"req%05d", num);
1126         return str;
1127 }
1128
1129
1130 int
1131 _AppArg::GetRequestId(const String& str)
1132 {
1133         int i = 0;
1134         String sub;
1135
1136         result r = str.SubString(3, sub);
1137         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1138
1139         r = Integer::Parse(sub, i);
1140         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1141
1142         return i;
1143 }
1144
1145
1146 void
1147 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1148 {
1149         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1150
1151         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1152         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1153
1154         int res = bundle_add(b, OSP_K_APPID, pId.get());
1155         if (res < 0 && errno == EPERM) // key exists
1156         {
1157                 bundle_del(b, OSP_K_APPID);
1158                 bundle_add(b, OSP_K_APPID, pId.get());
1159         }
1160
1161         appsvc_set_appid(b, pId.get());
1162 }
1163
1164
1165 void
1166 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1167 {
1168         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1169
1170         if (reqId < 0)
1171         {
1172                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1173                 return;
1174         }
1175
1176         char buffer[32] = {0, };
1177         snprintf(buffer, 32, "%d", reqId);
1178         int res = bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1179         if (res < 0 && errno == EPERM) // key exists
1180         {
1181                 bundle_del(pBundle, OSP_K_REQUEST_ID);
1182                 bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1183         }
1184 }
1185
1186 void
1187 _AppArg::UpdateKeyValue(bundle* pBundle, const char* pKey, const String& value)
1188 {
1189         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1190
1191         char pBuffer[128] = {0, };
1192         snprintf(pBuffer, 128, "%ls", value.GetPointer());
1193         int res = bundle_add(pBundle, pKey, pBuffer);
1194         if (res < 0 && errno == EPERM) // key exists
1195         {
1196                 bundle_del(pBundle, pKey);
1197                 bundle_add(pBundle, pKey, pBuffer);
1198         }
1199 }
1200
1201 int
1202 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1203 {
1204         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1205         if (p == NULL)
1206         {
1207                 return -1;
1208         }
1209
1210         int i = atoi(p);
1211         return (i < 0) ? -1 : i;
1212 }
1213
1214
1215 result
1216 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1217 {
1218         appsvc_allow_transient_app(pBundle, handle);
1219
1220         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1221
1222         return E_SUCCESS;
1223 }
1224
1225
1226 void
1227 _AppArg::PrintSvcHandle(void* svc)
1228 {
1229         service_h service = static_cast<service_h>(svc);
1230
1231         if (service == null)
1232         {
1233                 return;
1234         }
1235
1236         Print(GetBundleFromSvc(service));
1237 }
1238
1239
1240 static void
1241 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1242 {
1243         if (pKey && pVal)
1244         {
1245                 size_t size = 0;
1246                 char* pStr = NULL;
1247                 switch (type)
1248                 {
1249                 case BUNDLE_TYPE_STR:
1250                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1251                         if (pStr)
1252                         {
1253                                 SysSecureLog(NID_APP, "(%s, %s)", pKey, pStr);
1254                         }
1255                         break;
1256                 default:
1257                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1258                         break;
1259                 }
1260         }
1261 }
1262
1263 void
1264 _AppArg::Print(bundle* b)
1265 {
1266         if (b == null)
1267         {
1268                 return;
1269         }
1270
1271         const char* p = null;
1272         p = appsvc_get_data(b, AUL_K_CALLER_PID);
1273         if (p)
1274         {
1275                 SysLog(NID_APP, "CallerPId[%s]", p);
1276         }
1277
1278         p = appsvc_get_data(b, AUL_K_WAIT_RESULT);
1279         if (p)
1280         {
1281                 SysLog(NID_APP, "WaitResult[%s]", p);
1282         }
1283
1284         p = appsvc_get_data(b, OSP_K_COND);
1285         if (p)
1286         {
1287                 SysLog(NID_APP, "Condition[%s]", p);
1288         }
1289
1290         p = appsvc_get_operation(b);
1291         if (p)
1292         {
1293                 SysLog(NID_APP, "operation[%s]", p);
1294         }
1295
1296         p = appsvc_get_uri(b);
1297         if (p)
1298         {
1299                 SysLog(NID_APP, "uri[%s]", p);
1300         }
1301
1302         p = appsvc_get_mime(b);
1303         if (p)
1304         {
1305                 SysLog(NID_APP, "mime[%s]", p);
1306         }
1307
1308         p = appsvc_get_category(b);
1309         if (p)
1310         {
1311                 SysLog(NID_APP, "Category[%s]", p);
1312         }
1313
1314         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1315
1316         int len = 0;
1317         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1318         if (pa)
1319         {
1320                 for (int i = 0; i < len; i++)
1321                 {
1322                         if (pa[i])
1323                         {
1324                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1325                         }
1326                 }
1327         }
1328 }
1329
1330 } } // Tizen::App