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