Merge branch 'tizen_3.0' into tizen_4.0
[platform/core/api/webapi-plugins.git] / src / notification / notification_manager.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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 #include "notification/notification_manager.h"
18
19 #include <fcntl.h>
20 #include <unistd.h>
21
22 #include <app_common.h>
23 #include <app_control_internal.h>
24 #include <device/led.h>
25 #include <notification_internal.h>
26 #include <notification_list.h>
27
28 #include "common/converter.h"
29 #include "common/logger.h"
30 #include "common/scope_exit.h"
31
32 #include "notification/common_notification.h"
33 #include "notification/status_notification.h"
34 #include "notification/user_notification.h"
35
36 namespace extension {
37 namespace notification {
38
39 using namespace common;
40
41 NotificationManager::NotificationManager() {
42   LoggerD("Enter");
43 }
44
45 NotificationManager::~NotificationManager() {
46   LoggerD("Enter");
47 }
48
49 NotificationManager* NotificationManager::GetInstance() {
50   LoggerD("Enter");
51   static NotificationManager instance;
52   return &instance;
53 }
54
55 PlatformResult NotificationManager::Post(const picojson::object& args, picojson::object& out) {
56   LoggerD("Enter");
57   return StatusNotification::PostStatusNotification(args, false, &out);
58 }
59
60 PlatformResult NotificationManager::PostUserNoti(const picojson::object& args,
61                                                  picojson::object& out) {
62   LoggerD("Enter");
63   return UserNotification::PostUserNotification(args, false, &out);
64 }
65
66 PlatformResult NotificationManager::Update(const picojson::object& args) {
67   LoggerD("Enter");
68   return StatusNotification::PostStatusNotification(args, true, nullptr);
69 }
70
71 PlatformResult NotificationManager::UpdateUserNoti(const picojson::object& args) {
72   LoggerD("Enter");
73   return UserNotification::PostUserNotification(args, true, nullptr);
74 }
75
76 PlatformResult NotificationManager::Remove(const picojson::object& args) {
77   LoggerD("Enter");
78   int id = std::stoi(FromJson<std::string>(args, "id"));
79
80   int ret = notification_delete_by_priv_id(nullptr, NOTIFICATION_TYPE_NONE, id);
81   if (NOTIFICATION_ERROR_NONE != ret) {
82     return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Cannot remove notification error",
83                               ("Cannot remove notification error: %d", ret));
84   }
85
86   return PlatformResult(ErrorCode::NO_ERROR);
87 }
88
89 PlatformResult NotificationManager::RemoveAll() {
90   LoggerD("Enter");
91   int ret = notification_delete_all(NOTIFICATION_TYPE_NOTI);
92   if (NOTIFICATION_ERROR_NONE != ret) {
93     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification noti remove all failed",
94                               ("Notification remove all failed: %d", ret));
95   }
96
97   ret = notification_delete_all(NOTIFICATION_TYPE_ONGOING);
98   if (NOTIFICATION_ERROR_NONE != ret) {
99     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Notification ongoing remove all failed",
100                               ("Notification remove all failed: %d", ret));
101   }
102
103   return PlatformResult(ErrorCode::NO_ERROR);
104 }
105
106 PlatformResult NotificationManager::Get(const picojson::object& args, picojson::object& out,
107                                         bool is_new_impl) {
108   LoggerD("Enter");
109   int id;
110   try {
111     id = std::stoi(FromJson<std::string>(args, "id"));
112   } catch (...) {
113     LoggerE("Failed to convert string to int");
114     return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
115   }
116
117   app_control_h app_control = nullptr;
118   notification_h noti_handle = nullptr;
119
120   SCOPE_EXIT {
121     if (app_control) {
122       app_control_destroy(app_control);
123     }
124     free(noti_handle);
125   };
126
127   PlatformResult status = StatusNotification::GetNotiHandle(id, &noti_handle);
128   if (status.IsError()) {
129     LoggerE("Failed: GetNotiHandle");
130     return status;
131   }
132
133   status = StatusNotification::GetAppControl(noti_handle, &app_control);
134   if (status.IsError()) {
135     LoggerE("Failed: GetAppControl");
136     return status;
137   }
138
139   if (!is_new_impl) {
140     status = StatusNotification::ToJson(id, noti_handle, app_control, &out);
141   } else {
142     status = UserNotification::ToJson(id, noti_handle, app_control, &out);
143   }
144   if (status.IsError()) {
145     LoggerE("Failed: ToJson");
146     return status;
147   }
148   return PlatformResult(ErrorCode::NO_ERROR);
149 }
150
151 PlatformResult NotificationManager::GetAll(picojson::array& out, bool is_new_impl) {
152   LoggerD("Enter");
153   notification_h noti = nullptr;
154   notification_list_h noti_list = nullptr;
155   notification_list_h noti_list_iter = nullptr;
156   char* package = nullptr;
157
158   if (APP_ERROR_NONE == app_get_id(&package)) {
159     LoggerD("Package id: %s", package);
160   } else {
161     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Could not get package id");
162   }
163   const std::string package_str = package;
164   free(package);
165
166   int ret = notification_get_detail_list(package_str.c_str(), NOTIFICATION_GROUP_ID_NONE,
167                                          NOTIFICATION_PRIV_ID_NONE, -1, &noti_list);
168   if (NOTIFICATION_ERROR_NONE != ret) {
169     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Get notification list error",
170                               ("Get notification list error: %d", ret));
171   }
172
173   SCOPE_EXIT {
174     notification_free_list(noti_list);
175   };
176
177   noti_list_iter = notification_list_get_head(noti_list);
178
179   while (nullptr != noti_list_iter) {
180     noti = notification_list_get_data(noti_list_iter);
181     if (nullptr != noti) {
182       int noti_priv = -1;
183       ret = notification_get_id(noti, nullptr, &noti_priv);
184       if (NOTIFICATION_ERROR_NONE != ret) {
185         return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot get notification id error",
186                                   ("Cannot get notification id, error: %d", ret));
187       }
188
189       app_control_h app_control = nullptr;
190       PlatformResult status = StatusNotification::GetAppControl(noti, &app_control);
191
192       SCOPE_EXIT {
193         if (app_control) {
194           app_control_destroy(app_control);
195         }
196       };
197
198       if (status.IsError()) return status;
199
200       picojson::object noti_item = picojson::object();
201
202       if (!is_new_impl) {
203         status = StatusNotification::ToJson(noti_priv, noti, app_control, &noti_item);
204       } else {
205         status = UserNotification::ToJson(noti_priv, noti, app_control, &noti_item);
206       }
207       if (status.IsError()) return status;
208
209       out.push_back(picojson::value(noti_item));
210     }
211
212     noti_list_iter = notification_list_get_next(noti_list_iter);
213   }
214
215   return PlatformResult(ErrorCode::NO_ERROR);
216 }
217
218 PlatformResult NotificationManager::PlayLEDCustomEffect(const picojson::object& args) {
219   LoggerD("Enter");
220
221   int timeOn = FromJson<double>(args, "timeOn");
222   int timeOff = FromJson<double>(args, "timeOff");
223   unsigned int color = FromJson<double>(args, "color");
224
225   auto& flags = FromJson<picojson::array>(args, "flags");
226   unsigned int platformFlags = 0;
227   for (auto flag : flags) {
228     std::string flagStr = JsonCast<std::string>(flag);
229     if ("LED_CUSTOM_DEFAULT" == flagStr)
230       platformFlags |= LED_CUSTOM_DEFAULT;
231     else if ("LED_CUSTOM_DUTY_ON" == flagStr)
232       platformFlags |= LED_CUSTOM_DUTY_ON;
233   }
234
235   int ret;
236   ret = device_led_play_custom(timeOn, timeOff, color, platformFlags);
237   if (DEVICE_ERROR_NONE != ret) {
238     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot play LED custom effect",
239                               ("Cannot play LED custom effect: ", ret));
240   }
241
242   return PlatformResult(ErrorCode::NO_ERROR);
243 }
244
245 PlatformResult NotificationManager::StopLEDCustomEffect() {
246   LoggerD("Enter");
247
248   int ret = device_led_stop_custom();
249   if (DEVICE_ERROR_NONE != ret) {
250     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Cannot stop LED custom effect",
251                               ("Cannot stop LED custom effect: ", ret));
252   }
253
254   return PlatformResult(ErrorCode::NO_ERROR);
255 }
256
257 common::PlatformResult NotificationManager::SaveTemplate(const picojson::object& args) {
258   LoggerD("Enter");
259   std::string name = FromJson<std::string>(args, "name");
260   notification_h noti_handle = nullptr;
261   int ret;
262   SCOPE_EXIT {
263     notification_free(noti_handle);
264   };
265
266   PlatformResult status = PlatformResult(ErrorCode::NO_ERROR);
267   const auto& new_impl_it = args.find("newImpl");
268   const auto& noti_val_it = args.find("notification");
269   if (args.end() != new_impl_it && args.end() != noti_val_it && new_impl_it->second.get<bool>()) {
270     status = UserNotification::GetNotiHandleFromJson(noti_val_it->second, false, &noti_handle);
271   } else {
272     status = StatusNotification::GetNotiHandleFromJson(noti_val_it->second, false, &noti_handle);
273   }
274
275   if (status.IsError()) {
276     return status;
277   }
278
279   ret = notification_save_as_template(noti_handle, name.c_str());
280   if (NOTIFICATION_ERROR_NONE != ret) {
281     LoggerD("Error: %d (%s)", ret, get_error_message(ret));
282     if (NOTIFICATION_ERROR_MAX_EXCEEDED == ret) {
283       return LogAndCreateResult(ErrorCode::QUOTA_EXCEEDED_ERR,
284                                 "Maximum number of templates exceeded",
285                                 ("Maximum number of templates exceeded, error: %d", ret));
286     } else {
287       return LogAndCreateResult(ErrorCode::ABORT_ERR, "Saving template failed",
288                                 ("Saving template failed, error: %d", ret));
289     }
290   }
291
292   return PlatformResult(ErrorCode::NO_ERROR);
293 }
294
295 common::PlatformResult NotificationManager::CreateFromTemplate(const picojson::object& args,
296                                                                picojson::object& out) {
297   LoggerD("Enter");
298   std::string name = FromJson<std::string>(args, "name");
299
300   notification_h noti_handle = nullptr;
301   noti_handle = notification_create_from_template(name.c_str());
302   if (!noti_handle) {
303     return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "The template with given name not found",
304                               ("The template with given name not found, handle is nullptr"));
305   }
306
307   SCOPE_EXIT {
308     notification_free(noti_handle);
309   };
310
311   // This method is designed to return only UserNotification objects
312   PlatformResult status = UserNotification::ToJson(0, noti_handle, nullptr, &out);
313   if (status.IsError()) {
314     LoggerE("Failed: ToJson");
315     return status;
316   }
317   return PlatformResult(ErrorCode::NO_ERROR);
318 }
319
320 }  // namespace notification
321 }  // namespace extension