Resolve the "Klocwork" detected defect and add debug feature.
[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                 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
189
190                 pKb = arg.GetBundle();
191                 service_create_request(pKb, &svc);
192
193                 service_set_package(svc, pkgname);
194                 r = ConvertNotificationResult(ui_notification_set_service(core, svc));
195                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set service failed.", GetErrorMessage(r));
196
197                 SysLog(NID_APP, "Sending notification[%ls] for package %s.", messageText.GetPointer(), pkgname);
198
199                 r = ConvertNotificationResult(ui_notification_post(core));
200                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
201         }
202
203         if (badgeNumber >= 0)
204         {
205                 badge_error_e badgeError = badge_set_count(appinfo_get_appid(), badgeNumber);
206                 SysTryLog(NID_APP, badgeError == BADGE_ERROR_NONE, "badge_set_count failed(%d).", badgeError);
207         }
208
209 CATCH:
210         delete pPackageAppInfo;
211         delete[] pMsg;
212         delete[] pIcon;
213
214         if (pkgname)
215         {
216                 free(pkgname);
217         }
218         if (core)
219         {
220                 ui_notification_destroy(core);
221         }
222         service_destroy(svc);
223         return r;
224 }
225
226 result
227 _NotificationManagerImpl::NotifyImpl(const AppId& appId, const String& messageText, int badgeNumber,
228                                                                          const String& launchArguments,
229                                                                          bool isOngoing) const
230 {
231         result r = E_SUCCESS;
232         int retcode = 0;
233         String iconPath;
234         char* pMsg = null;
235         char* pIcon = null;
236         char* pName = null;
237         ui_notification_h core = NULL;
238         char buffer[256];
239         bundle* pKb = NULL;
240         service_h svc = NULL;
241         _AppArg arg;
242         PackageAppInfo* pPackageAppInfo = null;
243
244         memset(buffer, 0, 256);
245
246         bool inInstalled = _Aul::IsInstalled(appId);
247         SysTryReturnResult(NID_APP, inInstalled == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
248
249         if (!isOngoing || !messageText.IsEmpty())
250         {
251                 SysTryReturnResult(NID_APP,
252                                           messageText.GetLength() <= MAX_NOTIFICATION_MESSAGE_LENGTH, E_INVALID_ARG,
253                                           "MessageText is greater than MAX_NOTIFICATION_MESSAGE_LENGTH.");
254
255                 retcode = ui_notification_create(isOngoing, &core);
256                 SysTryReturnResult(NID_APP, retcode == UI_NOTIFICATION_ERROR_NONE, E_SYSTEM, "Notification creation error : 0x%x.", retcode);
257
258                 pMsg = _StringConverter::CopyToCharArrayN(messageText);
259
260                 int ret = ui_notification_set_content(core, pMsg);
261                 SysTryLog(NID_APP, ret == UI_NOTIFICATION_ERROR_NONE, "Setting notification content failure : %d.", ret);
262
263                 snprintf(buffer, 256, "%ls", appId.GetPointer());
264
265                 pPackageAppInfo = _PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId);
266                 if (pPackageAppInfo)
267                 {
268                         iconPath = pPackageAppInfo->GetAppNotificationIconPath();
269
270                         if (!iconPath.IsEmpty() && File::IsFileExist(iconPath))
271                         {
272                                 pIcon = _StringConverter::CopyToCharArrayN(iconPath);
273                                 r = ConvertNotificationResult(ui_notification_set_icon(core, pIcon));
274                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set icon failed.", GetErrorMessage(r));
275                         }
276                         else
277                         {
278                                 iconPath = pPackageAppInfo->GetAppMenuIconPath();
279                                 pIcon = _StringConverter::CopyToCharArrayN(iconPath);
280                                 r = ConvertNotificationResult(ui_notification_set_icon(core, pIcon));
281                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
282                         }
283
284                         const String& displayName = pPackageAppInfo->GetAppDisplayName();
285                         pName = _StringConverter::CopyToCharArrayN(displayName);
286
287                         r = ConvertNotificationResult(ui_notification_set_title(core, pName));
288                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set title failed.", GetErrorMessage(r));
289                 }
290                 else
291                 {
292                         SysLog(NID_APP, "No packageInfo found for %ls", appId.GetPointer());
293                 }
294
295
296                 r = arg.Construct(launchArguments);
297                 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
298
299                 pKb = arg.GetBundle();
300                 service_create_request(pKb, &svc);
301
302                 service_set_app_id(svc, buffer);
303                 r = ConvertNotificationResult(ui_notification_set_service(core, svc));
304                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification set service failed.", GetErrorMessage(r));
305
306                 SysLog(NID_APP, "Sending notification[%ls] for package %s.", messageText.GetPointer(), buffer);
307
308                 r = ConvertNotificationResult(ui_notification_post(core));
309                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
310         }
311
312         if (badgeNumber >= 0)
313         {
314                 badge_error_e badgeError = badge_set_count(buffer, badgeNumber);
315                 SysTryLog(NID_APP, badgeError == BADGE_ERROR_NONE, "badge_set_count failed(%d).", badgeError);
316         }
317
318 CATCH:
319         delete pPackageAppInfo;
320         delete[] pMsg;
321         delete[] pIcon;
322         delete[] pName;
323         
324         if (core)
325         {
326                 ui_notification_destroy(core);
327         }
328         service_destroy(svc);
329         return r;
330 }
331
332
333 result
334 _NotificationManagerImpl::RemoveImpl(const char* pAppId, notification_type_e type)
335 {
336         result r = E_SUCCESS;
337
338         notification_error_e err = notification_delete_all_by_type(pAppId, type);
339         switch (err)
340         {
341         case NOTIFICATION_ERROR_NONE:
342                 r = E_SUCCESS;
343                 break;
344
345         case NOTIFICATION_ERROR_INVALID_DATA:
346                 r = E_INVALID_ARG;
347                 break;
348
349         default:
350                 r = E_SYSTEM;
351                 break;
352         }
353
354         return r;
355 }
356
357
358 result
359 _NotificationManagerImpl::RemoveImpl(const AppId& appId, bool isOngoing)
360 {
361         const bool isValidAppId = _Aul::IsInstalled(appId);
362         SysTryReturnResult(NID_APP, isValidAppId, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
363
364         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
365         const notification_type_e notiType = (isOngoing) ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
366
367         return RemoveImpl(pAppId.get(), notiType);
368 }
369
370 result
371 _NotificationManagerImpl::Notify(int badgeNumber) const
372 {
373         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
374
375         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
376         {
377                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
378         }
379
380         String messageText = String(L"");
381         String appMessage = String(L"");
382
383         return NotifyImpl(messageText, badgeNumber, appMessage, false);
384 }
385
386 result
387 _NotificationManagerImpl::Notify(const String& messageText) const
388 {
389         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
390
391         String appMessage = String(L"");
392
393         return NotifyImpl(messageText, -1, appMessage, false);
394 }
395
396 result
397 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber) const
398 {
399         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
400         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
401
402         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
403         {
404                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
405         }
406
407         String appMessage = String(L"");
408
409         return NotifyImpl(messageText, badgeNumber, appMessage, false);
410 }
411
412 result
413 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber, const String& launchArguments) const
414 {
415         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
416         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
417         SysTryReturnResult(NID_APP,
418                                           launchArguments != null && launchArguments.GetLength() > 0, E_INVALID_ARG,
419                                           "launchArguments is less than 0.");
420
421         SysTryReturnResult(NID_APP,
422                                           launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
423                                           "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
424
425         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
426         {
427                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
428         }
429
430         return NotifyImpl(messageText, badgeNumber, launchArguments, false);
431 }
432
433 int
434 _NotificationManagerImpl::GetBadgeNumber(const AppId& appId) const
435 {
436         bool b = _Aul::IsInstalled(appId);
437
438         SysTryReturn(NID_APP, b == true, -1, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The application %ls is not installed",
439                                 appId.GetPointer());
440
441         char buffer[256];
442         unsigned int count = 0;
443
444         memset(buffer, 0, 256);
445
446         snprintf(buffer, 256, "%ls", appId.GetPointer());
447
448         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
449
450         badge_error_e badgeError = badge_get_count(pAppId.get(), &count);
451
452         if (badgeError == BADGE_ERROR_NONE)
453         {
454                 SysLog(NID_APP, "badge_get_count(%d)", count);
455         }
456         else
457         {
458                 SysLog(NID_APP, "badge_get_count failed(%d).", badgeError);
459                 return -1;
460         }
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