Merge "Apply pkgs config for haptic" 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                                         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* pb, const char* key, const IList* pList)
641 {
642         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
643
644         if (pList == null || pList->GetCount() == 0)
645         {
646                 SysLog(NID_APP, "No element added for bundle.");
647                 return E_SUCCESS;
648         }
649
650         _AppMessageImpl::AddValueArray(pb, key, pList);
651
652         _AppMessageImpl::AddData(pb, pList);
653
654         return E_SUCCESS;
655 }
656
657
658 result
659 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
660 {
661         bundle* pb = b;
662         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
663
664         if (pMap == null || pMap->GetCount() == 0)
665         {
666                 SysLog(NID_APP, "No element added for bundle.");
667                 return E_SUCCESS;
668         }
669
670         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
671         while(pEnum->MoveNext() == E_SUCCESS)
672         {
673                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
674                 const Object* pObj = pEnum->GetValue();
675
676                 if (pKey && pObj)
677                 {
678                         if (typeid(*pObj) == typeid(const String))
679                         {
680                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
681                                 if (pVal)
682                                 {
683                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
684                                 }
685                         }
686                         else if (typeid(*pObj) == typeid(const ArrayList))
687                         {
688                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
689                                 if (pList)
690                                 {
691                                         SysLog(NID_APP, "ArrayList type");
692
693                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
694                                 }
695                         }
696                         else if (typeid(*pObj) == typeid(const ByteBuffer))
697                         {
698                                 SysLog(NID_APP, "ByteBuffer type");
699                         }
700                 }
701         }
702
703         return E_SUCCESS;
704 }
705
706
707 result
708 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
709 {
710         if (pMap == null || pList == null)
711         {
712                 return E_SUCCESS;
713         }
714
715         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
716         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
717
718         String key;
719         String value;
720         while (pEnum->MoveNext() == E_SUCCESS)
721         {
722                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
723
724                 int index = -1;
725                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
726                 {
727                         continue;
728                 }
729                 pStr->SubString(0, index, key);
730                 if (key.IsEmpty())
731                 {
732                         continue;
733                 }
734
735                 pStr->SubString(index + 1, value);
736
737                 pMap->Add(new String(key), new String(value));
738
739                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
740         }
741
742         return E_SUCCESS;
743 }
744
745
746 result
747 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
748 {
749         switch (res)
750         {
751         case APP_CTRL_RESULT_SUCCEEDED:
752                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
753                 break;
754         case APP_CTRL_RESULT_CANCELED:
755                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
756                 return E_SUCCESS;
757         case APP_CTRL_RESULT_TERMINATED:
758                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
759                 return E_SUCCESS;
760         case APP_CTRL_RESULT_ABORTED:
761                 list.Add(* new (std::nothrow) String("aborted"));
762                 return E_SUCCESS;
763                 //case APP_CTRL_RESULT_FAILED:
764         default:
765                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
766                 return E_SUCCESS;
767         }
768
769         if (pArgs == null)
770         {
771                 return E_SUCCESS;
772         }
773
774         bool isPathRegistered = false;
775         // handle APP_CTRL_RESULT_SUCCEEDED only
776         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
777
778         while(pMapEnum->MoveNext() == E_SUCCESS)
779         {
780                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
781                 if (pKey == null)
782                 {
783                         SysLog(NID_APP, "Invalid entry.");
784                         continue;
785                 }
786
787                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
788                 {
789                         if (!isPathRegistered)
790                         {
791                                 isPathRegistered = true;
792                         }
793                         else
794                         {
795                                 SysLog(NID_APP, "Selected path key is already registered.");
796                                 continue;
797                         }
798                 }
799
800                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
801                 if (pVal)
802                 {
803                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
804
805                         StringTokenizer strTok(*pVal, L';');
806                         if (strTok.GetTokenCount() == 0)
807                         {
808                                 list.Add(* new (std::nothrow) String(*pVal));
809                         }
810                         else
811                         {
812                                 String token;
813                                 while(strTok.HasMoreTokens())
814                                 {
815                                         strTok.GetNextToken(token);
816                                         list.Add(* new (std::nothrow) String(token));
817                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
818                                 }
819                         }
820                 }
821         }
822
823         return E_SUCCESS;
824 }
825
826
827 ArrayList*
828 _AppArg::GetListN(bundle* b, const char* key)
829 {
830         bundle* pb = b;
831         if (pb == null)
832         {
833                 return null;
834         }
835
836         const char** pValArray = null;
837         int len = 0;
838
839         pValArray = appsvc_get_data_array(b, key, &len);
840         if (len == 0 || pValArray == null)
841         {
842                 return null;
843         }
844
845         ArrayList* pList = new (std::nothrow) ArrayList;
846         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
847
848         pList->Construct();
849
850         for (int i = 0; i < len; i++)
851         {
852                 pList->Add(*new (std::nothrow) String(pValArray[i]));
853         }
854
855         return pList;
856 }
857
858
859 result
860 _AppArg::CreateLaunchArg(bundle* b, const String& arg)
861 {
862         SysAssertf(b != null, "Valid bundle should be supplied");
863
864         bundle* pb = b;
865
866         if (!arg.IsEmpty())
867         {
868                 const char** pSa = new (std::nothrow) const char*[1];
869                 SysTryReturnResult(NID_APP, pSa != null, E_OUT_OF_MEMORY, "Insufficient memory.");
870                 pSa[0] = _StringConverter::CopyToCharArrayN(arg);
871                 bundle_add_str_array(pb, OSP_K_ARG, pSa, 1);
872
873                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pSa[0]);
874
875                 delete[] pSa[0];
876                 delete[] pSa;
877         }
878
879         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
880
881         return E_SUCCESS;
882 }
883
884
885 result
886 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
887 {
888         SysAssertf(b != null, "Valid bundle should be supplied");
889
890         bundle* pb = b;
891
892         AddStrArray(pb, OSP_K_ARG, pList);
893
894         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
895
896         return E_SUCCESS;
897 }
898
899
900 result
901 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
902 {
903         SysAssertf(b != null, "Valid bundle should be supplied");
904         SysLog(NID_APP, "");
905
906         bundle* pb = b;
907
908         AddStrArray(pb, OSP_K_ARG, pList);
909
910         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
911         if (p)
912         {
913                 bundle_add(pb, OSP_K_COND, p.get());
914         }
915
916         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
917
918         return E_SUCCESS;
919 }
920
921
922 result
923 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, 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         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
932         if (pOperation)
933         {
934                 appsvc_set_operation(pb, pOperation.get());
935         }
936
937         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
938
939         return E_SUCCESS;
940 }
941
942
943 result
944 _AppArg::CreateAppControlArg(bundle* b, const _AppControlImpl& ac, const String* pUriData, const String* pMimeType, const IMap* pList)
945 {
946         SysAssertf(b != null, "Valid bundle should be supplied");
947
948         bundle* pb = b;
949
950         std::unique_ptr<char[]> pOperation(_StringConverter::CopyToCharArrayN(ac._opId));
951         if (pOperation.get())
952         {
953                 appsvc_set_operation(pb, pOperation.get());
954         }
955
956         if (pUriData)
957         {
958                 std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
959                 if (pUri.get())
960                 {
961                         appsvc_set_uri(pb, pUri.get());
962                 }
963         }
964
965         if (pMimeType)
966         {
967                 std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pMimeType));
968                 if (pMime.get())
969                 {
970                         appsvc_set_mime(pb, pMime.get());
971                 }
972         }
973
974         AddStrMap(pb, pList);
975
976         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_APPCONTROL);
977
978         return E_SUCCESS;
979 }
980
981
982 namespace
983 {
984 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
985 }
986 result
987 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
988                                                                  const IList* pArgList)
989 {
990         SysAssertf(b != null, "Valid bundle should be supplied");
991
992         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
993
994         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
995         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
996         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
997
998         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
999         if (pProvider)
1000         {
1001                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1002         }
1003
1004         AddStrArray(b, OSP_K_ARG, pArgList);
1005
1006         return E_SUCCESS;
1007 }
1008
1009
1010 result
1011 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
1012                                                                  const IList* pArgList)
1013 {
1014         SysAssertf(b != null, "Valid bundle should be supplied");
1015
1016         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
1017
1018         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
1019         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
1020         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
1021
1022         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
1023         if (pProvider)
1024         {
1025                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
1026         }
1027
1028         AddStrArray(b, OSP_K_ARG, pArgList);
1029
1030         return E_SUCCESS;
1031 }
1032
1033
1034 result
1035 _AppArg::CreateResultArg(bundle* b, const IList* pList)
1036 {
1037         SysAssertf(b != null, "Valid bundle should be supplied");
1038
1039         bundle* pb = b;
1040
1041         AddStrArray(pb, OSP_K_ARG, pList);
1042
1043         _AppMessageImpl::AddData(pb, pList);
1044
1045         return E_SUCCESS;
1046 }
1047
1048
1049 result
1050 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
1051 {
1052         SysAssertf(b != null, "Valid bundle should be supplied");
1053
1054         bundle* pb = b;
1055
1056         AddStrMap(pb, pMap);
1057
1058         return E_SUCCESS;
1059 }
1060
1061
1062 bundle*
1063 _AppArg::CreateBundleFromSvc(void* svc)
1064 {
1065         bundle* pBundle = GetBundleFromSvc(svc);
1066         if (pBundle)
1067         {
1068                 return bundle_dup(pBundle);
1069         }
1070
1071         return null;
1072 }
1073
1074
1075 bundle*
1076 _AppArg::GetBundleFromSvc(void* svc)
1077 {
1078         struct DummyS
1079         {
1080                 int dummy1;
1081                 int dummy2;
1082                 bundle* pData;
1083         };
1084
1085         DummyS* pDummy = static_cast<DummyS*>(svc);
1086
1087         if (pDummy && pDummy->pData)
1088         {
1089                 return pDummy->pData;
1090         }
1091
1092         return NULL;
1093 }
1094
1095
1096 String
1097 _AppArg::GetRequestId(int num)
1098 {
1099         String str;
1100         str.Format(10, L"req%05d", num);
1101         return str;
1102 }
1103
1104
1105 int
1106 _AppArg::GetRequestId(const String& str)
1107 {
1108         int i = 0;
1109         String sub;
1110
1111         result r = str.SubString(3, sub);
1112         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1113
1114         r = Integer::Parse(sub, i);
1115         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
1116
1117         return i;
1118 }
1119
1120
1121 void
1122 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
1123 {
1124         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1125
1126         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
1127         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
1128
1129         bundle_add(b, OSP_K_APPID, pId.get());
1130
1131         appsvc_set_appid(b, pId.get());
1132 }
1133
1134
1135 void
1136 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1137 {
1138         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1139
1140         if (reqId < 0)
1141         {
1142                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1143                 return;
1144         }
1145
1146         char buffer[32] = {0, };
1147         snprintf(buffer, 32, "%d", reqId);
1148         bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1149 }
1150
1151
1152 int
1153 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1154 {
1155         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1156         if (p == NULL)
1157         {
1158                 return -1;
1159         }
1160
1161         int i = atoi(p);
1162         return (i < 0) ? -1 : i;
1163 }
1164
1165
1166 result
1167 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1168 {
1169         if (handle == -1)
1170         {
1171                 SysLog(NID_APP, "Invalid window handle.");
1172                 return E_SUCCESS;
1173         }
1174
1175         char handleName[32] = {0, };
1176         snprintf(handleName, 32, "%ld", handle);
1177
1178         bundle_add(pBundle, BUNDLE_KEY_WINDOW, handleName);
1179         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1180
1181         return E_SUCCESS;
1182 }
1183
1184
1185 void
1186 _AppArg::PrintSvcHandle(void* svc)
1187 {
1188         service_h service = static_cast<service_h>(svc);
1189
1190         if (service == null)
1191         {
1192                 return;
1193         }
1194
1195         Print(GetBundleFromSvc(service));
1196 }
1197
1198
1199 static void
1200 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1201 {
1202         if (pKey && pVal)
1203         {
1204                 size_t size = 0;
1205                 char* pStr = NULL;
1206                 switch (type)
1207                 {
1208                 case BUNDLE_TYPE_STR:
1209                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1210                         if (pStr)
1211                         {
1212                                 SysLog(NID_APP, "(%s, %s)", pKey, pStr);
1213                         }
1214                         break;
1215                 default:
1216                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1217                         break;
1218                 }
1219         }
1220 }
1221
1222 void
1223 _AppArg::Print(bundle* b)
1224 {
1225         if (b == null)
1226         {
1227                 return;
1228         }
1229
1230         const char* p = null;
1231         p = appsvc_get_data(b, AUL_K_CALLER_PID);
1232         if (p)
1233         {
1234                 SysLog(NID_APP, "CallerPId[%s]", p);
1235         }
1236
1237         p = appsvc_get_data(b, AUL_K_WAIT_RESULT);
1238         if (p)
1239         {
1240                 SysLog(NID_APP, "WaitResult[%s]", p);
1241         }
1242
1243         p = appsvc_get_data(b, OSP_K_COND);
1244         if (p)
1245         {
1246                 SysLog(NID_APP, "Condition[%s]", p);
1247         }
1248
1249         p = appsvc_get_operation(b);
1250         if (p)
1251         {
1252                 SysLog(NID_APP, "operation[%s]", p);
1253         }
1254
1255         p = appsvc_get_uri(b);
1256         if (p)
1257         {
1258                 SysLog(NID_APP, "uri[%s]", p);
1259         }
1260
1261         p = appsvc_get_mime(b);
1262         if (p)
1263         {
1264                 SysLog(NID_APP, "mime[%s]", p);
1265         }
1266
1267         p = appsvc_get_category(b);
1268         if (p)
1269         {
1270                 SysLog(NID_APP, "Category[%s]", p);
1271         }
1272
1273         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1274
1275         int len = 0;
1276         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1277         if (pa)
1278         {
1279                 for (int i = 0; i < len; i++)
1280                 {
1281                         if (pa[i])
1282                         {
1283                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1284                         }
1285                 }
1286         }
1287 }
1288
1289 } } // Tizen::App