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