sync with master
[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                                         String str = static_cast<char*>(*pArr);
391                                         for (size_t i = 1; i < size; i++)
392                                         {
393                                                 str += L';';
394                                                 str += static_cast<char*>(*(pArr + i));
395                                         }
396
397                                         SysLog(NID_APP, "(%s, %ls)", pKey, str.GetPointer());
398                                         pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(str));
399                                 }
400                                 else
401                                 {
402                                         SysLog(NID_APP, "No entry for str array %s(%d)", pKey, size);
403                                 }
404                         }
405                         break;
406                 default:
407                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
408                         break;
409                 }
410         }
411 }
412
413 result
414 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
415 {
416         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
417
418         return E_SUCCESS;
419 }
420
421 result
422 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
423 {
424         // actual argument below
425         int len = 0;
426         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
427         if (pa)
428         {
429                 for (int i = 0; i < len; i++)
430                 {
431                         if (pa[i])
432                         {
433                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
434                                 pList->Add(*new (std::nothrow) String(pa[i]));
435                         }
436                 }
437         }
438
439         const char* p = appsvc_get_uri(pBundle);
440         if (p)
441         {
442                 pList->Add(*new (std::nothrow) String(p));
443                 SysLog(NID_APP, "argument is %s", p);
444         }
445
446         String tmp;
447         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_CALLER);
448         if (p)
449         {
450                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_CALLER, p);
451                 pList->Add(*new (std::nothrow) String(tmp));
452                 SysLog(NID_APP, "service_caller is %s", p);
453         }
454         
455         p = appsvc_get_data(pBundle, SMS_KEY_SERVICE_DATA);
456         if (p)
457         {
458                 tmp.Format(60, L"%s:%s", SMS_KEY_SERVICE_DATA, p);
459                 pList->Add(*new (std::nothrow) String(tmp));
460                 SysLog(NID_APP, "service_data is set");
461         }
462         
463         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_ID);
464         if (p)
465         {
466                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_ID, p);
467                 pList->Add(*new (std::nothrow) String(tmp));
468                 SysLog(NID_APP, "client_id is %s", p);
469         }
470         
471         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET);
472         if (p)
473         {
474                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_CLIENT_SECRET, p);
475                 pList->Add(*new (std::nothrow) String(tmp));
476                 SysLog(NID_APP, "client_secret is %s", p);
477         }
478
479         p = appsvc_get_data(pBundle, SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY);
480         if (p)
481         {
482                 tmp.Format(60, L"%s:%s", SAMSUNG_ACCOUNT_KEY_SERVICE_CATEGORY, p);
483                 pList->Add(*new (std::nothrow) String(tmp));
484                 SysLog(NID_APP, "service_category is %s", p);
485         }
486
487         return E_SUCCESS;
488 }
489
490
491 String
492 _AppArg::GetValue(const char* key) const
493 {
494         const char* p = appsvc_get_data(__pBundle, key);
495         return String(p);
496 }
497
498
499 _AppHandler
500 _AppArg::GetHandler(bundle* b)
501 {
502         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
503
504         const char* p = null;
505
506         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
507
508         if (p)
509         {
510                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
511                 {
512                         return _APP_HANDLER_DATACONTROL;
513                 }
514
515                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
516                 {
517                         SysLog(NID_APP, "Building AppControl arguments.");
518
519                         return _APP_HANDLER_APPCONTROL;
520                 }
521                 else
522                 {
523                         // not appcontrol nor datacontrol => normal launch or condlaunch
524                         p = appsvc_get_data(b, OSP_K_COND);
525                         if (p)
526                         {
527                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
528                                 return _APP_HANDLER_LAUNCH_COND;
529                         }
530                         else
531                         {
532                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
533                                 return _APP_HANDLER_LAUNCH_NORMAL;
534                         }
535                 }
536         }
537
538         // fallback
539         return _APP_HANDLER_APPCONTROL;
540 }
541
542
543 int
544 _AppArg::GetCallerPid(bundle* pBundle)
545 {
546         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
547         if (pBundleValue == NULL)
548         {
549                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
550         }
551
552         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
553
554         return atoi(pBundleValue);
555 }
556
557
558 AppId
559 _AppArg::GetCallerAppId(void) const
560 {
561         pid_t callerPid = GetCallerPid();
562         SysTryReturn(NID_APP, callerPid > 0, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Wrong process id: %d.", callerPid);
563
564         char appId[PATH_MAX] = {0, };
565         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);
566
567         return String(appId);
568 }
569
570
571 AppId
572 _AppArg::GetCalleeAppId(void) const
573 {
574         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLEE_PID);
575
576         SysTryReturn(NID_APP, pBundleValue != null, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
577
578         pid_t calleePid = atoi(pBundleValue);
579         SysTryReturn(NID_APP, calleePid > 0, L"", E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Wrong process id: %d.", calleePid);
580
581         char appId[PATH_MAX] = {0, };
582         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);
583
584         String temp;
585         String retVal = appId;
586         // [INFO] ugly code for submode callee
587         retVal.SubString(11, temp);
588         if (temp == L"_AppControl")
589         {
590                 String id;
591                 retVal.SubString(0, 10, id);
592                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(id);
593
594                 retVal = id + L'.' + name;
595                 SysLog(NID_APP, "Converted caller Id is %ls", retVal.GetPointer());
596         }
597
598         return retVal;
599 }
600
601
602 void
603 _AppArg::SaveCalleeAppId(void)
604 {
605         const AppId& appId = GetCalleeAppId();
606
607         std::unique_ptr<char[]> pVal(_StringConverter::CopyToCharArrayN(appId));
608
609         appsvc_add_data(__pBundle, OSP_K_CALLEE_APPID, pVal.get());
610 }
611
612
613 void
614 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
615 {
616         bundle* pBundle = bk;
617
618         const char* p = appsvc_get_data(pBundle, key);
619         if (p)
620         {
621                 pList->Add(*new (std::nothrow) String(p));
622         }
623         else
624         {
625                 pList->Add(*new (std::nothrow) String(L""));
626         }
627 }
628
629
630 result
631 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
632 {
633         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
634
635         return AddStrArray(b, pKey.get(), pList);
636 }
637
638
639 result
640 _AppArg::AddStrArray(bundle* b, const char* key, const IList* pList)
641 {
642         bundle* pb = b;
643         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
644
645         if (pList == null || pList->GetCount() == 0)
646         {
647                 SysLog(NID_APP, "No element added for bundle.");
648                 return E_SUCCESS;
649         }
650
651         int i = 0;
652         const int count = pList->GetCount();
653
654         const char** pSa = new (std::nothrow) const char*[count];
655         SysTryReturnResult(NID_APP, pSa != null, E_OUT_OF_MEMORY, "Memory allocation failure with cound %d.", count);
656
657         for (i = 0; i < count; i++)
658         {
659                 pSa[i] = null;
660
661                 const String* pStr = static_cast<const String*>(pList->GetAt(i));
662                 if (pStr)
663                 {
664                         pSa[i] = _StringConverter::CopyToCharArrayN(*pStr);
665                 }
666         }
667
668         result r = E_SUCCESS;
669
670         int ret = bundle_add_str_array(pb, key, pSa, count);
671         if (ret >= 0)
672         {
673                 _AppMessageImpl::AddData(pb, pList);
674         }
675         else
676         {
677                 SysLog(NID_APP, "Bundle add failre :%d.", ret);
678                 r = E_SYSTEM;
679         }
680
681         _AppMessageImpl::AddData(pb, pList);
682
683 //CATCH:
684         for (i = 0; i < count; i++)
685         {
686                 delete[] pSa[i];
687         }
688
689         delete[] pSa;
690
691         return r;
692 }
693
694
695 result
696 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
697 {
698         bundle* pb = b;
699         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
700
701         if (pMap == null || pMap->GetCount() == 0)
702         {
703                 SysLog(NID_APP, "No element added for bundle.");
704                 return E_SUCCESS;
705         }
706
707         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
708         while(pEnum->MoveNext() == E_SUCCESS)
709         {
710                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
711                 const Object* pObj = pEnum->GetValue();
712
713                 if (pKey && pObj)
714                 {
715                         if (typeid(*pObj) == typeid(const String))
716                         {
717                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
718                                 if (pVal)
719                                 {
720                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
721                                 }
722                         }
723                         else if (typeid(*pObj) == typeid(const ArrayList))
724                         {
725                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
726                                 if (pList && *pKey == TIZEN_APPCONTROL_DATA_LEGACY)
727                                 {
728                                         SysLog(NID_APP, "Legacy AppControl argument");
729                                         _AppArg::AddStrArray(pb, OSP_K_ARG, pList);
730                                         _AppMessageImpl::AddData(pb, pList);
731                                 }
732                         }
733                         else if (typeid(*pObj) == typeid(const ByteBuffer))
734                         {
735                                 SysLog(NID_APP, "ByteBuffer type");
736                         }
737                 }
738         }
739
740         return E_SUCCESS;
741 }
742
743
744 result
745 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
746 {
747         if (pMap == null || pList == null)
748         {
749                 return E_SUCCESS;
750         }
751
752         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
753         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
754
755         String key;
756         String value;
757         while (pEnum->MoveNext() == E_SUCCESS)
758         {
759                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
760
761                 int index = -1;
762                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
763                 {
764                         continue;
765                 }
766                 pStr->SubString(0, index, key);
767                 if (key.IsEmpty())
768                 {
769                         continue;
770                 }
771
772                 pStr->SubString(index + 1, value);
773
774                 pMap->Add(new String(key), new String(value));
775
776                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
777         }
778
779         return E_SUCCESS;
780 }
781
782
783 result
784 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
785 {
786         switch (res)
787         {
788         case APP_CTRL_RESULT_SUCCEEDED:
789                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
790                 break;
791         case APP_CTRL_RESULT_CANCELED:
792                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
793                 return E_SUCCESS;
794         case APP_CTRL_RESULT_TERMINATED:
795                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
796                 return E_SUCCESS;
797         case APP_CTRL_RESULT_ABORTED:
798                 list.Add(* new (std::nothrow) String("aborted"));
799                 return E_SUCCESS;
800                 //case APP_CTRL_RESULT_FAILED:
801         default:
802                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
803                 return E_SUCCESS;
804         }
805
806         if (pArgs == null)
807         {
808                 return E_SUCCESS;
809         }
810
811         bool isPathRegistered = false;
812         // handle APP_CTRL_RESULT_SUCCEEDED only
813         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
814
815         while(pMapEnum->MoveNext() == E_SUCCESS)
816         {
817                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
818                 if (pKey == null)
819                 {
820                         SysLog(NID_APP, "Invalid entry.");
821                         continue;
822                 }
823
824                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
825                 {
826                         if (!isPathRegistered)
827                         {
828                                 isPathRegistered = true;
829                         }
830                         else
831                         {
832                                 SysLog(NID_APP, "Selected path key is already registered.");
833                                 continue;
834                         }
835                 }
836
837                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
838                 if (pVal)
839                 {
840                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
841
842                         StringTokenizer strTok(*pVal, L';');
843                         if (strTok.GetTokenCount() == 0)
844                         {
845                                 list.Add(* new (std::nothrow) String(*pVal));
846                         }
847                         else
848                         {
849                                 String token;
850                                 while(strTok.HasMoreTokens())
851                                 {
852                                         strTok.GetNextToken(token);
853                                         list.Add(* new (std::nothrow) String(token));
854                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
855                                 }
856                         }
857                 }
858         }
859
860         return E_SUCCESS;
861 }
862
863
864 ArrayList*
865 _AppArg::GetListN(bundle* b, const char* key)
866 {
867         bundle* pb = b;
868         if (pb == null)
869         {
870                 return null;
871         }
872
873         const char** pValArray = null;
874         int len = 0;
875
876         pValArray = appsvc_get_data_array(b, key, &len);
877         if (len == 0 || pValArray == null)
878         {
879                 return null;
880         }
881
882         ArrayList* pList = new (std::nothrow) ArrayList;
883         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
884
885         pList->Construct();
886
887         for (int i = 0; i < len; i++)
888         {
889                 pList->Add(*new (std::nothrow) String(pValArray[i]));
890         }
891
892         return pList;
893 }
894
895
896 result
897 _AppArg::CreateLaunchArg(bundle* b, const String& arg)
898 {
899         SysAssertf(b != null, "Valid bundle should be supplied");
900
901         bundle* pb = b;
902
903         if (!arg.IsEmpty())
904         {
905                 const char** pSa = new (std::nothrow) const char*[1];
906                 SysTryReturnResult(NID_APP, pSa != null, E_OUT_OF_MEMORY, "Insufficient memory.");
907                 pSa[0] = _StringConverter::CopyToCharArrayN(arg);
908                 bundle_add_str_array(pb, OSP_K_ARG, pSa, 1);
909
910                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pSa[0]);
911
912                 delete[] pSa[0];
913                 delete[] pSa;
914         }
915
916         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
917
918         return E_SUCCESS;
919 }
920
921
922 result
923 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
924 {
925         SysAssertf(b != null, "Valid bundle should be supplied");
926
927         bundle* pb = b;
928
929         AddStrArray(pb, OSP_K_ARG, pList);
930
931         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
932
933         return E_SUCCESS;
934 }
935
936
937 result
938 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
939 {
940         SysAssertf(b != null, "Valid bundle should be supplied");
941         SysLog(NID_APP, "");
942
943         bundle* pb = b;
944
945         AddStrArray(pb, OSP_K_ARG, pList);
946
947         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
948         if (p)
949         {
950                 bundle_add(pb, OSP_K_COND, p.get());
951         }
952
953         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
954
955         return E_SUCCESS;
956 }
957
958
959 result
960 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const IList* pList)
961 {
962         SysAssertf(b != null, "Valid bundle should be supplied");
963
964         bundle* pb = b;
965
966         AddStrArray(pb, OSP_K_ARG, pList);
967
968         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
969         if (pOperation)
970         {
971                 appsvc_set_operation(pb, pOperation.get());
972         }
973
974         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
975
976         return E_SUCCESS;
977 }
978
979
980 result
981 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const String* pUriData, const String* pMimeType, const IMap* pList)
982 {
983         SysAssertf(b != null, "Valid bundle should be supplied");
984
985         bundle* pb = b;
986
987         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
988         if (pOperation.get())
989         {
990                 appsvc_set_operation(pb, pOperation.get());
991         }
992
993         if (pUriData)
994         {
995                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
996                 if (pUri.get())
997                 {
998                         appsvc_set_uri(pb, pUri.get());
999                 }
1000         }
1001
1002         if (pMimeType)
1003         {
1004                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
1005                 if (pMime.get())
1006                 {
1007                         appsvc_set_mime(pb, pMime.get());
1008                 }
1009         }
1010
1011         AddStrMap(pb, pList);
1012
1013         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
1014
1015         return E_SUCCESS;
1016 }
1017
1018
1019 namespace
1020 {
1021 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
1022 }
1023 result
1024 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
1025                                                                  const IList* pArgList)
1026 {
1027         SysAssertf(b != null, "Valid bundle should be supplied");
1028
1029         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1030
1031         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1032         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
1033         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1034
1035         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1036         if (pProvider)
1037         {
1038                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1039         }
1040
1041         AddStrArray(b, OSP_K_ARG, pArgList);
1042
1043         return E_SUCCESS;
1044 }
1045
1046
1047 result
1048 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
1049                                                                  const IList* pArgList)
1050 {
1051         SysAssertf(b != null, "Valid bundle should be supplied");
1052
1053         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1054
1055         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1056         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
1057         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1058
1059         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1060         if (pProvider)
1061         {
1062                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1063         }
1064
1065         AddStrArray(b, OSP_K_ARG, pArgList);
1066
1067         return E_SUCCESS;
1068 }
1069
1070
1071 result
1072 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1073 {
1074         SysAssertf(b != null, "Valid bundle should be supplied");
1075
1076         bundle* pb = b;
1077
1078         AddStrArray(pb, OSP_K_ARG, pList);
1079
1080         _AppMessageImpl::AddData(pb, pList);
1081
1082         return E_SUCCESS;
1083 }
1084
1085
1086 result
1087 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1088 {
1089         SysAssertf(b != null, "Valid bundle should be supplied");
1090
1091         bundle* pb = b;
1092
1093         AddStrMap(pb, pMap);
1094
1095         return E_SUCCESS;
1096 }
1097
1098
1099 bundle*
1100 _AppArg::CreateBundleFromSvc(void* svc)
1101 {
1102         bundle* pBundle = GetBundleFromSvc(svc);
1103         if (pBundle)
1104         {
1105                 return bundle_dup(pBundle);
1106         }
1107
1108         return null;
1109 }
1110
1111
1112 bundle*
1113 _AppArg::GetBundleFromSvc(void* svc)
1114 {
1115         struct DummyS
1116         {
1117                 int dummy1;
1118                 int dummy2;
1119                 bundle* pData;
1120         };
1121
1122         DummyS* pDummy = static_cast<DummyS*>(svc);
1123
1124         if (pDummy && pDummy->pData)
1125         {
1126                 return pDummy->pData;
1127         }
1128
1129         return NULL;
1130 }
1131
1132
1133 String
1134 _AppArg::GetRequestId(int num)
1135 {
1136         String str;
1137         str.Format(10, L"req%05d", num);
1138         return str;
1139 }
1140
1141
1142 int
1143 _AppArg::GetRequestId(const String& str)
1144 {
1145         int i = 0;
1146         String sub;
1147
1148         result r = str.SubString(3, sub);
1149         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1150
1151         r = Integer::Parse(sub, i);
1152         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1153
1154         return i;
1155 }
1156
1157
1158 void
1159 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1160 {
1161         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1162
1163         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1164         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1165
1166         bundle_add(b, OSP_K_APPID, pId.get());
1167
1168         appsvc_set_appid(b, pId.get());
1169 }
1170
1171
1172 void
1173 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1174 {
1175         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1176
1177         if (reqId < 0)
1178         {
1179                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1180                 return;
1181         }
1182
1183         char buffer[32] = {0, };
1184         snprintf(buffer, 32, "%d", reqId);
1185         bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1186 }
1187
1188
1189 int
1190 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1191 {
1192         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1193         if (p == NULL)
1194         {
1195                 return -1;
1196         }
1197
1198         int i = atoi(p);
1199         return (i < 0) ? -1 : i;
1200 }
1201
1202
1203 result
1204 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1205 {
1206         if (handle == -1)
1207         {
1208                 SysLog(NID_APP, "Invalid window handle.");
1209                 return E_SUCCESS;
1210         }
1211
1212         char handleName[32] = {0, };
1213         snprintf(handleName, 32, "%ld", handle);
1214
1215         bundle_add(pBundle, BUNDLE_KEY_WINDOW, handleName);
1216         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1217
1218         return E_SUCCESS;
1219 }
1220
1221
1222 void
1223 _AppArg::PrintSvcHandle(void* svc)
1224 {
1225         service_h service = static_cast<service_h>(svc);
1226
1227         if (service == null)
1228         {
1229                 return;
1230         }
1231
1232         Print(GetBundleFromSvc(service));
1233 }
1234
1235
1236 static void
1237 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1238 {
1239         if (pKey && pVal)
1240         {
1241                 size_t size = 0;
1242                 char* pStr = NULL;
1243                 switch (type)
1244                 {
1245                 case BUNDLE_TYPE_STR:
1246                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1247                         if (pStr)
1248                         {
1249                                 SysLog(NID_APP, "(%s, %s)", pKey, pStr);
1250                         }
1251                         break;
1252                 default:
1253                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1254                         break;
1255                 }
1256         }
1257 }
1258
1259 void
1260 _AppArg::Print(bundle* b)
1261 {
1262         if (b == null)
1263         {
1264                 return;
1265         }
1266
1267         const char* p = null;
1268         p = appsvc_get_data(b, AUL_K_CALLER_PID);
1269         if (p)
1270         {
1271                 SysLog(NID_APP, "CallerPId[%s]", p);
1272         }
1273
1274         p = appsvc_get_data(b, AUL_K_WAIT_RESULT);
1275         if (p)
1276         {
1277                 SysLog(NID_APP, "WaitResult[%s]", p);
1278         }
1279
1280         p = appsvc_get_data(b, OSP_K_COND);
1281         if (p)
1282         {
1283                 SysLog(NID_APP, "Condition[%s]", p);
1284         }
1285
1286         p = appsvc_get_operation(b);
1287         if (p)
1288         {
1289                 SysLog(NID_APP, "operation[%s]", p);
1290         }
1291
1292         p = appsvc_get_uri(b);
1293         if (p)
1294         {
1295                 SysLog(NID_APP, "uri[%s]", p);
1296         }
1297
1298         p = appsvc_get_mime(b);
1299         if (p)
1300         {
1301                 SysLog(NID_APP, "mime[%s]", p);
1302         }
1303
1304         p = appsvc_get_category(b);
1305         if (p)
1306         {
1307                 SysLog(NID_APP, "Category[%s]", p);
1308         }
1309
1310         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1311
1312         int len = 0;
1313         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1314         if (pa)
1315         {
1316                 for (int i = 0; i < len; i++)
1317                 {
1318                         if (pa[i])
1319                         {
1320                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1321                         }
1322                 }
1323         }
1324 }
1325
1326 } } // Tizen::App