upload tizen1.0 source
[platform/framework/web/wrt.git] / src / view / view_logic_web_notification_support.cpp
1 /*
2  * Copyright (c) 2011 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  * @file    view_logic_web_notification_support.cpp
18  * @author  Jihoon Chung (jihoon.chung@samsung.com)
19  * @brief   Implementation file of web Notification API used by ViewLogic
20  */
21
22 #include "view_logic_web_notification_support.h"
23 #include <string>
24 #include <dpl/log/log.h>
25 #include <dpl/string.h>
26
27 #include <notification.h>
28 #include <pcrecpp.h>
29 #include <sstream>
30 #include <curl/curl.h>
31 #include <widget_model.h>
32
33 namespace {
34 const char* PATTERN_CHECK_EXTERNAL = "^(http(s)?://)?\\w+.*$";
35 }
36
37 namespace ViewModule {
38 namespace WebNotification {
39
40 bool notificationShow(webNotificationDataPtr notiData);
41 bool notificationHide(webNotificationDataPtr notiData);
42 bool isExternalUri(const std::string &pattern, const std::string &uri);
43 bool downloadImage(webNotificationDataPtr notiData);
44 size_t curlWriteData(void *ptr, size_t size, size_t nmemb, FILE *stream);
45
46 WebNotificationData::WebNotificationData(
47     WidgetModel* widgetModel, int id) :
48     m_widgetModel(widgetModel), m_id(id)
49 {
50     Assert(m_widgetModel);
51 }
52
53 WebNotificationData::~WebNotificationData()
54 {
55 }
56
57 bool showWebNotification(webNotificationDataPtr notiData)
58 {
59     LogInfo("showWebNotification called");
60
61     /* TODO : register notification to database */
62     return notificationShow(notiData);
63 }
64
65 bool cancelWebNotification(webNotificationDataPtr /*notiData*/)
66 {
67     LogInfo("cancelWebNotification called");
68     return false;
69 }
70
71 bool notificationShow(webNotificationDataPtr notiData)
72 {
73     LogInfo("notificationShow called");
74     Assert(notiData);
75     notification_h noti_h = NULL;
76     notification_error_e error = NOTIFICATION_ERROR_NONE;
77
78     Try {
79         // create notification
80         noti_h = notification_new(
81             NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_NONE, notiData->m_id);
82         if (!noti_h) {
83             LogError("Fail to notification_new");
84             return false;
85         }
86
87         // set notification title
88         error = notification_set_text(
89             noti_h,
90             NOTIFICATION_TEXT_TYPE_TITLE,
91             notiData->m_title.c_str(),
92             NULL,
93             NOTIFICATION_VARIABLE_TYPE_NONE);
94         if (error != NOTIFICATION_ERROR_NONE) {
95             ThrowMsg(Exception::NotificationShowError, "Fail to set title");
96         }
97
98         // set notification content
99         error = notification_set_text(
100             noti_h,
101             NOTIFICATION_TEXT_TYPE_CONTENT,
102             notiData->m_body.c_str(),
103             NULL,
104             NOTIFICATION_VARIABLE_TYPE_NONE);
105         if (error != NOTIFICATION_ERROR_NONE) {
106             ThrowMsg(Exception::NotificationShowError, "Fail to set content");
107         }
108
109         //check uri is "http", https" or not
110         bool validIconURL = true;
111         LogInfo("url path is " << notiData->m_iconURL);
112         if (isExternalUri(PATTERN_CHECK_EXTERNAL, notiData->m_iconURL)) {
113             //download image from url
114             validIconURL = downloadImage(notiData);
115         }
116
117         //set image
118         // If fail to download external image, skip to set image.
119         // In this case, set to default package image.
120         if (true == validIconURL) {
121             error = notification_set_image(
122                 noti_h,
123                 NOTIFICATION_IMAGE_TYPE_ICON,
124                 notiData->m_iconURL.c_str());
125             if (error != NOTIFICATION_ERROR_NONE) {
126                 ThrowMsg(Exception::NotificationShowError,
127                          "Fail to free notification");
128             }
129         }
130
131         // insert notification
132         int priv_id = 0;
133         error = notification_insert(noti_h, &priv_id);
134         if (error != NOTIFICATION_ERROR_NONE) {
135             ThrowMsg(Exception::NotificationShowError,
136                      "Fail to insert notification");
137         }
138
139         LogInfo("Notification is inserted!");
140         LogInfo("noti id =[" << notiData->m_id << "] " <<
141                 "priv_id =[" << priv_id << "]");
142
143         if (noti_h) {
144             error = notification_free(noti_h);
145             if (error != NOTIFICATION_ERROR_NONE) {
146                         ThrowMsg(Exception::NotificationShowError,
147                                  "Fail to free notification");
148             }
149             noti_h = NULL;
150         }
151         return true;
152     } Catch(Exception::NotificationShowError) {
153         notification_free(noti_h);
154         noti_h = NULL;
155         return false;
156     } Catch(DPL::Exception) {
157         return false;
158     }
159 }
160
161 bool notificationHide(webNotificationDataPtr notiData)
162 {
163     LogInfo("notificationHide called");
164     Assert(notiData);
165     return true;
166 }
167
168 bool isExternalUri(const std::string &pattern, const std::string &uri)
169 {
170     LogInfo("isExternalUri called");
171
172     pcrecpp::RE_Options pcreOpt;
173     pcreOpt.set_caseless(true);
174     pcrecpp::RE re(pattern, pcreOpt);
175
176     return re.PartialMatch(uri);
177 }
178
179 bool downloadImage(webNotificationDataPtr notiData)
180 {
181     LogInfo("downloadImage called");
182     Assert(notiData);
183     // download path is
184     // /opt/apps/pkgname/data + '/' + filename
185     std::string downloadPath =
186     DPL::ToUTF8String(
187             notiData->m_widgetModel->PersistentStoragePath.Get()) +  "/";
188     LogDebug("downloadPath " << downloadPath);
189
190     // Make valid filename
191     // If there is already exist filename, rename to "filename_%d"
192     std::string fileName =
193         notiData->m_iconURL.substr(notiData->m_iconURL.rfind('/') + 1);
194     LogDebug("fileName from URL: " << fileName);
195     std::string rename = fileName;
196     unsigned int renameSuffixNb = 0;
197     while (0 == access((downloadPath + rename).c_str(), F_OK)) {
198         std::ostringstream suffixOstr;
199         suffixOstr.str("");
200         suffixOstr << fileName << "_" << renameSuffixNb++;
201
202         rename = fileName;
203         rename.insert(rename.find('.'), suffixOstr.str());
204     }
205
206     downloadPath += rename;
207     LogDebug("Valiad file path : " << downloadPath);
208
209     // Download image by curl
210     FILE *fp = NULL;
211     CURL *curl = NULL;
212
213     Try {
214         curl = curl_easy_init();
215         if (NULL == curl) {
216             ThrowMsg(Exception::InitError, "fail to curl_easy_init");
217         }
218
219         fp = fopen(downloadPath.c_str(), "wb");
220         if (fp == NULL) {
221             curl_easy_cleanup(curl);
222             ThrowMsg(Exception::InitError, "fail to open");
223         }
224
225         curl_easy_setopt(curl, CURLOPT_URL, notiData->m_iconURL.c_str());
226         curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
227         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlWriteData);
228
229         if (curl_easy_perform(curl) != 0) {
230             ThrowMsg(Exception::DownloadImageError,
231                      "fail to curl_easy_perform");
232         }
233         curl_easy_cleanup(curl);
234         fclose(fp);
235     } Catch (Exception::DownloadImageError) {
236         fclose(fp);
237         curl_easy_cleanup(curl);
238         return false;
239     } Catch (DPL::Exception) {
240         return false;
241     }
242
243     LogDebug("Download success.. downloadedImgPath: " << downloadPath);
244     notiData->m_iconURL = downloadPath;
245     return true;
246 }
247
248 size_t curlWriteData(void *ptr, size_t size, size_t nmemb, FILE *stream)
249 {
250     size_t written = fwrite(ptr, size, nmemb, stream);
251     return written;
252 }
253
254 } // namespace WebNotification
255 } //namespace ViewModule