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