Add new APIs for NotificationRequest and more for NotificationManager.
[platform/framework/native/shell.git] / src / core / FShell_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                FShell_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 #include <badge.h>
31
32 #include <FBaseSysLog.h>
33 #include <FApp.h>
34 //#include <FAppTypes.h>
35 #include <FShellNotificationManager.h>
36 #include <FShellNotificationRequest.h>
37
38 //#include <FBaseInternalTypes.h>
39 #include <FBase_StringConverter.h>
40 #include "FApp_AppInfo.h"
41 #include "FApp_Aul.h"
42 #include "FIoFile.h"
43 #include "FAppPkg_PackageManagerImpl.h"
44 #include "FApp_AppArg.h"
45 #include "FAppPkgPackageAppInfo.h"
46 #include "FAppPkg_PackageAppInfoImpl.h"
47 #include "FShell_NotificationManagerImpl.h"
48 #include "FShell_NotificationManagerProxy.h"
49 #include "FShell_NotificationRequestImpl.h"
50
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::App;
54 using namespace Tizen::App::Package;
55 using namespace Tizen::Io;
56 using namespace Tizen::Shell;
57
58 extern "C" int service_create_request(bundle *data, service_h *service);
59 extern "C" int service_to_bundle(service_h service, bundle** data);
60
61 namespace
62 {
63
64 result
65 ConvertNotificationResult(int error)
66 {
67         switch (error)
68         {
69         case NOTIFICATION_ERROR_NONE:
70                 return E_SUCCESS;
71         case NOTIFICATION_ERROR_INVALID_DATA:
72                 return E_INVALID_ARG;
73         case NOTIFICATION_ERROR_NO_MEMORY:
74                 return E_OUT_OF_MEMORY;
75         case NOTIFICATION_ERROR_FROM_DB:
76                 return E_DATABASE;
77         case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
78                 return E_OPERATION_FAILED;
79         case NOTIFICATION_ERROR_NOT_EXIST_ID:
80                 return E_OPERATION_FAILED;
81         default:
82                 return E_OPERATION_FAILED;
83         }
84 }
85
86 bool
87 IsPosted(ui_notification_h handle)
88 {
89         struct ui_notification_s
90         {
91                 void* raw_handle;
92                 bool ongoing;
93                 bool posted;
94                 bool removed;
95                 char *icon;
96                 struct tm *time;
97                 char *title;
98                 char *content;
99                 service_h service;
100                 char *sound;
101                 bool vibration;
102         };
103
104         if (handle == NULL)
105         {
106                 return false;
107         }
108
109         ui_notification_s* pStruct = reinterpret_cast<ui_notification_s*>(handle);
110
111         return pStruct->posted;
112 }
113
114 } // namespace
115
116
117 namespace Tizen { namespace Shell
118 {
119
120 _NotificationManagerImpl::_NotificationManagerImpl(void)
121         : __pNotificationManagerProxy(null)
122         , __notifyPrivitId(-1)
123         , __notifyPrivitIdForOngoing(-1)
124 {
125 }
126
127 _NotificationManagerImpl::~_NotificationManagerImpl(void)
128 {
129 }
130
131 result
132 _NotificationManagerImpl::Construct(void)
133 {
134         return E_SUCCESS;
135 }
136
137 const _NotificationManagerImpl*
138 _NotificationManagerImpl::GetInstance(const NotificationManager& notiMgr)
139 {
140         return notiMgr.__pNotificationManagerImpl;
141 }
142
143 _NotificationManagerImpl*
144 _NotificationManagerImpl::GetInstance(NotificationManager& notiMgr)
145 {
146         return notiMgr.__pNotificationManagerImpl;
147 }
148
149 int
150 _NotificationManagerImpl::GetBadgeNumber(void) const
151 {
152         Tizen::App::App* pApp = Tizen::App::App::GetInstance();
153         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(pApp->GetAppId()));
154
155         int count = GetBadgeCount(pAppId.get());
156         SysTryReturn(NID_APP, count != -1, count, E_OPERATION_FAILED, "[%s] The operation has failed. Badge may not exist.",
157                                  GetErrorMessage(E_OPERATION_FAILED));
158
159         ClearLastResult();
160         return count;
161 }
162
163 result
164 _NotificationManagerImpl::NotifyMessageImpl(const NotificationRequest& notiMessage, bool isOngoing)
165 {
166         return NotifyMessage(NOTIFY_TYPE_SIMPLE, isOngoing, notiMessage);
167 }
168
169 result
170 _NotificationManagerImpl::NotifyMessageImpl(const AppId& appId, const NotificationRequest& notiMessage, bool isOngoing)
171 {
172         return NotifyMessage(NOTIFY_TYPE_APP_ID, isOngoing, notiMessage, &appId);
173         // No more partner, no need to use IPC.
174         //return __pNotificationManagerProxy->NotifyMessage(appId, notiMessage, isOngoing);
175 }
176
177
178 result
179 _NotificationManagerImpl::Notify(int badgeNumber)
180 {
181         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
182
183         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
184         {
185                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
186         }
187
188         Tizen::App::App* pApp = Tizen::App::App::GetInstance();
189         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(pApp->GetAppId()));
190
191         if (badgeNumber == 0)
192         {
193                 RemoveBadge(pAppId.get());
194         }
195         else
196         if (badgeNumber > 0)
197         {
198                 SetBadgeCount(pAppId.get(), badgeNumber);
199         }
200
201         return E_SUCCESS;
202 }
203
204 result
205 _NotificationManagerImpl::Notify(const String& messageText)
206 {
207         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
208
209         NotificationRequest request;
210         request.SetAlertText(messageText);
211         request.SetAppMessage(L"");
212
213         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
214 }
215
216 result
217 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber)
218 {
219         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
220         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
221
222         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
223         {
224                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
225         }
226
227         NotificationRequest request;
228         request.SetAlertText(messageText);
229         request.SetBadgeNumber(badgeNumber);
230         request.SetAppMessage(L"");
231
232         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
233 }
234
235 result
236 _NotificationManagerImpl::Notify(const String& messageText, int badgeNumber, const String& launchArguments)
237 {
238         SysTryReturnResult(NID_APP, badgeNumber >= 0, E_INVALID_ARG, "BadgeNumber is less than 0.");
239         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
240         SysTryReturnResult(NID_APP, launchArguments != null && launchArguments.GetLength() > 0, E_INVALID_ARG,
241                                            "launchArguments is less than 0.");
242
243         SysTryReturnResult(NID_APP, launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
244                                            "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
245
246         if (badgeNumber > MAX_NOTIFICATION_BADGE_NUMBER)
247         {
248                 badgeNumber = MAX_NOTIFICATION_BADGE_NUMBER;
249         }
250
251         NotificationRequest request;
252         request.SetAlertText(messageText);
253         request.SetBadgeNumber(badgeNumber);
254         request.SetAppMessage(launchArguments);
255
256         return NotifyMessage(NOTIFY_TYPE_SIMPLE, false, request);
257 }
258
259 int
260 _NotificationManagerImpl::GetBadgeNumber(const AppId& appId) const
261 {
262         bool b = _Aul::IsInstalled(appId);
263         SysTryReturn(NID_APP, b == true, -1, E_APP_NOT_INSTALLED, "[E_OBJ_NOT_FOUND] The application %ls is not installed",
264                                  appId.GetPointer());
265         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
266         int count = GetBadgeCount(pAppId.get());
267
268         SysTryReturn(NID_APP, count != -1, count, E_OPERATION_FAILED, "[%s] The operation has failed. Badge may not exist.",
269                                  GetErrorMessage(E_OPERATION_FAILED));
270         ClearLastResult();
271
272         return count;
273 }
274
275 result
276 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText)
277 {
278         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
279
280         NotificationRequest request;
281         request.SetAlertText(messageText);
282
283         return NotifyMessage(NOTIFY_TYPE_SIMPLE, true, request);
284 }
285
286 result
287 _NotificationManagerImpl::NotifyOngoingActivity(const String& messageText, const String& launchArguments)
288 {
289         SysTryReturnResult(NID_APP, messageText.GetLength() > 0, E_INVALID_ARG, "MessageText is less than 0.");
290         SysTryReturnResult(NID_APP, launchArguments.GetLength() > 0, E_INVALID_ARG, "launchArguments is less than 0.");
291         SysTryReturnResult(NID_APP, launchArguments.GetLength() <= MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH, E_INVALID_ARG,
292                                            "launchArguments is greater than MAX_NOTIFICATION_LAUNCH_ARGUMENTS_LENGTH.");
293
294         NotificationRequest request;
295         request.SetAlertText(messageText);
296         request.SetAppMessage(launchArguments);
297
298         return NotifyMessage(NOTIFY_TYPE_SIMPLE, true, request);
299 }
300
301 result
302 _NotificationManagerImpl::RemoveOngoingActivityNotificationByAppId(const AppId& appId)
303 {
304         return RemoveNotificationByAppId(appId, true);
305         // No more partner, no need to use IPC.
306         //return __pNotificationManagerProxy->RemoveNotification(appId, true);
307 }
308
309
310 result
311 _NotificationManagerImpl::RemoveNotificationByAppId(const AppId& appId)
312 {
313         return RemoveNotificationByAppId(appId, false);
314
315         // No more partner, no need to use IPC.
316         //return __pNotificationManagerProxy->RemoveNotification(appId,false);
317 }
318
319 result
320 _NotificationManagerImpl::NotifyTextMessage(const String& messageText) const
321 {
322         SysTryReturnResult(NID_APP, !messageText.IsEmpty(), E_INVALID_ARG, "MessageText is less than 0.");
323
324         std::unique_ptr<char[]> pMsg(_StringConverter::CopyToCharArrayN(messageText));
325         int res = notification_status_message_post(pMsg.get());
326
327         result r = E_SUCCESS;
328         switch (res)
329         {
330         case NOTIFICATION_ERROR_NONE:
331                 // success
332                 break;
333         case NOTIFICATION_ERROR_INVALID_DATA:
334                 r = E_INVALID_ARG;
335                 break;
336         case NOTIFICATION_ERROR_IO:
337                 r = E_SYSTEM;
338                 break;
339         default:
340                 r = E_SYSTEM;
341                 break;
342         }
343
344         SysLog(NID_APP, "[%s] %ls posted.", GetErrorMessage(r), messageText.GetPointer());
345         return r;
346 }
347
348 result
349 _NotificationManagerImpl::NotifyByAppControl(const Tizen::Base::String& operationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType,
350                                                                                          const Tizen::Base::Collection::IMap* pExtraData, const NotificationRequest& request)
351 {
352         result r = E_SUCCESS;
353
354         r = NotifyMessage(NOTIFY_TYPE_APP_CONTROL, false, request, null, &operationId, pUriData, pDataType, pExtraData);
355         return r;
356 }
357
358 result
359 _NotificationManagerImpl::NotifyOngoingActivityByAppControl(const Tizen::Base::String& operationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType,
360                                                                                                                         const Tizen::Base::Collection::IMap* pExtraData, const NotificationRequest& request)
361 {
362         result r = E_SUCCESS;
363
364         r = NotifyMessage(NOTIFY_TYPE_APP_CONTROL, true, request, null, &operationId, pUriData, pDataType, pExtraData);
365         return r;
366 }
367
368
369 result
370 _NotificationManagerImpl::NotifyMessage(_NotifyType notifyType, bool isOngoing, const NotificationRequest& notifyRequest, const AppId* pAppId,
371                                                                                 const Tizen::Base::String* pOperationId, const Tizen::Base::String* pUriData, const Tizen::Base::String* pDataType, const Tizen::Base::Collection::IMap* pExtraData)
372 {
373         result r = E_SUCCESS;
374         std::unique_ptr<char[]> pAppIdChar(null);
375         const _NotificationRequestImpl* pRequestImpl = _NotificationRequestImpl::GetInstance(notifyRequest);
376         SysTryReturnResult(NID_APP, pRequestImpl != null, E_INVALID_ARG, "Invalid argument is used.");
377
378         // Set pAppIdChar
379         if ((notifyType == NOTIFY_TYPE_SIMPLE) || (notifyType == NOTIFY_TYPE_APP_CONTROL))
380         {
381 //              char* pkgname = null;
382 //              app_get_id(&pkgname);   // AppId. (Not package Id)
383 //              SysTryReturnResult(NID_APP, pkgname != NULL, E_OBJ_NOT_FOUND,"Cannot acquire package name for current application.");
384 //              const String currentAppId(pkgname);
385 //              free(pkgname);
386                 Tizen::App::App* pApp = Tizen::App::App::GetInstance();
387                 const String currentAppId = pApp->GetAppId();
388                 std::unique_ptr<char[]> pAppIdTemp(_StringConverter::CopyToCharArrayN(currentAppId));
389                 pAppIdChar = std::move(pAppIdTemp);
390                 SysLog(NID_APP, "app_get_id: %ls", currentAppId.GetPointer());
391         }
392         else
393         if (notifyType == NOTIFY_TYPE_APP_ID)
394         {
395                 bool isAppInstalled = _Aul::IsInstalled(*pAppId);
396                 SysTryReturnResult(NID_APP, isAppInstalled == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", pAppId->GetPointer());
397                 std::unique_ptr<char[]> pAppIdTemp(_StringConverter::CopyToCharArrayN(*pAppId));
398                 pAppIdChar = std::move(pAppIdTemp);
399         }
400         else
401         {
402                 SysTryReturnResult(NID_APP, false, E_INVALID_ARG, "Invalid argument is used.");
403         }
404
405         const int badgeNumber = notifyRequest.GetBadgeNumber();
406         const int badgeOffset = notifyRequest.GetBadgeOffset();
407         const String& contentText = notifyRequest.GetAlertText();
408         // Allow change the badge without other properties.
409         if (badgeNumber != -1 || badgeOffset != -1)
410         {
411                 // Set - Badge
412                 if (badgeOffset != 0)
413                 {
414                         int badgeNumber = GetBadgeCount(pAppIdChar.get());
415                         if (badgeNumber <= 0)
416                         {
417                                 SetBadgeCount(pAppIdChar.get(), badgeOffset);
418                         }
419                         else
420                         {
421                                 SetBadgeCount(pAppIdChar.get(), badgeNumber + badgeOffset);
422                         }
423                 }
424                 else
425                 {
426                         if (badgeNumber == 0)
427                         {
428                                 RemoveBadge(pAppIdChar.get());
429                         }
430                         else
431                         if (badgeNumber > 0)
432                         {
433                                 SetBadgeCount(pAppIdChar.get(), badgeNumber);
434                         }
435                 }
436                 if (!(isOngoing || !contentText.IsEmpty()))
437                 {
438                         SysLog(NID_APP, "No valid for Notification, just for set a badgeNumber update.");
439                         return E_SUCCESS;
440                 }
441         }
442         SysTryReturnResult(NID_APP, (isOngoing || !contentText.IsEmpty()), E_INVALID_ARG, "Invalid argument is used. MessageText is Empty");
443
444         const String& titleText = notifyRequest.GetTitleText();
445         const String& launchArguments = notifyRequest.GetAppMessage();
446         const String& iconPath = notifyRequest.GetIconFilePath();
447         const String& soundPath = notifyRequest.GetSoundFilePath();
448         const notification_type_e notiType = isOngoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
449         int notiPrivateId = isOngoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
450         notification_h notiHandle = null;
451         bundle* pBundle = null;
452         bool needUpdate = false;
453         bundle* service_data = null;
454         _AppArg arg;
455         service_h hSvc = null;
456         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
457
458         // Notification creation
459         if (notiPrivateId != -1)
460         {
461                 notiHandle = notification_load(pAppIdChar.get(), notiPrivateId);
462                 SysTryLog(NID_APP, notiHandle != null, "Get notiHandle(%d) from notiPrivateId(%d).", notiHandle, notiPrivateId);
463         }
464
465         if (notiHandle == null)
466         {
467                 SysLog(NID_APP, "Previous notification(%d) no more valid - create new notification", notiPrivateId);
468                 notiPrivateId = -1;             // reset
469                 notiHandle = notification_create(notiType);
470         }
471         else
472         {
473                 needUpdate = true;              // No need to notification_insert.
474         }
475         SysTryReturnResult(NID_APP, notiHandle != null , E_SYSTEM, "A system error has been occurred. Notification creation/load failed ");
476
477         // Content text(Alert text)
478         std::unique_ptr<char[]> pMsg(_StringConverter::CopyToCharArrayN(contentText));
479
480         // Title text
481         std::unique_ptr<char[]> pTitleText(null);
482         if (!titleText.IsEmpty())
483         {
484                 std::unique_ptr<char[]> pTitleTextTemp(_StringConverter::CopyToCharArrayN(titleText));
485                 pTitleText = std::move(pTitleTextTemp);
486         }
487         else
488         {
489                 char* pAppName = null;
490                 app_manager_get_app_name(pAppIdChar.get(), &pAppName);
491                 if (pAppName)
492                 {
493                         String appName(pAppName);
494                         std::unique_ptr<char[]> pTitleTextTemp(_StringConverter::CopyToCharArrayN(appName));
495                         pTitleText = std::move(pTitleTextTemp);
496                         free(pAppName);
497                         //SysLog(NID_APP, "Application Id is %ls.", appName.GetPointer());
498                 }
499                 else
500                 {
501                         SysTryLog(NID_APP, pTitleText, "Failed to get title from app_manager_get_app_name for default setting.");
502                 }
503         }
504         // Icon file path
505         std::unique_ptr<char[]> pIconPath(null);
506         if (!iconPath.IsEmpty())
507         {
508                 std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(iconPath));
509                 pIconPath = std::move(pIconPathTemp);
510         }
511         else
512         {
513                 std::unique_ptr<PackageAppInfo> pPackageAppInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(pAppIdChar.get()));
514                 const String& appIconPath(_PackageAppInfoImpl::GetInstance(pPackageAppInfo.get())->GetAppNotificationIconPath());
515
516                 if (!appIconPath.IsEmpty() && File::IsFileExist(appIconPath))
517                 {
518                         std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(appIconPath));
519                         pIconPath = std::move(pIconPathTemp);
520                 }
521                 else
522                 {
523                         char* pDefaultIconPath = null;
524                         app_manager_get_app_icon_path(pAppIdChar.get(), &pDefaultIconPath);
525                         if (pDefaultIconPath)
526                         {
527                                 String iconPath(pDefaultIconPath);
528                                 std::unique_ptr<char[]> pIconPathTemp(_StringConverter::CopyToCharArrayN(iconPath));
529                                 pIconPath = std::move(pIconPathTemp);
530                                 free(pDefaultIconPath);
531                         }
532                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
533                 }
534         }
535         // Sound file path
536         std::unique_ptr<char[]> pSoundPath(null);
537         if (!soundPath.IsEmpty())
538         {
539                 std::unique_ptr<char[]> pSoundPathTemp(_StringConverter::CopyToCharArrayN(soundPath));
540                 pSoundPath = std::move(pSoundPathTemp);
541         }
542         // Set - AppId
543         if (notifyType == NOTIFY_TYPE_APP_ID)
544         {
545                 r = ConvertNotificationResult(notification_set_pkgname(notiHandle, pAppIdChar.get()));
546                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Package name failed.", GetErrorMessage(r));
547         }
548         // Set - title text
549         if (pTitleText.get())
550         {
551                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_TITLE, pTitleText.get(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
552                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Title Text failed.", GetErrorMessage(r));
553         }
554         // Set - content text
555         if (pMsg.get())
556         {
557                 r = notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_CONTENT, pMsg.get(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
558                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Title Text failed.", GetErrorMessage(r));
559         }
560         // Set - icon file path
561         r = ConvertNotificationResult(notification_set_image(notiHandle, NOTIFICATION_IMAGE_TYPE_ICON, pIconPath.get()));
562         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set icon path  failed.", GetErrorMessage(r));
563         // Set - sound file path
564         r = ConvertNotificationResult(notification_set_sound(notiHandle, NOTIFICATION_SOUND_TYPE_USER_DATA, pSoundPath.get()));
565         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set sound  failed.", GetErrorMessage(r));
566
567         // Set extended - text, thumbnail and background image
568         if (!isOngoing)
569         {
570                 // Extended style set
571                 String countText = notifyRequest.GetNotificationCountText();
572                 NotificationStyle notiStyle= notifyRequest.GetNotificationStyle();
573                 if (notiStyle == NOTIFICATION_STYLE_THUMBNAIL)
574                 {
575                         layout = NOTIFICATION_LY_NOTI_THUMBNAIL;
576                 }
577                 else
578                 if (notiStyle == NOTIFICATION_STYLE_NORMAL && !countText.IsEmpty())
579                 {
580                         layout = NOTIFICATION_LY_NOTI_EVENT_MULTIPLE;
581                 }
582
583                 if (!countText.IsEmpty())
584                 {
585                         std::unique_ptr<char[]> text(_StringConverter::CopyToCharArrayN(countText));
586                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, text.get(),
587                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
588                 }
589
590                 String bgImageFilePath = notifyRequest.GetBackgroundImageFilePath();
591                 if (!bgImageFilePath.IsEmpty() && File::IsFileExist(bgImageFilePath))
592                 {
593                         std::unique_ptr<char[]> pBgImageFilePath(_StringConverter::CopyToCharArrayN(bgImageFilePath));
594                         r = ConvertNotificationResult(notification_set_image(notiHandle, NOTIFICATION_IMAGE_TYPE_BACKGROUND, pBgImageFilePath.get()));
595                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Background image path failed.", GetErrorMessage(r));
596                 }
597
598
599                 if (notiStyle == NOTIFICATION_STYLE_THUMBNAIL)
600                 {
601                         const IList* pThumbnailList = pRequestImpl->GetMessageThumbnailFilePathList();
602                         if (pThumbnailList)
603                         {
604                                 const static notification_image_type_e thumbnailListEnum[] = {NOTIFICATION_IMAGE_TYPE_LIST_1, NOTIFICATION_IMAGE_TYPE_LIST_2,
605                                                 NOTIFICATION_IMAGE_TYPE_LIST_3, NOTIFICATION_IMAGE_TYPE_LIST_4, NOTIFICATION_IMAGE_TYPE_LIST_5 };
606                                 int itemCount = pThumbnailList->GetCount();
607                                 const int maxCount = sizeof(thumbnailListEnum)/sizeof(thumbnailListEnum[0]);
608                                 if (itemCount > maxCount)
609                                 {
610                                         itemCount = maxCount;
611                                 }
612                                 for (int i = 0; i < itemCount; i++)
613                                 {
614                                         const String* pThumbnailPath = static_cast<const String*>(pThumbnailList->GetAt(i));
615                                         // TODO: check pThumbnailPath
616                                         std::unique_ptr<char[]> filePath(_StringConverter::CopyToCharArrayN(*pThumbnailPath));
617                                         r = ConvertNotificationResult(notification_set_image(notiHandle, thumbnailListEnum[i], filePath.get()));
618                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set thumnail path  failed.", GetErrorMessage(r));
619                                 }
620                         }
621                 }
622                 else
623                 {
624                         // TODO: Check the valid
625                         const IList* pMessageTextList = pRequestImpl->GetMessageTextList();
626                         if (pMessageTextList && pMessageTextList->GetCount())
627                         {
628                                 const String* pText1 = static_cast<const String*>(pMessageTextList->GetAt(0));
629                                 if (pText1)
630                                 {
631                                         int matchIndex;
632                                         if (E_SUCCESS == pText1->IndexOf(L'\t', 0, matchIndex))
633                                         {
634                                                 // Make two token
635                                                 String subText;
636                                                 pText1->SubString(0, matchIndex+1, subText);
637                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(subText));
638                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, leftText.get(),
639                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
640                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
641                                                 subText.Clear();
642                                                 if (E_SUCCESS == pText1->SubString(matchIndex+1, subText))
643                                                 {
644                                                         std::unique_ptr<char[]> rightText(_StringConverter::CopyToCharArrayN(subText));
645                                                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_SUB_1, rightText.get(),
646                                                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
647                                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Sub Text failed.", GetErrorMessage(r));
648                                                 }
649                                         }
650                                         else
651                                         {
652                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(*pText1));
653                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, leftText.get(),
654                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
655                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
656                                         }
657                                 }
658                                 const String* pText2 = static_cast<const String*>(pMessageTextList->GetAt(1));
659                                 if (pText2)
660                                 {
661                                         int matchIndex;
662                                         // 2.1: Multiple layout has single line text for 2nd information text.
663                                         if ((layout == NOTIFICATION_LY_NOTI_EVENT_MULTIPLE && E_SUCCESS) == (pText2->IndexOf(L'\t', 0, matchIndex)))
664                                         {
665                                                 // Make two token
666                                                 String subText;
667                                                 pText2->SubString(0, matchIndex+1, subText);
668                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(subText));
669                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_2, leftText.get(),
670                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
671                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
672                                                 subText.Clear();
673                                                 if (E_SUCCESS == pText2->SubString(matchIndex+1, subText))
674                                                 {
675                                                         std::unique_ptr<char[]> rightText(_StringConverter::CopyToCharArrayN(subText));
676                                                         r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_SUB_2, rightText.get(),
677                                                                                                                                                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
678                                                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Sub Text failed.", GetErrorMessage(r));
679                                                 }
680                                         }
681                                         else
682                                         {
683                                                 std::unique_ptr<char[]> leftText(_StringConverter::CopyToCharArrayN(*pText2));
684                                                 r = ConvertNotificationResult(notification_set_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_2, leftText.get(),
685                                                                                                                                                         NULL, NOTIFICATION_VARIABLE_TYPE_NONE));
686                                                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification Set Info1 Text failed.", GetErrorMessage(r));
687                                         }
688                                 }
689                         }
690                         else
691                         if (needUpdate)
692                         {       // Reset text for update case. also must be check the previous text with get_text
693                                 char* pRetStr = null;
694                                 notification_get_text(notiHandle, NOTIFICATION_TEXT_TYPE_INFO_1, &pRetStr);
695                                 if (pRetStr)
696                                 {
697                                         const static notification_text_type_e infoTextEnums[] = { NOTIFICATION_TEXT_TYPE_INFO_1, NOTIFICATION_TEXT_TYPE_INFO_SUB_1,
698                                                                                                                                                          NOTIFICATION_TEXT_TYPE_INFO_2, NOTIFICATION_TEXT_TYPE_INFO_SUB_2 };
699                                         for (unsigned int i = 0; i < sizeof(infoTextEnums)/sizeof(infoTextEnums[0]); i++)
700                                         {
701                                                 notification_set_text(notiHandle, infoTextEnums[i], null, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
702                                         }
703                                 }
704                         }
705                 }
706         }
707
708         // Set - service
709         r = arg.Construct(launchArguments);
710         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
711
712         pBundle = arg.GetBundle();
713
714         service_create_request(pBundle, &hSvc);
715         SysTryCatch(NID_APP, hSvc != null, r = E_SYSTEM, r, "[%s] A system error has been occurred. service_create_request failed.", GetErrorMessage(E_SYSTEM));
716
717         if (notifyType == NOTIFY_TYPE_SIMPLE || notifyType == NOTIFY_TYPE_APP_ID)
718         {
719                 service_set_app_id(hSvc, pRequestImpl->IsAppBinding() ? pAppIdChar.get() : null);
720         }
721         else
722         if (notifyType == NOTIFY_TYPE_APP_CONTROL)
723         {
724
725                 std::unique_ptr<char[]> pOperationIdChar(_StringConverter::CopyToCharArrayN(*pOperationId));
726                 service_set_operation(hSvc, pOperationIdChar.get());
727                 if (pUriData)
728                 {
729                         std::unique_ptr<char[]> pUri(_StringConverter::CopyToCharArrayN(*pUriData));
730                         service_set_uri(hSvc, pUri.get());
731                 }
732                 if (pDataType)
733                 {
734                         std::unique_ptr<char[]> pMime(_StringConverter::CopyToCharArrayN(*pDataType));
735                         service_set_mime(hSvc, pMime.get());
736                 }
737                 if (pExtraData)
738                 {
739                         std::unique_ptr<Tizen::Base::Collection::IMapEnumerator> pMapEnum(pExtraData->GetMapEnumeratorN());
740                         if (pMapEnum)
741                         {
742                                 while (pMapEnum->MoveNext() == E_SUCCESS)
743                                 {
744                                         String* pKey = static_cast<String* > (pMapEnum->GetKey());
745                                         String* pValue = static_cast<String* > (pMapEnum->GetValue());
746                                         if (pKey && pValue)
747                                         {
748                                                 std::unique_ptr<char[]> pKeyString(_StringConverter::CopyToCharArrayN(*pKey));
749                                                 std::unique_ptr<char[]> pValueString(_StringConverter::CopyToCharArrayN(*pValue));
750                                                 service_add_extra_data(hSvc, pKeyString.get(), pValueString.get());
751                                         }
752                                         else
753                                         {
754                                                 SysLog(NID_APP, "pKey or pValue is ivalid.");
755                                         }
756                                 }
757                         }
758                 }
759         }
760
761         if (service_to_bundle(hSvc, &service_data) == SERVICE_ERROR_NONE)
762         {
763                 notification_set_property(notiHandle, 0);
764                 notification_set_execute_option(notiHandle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data);
765         }
766         else
767         {
768                 SysLog(NID_APP, "service_to_bundle failed");
769         }
770
771         // Set layout
772         if (isOngoing)
773         {
774                 OngoingActivityType activityType = notifyRequest.GetOngoingActivityType();
775                 if (activityType == ONGOING_ACTIVITY_TYPE_TEXT)
776                 {
777                         layout = NOTIFICATION_LY_ONGOING_EVENT;
778                 }
779                 else
780                 {
781                         layout = NOTIFICATION_LY_ONGOING_PROGRESS;
782                 }
783         }
784         notification_set_layout(notiHandle, layout);
785
786         // For ongoing
787         if (isOngoing)
788         {
789                 OngoingActivityType activityType = notifyRequest.GetOngoingActivityType();
790                 int progress = notifyRequest.GetOngoingActivityProgress();
791
792                 switch (activityType)
793                 {
794                 case ONGOING_ACTIVITY_TYPE_PROGRESS_PERCENTAGE:
795                         if (needUpdate)
796                         {
797                                 r = ConvertNotificationResult(notification_update_progress(notiHandle, notiPrivateId, progress/100.));
798                         }
799                         else
800                         {
801                                 r = ConvertNotificationResult(notification_set_progress(notiHandle, progress/100.));
802                         }
803                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
804                         break;
805
806                 case ONGOING_ACTIVITY_TYPE_PROGRESS_BYTE:
807                         if (needUpdate)
808                         {
809                                 r = ConvertNotificationResult(notification_update_size(notiHandle, notiPrivateId, progress));
810                         }
811                         else
812                         {
813                                 r = ConvertNotificationResult(notification_set_size(notiHandle, progress));
814                         }
815                         SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
816                         break;
817
818                 case ONGOING_ACTIVITY_TYPE_TEXT:
819                         // Do nothing
820                         break;
821
822                 default:
823                         r = E_OPERATION_FAILED;
824                         break;
825                 }
826                 if (needUpdate)
827                 {
828                         r = ConvertNotificationResult(notification_update_content(notiHandle, notiPrivateId, pMsg.get()));
829                 }
830                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification update failure.", GetErrorMessage(r));
831         }
832
833         // insert for new notification
834         if (!needUpdate)
835         {       // new
836                 r = ConvertNotificationResult(notification_insert(notiHandle, &notiPrivateId));
837                 SysLog(NID_APP, "Insert notification and get new notiPrivateId(%d)", notiPrivateId);
838                 SysTryLog(NID_APP, !IsFailed(r), "[%s] Notification post failure.", GetErrorMessage(r));
839                 if (isOngoing)
840                 {
841                         __notifyPrivitIdForOngoing  = notiPrivateId;
842                 }
843                 else
844                 {
845                         __notifyPrivitId = notiPrivateId;
846                 }
847         }
848
849         // notification_update just for non ongoing and text type ongoing only.
850         if (needUpdate && !isOngoing)
851         {
852                 notification_update(notiHandle);
853                 SysLog(NID_APP, "Notification update from notiPrivateId(%d)", notiPrivateId);
854         }
855
856
857 CATCH:
858         service_destroy(hSvc);
859         notification_free(notiHandle);
860         return r;
861 }
862
863 result
864 _NotificationManagerImpl::RemoveNotification(void)
865 {
866         return RemoveNotification(false);
867 }
868
869 result
870 _NotificationManagerImpl::RemoveOngoingActivityNotification(void)
871 {
872         return RemoveNotification(true);
873 }
874
875 result
876 _NotificationManagerImpl::RemoveNotification(bool onGoing)
877 {
878         result r = E_SUCCESS;
879         notification_error_e err = NOTIFICATION_ERROR_NONE;
880         const notification_type_e notiType = onGoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
881         const int notiPrivateId = onGoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
882
883         if (notiPrivateId != -1)
884         {
885                 notification_h notiHandle = notification_load(null, notiPrivateId);
886                 if (notiHandle)
887                 {
888                         err = notification_delete(notiHandle);
889                         SysLog(NID_APP, "Notification deleted.");
890                 }
891                 else
892                 {
893                         SysLog(NID_APP, "Notification already deleted.");
894                 }
895                 notification_free(notiHandle);
896         }
897         else
898         {
899                 err = notification_delete_all_by_type(null, notiType);
900                 SysLog(NID_APP, "All [%s] notification deleted.", onGoing ? "Ongoing" : "Normal");
901         }
902
903         switch (err)
904         {
905         case NOTIFICATION_ERROR_NONE:
906                 r = E_SUCCESS;
907                 break;
908
909         case NOTIFICATION_ERROR_INVALID_DATA:
910                 r = E_INVALID_ARG;
911                 break;
912
913         default:
914                 r = E_SYSTEM;
915                 break;
916         }
917
918         return r;
919 }
920
921 result
922 _NotificationManagerImpl::RemoveNotificationByAppId(const Tizen::App::AppId& appId, bool onGoing)
923 {
924         result r = E_SUCCESS;
925         notification_error_e err = NOTIFICATION_ERROR_NONE;
926         bool isValidAppId = _Aul::IsInstalled(appId);
927         SysTryReturnResult(NID_APP, isValidAppId == true, E_APP_NOT_INSTALLED, "The application %ls is not installed", appId.GetPointer());
928
929         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
930         const notification_type_e notiType = onGoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI;
931         const int notiPrivateId = onGoing ? __notifyPrivitIdForOngoing : __notifyPrivitId;
932
933         if (notiPrivateId != -1)
934         {
935                 notification_h notiHandle = notification_load(pAppId.get(), notiPrivateId);
936                 if (notiHandle)
937                 {
938                         err = notification_delete(notiHandle);
939                         SysLog(NID_APP, "Notification deleted.");
940                 }
941                 else
942                 {
943                         SysLog(NID_APP, "Notification already deleted.");
944                 }
945                 notification_free(notiHandle);
946         }
947         else
948         {
949                 err = notification_delete_all_by_type(pAppId.get(), notiType);
950                 SysLog(NID_APP, "All [%s] notification deleted.", onGoing ? "Ongoing" : "Normal");
951         }
952
953         switch (err)
954         {
955         case NOTIFICATION_ERROR_NONE:
956                 r = E_SUCCESS;
957                 break;
958
959         case NOTIFICATION_ERROR_INVALID_DATA:
960                 r = E_INVALID_ARG;
961                 break;
962
963         default:
964                 r = E_SYSTEM;
965                 break;
966         }
967
968         return r;
969 }
970
971 void
972 _NotificationManagerImpl::RemoveBadge(const char* pkgName) const
973 {
974         bool badgeExist = false;
975         badge_error_e badgeError = badge_is_existing(pkgName, &badgeExist);
976         SysLog(NID_APP, "badge_is_existing: exitst= %d, error= %d.", badgeExist, badgeError);   //#####
977         if (badgeExist)
978         {
979                 badgeError = badge_remove(pkgName);
980                 SysLog(NID_APP, "badge_remove: error= %d.", badgeError);        //#####
981         }
982         SysLog(NID_APP, "Badge removed.");
983 }
984
985 void
986 _NotificationManagerImpl::SetBadgeCount(const char* pkgName, int badgeCount) const
987 {
988         bool badgeExist;
989         badge_error_e badgeError = badge_is_existing(pkgName, &badgeExist);
990         SysLog(NID_APP, "badge_is_existing: error= %d.", badgeError);   //#####
991         if (!badgeExist)
992         {
993                 badgeError = badge_create(pkgName, pkgName);
994                 SysLog(NID_APP, "badge_create: error= %d.", badgeError);        //#####
995         }
996
997         badge_set_count(pkgName, badgeCount);
998         SysLog(NID_APP, "badge_set_count: badgeNumber= %d.", badgeCount);
999 }
1000
1001 int
1002 _NotificationManagerImpl::GetBadgeCount(const char* pkgName) const
1003 {
1004         unsigned int count = 0;
1005
1006         badge_error_e badgeError = badge_get_count(pkgName, &count);
1007         if (badgeError == BADGE_ERROR_NONE)
1008         {
1009                 SysLog(NID_APP, "badge_get_count: ret= %d.", count);
1010                 return count;
1011         }
1012         else
1013         {
1014                 SysLog(NID_APP, "badge_get_count: error= %d.", badgeError);
1015                 return -1;
1016         }
1017 }
1018
1019 } }    // Tizen::Shell