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