Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / app / FApp_AppArg.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18 * @file     FApp_AppArg.cpp
19 * @brief        This is the implementation for the _AppArg.cpp class.
20 */
21
22 #include <cstdio>
23 #include <cstdlib>
24 #include <new>
25 #include <typeinfo>
26 #include <unique_ptr.h>
27
28 #include <aul.h>
29 #include <app.h>
30 #include <bundle.h>
31 #include <appsvc/appsvc.h>
32 #include <Ecore_X.h>
33
34 #include <FBaseInteger.h>
35 #include <FBaseColArrayList.h>
36 #include <FBaseColHashMap.h>
37 #include <FBaseByteBuffer.h>
38 #include <FBaseUtilStringTokenizer.h>
39 #include <FBaseSysLog.h>
40
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 "FApp_Aul.h"
50
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::Base::Utility;
54
55
56 extern "C" int appsvc_allow_transient_app(bundle*, Ecore_X_Window);
57
58 namespace Tizen { namespace App
59 {
60
61 static const char OSP_V_LAUNCH_TYPE_LAUNCH[] = "launch";
62 static const char OSP_V_LAUNCH_TYPE_APPCONTROL[] = "appcontrol";
63 static const char OSP_V_LAUNCH_TYPE_DATACONTROL[] = "datacontrol";
64 static const char OSP_V_LAUNCH_TYPE_CONDTION[] = "condition";
65 static const char OSP_V_REQUEST_TYPE_SQL_QUERY[] = "sql_query";
66 static const char OSP_V_REQUEST_TYPE_SQL_INSERT[] = "sql_insert";
67 static const char OSP_V_REQUEST_TYPE_SQL_UPDATE[] = "sql_update";
68 static const char OSP_V_REQUEST_TYPE_SQL_DELETE[] = "sql_delete";
69 static const char OSP_V_REQUEST_TYPE_MAP_QEURY[] = "map_query";
70 static const char OSP_V_REQUEST_TYPE_MAP_INSERT[] = "map_insert";
71 static const char OSP_V_REQUEST_TYPE_MAP_UPDATE[] = "map_update";
72 static const char OSP_V_REQUEST_TYPE_MAP_DELETE[] = "map_delete";
73 static const char OSP_V_VERSION_2_1_0_3[] = "ver_2.1.0.3";
74
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 static const char BUNDLE_KEY_PREFIX_UG[] = "__UG_";
79
80 static const char OSP_K_RAISE_MODE[] = "__OSP_RAISE_MODE__";
81
82
83 _AppArg::_AppArg(void)
84         : __pBundle(null)
85 {
86 }
87
88
89 _AppArg::~_AppArg(void)
90 {
91         if (__pBundle)
92         {
93                 bundle_free(__pBundle);
94         }
95 }
96
97
98 result
99 _AppArg::Construct(const String& argText)
100 {
101         __pBundle = bundle_create();
102         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
103
104         return CreateNotificationArg(__pBundle, argText);
105 }
106
107
108 result
109 _AppArg::Construct(const IList* pList)
110 {
111         __pBundle = bundle_create();
112         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
113
114         return CreateLaunchArg(__pBundle, pList);
115 }
116
117
118 result
119 _AppArg::Construct(const _SqlDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
120 {
121         __pBundle = bundle_create();
122         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
123
124         return CreateSqlDataControlArg(__pBundle, dc, requestType, pList);
125 }
126
127
128 result
129 _AppArg::Construct(const _MapDataControlImpl& dc, _DataControlRequestType requestType, const IList* pList)
130 {
131         __pBundle = bundle_create();
132         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
133
134         return CreateMapDataControlArg(__pBundle, dc, requestType, pList);
135 }
136
137
138 result
139 _AppArg::ConstructResult(const _AppArg& arg, const IList* pList)
140 {
141         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
142         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
143
144         return CreateResultArg(__pBundle, pList);
145 }
146
147
148 result
149 _AppArg::ConstructResult(const _AppArg& arg, const IMap* pMap)
150 {
151         int ret = aul_create_result_bundle(arg.GetBundle(), &__pBundle);
152         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure : %d.", ret);
153
154         return CreateResultArg(__pBundle, pMap);
155 }
156
157
158 result
159 _AppArg::Construct(const bundle* b)
160 {
161         __pBundle = bundle_dup(const_cast<bundle*>(b));
162         SysTryReturnResult(NID_APP, __pBundle != null, E_INVALID_STATE, "Bundle creatioin from service handle failure.");
163
164         return E_SUCCESS;
165 }
166
167
168 result
169 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList)
170 {
171         __pBundle = bundle_create();
172         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
173
174         return CreateAppLaunchConditionArg(__pBundle, condition, pList);
175 }
176
177 result
178 _AppArg::ConstructForAppLaunchCondition(const String& condition, const IList* pList, const IMap* pMap)
179 {
180         __pBundle = bundle_create();
181         SysTryReturnResult(NID_APP, __pBundle != null, E_OUT_OF_MEMORY, "Bundle creation failure.");
182
183         CreateAppLaunchConditionArg(__pBundle, condition, pList);
184
185         return CreateResultArg(__pBundle, pMap);
186 }
187
188 ArrayList*
189 _AppArg::GetArgListN(int num) const
190 {
191         bundle* pBundle = __pBundle;
192         SysTryReturn(NID_APP, pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
193
194         ArrayList* pList = new (std::nothrow) ArrayList();
195         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
196
197         pList->Construct();
198
199         const char* p = NULL;
200         _AppHandler launch_type = GetHandler(pBundle);
201
202         switch (launch_type)
203         {
204         case _APP_HANDLER_APPCONTROL:
205                 // request Id
206                 // [FIXME] proper request Id required
207                 pList->Add(*new (std::nothrow) String(GetRequestId(num)));
208
209                 // category
210                 p = appsvc_get_category(pBundle);
211                 if (p)
212                 {
213                         pList->Add(*new (std::nothrow) String(p));
214                 }
215                 else
216                 {
217                         pList->Add(*new (std::nothrow) String(L""));
218                 }
219
220                 // MIME type
221                 p = appsvc_get_mime(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                 // URI scheme
232                 p = appsvc_get_uri(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                 break;
243
244         case _APP_HANDLER_DATACONTROL:
245                 // appId
246                 AddListFromBundle(pList, pBundle, OSP_K_APPID);
247                 // request type
248                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
249                 // reqId
250                 AddListFromBundle(pList, pBundle, OSP_K_REQUEST_ID);
251                 // providerId
252                 AddListFromBundle(pList, pBundle, OSP_K_DATACONTROL_PROVIDER);
253                 break;
254
255         case _APP_HANDLER_LAUNCH_COND:
256                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_CONDITIONAL));
257                 AddListFromBundle(pList, pBundle, OSP_K_COND);
258                 break;
259
260         case _APP_HANDLER_LAUNCH_NORMAL:
261                 pList->Add(*new (std::nothrow) String(LEGACY_LAUNCH_REASON_NORMAL));
262                 pList->Add(*new (std::nothrow) String(LEGACY_OPERATION_MAIN));
263                 break;
264
265         default:
266                 SysLog(NID_APP, "Invalid handler type");
267                 break;
268         }
269
270         SetArgList(__pBundle, pList);
271
272         return pList;
273 }
274
275
276 ArrayList*
277 _AppArg::GetArgListN(void) const
278 {
279         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
280
281         ArrayList* pList = new (std::nothrow) ArrayList();
282         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "ArrayList creation failure.");
283
284         pList->Construct();
285
286         SetArgList(__pBundle, pList);
287
288         return pList;
289 }
290
291 // the returned map is allocated using SingleObjectDeleter
292 HashMap*
293 _AppArg::GetArgMapN(void) const
294 {
295         SysTryReturn(NID_APP, __pBundle != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
296
297         //Print();
298
299         HashMap* pHashMap = new (std::nothrow) HashMap(SingleObjectDeleter);
300         SysTryReturn(NID_APP, pHashMap != null, null, E_OUT_OF_MEMORY, "HashMap creation failure.");
301
302         pHashMap->Construct();
303
304         SetArgMap(__pBundle, pHashMap);
305
306         if (pHashMap->GetCount() == 0)
307         {
308                 delete pHashMap;
309                 return null;
310         }
311
312         return pHashMap;
313 }
314
315 static bool
316 IsInternalKey(const char* pKey)
317 {
318         if (strncmp(BUNDLE_KEY_PREFIX_AUL, pKey, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
319         {
320                 return true;
321         }
322
323         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, pKey, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
324         {
325                 return true;
326         }
327
328         if (strncmp(BUNDLE_KEY_PREFIX_OSP, pKey, strlen(BUNDLE_KEY_PREFIX_OSP)) == 0)
329         {
330                 return true;
331         }
332
333         if (strncmp(BUNDLE_KEY_PREFIX_UG, pKey, strlen(BUNDLE_KEY_PREFIX_UG)) == 0)
334         {
335                 return true;
336         }
337
338         return false;
339 }
340
341 static void
342 BundleIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
343 {
344         HashMap* pMap = static_cast<HashMap*>(pData);
345
346         if (pKey && pVal && pMap)
347         {
348                 if (IsInternalKey(pKey))
349                 {
350                         //SysLog(NID_APP, "(%s)", pKey);
351                         return;
352                 }
353
354                 size_t size = 0;
355                 char* pStr = NULL;
356                 switch (type)
357                 {
358                 case BUNDLE_TYPE_STR:
359                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
360                         if (pStr)
361                         {
362                                 pMap->Add(new (std::nothrow) String(pKey), new (std::nothrow) String(pStr));
363                         }
364                         break;
365                 case BUNDLE_TYPE_STR_ARRAY:
366                         {
367                                 void** pArr = NULL;
368                                 bundle_keyval_get_array_val(const_cast<bundle_keyval_t*>(pVal), &pArr, &size, NULL);
369                                 if (pArr && size > 0)
370                                 {
371                                         ArrayList* pList = new (std::nothrow) ArrayList(SingleObjectDeleter);
372                                         if (pList)
373                                         {
374                                                 pList->Construct();
375
376                                                 for (size_t i = 0; i < size; i++)
377                                                 {
378                                                         // type unsafe ugly static casting required
379                                                         pList->Add(new (std::nothrow) String(static_cast<char*>(*(pArr + i))));
380                                                 }
381
382                                                 const int count = pList->GetCount();
383                                                 if (count != 0)
384                                                 {
385                                                         SysLog(NID_APP, "Adding %d elements for %s", count, pKey);
386                                                         pMap->Add(new (std::nothrow) String(pKey), pList);
387                                                 }
388                                                 else
389                                                 {
390                                                         SysLog(NID_APP, "No object for %s", pKey);
391                                                         delete pList;
392                                                 }
393                                         }
394                                 }
395                                 else
396                                 {
397                                         SysLog(NID_APP, "No entry for str array %s(%d)", pKey, size);
398                                 }
399                         }
400                         break;
401                 case BUNDLE_TYPE_BYTE:
402                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
403
404                         SysLog(NID_IO, "Bundle byte value = %s, size = %d", pStr, size);
405
406                         if (pStr)
407                         {
408                                 ByteBuffer* pBuffer = new (std::nothrow) ByteBuffer();
409                                 SysTryLog(NID_IO, pBuffer != null, "The memory is insufficient.");
410                                 result r = pBuffer->Construct(size);
411                                 SysTryLog(NID_IO, r == E_SUCCESS, "Constructing pBuffer is failed.");
412
413                                 r = pBuffer->SetArray((const byte*)pStr, 0, size);
414                                 SysTryLog(NID_IO, r == E_SUCCESS, "SetArray()for ByteBuffer is failed.");
415
416                                 pBuffer->Flip();
417
418                                 pMap->Add(new (std::nothrow) String(pKey), pBuffer);
419                         }
420                         break;
421                 default:
422                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
423                         break;
424                 }
425         }
426 }
427
428 result
429 _AppArg::SetArgMap(bundle* pBundle, HashMap* pMap)
430 {
431         bundle_foreach(pBundle, BundleIterFnCb, reinterpret_cast<void*>(pMap));
432
433         return E_SUCCESS;
434 }
435
436 result
437 _AppArg::SetArgList(bundle* pBundle, ArrayList* pList)
438 {
439         // actual argument below
440         int len = 0;
441         const char** pa = appsvc_get_data_array(pBundle, OSP_K_ARG, &len);
442         if (pa)
443         {
444                 for (int i = 0; i < len; i++)
445                 {
446                         if (pa[i])
447                         {
448                                 //SysLog(NID_APP, "%d/%dth arg [%s]", i, len, pa[i]);
449                                 pList->Add(*new (std::nothrow) String(pa[i]));
450                         }
451                 }
452         }
453
454         const char* p = appsvc_get_uri(pBundle);
455         if (p)
456         {
457                 pList->Add(*new (std::nothrow) String(p));
458                 SysLog(NID_APP, "argument is %s", p);
459         }
460
461         return E_SUCCESS;
462 }
463
464
465 String
466 _AppArg::GetValue(const char* key) const
467 {
468         const char* p = appsvc_get_data(__pBundle, key);
469         return String(p);
470 }
471
472
473 _AppHandler
474 _AppArg::GetHandler(bundle* b)
475 {
476         SysTryReturn(NID_APP, b != null, _APP_HANDLER_NONE, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
477
478         const char* p = null;
479
480         p = appsvc_get_data(b, OSP_K_LAUNCH_TYPE);
481
482         if (p)
483         {
484                 if (strcmp(p, OSP_V_LAUNCH_TYPE_DATACONTROL) == 0)
485                 {
486                         return _APP_HANDLER_DATACONTROL;
487                 }
488
489                 if (strcmp(p, OSP_V_LAUNCH_TYPE_APPCONTROL) == 0)
490                 {
491                         SysLog(NID_APP, "Building AppControl arguments.");
492
493                         return _APP_HANDLER_APPCONTROL;
494                 }
495                 else
496                 {
497                         // not appcontrol nor datacontrol => normal launch or condlaunch
498                         p = appsvc_get_data(b, OSP_K_COND);
499                         if (p)
500                         {
501                                 SysLog(NID_APP, "Building Conditional AppLaunch arguments.");
502                                 return _APP_HANDLER_LAUNCH_COND;
503                         }
504                         else
505                         {
506                                 SysLog(NID_APP, "Building Normal AppLaunch arguments.");
507                                 return _APP_HANDLER_LAUNCH_NORMAL;
508                         }
509                 }
510         }
511
512         // fallback
513         return _APP_HANDLER_APPCONTROL;
514 }
515
516
517 int
518 _AppArg::GetCallerPid(bundle* pBundle)
519 {
520         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_ORG_CALLER_PID);
521         if (pBundleValue == NULL)
522         {
523                 pBundleValue = bundle_get_val(pBundle, AUL_K_CALLER_PID);
524         }
525
526         SysTryReturn(NID_APP, pBundleValue != null, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Object not found.");
527
528         return atoi(pBundleValue);
529 }
530
531
532 AppId
533 _AppArg::GetCallerAppId(void) const
534 {
535         const char* pBundleValue = bundle_get_val(__pBundle, AUL_K_CALLER_APPID);
536
537         return String(pBundleValue);
538 }
539
540
541 AppId
542 _AppArg::GetCalleeAppId(bundle* pBundle)
543 {
544         const char* pBundleValue = bundle_get_val(pBundle, AUL_K_CALLEE_APPID);
545
546         const AppId retVal = pBundleValue;
547
548         return _Aul::GetRealAppId(retVal);
549 }
550
551
552 void
553 _AppArg::AddListFromBundle(ArrayList* pList, bundle* bk, const char* key)
554 {
555         bundle* pBundle = bk;
556
557         const char* p = appsvc_get_data(pBundle, key);
558         if (p)
559         {
560                 pList->Add(*new (std::nothrow) String(p));
561         }
562         else
563         {
564                 pList->Add(*new (std::nothrow) String(L""));
565         }
566 }
567
568
569 result
570 _AppArg::AddStrArray(bundle* b, const String& key, const IList* pList)
571 {
572         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
573
574         return AddStrArray(b, pKey.get(), pList);
575 }
576
577
578 result
579 _AppArg::AddStrArray(bundle* pb, const char* key, const IList* pList)
580 {
581         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
582
583         if (pList == null || pList->GetCount() == 0)
584         {
585                 SysLog(NID_APP, "No element added for bundle.");
586                 return E_SUCCESS;
587         }
588
589         _AppMessageImpl::AddValueArray(pb, key, pList);
590
591         _AppMessageImpl::AddData(pb, pList);
592
593         return E_SUCCESS;
594 }
595
596
597 result
598 _AppArg::AddStrMap(bundle* b, const IMap* pMap)
599 {
600         bundle* pb = b;
601         SysTryReturnResult(NID_APP, pb != NULL, E_INVALID_ARG, "Empty bundle.");
602
603         if (pMap == null || pMap->GetCount() == 0)
604         {
605                 SysLog(NID_APP, "No element added for bundle.");
606                 return E_SUCCESS;
607         }
608
609         std::unique_ptr<IMapEnumerator> pEnum (pMap->GetMapEnumeratorN());
610         while(pEnum->MoveNext() == E_SUCCESS)
611         {
612                 const String* pKey = static_cast<const String*>(pEnum->GetKey());
613                 const Object* pObj = pEnum->GetValue();
614
615                 if (pKey && pObj)
616                 {
617                         if (typeid(*pObj) == typeid(const String))
618                         {
619                                 const String* pVal = static_cast<const String*>(pEnum->GetValue());
620                                 if (pVal)
621                                 {
622                                         _AppMessageImpl::AddData(pb, *pKey, *pVal);
623                                 }
624                         }
625                         else if (typeid(*pObj) == typeid(const ArrayList))
626                         {
627                                 const ArrayList* pList = static_cast<const ArrayList*>(pEnum->GetValue());
628                                 if (pList)
629                                 {
630                                         SysLog(NID_APP, "ArrayList type");
631
632                                         _AppMessageImpl::AddValueArray(pb, *pKey, pList);
633                                 }
634                         }
635                         else if (typeid(*pObj) == typeid(const ByteBuffer))
636                         {
637                                 SysLog(NID_APP, "ByteBuffer type");
638                                 const ByteBuffer* pBuffer = static_cast<const ByteBuffer*>(pObj);
639
640                                 std::unique_ptr<char[]> pBundleKey(_StringConverter::CopyToCharArrayN(*pKey));
641                                 bundle_add_byte(b, pBundleKey.get(), pBuffer->GetPointer(), pBuffer->GetLimit());
642                         }
643                 }
644         }
645
646         return E_SUCCESS;
647 }
648
649
650 result
651 _AppArg::FillMapFromList(IMap* pMap, const IList* pList)
652 {
653         if (pMap == null || pList == null)
654         {
655                 return E_SUCCESS;
656         }
657
658         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
659         SysTryReturnResult(NID_APP, pEnum != null, E_OUT_OF_MEMORY, "Getting enumerator failed.");
660
661         String key;
662         String value;
663         while (pEnum->MoveNext() == E_SUCCESS)
664         {
665                 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
666
667                 int index = -1;
668                 if (pStr == null || pStr->IndexOf(L':', 0, index) != E_SUCCESS)
669                 {
670                         continue;
671                 }
672                 pStr->SubString(0, index, key);
673                 if (key.IsEmpty())
674                 {
675                         continue;
676                 }
677
678                 pStr->SubString(index + 1, value);
679
680                 pMap->Add(new String(key), new String(value));
681
682                 SysLog(NID_APP, "Added (%ls, %ls).", key.GetPointer(), value.GetPointer());
683         }
684
685         return E_SUCCESS;
686 }
687
688
689 result
690 _AppArg::FillLegacyAppControlResult(IList& list, int res, const IMap* pArgs, const Tizen::Base::String& aId)
691 {
692         switch (res)
693         {
694         case APP_CTRL_RESULT_SUCCEEDED:
695                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_SUCCEEDED));
696                 break;
697         case APP_CTRL_RESULT_CANCELED:
698                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_CANCELED));
699                 return E_SUCCESS;
700         case APP_CTRL_RESULT_TERMINATED:
701                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_TERMINATED));
702                 return E_SUCCESS;
703         case APP_CTRL_RESULT_ABORTED:
704                 list.Add(* new (std::nothrow) String("aborted"));
705                 return E_SUCCESS;
706                 //case APP_CTRL_RESULT_FAILED:
707         default:
708                 list.Add(* new (std::nothrow) String(APPCONTROL_RESULT_FAILED));
709                 return E_SUCCESS;
710         }
711
712         if (pArgs == null)
713         {
714                 return E_SUCCESS;
715         }
716
717         bool isPathRegistered = false;
718         // handle APP_CTRL_RESULT_SUCCEEDED only
719         std::unique_ptr<IMapEnumerator> pMapEnum(pArgs->GetMapEnumeratorN());
720
721         while(pMapEnum->MoveNext() == E_SUCCESS)
722         {
723                 String* pKey = static_cast<String*>(pMapEnum->GetKey());
724                 if (pKey == null)
725                 {
726                         SysLog(NID_APP, "Invalid entry.");
727                         continue;
728                 }
729
730                 if (*pKey == L"path" || *pKey == L"http://tizen.org/appcontrol/data/selected")
731                 {
732                         if (!isPathRegistered)
733                         {
734                                 isPathRegistered = true;
735                         }
736                         else
737                         {
738                                 SysLog(NID_APP, "Selected path key is already registered.");
739                                 continue;
740                         }
741                 }
742
743                 String* pVal = dynamic_cast<String*>(pMapEnum->GetValue());
744                 if (pVal)
745                 {
746                         SysLog(NID_APP, "Adding value (%ls).", pVal->GetPointer());
747
748                         StringTokenizer strTok(*pVal, L';');
749                         if (strTok.GetTokenCount() == 0)
750                         {
751                                 list.Add(* new (std::nothrow) String(*pVal));
752                         }
753                         else
754                         {
755                                 String token;
756                                 while(strTok.HasMoreTokens())
757                                 {
758                                         strTok.GetNextToken(token);
759                                         list.Add(* new (std::nothrow) String(token));
760                                         SysLog(NID_APP, "Adding tokenized value (%ls).", token.GetPointer());
761                                 }
762                         }
763                 }
764         }
765
766         return E_SUCCESS;
767 }
768
769
770 ArrayList*
771 _AppArg::GetListN(bundle* b, const char* key)
772 {
773         bundle* pb = b;
774         if (pb == null)
775         {
776                 return null;
777         }
778
779         const char** pValArray = null;
780         int len = 0;
781
782         pValArray = appsvc_get_data_array(b, key, &len);
783         if (len == 0 || pValArray == null)
784         {
785                 return null;
786         }
787
788         ArrayList* pList = new (std::nothrow) ArrayList;
789         SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
790
791         pList->Construct();
792
793         for (int i = 0; i < len; i++)
794         {
795                 pList->Add(*new (std::nothrow) String(pValArray[i]));
796         }
797
798         return pList;
799 }
800
801
802 result
803 _AppArg::CreateNotificationArg(bundle* b, const String& arg)
804 {
805         SysAssertf(b != null, "Valid bundle should be supplied");
806
807         bundle* pb = b;
808
809         if (!arg.IsEmpty())
810         {
811                 std::unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(arg));
812                 bundle_add(pb, TIZEN_NOTIFICATION_DATA, pStr.get());
813         }
814
815         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
816
817         return E_SUCCESS;
818 }
819
820
821 result
822 _AppArg::CreateLaunchArg(bundle* b, const IList* pList)
823 {
824         SysAssertf(b != null, "Valid bundle should be supplied");
825
826         bundle* pb = b;
827
828         AddStrArray(pb, OSP_K_ARG, pList);
829
830         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_LAUNCH);
831
832         return E_SUCCESS;
833 }
834
835
836 result
837 _AppArg::CreateAppLaunchConditionArg(bundle* b, const String& condition, const IList* pList)
838 {
839         SysAssertf(b != null, "Valid bundle should be supplied");
840         SysLog(NID_APP, "");
841
842         bundle* pb = b;
843
844         AddStrArray(pb, OSP_K_ARG, pList);
845
846         std::unique_ptr<char[]> p(_StringConverter::CopyToCharArrayN(condition));
847         if (p)
848         {
849                 bundle_add(pb, OSP_K_COND, p.get());
850         }
851
852         bundle_add(pb, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_CONDTION);
853
854         return E_SUCCESS;
855 }
856
857
858 namespace
859 {
860 const int MAX_LEN_DATA_CONTROL_REQ_TYPE = 8;
861 }
862 result
863 _AppArg::CreateSqlDataControlArg(bundle* b, const _SqlDataControlImpl& dc, _DataControlRequestType requestType,
864                                                                  const IList* pArgList)
865 {
866         SysAssertf(b != null, "Valid bundle should be supplied");
867
868         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
869
870         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
871         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast<int>(requestType));
872         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
873         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
874         bundle_add(b, AUL_K_NO_CANCEL, "1");
875
876         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
877         if (pProvider)
878         {
879                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
880         }
881
882         AddStrArray(b, OSP_K_ARG, pArgList);
883
884         return E_SUCCESS;
885 }
886
887
888 result
889 _AppArg::CreateMapDataControlArg(bundle* b, const _MapDataControlImpl& dc, _DataControlRequestType requestType,
890                                                                  const IList* pArgList)
891 {
892         SysAssertf(b != null, "Valid bundle should be supplied");
893
894         bundle_add(b, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
895
896         char dataControlRequestType[MAX_LEN_DATA_CONTROL_REQ_TYPE] = {0, };
897         snprintf(dataControlRequestType, MAX_LEN_DATA_CONTROL_REQ_TYPE, "%d", static_cast < int >(requestType));
898         bundle_add(b, OSP_K_DATACONTROL_REQUEST_TYPE, dataControlRequestType);
899         bundle_add(b, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
900         bundle_add(b, AUL_K_NO_CANCEL, "1");
901
902         std::unique_ptr<char[]> pProvider(_StringConverter::CopyToCharArrayN(dc.__providerId));
903         if (pProvider)
904         {
905                 bundle_add(b, OSP_K_DATACONTROL_PROVIDER, pProvider.get());
906         }
907
908         AddStrArray(b, OSP_K_ARG, pArgList);
909
910         return E_SUCCESS;
911 }
912
913
914 result
915 _AppArg::CreateResultArg(bundle* b, const IList* pList)
916 {
917         SysAssertf(b != null, "Valid bundle should be supplied");
918
919         bundle* pb = b;
920
921         AddStrArray(pb, OSP_K_ARG, pList);
922
923         _AppMessageImpl::AddData(pb, pList);
924
925         return E_SUCCESS;
926 }
927
928
929 result
930 _AppArg::CreateResultArg(bundle* b, const IMap* pMap)
931 {
932         SysAssertf(b != null, "Valid bundle should be supplied");
933
934         bundle* pb = b;
935
936         AddStrMap(pb, pMap);
937
938         return E_SUCCESS;
939 }
940
941
942 bundle*
943 _AppArg::CreateBundleFromSvc(void* svc)
944 {
945         bundle* pBundle = GetBundleFromSvc(svc);
946         if (pBundle)
947         {
948                 return bundle_dup(pBundle);
949         }
950
951         return null;
952 }
953
954
955 bundle*
956 _AppArg::GetBundleFromSvc(void* svc)
957 {
958         bundle* pBundle = NULL;
959         int ret = service_to_bundle(static_cast<service_h>(svc), &pBundle);
960
961         return (ret == SERVICE_ERROR_NONE) ? pBundle : NULL;
962 }
963
964
965 String
966 _AppArg::GetRequestId(int num)
967 {
968         String str;
969         str.Format(10, L"req%05d", num);
970         return str;
971 }
972
973
974 int
975 _AppArg::GetRequestId(const String& str)
976 {
977         int i = 0;
978         String sub;
979
980         result r = str.SubString(3, sub);
981         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
982
983         r = Integer::Parse(sub, i);
984         SysTryReturn(NID_APP, !IsFailed(r), -1, r, "[%s] Propagating.", GetErrorMessage(r));
985
986         return i;
987 }
988
989
990 void
991 _AppArg::UpdateAppId(bundle* b, const AppId& appId)
992 {
993         SysTryReturnVoidResult(NID_APP, b != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
994
995         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
996         SysTryReturnVoidResult(NID_APP, pId != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Converting %ls failed.", appId.GetPointer());
997
998         int res = bundle_add(b, OSP_K_APPID, pId.get());
999         if (res < 0 && errno == EPERM) // key exists
1000         {
1001                 bundle_del(b, OSP_K_APPID);
1002                 bundle_add(b, OSP_K_APPID, pId.get());
1003         }
1004
1005         appsvc_set_appid(b, pId.get());
1006 }
1007
1008
1009 void
1010 _AppArg::UpdateRequestId(bundle* pBundle, int reqId)
1011 {
1012         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1013
1014         if (reqId < 0)
1015         {
1016                 //SysLog(NID_APP, "Requested ID is %d", reqId);
1017                 return;
1018         }
1019
1020         char buffer[32] = {0, };
1021         snprintf(buffer, 32, "%d", reqId);
1022         int res = bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1023         if (res < 0 && errno == EPERM) // key exists
1024         {
1025                 bundle_del(pBundle, OSP_K_REQUEST_ID);
1026                 bundle_add(pBundle, OSP_K_REQUEST_ID, buffer);
1027         }
1028 }
1029
1030 void
1031 _AppArg::UpdateKeyValue(bundle* pBundle, const char* pKey, const String& value)
1032 {
1033         SysTryReturnVoidResult(NID_APP, pBundle != null, E_INVALID_STATE, "[E_INVALID_STATE] Improper bundle state.");
1034
1035         char pBuffer[128] = {0, };
1036         snprintf(pBuffer, 128, "%ls", value.GetPointer());
1037         int res = bundle_add(pBundle, pKey, pBuffer);
1038         if (res < 0 && errno == EPERM) // key exists
1039         {
1040                 bundle_del(pBundle, pKey);
1041                 bundle_add(pBundle, pKey, pBuffer);
1042         }
1043 }
1044
1045
1046 void
1047 _AppArg::UpdateRaiseMode(bundle* pBundle)
1048 {
1049         appsvc_add_data(pBundle, OSP_K_RAISE_MODE, "1");
1050 }
1051
1052
1053 bool
1054 _AppArg::IsRaiseMode(bundle* pBundle)
1055 {
1056         const char* p = appsvc_get_data(pBundle, OSP_K_RAISE_MODE);
1057         return (p && (strncmp(p, "1", sizeof(char)) == 0));
1058 }
1059
1060 int
1061 _AppArg::GetRequestIdFromBundle(bundle* pBundle)
1062 {
1063         const char* p = appsvc_get_data(pBundle, OSP_K_REQUEST_ID);
1064         if (p == NULL)
1065         {
1066                 return -1;
1067         }
1068
1069         int i = atoi(p);
1070         return (i < 0) ? -1 : i;
1071 }
1072
1073
1074 result
1075 _AppArg::UpdateWindowHandle(bundle* pBundle, long handle)
1076 {
1077         appsvc_allow_transient_app(pBundle, handle);
1078
1079         SysLog(NID_APP, "Window Handle 0x%x added.", handle);
1080
1081         return E_SUCCESS;
1082 }
1083
1084
1085 void
1086 _AppArg::PrintSvcHandle(void* svc)
1087 {
1088         service_h service = static_cast<service_h>(svc);
1089
1090         if (service == null)
1091         {
1092                 return;
1093         }
1094
1095         Print(GetBundleFromSvc(service));
1096 }
1097
1098
1099 static void
1100 BundlePrintIterFnCb(const char* pKey, const int type, const bundle_keyval_t* pVal, void* pData)
1101 {
1102         if (pKey && pVal)
1103         {
1104                 size_t size = 0;
1105                 char* pStr = NULL;
1106                 switch (type)
1107                 {
1108                 case BUNDLE_TYPE_STR:
1109                         bundle_keyval_get_basic_val(const_cast<bundle_keyval_t*>(pVal), reinterpret_cast<void**>(&pStr), &size);
1110                         if (pStr)
1111                         {
1112                                 SysSecureLog(NID_APP, "(%s, %s)", pKey, pStr);
1113                         }
1114                         break;
1115                 default:
1116                         SysLog(NID_APP, "Invalid type for %s : %d", pKey, type);
1117                         break;
1118                 }
1119         }
1120 }
1121
1122 void
1123 _AppArg::Print(bundle* b)
1124 {
1125         if (b == null)
1126         {
1127                 return;
1128         }
1129
1130         bundle_foreach(b, BundlePrintIterFnCb, NULL);
1131
1132         int len = 0;
1133         const char** pa = appsvc_get_data_array(b, OSP_K_ARG, &len);
1134         if (pa)
1135         {
1136                 for (int i = 0; i < len; i++)
1137                 {
1138                         if (pa[i])
1139                         {
1140                                 SysLog(NID_APP, "%dth arg [%s]", i, pa[i]);
1141                         }
1142                 }
1143         }
1144 }
1145
1146 } } // Tizen::App