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