Merge "GetnMenuIconPathN() is updated." into tizen_2.1
[platform/framework/native/appfw.git] / src / app / FApp_AppArg.cpp
1 //
2 // Open Service Platform
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     FApp_AppArg.cpp
20 * @brief        This is the implementation for the _AppArg.cpp class.
21 */
22
23 #include <cstdio>
24 #include <cstdlib>
25 #include <vector>
26 #include <new>
27 #include <typeinfo>
28 #include <unique_ptr.h>
29
30 #include <aul.h>
31 #include <app.h>
32 #include <appsvc/appsvc.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 "FAppPkg_PackageManagerImpl.h"
49
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::Base::Utility;
53 using namespace Tizen::App::Package;
54
55 namespace Tizen { namespace App
56 {
57
58 static const char OSP_V_LAUNCH_TYPE_LAUNCH[] = "launch";
59 static const char OSP_V_LAUNCH_TYPE_APPCONTROL[] = "appcontrol";
60 static const char OSP_V_LAUNCH_TYPE_DATACONTROL[] = "datacontrol";
61 static const char OSP_V_LAUNCH_TYPE_CONDTION[] = "condition";
62 static const char OSP_V_REQUEST_TYPE_SQL_QUERY[] = "sql_query";
63 static const char OSP_V_REQUEST_TYPE_SQL_INSERT[] = "sql_insert";
64 static const char OSP_V_REQUEST_TYPE_SQL_UPDATE[] = "sql_update";
65 static const char OSP_V_REQUEST_TYPE_SQL_DELETE[] = "sql_delete";
66 static const char OSP_V_REQUEST_TYPE_MAP_QEURY[] = "map_query";
67 static const char OSP_V_REQUEST_TYPE_MAP_INSERT[] = "map_insert";
68 static const char OSP_V_REQUEST_TYPE_MAP_UPDATE[] = "map_update";
69 static const char OSP_V_REQUEST_TYPE_MAP_DELETE[] = "map_delete";
70 static const char BUNDLE_KEY_WINDOW[] = "__APP_SVC_K_WIN_ID__";
71 static const char BUNDLE_KEY_PREFIX_AUL[] = "__AUL_";
72 static const char BUNDLE_KEY_PREFIX_SERVICE[] = "__APP_SVC_";
73 static const char BUNDLE_KEY_PREFIX_OSP[] = "__OSP_";
74 const char TIZEN_NOTIFICATION_DATA[] = "http://tizen.org/appcontrol/data/notification";
75
76 static const char SAMSUNG_ACCOUNT_KEY_CLIENT_ID[] = "client_id";
77 static const char SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET[] = "client_secret";
78 static const char SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY[] = "service_category";
79
80 static const char SMS_KEY_SERVICE_CALLER[] = "service_caller";
81 static const char SMS_KEY_SERVICE_DATA[] = "service_data";
82
83
84 _AppArg::_AppArg(void)
85         : __pBundle(null)
86 {
87 }
88
89
90 _AppArg::~_AppArg(void)
91 {
92         if (__pBundle)
93         {
94                 bundle_free(__pBundle);
95         }
96 }
97
98
99 result
100 _AppArg::Construct(const String& argText)
101 {
102         __pBundle = bundle_create();
103         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
104
105         return CreateLaunchArg(__pBundle, argText);
106 }
107
108
109 result
110 _AppArg::Construct(const IList* pList)
111 {
112         __pBundle = bundle_create();
113         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
114
115         return CreateLaunchArg(__pBundle, pList);
116 }
117
118
119 result
120 _AppArg::Construct(const _AppControlImpl& ac, const IList* pList)
121 {
122         __pBundle = bundle_create();
123         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
124
125         return CreateAppControlArg(__pBundle, ac, pList);
126 }
127
128
129 result
130 _AppArg::Construct(const _AppControlImpl& ac, const String* pUri, const String* pMime, const IMap* pList)
131 {
132         __pBundle = bundle_create();
133         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
134
135         return CreateAppControlArg(__pBundle, ac, pUri, pMime, pList);
136 }
137
138
139 result
140 _AppArg::Construct(const _SqlDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
141 {
142         __pBundle = bundle_create();
143         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
144
145         return CreateSqlDataControlArg(__pBundle, dc, requestType, pList);
146 }
147
148
149 result
150 _AppArg::Construct(const _MapDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
151 {
152         __pBundle = bundle_create();
153         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
154
155         return CreateMapDataControlArg(__pBundle, dc, requestType, pList);
156 }
157
158
159 result
160 _AppArg::ConstructResult(const _AppArg& arg, const IList* pList)
161 {
162         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
163         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
164
165         return CreateResultArg(__pBundle, pList);
166 }
167
168
169 result
170 _AppArg::ConstructResult(const _AppArg& arg, const IMap* pMap)
171 {
172         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
173         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
174
175         return CreateResultArg(__pBundle, pMap);
176 }
177
178
179 result
180 _AppArg::Construct(bundle* b)
181 {
182         __pBundle = bundle_dup(b);
183         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure.");
184
185         return E_SUCCESS;
186 }
187
188
189 result
190 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList)
191 {
192         __pBundle = bundle_create();
193         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
194
195         return CreateAppLaunchConditionArg(__pBundle, condition, pList);
196 }
197
198 result
199 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList, const IMap* pMap)
200 {
201         __pBundle = bundle_create();
202         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
203
204         CreateAppLaunchConditionArg(__pBundle, condition, pList);
205
206         return CreateResultArg(__pBundle, pMap);
207 }
208
209 ArrayList*
210 _AppArg::GetArgListN(int num) const
211 {
212         bundle* pBundle = __pBundle;
213         SysTryReturn(NID_APP, pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
214
215         ArrayList* pList = new (std::nothrow) ArrayList();
216         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
217
218         pList->Construct();
219
220         const char* p = NULL;
221         _AppHandler launch_type = GetHandler(pBundle);
222
223         switch (launch_type)
224         {
225         case _APP_HANDLER_APPCONTROL:
226                 // request Id
227                 // [FIXME] proper request Id required
228                 pList->Add(*new (std::nothrow) String(GetRequestId(num)));
229
230                 // category
231                 p = appsvc_get_category(pBundle);
232                 if (p)
233                 {
234                         pList->Add(*new (std::nothrow) String(p));
235                 }
236                 else
237                 {
238                         pList->Add(*new (std::nothrow) String(L""));
239                 }
240
241                 // MIME type
242                 p = appsvc_get_mime(pBundle);
243                 if (p)
244                 {
245                         pList->Add(*new (std::nothrow) String(p));
246                 }
247                 else
248                 {
249                         pList->Add(*new (std::nothrow) String(L""));
250                 }
251
252                 // URI scheme
253                 p = appsvc_get_uri(pBundle);
254                 if (p)
255                 {
256                         pList->Add(*new (std::nothrow) String(p));
257                 }
258                 else
259                 {
260                         pList->Add(*new (std::nothrow) String(L""));
261                 }
262
263                 break;
264
265         case _APP_HANDLER_DATACONTROL:
266                 // appId
267                 AddListFromBundle(pList, pBundle, OSP_K_APPID);
268                 // request type
269                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
270                 // reqId
271                 AddListFromBundle(pList, pBundle, OSP_K_REQUEST_ID);
272                 // providerId
273                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_PROVIDER);
274                 break;
275
276         case _APP_HANDLER_LAUNCH_COND:
277                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_CONDITIONAL));
278                 AddListFromBundle(pList, pBundle, OSP_K_COND);
279                 break;
280
281         case _APP_HANDLER_LAUNCH_NORMAL:
282                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_NORMAL));
283                 pList->Add(*new (std::nothrow) String(L"osp.operation.MAIN"));
284                 break;
285
286         default:
287                 SysLog(NID_APP, "Invalid handler type");
288                 break;
289         }
290
291         SetArgList(__pBundle, pList);
292
293         return pList;
294 }
295
296
297 ArrayList*
298 _AppArg::GetArgListN(void) const
299 {
300         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
301
302         ArrayList* pList = new (std::nothrow) ArrayList();
303         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
304
305         pList->Construct();
306
307         SetArgList(__pBundle, pList);
308
309         return pList;
310 }
311
312 // the returned map is allocated using SingleObjectDeleter
313 HashMap*
314 _AppArg::GetArgMapN(void) const
315 {
316         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
317
318         HashMap* pHashMap = new (std::nothrow) HashMap(SingleObjectDeleter);
319         SysTryReturn(NID_APP, pHashMap != null, null, E_OUT_OF_MEMORY, "HashMap creation failure.");
320
321         pHashMap->Construct();
322
323         SetArgMap(__pBundle, pHashMap);
324
325         if (pHashMap->GetCount() == 0)
326         {
327                 delete pHashMap;
328                 return null;
329         }
330
331         ArrayList* pList = _AppMessageImpl::GetValueArray(__pBundle, OSP_K_ARG);
332         if (pList)
333         {
334                 pHashMap->Add(new (std::nothrow) String(TIZEN_APPCONTROL_DATA_LEGACY), pList);
335         }
336         return pHashMap;
337 }
338
339 static bool
340 IsInternalKey(const char* pKey)
341 {
342         if (strncmp(BUNDLE_KEY_PREFIX_AUL, pKey, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
343         {
344                 return true;
345         }
346
347         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, pKey, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
348         {
349                 return true;
350         }
351
352         if (strncmp(BUNDLE_KEY_PREFIX_OSP, pKey, strlen(BUNDLE_KEY_PREFIX_OSP)) == 0)
353         {
354                 return true;
355         }
356
357         return false;
358 }
359
360 static void
361 BundleIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
362 {
363         HashMap* pMap = static_cast<HashMap*>(pData);
364
365         if (pKey && pVal && pMap)
366         {
367                 if (IsInternalKey(pKey))
368                 {
369                         //SysLog(NID_APP, "(%s)", pKey);
370                         return;
371                 }
372
373                 size_t size = 0;
374                 char* pStr = NULL;
375                 switch (type)
376                 {
377                 case BUNDLE_TYPE_STR:
378                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
379                         if (pStr)
380                         {
381                                 pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(pStr));
382                         }
383                         break;
384                 case BUNDLE_TYPE_STR_ARRAY:
385                         {
386                                 void** pArr = NULL;
387                                 bundle_keyval_get_array_val(const_cast<bundle_keyval_t*>(pVal), &pArr, &size, NULL);
388                                 if (pArr && size > 0)
389                                 {
390                                         ArrayList* pList = new (std::nothrow) ArrayList(SingleObjectDeleter);
391                                         if (pList)
392                                         {
393                                                 pList->Construct();
394
395                                                 for (size_t i = 0; i < size; i++)
396                                                 {
397                                                         // type unsafe ugly static casting required
398                                                         pList->Add(new (std::nothrow) String(static_cast<char*>(*(pArr + i))));
399                                                 }
400
401                                                 const int count = pList->GetCount();
402                                                 if (count != 0)
403                                                 {
404                                                         SysLog(NID_APP, "Adding %d elements for %s", count, pKey);
405                                                         pMap->Add(new (std::nothrow) String(pKey), pList);
406                                                 }
407                                                 else
408                                                 {
409                                                         SysLog(NID_APP, "No object for %s", pKey);
410                                                         delete pList;
411                                                 }
412                                         }
413                                 }
414                                 else
415                                 {
416                                         SysLog(NID_APP, "No entry for str array %s(%d)", pKey, size);
417                                 }
418                         }
419                         break;
420                 default:
421                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
422                         break;
423                 }
424         }
425 }
426
427 result
428 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
429 {
430         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
431
432         return E_SUCCESS;
433 }
434
435 result
436 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
437 {
438         // actual argument below
439         int len = 0;
440         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
441         if (pa)
442         {
443                 for (int i = 0; i < len; i++)
444                 {
445                         if (pa[i])
446                         {
447                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
448                                 pList->Add(*new (std::nothrow) String(pa[i]));
449                         }
450                 }
451         }
452
453         const char* p = appsvc_get_uri(pBundle);
454         if (p)
455         {
456                 pList->Add(*new (std::nothrow) String(p));
457                 SysLog(NID_APP, "argument is %s", p);
458         }
459
460         String tmp;
461         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_CALLER);
462         if (p)
463         {
464                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_CALLER, p);
465                 pList->Add(*new (std::nothrow) String(tmp));
466                 SysLog(NID_APP, "service_caller is %s", p);
467         }
468         
469         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_DATA);
470         if (p)
471         {
472                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_DATA, p);
473                 pList->Add(*new (std::nothrow) String(tmp));
474                 SysLog(NID_APP, "service_data is set");
475         }
476         
477         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_ID);
478         if (p)
479         {
480                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_ID, p);
481                 pList->Add(*new (std::nothrow) String(tmp));
482                 SysLog(NID_APP, "client_id is %s", p);
483         }
484         
485         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET);
486         if (p)
487         {
488                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET, p);
489                 pList->Add(*new (std::nothrow) String(tmp));
490                 SysLog(NID_APP, "client_secret is %s", p);
491         }
492
493         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY);
494         if (p)
495         {
496                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY, p);
497                 pList->Add(*new (std::nothrow) String(tmp));
498                 SysLog(NID_APP, "service_category is %s", p);
499         }
500
501         return E_SUCCESS;
502 }
503
504
505 String
506 _AppArg::GetValue(const char* key) const
507 {
508         const char* p = appsvc_get_data(__pBundle, key);
509         return String(p);
510 }
511
512
513 _AppHandler
514 _AppArg::GetHandler(bundle* b)
515 {
516         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
517
518         const char* p = null;
519
520         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
521
522         if (p)
523         {
524                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
525                 {
526                         return _APP_HANDLER_DATACONTROL;
527                 }
528
529                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
530                 {
531                         SysLog(NID_APP, "Building AppControl arguments.");
532
533                         return _APP_HANDLER_APPCONTROL;
534                 }
535                 else
536                 {
537                         // not appcontrol nor datacontrol => normal launch or condlaunch
538                         p = appsvc_get_data(b, OSP_K_COND);
539                         if (p)
540                         {
541                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
542                                 return _APP_HANDLER_LAUNCH_COND;
543                         }
544                         else
545                         {
546                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
547                                 return _APP_HANDLER_LAUNCH_NORMAL;
548                         }
549                 }
550         }
551
552         // fallback
553         return _APP_HANDLER_APPCONTROL;
554 }
555
556
557 int
558 _AppArg::GetCallerPid(bundle* pBundle)
559 {
560         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
561         if (pBundleValue == NULL)
562         {
563                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
564         }
565
566         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
567
568         return atoi(pBundleValue);
569 }
570
571
572 AppId
573 _AppArg::GetCallerAppId(void) const
574 {
575         pid_t callerPid = GetCallerPid();
576         SysTryReturn(NID_APP, callerPid > 0, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Wrong process id: %d.", callerPid);
577
578         char appId[PATH_MAX] = {0, };
579         SysTryReturn(NID_APP, aul_app_get_appid_bypid(callerPid, appId, sizeof(appId)) == AUL_R_OK, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found for %d.", callerPid);
580
581         return String(appId);
582 }
583
584
585 AppId
586 _AppArg::GetCalleeAppId(void) const
587 {
588         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLEE_PID);
589
590         SysTryReturn(NID_APP, pBundleValue != null, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
591
592         pid_t calleePid = atoi(pBundleValue);
593         SysTryReturn(NID_APP, calleePid > 0, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Wrong process id: %d.", calleePid);
594
595         char appId[PATH_MAX] = {0, };
596         SysTryReturn(NID_APP, aul_app_get_appid_bypid(calleePid, appId, sizeof(appId)) == AUL_R_OK, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found for %d.", calleePid);
597
598         String temp;
599         String retVal = appId;
600         // [INFO] ugly code for submode callee
601         retVal.SubString(11, temp);
602         if (temp == L"_AppControl")
603         {
604                 String id;
605                 retVal.SubString(0, 10, id);
606                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(id);
607
608                 retVal = id + L'.' + name;
609                 SysLog(NID_APP, "Converted caller Id is %ls", retVal.GetPointer());
610         }
611
612         return retVal;
613 }
614
615
616 void
617 _AppArg::SaveCalleeAppId(void)
618 {
619         const AppId& appId = GetCalleeAppId();
620
621         std::unique_ptr<char[]> pVal(_StringConverter::CopyToCharArrayN(appId));
622
623         appsvc_add_data(__pBundle, OSP_K_CALLEE_APPID, pVal.get());
624 }
625
626
627 void
628 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
629 {
630         bundle* pBundle = bk;
631
632         const char* p = appsvc_get_data(pBundle, key);
633         if (p)
634         {
635                 pList->Add(*new (std::nothrow) String(p));
636         }
637         else
638         {
639                 pList->Add(*new (std::nothrow) String(L""));
640         }
641 }
642
643
644 result
645 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
646 {
647         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
648
649         return AddStrArray(b, pKey.get(), pList);
650 }
651
652
653 result
654 _AppArg::AddStrArray(bundle* pb, const char* key, const IList* pList)
655 {
656         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
657
658         if (pList == null || pList->GetCount() == 0)
659         {
660                 SysLog(NID_APP, "No element added for bundle.");
661                 return E_SUCCESS;
662         }
663
664         _AppMessageImpl::AddValueArray(pb, key, pList);
665
666         _AppMessageImpl::AddData(pb, pList);
667
668         return E_SUCCESS;
669 }
670
671
672 result
673 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
674 {
675         bundle* pb = b;
676         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
677
678         if (pMap == null || pMap->GetCount() == 0)
679         {
680                 SysLog(NID_APP, "No element added for bundle.");
681                 return E_SUCCESS;
682         }
683
684         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
685         while(pEnum->MoveNext() == E_SUCCESS)
686         {
687                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
688                 const Object* pObj = pEnum->GetValue();
689
690                 if (pKey && pObj)
691                 {
692                         if (typeid(*pObj) == typeid(const String))
693                         {
694                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
695                                 if (pVal)
696                                 {
697                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
698                                 }
699                         }
700                         else if (typeid(*pObj) == typeid(const ArrayList))
701                         {
702                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
703                                 if (pList)
704                                 {
705                                         SysLog(NID_APP, "ArrayList type");
706
707                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
708                                 }
709                         }
710                         else if (typeid(*pObj) == typeid(const ByteBuffer))
711                         {
712                                 SysLog(NID_APP, "ByteBuffer type");
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* pList)
959 {
960         SysAssertf(b != null, "Valid bundle should be supplied");
961
962         bundle* pb = b;
963
964         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
965         if (pOperation.get())
966         {
967                 appsvc_set_operation(pb, pOperation.get());
968         }
969
970         if (pUriData)
971         {
972                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
973                 if (pUri.get())
974                 {
975                         appsvc_set_uri(pb, pUri.get());
976                 }
977         }
978
979         if (pMimeType)
980         {
981                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
982                 if (pMime.get())
983                 {
984                         appsvc_set_mime(pb, pMime.get());
985                 }
986         }
987
988         AddStrMap(pb, pList);
989
990         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
991
992         return E_SUCCESS;
993 }
994
995
996 namespace
997 {
998 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
999 }
1000 result
1001 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
1002                                                                  const IList* pArgList)
1003 {
1004         SysAssertf(b != null, "Valid bundle should be supplied");
1005
1006         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1007
1008         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1009         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
1010         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1011
1012         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1013         if (pProvider)
1014         {
1015                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1016         }
1017
1018         AddStrArray(b, OSP_K_ARG, pArgList);
1019
1020         return E_SUCCESS;
1021 }
1022
1023
1024 result
1025 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
1026                                                                  const IList* pArgList)
1027 {
1028         SysAssertf(b != null, "Valid bundle should be supplied");
1029
1030         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1031
1032         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1033         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
1034         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1035
1036         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1037         if (pProvider)
1038         {
1039                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1040         }
1041
1042         AddStrArray(b, OSP_K_ARG, pArgList);
1043
1044         return E_SUCCESS;
1045 }
1046
1047
1048 result
1049 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1050 {
1051         SysAssertf(b != null, "Valid bundle should be supplied");
1052
1053         bundle* pb = b;
1054
1055         AddStrArray(pb, OSP_K_ARG, pList);
1056
1057         _AppMessageImpl::AddData(pb, pList);
1058
1059         return E_SUCCESS;
1060 }
1061
1062
1063 result
1064 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1065 {
1066         SysAssertf(b != null, "Valid bundle should be supplied");
1067
1068         bundle* pb = b;
1069
1070         AddStrMap(pb, pMap);
1071
1072         return E_SUCCESS;
1073 }
1074
1075
1076 bundle*
1077 _AppArg::CreateBundleFromSvc(void* svc)
1078 {
1079         bundle* pBundle = GetBundleFromSvc(svc);
1080         if (pBundle)
1081         {
1082                 return bundle_dup(pBundle);
1083         }
1084
1085         return null;
1086 }
1087
1088
1089 bundle*
1090 _AppArg::GetBundleFromSvc(void* svc)
1091 {
1092         struct DummyS
1093         {
1094                 int dummy1;
1095                 int dummy2;
1096                 bundle* pData;
1097         };
1098
1099         DummyS* pDummy = static_cast<DummyS*>(svc);
1100
1101         if (pDummy && pDummy->pData)
1102         {
1103                 return pDummy->pData;
1104         }
1105
1106         return NULL;
1107 }
1108
1109
1110 String
1111 _AppArg::GetRequestId(int num)
1112 {
1113         String str;
1114         str.Format(10, L"req%05d", num);
1115         return str;
1116 }
1117
1118
1119 int
1120 _AppArg::GetRequestId(const String& str)
1121 {
1122         int i = 0;
1123         String sub;
1124
1125         result r = str.SubString(3, sub);
1126         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1127
1128         r = Integer::Parse(sub, i);
1129         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1130
1131         return i;
1132 }
1133
1134
1135 void
1136 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1137 {
1138         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1139
1140         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1141         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1142
1143         bundle_add(b, OSP_K_APPID, pId.get());
1144
1145         appsvc_set_appid(b, pId.get());
1146 }
1147
1148
1149 void
1150 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1151 {
1152         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1153
1154         if (reqId < 0)
1155         {
1156                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1157                 return;
1158         }
1159
1160         char buffer[32] = {0, };
1161         snprintf(buffer, 32, "%d", reqId);
1162         bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1163 }
1164
1165
1166 int
1167 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1168 {
1169         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1170         if (p == NULL)
1171         {
1172                 return -1;
1173         }
1174
1175         int i = atoi(p);
1176         return (i < 0) ? -1 : i;
1177 }
1178
1179
1180 result
1181 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1182 {
1183         if (handle == -1)
1184         {
1185                 SysLog(NID_APP, "Invalid window handle.");
1186                 return E_SUCCESS;
1187         }
1188
1189         char handleName[32] = {0, };
1190         snprintf(handleName, 32, "%ld", handle);
1191
1192         bundle_add(pBundle, BUNDLE_KEY_WINDOW, handleName);
1193         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1194
1195         return E_SUCCESS;
1196 }
1197
1198
1199 void
1200 _AppArg::PrintSvcHandle(void* svc)
1201 {
1202         service_h service = static_cast<service_h>(svc);
1203
1204         if (service == null)
1205         {
1206                 return;
1207         }
1208
1209         Print(GetBundleFromSvc(service));
1210 }
1211
1212
1213 static void
1214 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1215 {
1216         if (pKey && pVal)
1217         {
1218                 size_t size = 0;
1219                 char* pStr = NULL;
1220                 switch (type)
1221                 {
1222                 case BUNDLE_TYPE_STR:
1223                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1224                         if (pStr)
1225                         {
1226                                 SysLog(NID_APP, "(%s, %s)", pKey, pStr);
1227                         }
1228                         break;
1229                 default:
1230                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1231                         break;
1232                 }
1233         }
1234 }
1235
1236 void
1237 _AppArg::Print(bundle* b)
1238 {
1239         if (b == null)
1240         {
1241                 return;
1242         }
1243
1244         const char* p = null;
1245         p = appsvc_get_data(b, AUL_K_CALLER_PID);
1246         if (p)
1247         {
1248                 SysLog(NID_APP, "CallerPId[%s]", p);
1249         }
1250
1251         p = appsvc_get_data(b, AUL_K_WAIT_RESULT);
1252         if (p)
1253         {
1254                 SysLog(NID_APP, "WaitResult[%s]", p);
1255         }
1256
1257         p = appsvc_get_data(b, OSP_K_COND);
1258         if (p)
1259         {
1260                 SysLog(NID_APP, "Condition[%s]", p);
1261         }
1262
1263         p = appsvc_get_operation(b);
1264         if (p)
1265         {
1266                 SysLog(NID_APP, "operation[%s]", p);
1267         }
1268
1269         p = appsvc_get_uri(b);
1270         if (p)
1271         {
1272                 SysLog(NID_APP, "uri[%s]", p);
1273         }
1274
1275         p = appsvc_get_mime(b);
1276         if (p)
1277         {
1278                 SysLog(NID_APP, "mime[%s]", p);
1279         }
1280
1281         p = appsvc_get_category(b);
1282         if (p)
1283         {
1284                 SysLog(NID_APP, "Category[%s]", p);
1285         }
1286
1287         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1288
1289         int len = 0;
1290         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1291         if (pa)
1292         {
1293                 for (int i = 0; i < len; i++)
1294                 {
1295                         if (pa[i])
1296                         {
1297                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1298                         }
1299                 }
1300         }
1301 }
1302
1303 } } // Tizen::App