Fix various build warnings
[platform/framework/web/web-provider.git] / src / Core / BoxSchemeHandler.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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    BoxSchemeHandler.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20
21 #include <string.h>
22 #include <ctime>
23 #include "Box.h"
24 #include "Service/AppControl.h"
25 #include "Service/PeriodChanger.h"
26 #include "Service/ScrollHolder.h"
27 #include "Service/MessageManager.h"
28 #include "Util/Log.h"
29 #include "Util/Util.h"
30 #include "BoxSchemeHandler.h"
31
32 using namespace Service;
33
34 static const std::string BOX_SCHEME("box://");
35 static const std::string BOX_SCHEME_RELOAD("box://reload");
36 static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
37 static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
38 static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
39 static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
40 static const std::string BOX_SCHEME_SEND_MESSAGE_TO_PD("box://send-message-to-pd");
41 static const std::string BOX_SCHEME_SEND_MESSAGE_TO_BOX("box://send-message-to-box");
42
43 static const std::string HTTP_SCHEME("http://");
44 static const std::string HTTPS_SCHEME("https://");
45
46 // static variable intialization
47 BoxSchemeHandler* BoxSchemeHandler::s_instance = NULL;
48
49 BoxSchemeHandler::BoxSchemeHandler()
50     : m_boxMap()
51 {
52     LogD("enter");
53 }
54
55 BoxSchemeHandler::~BoxSchemeHandler()
56 {
57     LogD("enter");
58 }
59
60 BoxSchemeHandler* BoxSchemeHandler::Instance()
61 {
62     LogD("enter");
63     if (!s_instance) {
64         s_instance = new BoxSchemeHandler();
65     }
66
67     return s_instance;
68 }
69
70 void BoxSchemeHandler::registerBox(std::string& instanceId, Box* box)
71 {
72     LogD("enter");
73
74     if (getBox(instanceId)) {
75         LogD("already registered");
76         return;
77     }
78
79     m_boxMap.insert(BoxMapPair(instanceId, box));
80 }
81
82 void BoxSchemeHandler::unregisterBox(std::string& instanceId)
83 {
84     LogD("enter");
85     m_boxMap.erase(instanceId);
86 }
87
88 bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
89 {
90     LogD("enter");
91
92     if (!isBoxScheme(uri)) {
93         return false;
94     }
95
96     if (!uri.compare(BOX_SCHEME_RELOAD)) {
97        return handleReload(instanceId);
98     }
99
100     if (!uri.compare(
101                 0,
102                 BOX_SCHEME_CHANGE_PERIOD.size(),
103                 BOX_SCHEME_CHANGE_PERIOD))
104     {
105         std::string key("period");
106         std::string period = parse(uri, key);
107         if (period.empty()) {
108             return handleChangePeriod(instanceId);
109         }
110
111         return handleChangePeriod(instanceId, std::atof(period.c_str()));
112     }
113
114     if (!uri.compare(
115                 0,
116                 BOX_SCHEME_LAUNCH_BROWSER.size(),
117                 BOX_SCHEME_LAUNCH_BROWSER))
118     {
119         std::string key("url");
120         std::string url = parse(uri, key);
121         return handleLaunchBrowser(instanceId, url);
122     }
123
124     if (!uri.compare(BOX_SCHEME_SCROLL_START)) {
125        return handleScroll(instanceId, true);
126     }
127
128     if (!uri.compare(BOX_SCHEME_SCROLL_STOP)) {
129        return handleScroll(instanceId, false);
130     }
131
132     if (!uri.compare(
133                 0,
134                 BOX_SCHEME_SEND_MESSAGE_TO_BOX.size(),
135                 BOX_SCHEME_SEND_MESSAGE_TO_BOX))
136     {
137         std::string key("message");
138         std::string message = parse(uri, key);
139         return handleSendMessage(instanceId, MessageManager::TO_BOX, message);
140     }
141
142     if (!uri.compare(
143                 0,
144                 BOX_SCHEME_SEND_MESSAGE_TO_PD.size(),
145                 BOX_SCHEME_SEND_MESSAGE_TO_PD))
146     {
147         std::string key("message");
148         std::string message = parse(uri, key);
149         return handleSendMessage(instanceId, MessageManager::TO_PD, message);
150     }
151     LogD("unknown box scheme protocol");
152     return false;
153 }
154
155 bool BoxSchemeHandler::isBoxScheme(std::string& uri)
156 {
157     LogD("enter");
158     if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
159         return true;
160     }
161
162     return false;
163 }
164
165 Box* BoxSchemeHandler::getBox(std::string& instanceId)
166 {
167     LogD("enter");
168
169     auto it = m_boxMap.find(instanceId);
170     if (it != m_boxMap.end()) {
171         LogD("registered: %s (%p)", it->first.c_str(), it->second);
172         return it->second;
173     }
174
175     return NULL;
176 }
177
178 bool BoxSchemeHandler::handleScroll(std::string& instanceId, bool start)
179 {
180     using namespace Service::ScrollHolder;
181
182     LogD("enter");
183         Box* box = getBox(instanceId);
184     if (!box) {
185         LogD("unregistered instance");
186         return false;
187     }
188
189     holdHorizontalScroll(box->m_boxInfo->boxId, instanceId, start);
190     return true;
191 }
192
193 bool BoxSchemeHandler::handleReload(std::string& instanceId)
194 {
195     LogD("enter");
196     Box* box = getBox(instanceId);
197     if (!box) {
198         LogD("unregistered instance");
199         return false;
200     }
201
202     // In the future, new content info can be set by caller
203     box->updateInternal();
204     return true;
205 }
206
207 bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId, float requestedPeriod)
208 {
209     LogD("enter");
210
211     Box* box = getBox(instanceId);
212     if (!box) {
213         LogD("no box for update period");
214         return false;
215     }
216
217     m_periodChanger =
218         Service::PeriodChanger::create(
219             box->m_boxInfo->boxId, instanceId,
220             box->m_boxInfo->period, requestedPeriod);
221
222     return m_periodChanger->change();
223 }
224
225 bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
226 {
227     LogD("enter");
228     UNUSED_PARAM(instanceId);
229
230     if (!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
231         !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
232     {
233         return Service::AppControl::launchBrowser(url);
234     }
235
236     return false;
237 }
238
239 bool BoxSchemeHandler::handleSendMessage(
240         std::string& instanceId,
241         MessageManager::ReceiverType receiver,
242         std::string& message)
243 {
244     LogD("enter");
245     Box* box = getBox(instanceId);
246     if (!box) {
247         LogD("no box for update period");
248         return false;
249     };
250
251     // set webview of receiver
252     Evas_Object* webview;
253     switch (receiver) {
254     case MessageManager::TO_BOX:
255         webview = box->m_view->getBoxWebView();
256         break;
257     case MessageManager::TO_PD:
258         webview = box->m_view->getPdWebView();
259         break;
260     default:
261         LogD("not supported receiver");
262         return false;
263     }
264
265     return m_messageManager->send(webview, receiver, message);
266 }
267
268 std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
269 {
270     LogD("enter");
271
272     // TODO url parameter SHOULD be parsed using std::regex, not manually
273     std::string value("");
274
275     unsigned found = uri.find_first_of("?");
276     if (found == std::string::npos) {
277         LogD("no query");
278         return value;
279     }
280
281     std::string query = std::string(uri, found + 1);
282     found = 0;
283     do {
284         LogD("enter\n");
285         unsigned seperator = query.find_first_of("=", found + 1);
286         if (seperator == std::string::npos) {
287             LogD("no '=' character\n");
288             break;
289         }
290
291         unsigned next = query.find_first_of("@", found + 1);
292         if (!query.compare(found, key.size(), key)) {
293             LogD("key matched!\n");
294             value = std::string(query, seperator + 1, next - seperator - 1);
295             break;
296         }
297
298         found = next + 1;
299     } while (found && found != std::string::npos);
300
301     LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
302     return value;
303 }