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