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