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