AppControl 2.0/2.1 argument handling
[platform/framework/native/appfw.git] / src / app / FApp_NotificationManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FApp_NotificationManagerImpl.cpp
20  * @brief               This is the placeholder for _NotificationManagerImpl class.
21  */
22
23 #include <unique_ptr.h>
24 #include <appsvc/appsvc.h>
25 #include <bundle.h>
26 #include <notification/notification.h>
27 #include <appfw/app.h>
28 #include <appfw/app_manager.h>
29 #include <appfw/app_ui_notification.h>
30
31 #include <FBaseSysLog.h>
32 #include <FAppNotificationManager.h>
33
34 #include <FBaseInternalTypes.h>
35 #include <FBase_StringConverter.h>
36 #include "FApp_NotificationManagerImpl.h"
37 #include "FApp_AppInfo.h"
38 #include "FIoFile.h"
39 #include "FAppPkg_PackageManagerImpl.h"
40 #include "FApp_Aul.h"
41 #include "FApp_AppArg.h"
42 #include "FAppPkgPackageAppInfo.h"
43 #include "FAppPkg_PackageAppInfoImpl.h"
44
45 using namespace Tizen::Base;
46 using namespace Tizen::App;
47 using namespace Tizen::App::Package;
48 using namespace Tizen::Io;
49
50 extern "C" int service_create_request(bundle *data, service_h *service);
51
52 namespace
53 {
54
55 result
56 ConvertNotificationResult(int error)
57 {
58         switch (error)
59         {
60         case UI_NOTIFICATION_ERROR_NONE:
61                 return E_SUCCESS;
62         case UI_NOTIFICATION_ERROR_INVALID_PARAMETER:
63                 return E_INVALID_ARG;
64         case UI_NOTIFICATION_ERROR_OUT_OF_MEMORY:
65                 return E_OUT_OF_MEMORY;
66         case UI_NOTIFICATION_ERROR_DB_FAILED:
67                 return E_DATABASE;
68         case UI_NOTIFICATION_ERROR_NO_SUCH_FILE:
69                 return E_SYSTEM;
70         case UI_NOTIFICATION_ERROR_INVALID_STATE:
71                 return E_SYSTEM;
72         default:
73                 return E_SYSTEM;
74         }
75 }
76
77 bool
78 IsPosted(ui_notification_h handle)
79 {
80         struct ui_notification_s
81         {
82                 void* raw_handle;
83                 bool ongoing;
84                 bool posted;
85                 bool removed;
86                 char *icon;
87                 struct tm *time;
88                 char *title;
89                 char *content;
90                 service_h service;
91                 char *sound;
92                 bool vibration;
93         };
94
95         if (handle == NULL)
96         {
97                 return false;
98         }
99
100         ui_notification_s* pStruct = reinterpret_cast<ui_notification_s*>(handle);
101
102         return pStruct->posted;
103 }
104
105 }
106
107 namespace Tizen { namespace App
108 {
109
110 _NotificationManagerImpl::_NotificationManagerImpl(void)
111 {
112 }
113
114 _NotificationManagerImpl::~_NotificationManagerImpl(void)
115 {
116 }
117
118 result
119 _NotificationManagerImpl::Construct(void)
120 {
121         return E_SUCCESS;
122 }
123
124 const _NotificationManagerImpl*
125 _NotificationManagerImpl::GetInstance(const NotificationManager& notiMgr)
126 {
127         return notiMgr.__pNotificationManagerImpl;
128 }
129
130 _NotificationManagerImpl*
131 _NotificationManagerImpl::GetInstance(NotificationManager& notiMgr)
132 {
133         return notiMgr.__pNotificationManagerImpl;
134 }
135
136 int
137 _NotificationManagerImpl::GetBadgeNumber(void) const
138 {
139         int count = -1;
140         notification_get_badge(NULL, NOTIFICATION_GROUP_ID_NONE, &count);
141         return count;
142 }
143
144 result
145 _NotificationManagerImpl::OngoingImpl(const String& messageText, const String& launchArguments) const
146 {
147         return NotifyImpl(messageText, -1, launchArguments, true);
148 }
149
150 result
151 _NotificationManagerImpl::OngoingImpl(const AppId& appId, const String& messageText, const String& launchArguments) const
152 {
153
154         return NotifyImpl(appId, messageText, -1, launchArguments, true);
155 }
156
157 result
158 _NotificationManagerImpl::NotifyImpl(const String& messageText, int badgeNumber,
159                                                                          const String& launchArguments,
160                                                                          bool isOngoing) const
161 {
162         result r = E_SUCCESS;
163         int retcode = 0;
164         char* pMsg = null;
165         char* pkgname = NULL;
166         char* pIcon = NULL;
167         bundle* pKb = NULL;
168         service_h svc = NULL;
169         _AppArg arg;
170         String iconPath;
171         ui_notification_h core = NULL;
172         PackageAppInfo* pPackageAppInfo = NULL;
173
174         if (!messageText.IsEmpty())
175         {
176                 SysTryReturnResult(NID_APP,
177                                           messageText.GetLength() <= MAX_NOTIFICATION_MESSAGE_LENGTH, E_INVALID_ARG,
178                                           "MessageText is greater than MAX_NOTIFICATION_MESSAGE_LENGTH.");
179
180                 retcode = ui_notification_create(isOngoing, &core);
181                 SysTryReturnResult(NID_APP, retcode == UI_NOTIFICATION_ERROR_NONE, E_SYSTEM, "Notification creation error : 0x%x.", retcode);
182
183                 pMsg = _StringConverter::CopyToCharArrayN(messageText);
184
185                 int ret = ui_notification_set_content(core, pMsg);
186                 SysTryLog(NID_APP, ret == UI_NOTIFICATION_ERROR_NONE, "Setting notification content failure : %d.", ret);
187
188                 const String& currappId = _AppInfo::GetApplicationId();
189
190                 pPackageAppInfo = _PackageManagerImpl::GetInstance()->GetPackageAppInfoN(currappId);
191                 iconPath = _PackageAppInfoImpl::GetInstance(pPackageAppInfo)->GetAppNotificationIconPath();
192
193                 if (!iconPath.IsEmpty() && File::IsFileExist(iconPath))
194                 {
195                         pIcon = _StringConverter::CopyToCharArrayN(iconPath);
196                         r = ConvertNotificationResult(ui_notification_set_icon(core, pIcon));
197                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set icon failed.", GetErrorMessage(r));
198                 }
199
200                 app_get_package(&pkgname);
201                 SysTryCatch(NID_APP, pkgname != NULL, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Cannot acquire package name for current application.");
202
203                 r = arg.Construct(launchArguments);
204                 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
205
206                 pKb = arg.GetBundle();
207                 service_create_request(pKb, &svc);
208
209                 service_set_package(svc, pkgname);
210                 r = ConvertNotificationResult(ui_notification_set_service(core, svc));
211                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set service failed.", GetErrorMessage(r));
212
213                 SysLog(NID_APP, "Sending notification[%ls] for package %s.", messageText.GetPointer(), pkgname);
214
215                 r = ConvertNotificationResult(ui_notification_post(core));
216                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
217         }
218
219         if (badgeNumber >= 0)
220         {
221                 notification_set_badge(NULL, NOTIFICATION_GROUP_ID_NONE, badgeNumber);
222                 SysLog(NID_APP, "Badge number is set to %d.", badgeNumber);
223         }
224
225 CATCH:
226         delete pPackageAppInfo;
227         delete[] pMsg;
228         delete[] pIcon;
229
230         if (pkgname)
231         {
232                 free(pkgname);
233         }
234         if (core)
235         {
236                 ui_notification_destroy(core);
237         }
238         service_destroy(svc);
239         return r;
240 }
241
242 result
243 _NotificationManagerImpl::NotifyImpl(const AppId& appId, const String& messageText, int badgeNumber,
244                                                                          const String& launchArguments,
245                                                                          bool isOngoing) const
246 {
247         result r = E_SUCCESS;
248         int retcode = 0;
249         String iconPath;
250         char* pMsg = null;
251         char* pIcon = null;
252         char* pDefaultIconPath = NULL;
253         char* pName = NULL;
254         ui_notification_h core = NULL;
255         char buffer[256];
256         bundle* pKb = NULL;
257         service_h svc = NULL;
258         _AppArg arg;
259         PackageAppInfo* pPackageAppInfo = null;
260
261         memset(buffer, 0, 256);
262
263         bool inInstalled = _Aul::IsInstalled(appId);
264         SysTryReturnResult(NID_APP, inInstalled == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
265
266         if (!isOngoing || !messageText.IsEmpty())
267         {
268                 SysTryReturnResult(NID_APP,
269                                           messageText.GetLength() <= MAX_NOTIFICATION_MESSAGE_LENGTH, E_INVALID_ARG,
270                                           "MessageText is greater than MAX_NOTIFICATION_MESSAGE_LENGTH.");
271
272                 retcode = ui_notification_create(isOngoing, &core);
273                 SysTryReturnResult(NID_APP, retcode == UI_NOTIFICATION_ERROR_NONE, E_SYSTEM, "Notification creation error : 0x%x.", retcode);
274
275                 pMsg = _StringConverter::CopyToCharArrayN(messageText);
276
277                 int ret = ui_notification_set_content(core, pMsg);
278                 SysTryLog(NID_APP, ret == UI_NOTIFICATION_ERROR_NONE, "Setting notification content failure : %d.", ret);
279
280                 snprintf(buffer, 256, "%ls", appId.GetPointer());
281
282                 pPackageAppInfo = _PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId);
283                 iconPath = _PackageAppInfoImpl::GetInstance(pPackageAppInfo)->GetAppNotificationIconPath();
284
285                 if (!iconPath.IsEmpty() && File::IsFileExist(iconPath))
286                 {
287                         pIcon = _StringConverter::CopyToCharArrayN(iconPath);
288                         r = ConvertNotificationResult(ui_notification_set_icon(core, pIcon));
289                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set icon failed.", GetErrorMessage(r));
290                 }
291                 else
292                 {
293                         app_manager_get_app_icon_path(buffer, &pDefaultIconPath);
294                         r = ConvertNotificationResult(ui_notification_set_icon(core, pDefaultIconPath));
295                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
296                 }
297
298                 app_manager_get_app_name(buffer, &pName);
299                 r = ConvertNotificationResult(ui_notification_set_title(core, pName));
300                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set title failed.", GetErrorMessage(r));
301
302                 r = arg.Construct(launchArguments);
303                 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
304
305                 pKb = arg.GetBundle();
306                 service_create_request(pKb, &svc);
307
308                 service_set_app_id(svc, buffer);
309                 r = ConvertNotificationResult(ui_notification_set_service(core, svc));
310                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set service failed.", GetErrorMessage(r));
311
312                 SysLog(NID_APP, "Sending notification[%ls] for package %s.", messageText.GetPointer(), buffer);
313
314                 r = ConvertNotificationResult(ui_notification_post(core));
315                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
316         }
317
318         if (badgeNumber >= 0)
319         {
320                 notification_set_badge(buffer, NOTIFICATION_GROUP_ID_NONE, badgeNumber);
321                 SysLog(NID_APP, "Badge number is set to %d.", badgeNumber);
322         }
323
324 CATCH:
325         delete pPackageAppInfo;
326         delete[] pMsg;
327         delete[] pIcon;
328         if (pDefaultIconPath)
329         {
330                 free(pDefaultIconPath);
331         }
332         if (core)
333         {
334                 ui_notification_destroy(core);
335         }
336         if (pName)
337         {
338                 free(pName);
339         }
340         service_destroy(svc);
341         return r;
342 }
343
344
345 result
346 _NotificationManagerImpl::RemoveImpl(const char* pAppId, notification_type_e type)
347 {
348         result r = E_SUCCESS;
349
350         notification_error_e err = notification_delete_all_by_type(pAppId, type);
351         switch (err)
352         {
353         case NOTIFICATION_ERROR_NONE:
354                 r = E_SUCCESS;
355                 break;
356
357         case NOTIFICATION_ERROR_INVALID_DATA:
358                 r = E_INVALID_ARG;
359                 break;
360
361         default:
362                 r = E_SYSTEM;
363                 break;
364         }
365
366         return r;
367 }
368
369
370 result
371 _NotificationManagerImpl::RemoveImpl(const AppId& appId, bool isOngoing)
372 {
373         const bool isValidAppId = _Aul::IsInstalled(appId);
374         SysTryReturnResult(NID_APP, isValidAppId, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
375
376         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
377         const notification_type_e notiType = (isOngoing) ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
378
379         return RemoveImpl(pAppId.get(), notiType);
380 }
381
382 result
383 _NotificationManagerImpl::Notify(int badgeNumber) const
384 {
385         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
386
387         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
388         {
389                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
390         }
391
392         String messageText = String(L"");
393         String appMessage = String(L"");
394
395         return NotifyImpl(messageText, badgeNumber, appMessage, false);
396 }
397
398 result
399 _NotificationManagerImpl::Notify(const String& messageText) const
400 {
401         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
402
403         String appMessage = String(L"");
404
405         return NotifyImpl(messageText, -1, appMessage, false);
406 }
407
408 result
409 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber) const
410 {
411         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
412         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
413
414         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
415         {
416                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
417         }
418
419         String appMessage = String(L"");
420
421         return NotifyImpl(messageText, badgeNumber, appMessage, false);
422 }
423
424 result
425 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber, const String& launchArguments) const
426 {
427         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
428         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
429         SysTryReturnResult(NID_APP,
430                                           launchArguments != null && launchArguments.GetLength() > 0, E_INVALID_ARG,
431                                           "launchArguments is less than 0.");
432
433         SysTryReturnResult(NID_APP,
434                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
435                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
436
437         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
438         {
439                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
440         }
441
442         return NotifyImpl(messageText, badgeNumber, launchArguments, false);
443 }
444
445 int
446 _NotificationManagerImpl::GetBadgeNumber(const AppId& appId) const
447 {
448         bool b = _Aul::IsInstalled(appId);
449
450         SysTryReturn(NID_APP, b == true, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The application %ls is not installed",
451                                 appId.GetPointer());
452
453         char buffer[256];
454         int count = -1;
455
456         memset(buffer, 0, 256);
457
458         snprintf(buffer, 256, "%ls", appId.GetPointer());
459
460         notification_get_badge(buffer, NOTIFICATION_GROUP_ID_NONE, &count);
461
462         return count;
463 }
464
465
466 result
467 _NotificationManagerImpl::NotifyOnBehalf(const AppId& appId, int badgeNumber) const
468 {
469         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
470
471         String messageText = String(L"");
472         String appMessage = String(L"");
473         return NotifyImpl(appId, messageText, badgeNumber, appMessage);
474 }
475
476 result
477 _NotificationManagerImpl::NotifyOnBehalf(const AppId& appId, const String& messageText) const
478 {
479         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
480
481         return NotifyImpl(appId, messageText, -1, String(L""));
482 }
483
484 result
485 _NotificationManagerImpl::NotifyOnBehalf(const AppId& appId, const String& messageText, int badgeNumber) const
486 {
487         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
488         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
489
490         return NotifyImpl(appId, messageText, badgeNumber, String(L""));
491 }
492
493 result
494 _NotificationManagerImpl::NotifyOnBehalf(const AppId& appId, const String& messageText, const String& launchArguments) const
495 {
496         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
497         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
498         SysTryReturnResult(NID_APP,
499                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
500                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
501
502         return NotifyImpl(appId, messageText, -1, launchArguments);
503 }
504
505 result
506 _NotificationManagerImpl::NotifyOnBehalf(const AppId& appId, const String& messageText, int badgeNumber,
507                                                                                  const String& launchArguments) const
508 {
509         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
510         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
511         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
512         SysTryReturnResult(NID_APP,
513                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
514                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
515
516         return NotifyImpl(appId, messageText, badgeNumber, launchArguments);
517 }
518
519 result
520 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText) const
521 {
522         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
523
524         return OngoingImpl(messageText, String(L""));
525 }
526
527 result
528 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText, const String& launchArguments) const
529 {
530         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
531         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
532         SysTryReturnResult(NID_APP,
533                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
534                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
535
536         return OngoingImpl(messageText, launchArguments);
537 }
538
539 result
540 _NotificationManagerImpl::NotifyOngoingActivityOnBehalf(const AppId& appId, const String& messageText) const
541 {
542         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
543
544         return OngoingImpl(appId, messageText, String(L""));
545 }
546
547 result
548 _NotificationManagerImpl::NotifyOngoingActivityOnBehalf(const AppId& appId, const String& messageText,
549                                                                                                                 const String& launchArguments) const
550 {
551         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
552         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
553         SysTryReturnResult(NID_APP,
554                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
555                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
556
557         return OngoingImpl(appId, messageText, launchArguments);
558 }
559
560 result
561 _NotificationManagerImpl::RemoveOngoingActivityNotification(void)
562 {
563         return RemoveImpl(NULL, NOTIFICATION_TYPE_ONGOING);
564 }
565
566 result
567 _NotificationManagerImpl::RemoveOngoingActivityNotificationOnBehalf(const AppId& appId)
568 {
569         return RemoveImpl(appId, true);
570 }
571
572 result
573 _NotificationManagerImpl::RemoveNotification(void)
574 {
575         return RemoveImpl(NULL, NOTIFICATION_TYPE_NOTI);
576 }
577
578 result
579 _NotificationManagerImpl::RemoveNotificationOnBehalf(const AppId& appId)
580 {
581         return RemoveImpl(appId, false);
582 }
583
584 };
585 };    // Tizen::App