2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file wrt-wk2-bundle.cpp
18 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
19 * @brief Implementation file for view logic for Webkit2
21 #include "wrt-wk2-bundle.h"
24 #include <WKBundleInitialize.h>
25 #include <WKBundlePage.h>
26 #include <WKBundleFrame.h>
27 #include <WKURLRequest.h>
32 #include <WKURLResponseTizen.h>
33 #include <WKBundlePagePrivate.h>
40 #include <openssl/sha.h>
41 #include <openssl/hmac.h>
42 #include <openssl/evp.h>
43 #include <openssl/bio.h>
44 #include <openssl/buffer.h>
46 #include <dpl/log/log.h>
47 #include <dpl/foreach.h>
48 #include <dpl/assert.h>
49 #include <dpl/wrt-dao-ro/WrtDatabase.h>
50 #include <dpl/localization/localization_utils.h>
51 #include <dpl/string.h>
52 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
53 #include <dpl/utils/mime_type_utils.h>
54 #include <dpl/localization/LanguageTagsProvider.h>
55 #include <dpl/event/main_event_dispatcher.h>
56 #include <FBaseByteBuffer.h>
57 #include <security/FSecCrypto_TrustZoneService.h>
59 #include <wrt_plugin_module.h>
60 #include <profiling_util.h>
63 #include <appcore-efl.h>
65 #include "messages_names.h"
68 #include <scheme_action_map_type.h>
69 #include <scheme_action_map_data.h>
71 #include <js_overlay_types.h>
73 // URI localization on WebProcess side
74 #include "bundle_uri_handling.h"
77 const char * const uriChangedMessageName = "uri_changed_msg";
78 const char * const uriBlockedMessageName = "uri_blocked_msg";
79 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
80 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
81 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
82 const char * const URICHANGE_BLOCKED_URL = "null";
83 const char * const SCHEME_HTTP = "http";
84 const char * const SCHEME_HTTPS = "https";
85 const char * const SCHEME_FILE = "file://";
86 const char * const DATA_STRING = "data:";
87 const char * const BASE64_STRING = ";base64,";
88 const char * const BLANK_PAGE_URL = "about:blank";
89 const char * const HTML_MIME = "text/html";
90 const char * const PHP_MIME = "application/x-php";
91 const char * const VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
92 const char * const VIEWMODE_TYPE_MAXIMIZED = "maximized";
93 const std::size_t FILE_BUF_MAX_SIZE = 1024; // bytes
94 const std::size_t PLAIN_CHUNK_SIZE = 1008; // bytes
97 Bundle::Bundle(WKBundleRef bundle) :
102 m_willRemoveContext(NULL),
104 m_widgetType(WrtDB::APP_TYPE_UNKNOWN),
107 LOG_PROFILE_START("Bundle attachToThread");
108 WrtDB::WrtDatabase::attachToThreadRO();
109 m_uriChangedMessage = WKStringCreateWithUTF8CString(uriChangedMessageName);
110 LOG_PROFILE_STOP("Bundle attachToThread");
115 WrtDB::WrtDatabase::detachFromThread();
117 if (!m_pagesList.empty()) {
118 LogError("There are not closed pages!");
121 WKRelease(m_uriChangedMessage);
125 void Bundle::didCreatePageCallback(
126 WKBundleRef /*bundle*/,
127 WKBundlePageRef page,
128 const void* clientInfo)
130 LOG_PROFILE_START("didCreatePageCallback");
131 LogDebug("didCreatePageCallback called");
132 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
133 This->didCreatePage(page);
134 LOG_PROFILE_STOP("didCreatePageCallback");
137 void Bundle::didReceiveMessageCallback(
138 WKBundleRef /*bundle*/,
139 WKStringRef messageName,
140 WKTypeRef messageBody,
141 const void *clientInfo)
143 LogDebug("didReceiveMessageCallback called");
144 Bundle* bundle = static_cast<Bundle*>(const_cast<void*>(clientInfo));
145 bundle->didReceiveMessage(messageName, messageBody);
148 void Bundle::willDestroyPageCallback(
149 WKBundleRef /*bundle*/,
150 WKBundlePageRef page,
151 const void* clientInfo)
153 LogDebug("willDestroyPageCallback called");
154 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
155 This->willDestroyPage(page);
158 void Bundle::didCreatePage(WKBundlePageRef page)
160 auto mainFrame = WKBundlePageGetMainFrame(page);
161 auto context = WKBundleFrameGetJavaScriptContext(mainFrame);
162 m_pagesList.push_back(page);
163 m_pageGlobalContext[page] = context;
164 LogDebug("created Page : " << page << " created JSContext : " << context);
166 WKBundlePageResourceLoadClient resourceLoadClient = {
167 kWKBundlePageResourceLoadClientCurrentVersion, /* version */
168 this, /* clientinfo */
169 0, /* didInitiateLoadForResource */
170 willSendRequestForFrameCallback, /* willSendRequestForFrame */
171 0, /* didReceiveResponseForResource */
172 0, /* didReceiveContentLengthForResource */
173 didFinishLoadForResourceCallback, /* didFinishLoadForResource */
174 0, /* didFailLoadForResource */
175 0, /* shouldCacheResponse */
176 0, /* shouldUseCredentialStorage */
178 WKBundlePageSetResourceLoadClient(page, &resourceLoadClient);
180 WKBundlePageLoaderClient loaderClient = {
181 kWKBundlePageLoaderClientCurrentVersion,
182 this, /* clientinfo */
183 didStartProvisionalLoadForFrameCallback, /* didStartProvisionalLoadForFrame */
184 0, /* didReceiveServerRedirectForProvisionalLoadForFrame */
185 0, /* didFailProvisionalLoadWithErrorForFrame */
186 didCommitLoadForFrameCallback, /* didCommitLoadForFrame */
187 0, /* didFinishDocumentLoadForFrame */
188 0, /* didFinishLoadForFrame */
189 0, /* didFailLoadWithErrorForFrame */
190 0, /* didSameDocumentNavigationForFrame */
191 0, /* didReceiveTitleForFrame */
192 0, /* didFirstLayoutForFrame */
193 0, /* didFirstVisuallyNonEmptyLayoutForFrame */
194 didRemoveFrameFromHierarchyCallback, /* didRemoveFrameFromHierarchy */
195 0, /* didDisplayInsecureContentForFrame */
196 0, /* didRunInsecureContentForFrame */
197 0, /* didClearWindowObjectForFrame */
198 0, /* didCancelClientRedirectForFrame */
199 0, /* willPerformClientRedirectForFrame */
200 0, /* didHandleOnloadEventsForFrame */
201 0, /* didLayoutForFrame */
202 0, /* didNewFirstVisuallyNonEmptyLayout */
203 0, /* didDetectXSSForFrame */
204 0, /* shouldGoToBackForwardListItem */
205 0, /* globalObjectIsAvailableForFrame */
206 0, /* willDisconnectDOMWindowExtensionFromGlobalObject */
207 0, /* didReconnectDOMWindowExtensionToGlobalObject */
208 0, /* willDestroyGlobalObjectForDOMWindowExtension */
209 0, /* didFinishProgress */
210 0, /* shouldForceUniversalAccessFromLocalURL */
211 0, /* didReceiveIntentForFrame */
212 0, /* registerIntentServiceForFrame */
214 WKBundlePageSetPageLoaderClient(page, &loaderClient);
217 WKBundlePagePolicyClient policyClient = {
218 kWKBundlePagePolicyClientCurrentVersion, /* version */
219 this, /* clientInfo */
220 pageDecidePolicyForNavigationActionCallback, /**/
221 0, /* decidePolicyForNewWindowAction */
222 pageDecidePolicyForResponseCallback, /* decidePolicyForResponse */
223 0, /* unableToImplementPolicy */
225 WKBundlePageSetPolicyClient(page, &policyClient);
228 void Bundle::willDestroyPage(WKBundlePageRef page)
230 LogDebug("Destroyed page : " << page);
232 auto context = m_pageGlobalContext[page];
233 m_pagesList.remove(page);
234 m_pageGlobalContext.erase(page);
235 m_pageContext[page].erase(context);
237 PluginModule::unloadFrame(context);
238 PluginModule::stop(context);
241 void Bundle::fixWKMessageArgs(std::string & argScale,
242 std::string & argEncodedBundle,
243 std::string & argTheme)
245 if (argScale != "null" && argScale[0] == '_') {
246 argScale.erase(0, 1);
248 std::stringstream ssScale(argScale);
252 if (argEncodedBundle != "null" && argEncodedBundle[0] == '_') {
253 argEncodedBundle.erase(0, 1);
255 m_encodedBundle = argEncodedBundle;
258 if (argTheme != "null" && argTheme[0] == '_') {
259 argTheme.erase(0, 1);
265 void Bundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
267 LogDebug("got message type: " << toString(messageName).c_str());
268 if (WKStringIsEqualToUTF8CString(messageName,
269 BundleMessages::START))
271 if (!messageBody || WKStringGetTypeID() != WKGetTypeID(messageBody)) {
272 LogError("Wrong message format received, ignoring");
276 auto msgString = toString(static_cast<WKStringRef>(messageBody));
277 LogDebug("Got message text: " << msgString);
278 LogDebug("loading Page : " << m_pagesList.back() <<
279 " loading JSContext : " <<
280 m_pageGlobalContext[m_pagesList.back()]);
281 // set information from ui process
282 std::stringstream ssMsg(msgString);
283 std::string argScale;
284 std::string argEncodedBundle;
285 std::string argTheme;
289 m_widgetTizenId = DPL::FromASCIIString(id);
292 ssMsg >> argEncodedBundle;
294 ssMsg >> m_encrypted;
296 // ** Language tags setting completed **
297 fixWKMessageArgs(argScale, argEncodedBundle, argTheme);
298 } else if (WKStringIsEqualToUTF8CString(messageName,
299 BundleMessages::SHUTDOWN))
301 LogDebug("shutdown plugins");
303 if (m_pagesList.empty()) {
304 PluginModule::shutdown();
307 "PluginModule shutdown ignored, there are still alive pages!");
310 else if (WKStringIsEqualToUTF8CString(messageName,
311 BundleMessages::SET_CUSTOM_PROPERTIES))
313 LogDebug("reset custom properties of window objects");
314 // set information from ui process
315 auto msgString = toString(static_cast<WKStringRef>(messageBody));
317 std::string argScale;
318 std::string argEncodedBundle;
319 std::string argTheme;
321 std::stringstream ssMsg(msgString);
323 ssMsg >> argEncodedBundle;
326 fixWKMessageArgs(argScale, argEncodedBundle, argTheme);
328 //apply for each context
329 PageGlobalContext::iterator it = m_pageGlobalContext.begin();
330 for (; it != m_pageGlobalContext.end(); ++it) {
331 PluginModule::setCustomProperties(it->second,
333 m_encodedBundle.c_str(),
336 } else if (WKStringIsEqualToUTF8CString(
338 BundleMessages::DISPATCH_JAVASCRIPT_EVENT))
340 LogDebug("dispatch javascript event to created frames");
341 // set information from ui process
342 auto text = toString(static_cast<WKStringRef>(messageBody));
345 std::stringstream ss(text);
348 using namespace WrtPlugins::W3C;
349 // set arguments to be sent to js handler of this custom event
350 if (eventType == SoftKeyboardChangeCustomEvent) {
351 args = new SoftKeyboardChangeArgs;
352 ss >> static_cast<SoftKeyboardChangeArgs *>(args)->state;
353 ss >> static_cast<SoftKeyboardChangeArgs *>(args)->width;
354 ss >> static_cast<SoftKeyboardChangeArgs *>(args)->height;
357 //apply for each context
358 PageGlobalContext::iterator it = m_pageGlobalContext.begin();
359 for (; it != m_pageGlobalContext.end(); ++it) {
360 PluginModule::dispatchJavaScriptEvent(
362 static_cast<WrtPlugins::W3C::CustomEventType>(eventType),
367 delete static_cast<SoftKeyboardChangeArgs *>(args);
369 } else if (WKStringIsEqualToUTF8CString(
371 BundleMessages::INIT))
373 LogDebug("initializing plugins");
377 auto msgString = toString(static_cast<WKStringRef>(messageBody));
379 m_widgetTizenId = DPL::FromASCIIString(msgString);
381 WrtDB::WidgetDAOReadOnly dao(m_widgetTizenId);
382 /* This type of message is received when widget is restarting
383 * (proably in other situation too). Widget restart can be
384 * called after system language change so language tags have to
386 * Do NOT MOVE LanguageTags reset before m_widgetHandle initialization
388 // reset language tags (create new tags based on system locales)
389 LanguageTagsProviderSingleton::Instance().resetLanguageTags();
390 DPL::OptionalString defaultLocale = dao.getDefaultlocale();
391 if (!defaultLocale.IsNull()) {
392 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
396 LanguageTagsProviderSingleton::Instance().getLanguageTags();
397 LogDebug("Current widget locales (language tags):");
399 LogDebug("Locale: " << *it);
402 m_widgetType = dao.getWidgetType();
403 LogDebug("m_widgetType : " << m_widgetType.getApptypeToString() <<
404 "(m_widgetTizenId:" << m_widgetTizenId << ")");
406 LogDebug("Preload PluginLogicSingleton");
407 PluginModule::init(WrtDB::WidgetDAOReadOnly::getHandle(m_widgetTizenId));
408 LogDebug("Preload PluginLogicSingleton_end");
410 m_initialized = true;
414 LogDebug("already initalized");
419 WKURLRequestRef Bundle::willSendRequestForFrameCallback(
420 WKBundlePageRef /*page*/,
421 WKBundleFrameRef /*frame*/,
422 uint64_t /*resourceIdentifier*/,
423 WKURLRequestRef request,
424 WKURLResponseRef /*response*/,
425 const void *clientInfo)
427 LogDebug("willSendRequestForFrameCallback called");
428 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
429 return This->willSendRequestForFrame(request);
432 void Bundle::didStartProvisionalLoadForFrameCallback(
433 WKBundlePageRef page,
434 WKBundleFrameRef frame,
435 WKTypeRef* /*userData*/,
436 const void *clientInfo)
438 LogDebug("didStartProvisionalLoadForFrameCallback called");
439 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
442 WrtDB::WidgetDAOReadOnly dao(This->m_widgetTizenId);
443 WrtDB::WindowModeList modeList = dao.getWindowModes();
444 FOREACH(it, modeList) {
445 std::string viewMode = DPL::ToUTF8String(*it);
446 if (viewMode == VIEWMODE_TYPE_FULLSCREEN
447 || viewMode == VIEWMODE_TYPE_MAXIMIZED)
449 WKBundlePageSetViewMode(
451 WKStringCreateWithUTF8CString(viewMode.c_str()));
456 if (This->m_pageGlobalContext.count(page) == 0) {
459 if (This->m_pageContext.count(page) == 0) {
463 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
465 ContextSet::iterator i = This->m_pageContext[page].find(context);
467 if (i == This->m_pageContext[page].end()) {
468 LogDebug("Initially attached frame");
472 This->m_pageContext[page].erase(i);
473 This->m_willRemoveContext = context;
476 void Bundle::didRemoveFrameFromHierarchyCallback(
477 WKBundlePageRef page,
478 WKBundleFrameRef frame,
479 WKTypeRef* /*userData*/,
480 const void *clientInfo)
482 LogDebug("didRemoveFrameFromHierarchyCallback called");
483 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
485 if (This->m_pageContext.count(page) == 0) {
486 LogDebug("his->m_pageContext.count(page) == 0");
490 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
492 ContextSet::iterator i = This->m_pageContext[page].find(context);
494 if (i == This->m_pageContext[page].end()) {
495 LogWarning("Tried to unload frame which has never been loaded");
499 This->m_pageContext[page].erase(i);
501 PluginModule::unloadFrame(context);
504 void Bundle::didFinishLoadForResourceCallback(
505 WKBundlePageRef /*page*/,
506 WKBundleFrameRef /*frame*/,
507 uint64_t /*resourceIdentifier*/,
508 const void* /*clientInfo*/)
510 LogDebug("didFinishLoadForResourceCallback called");
513 void Bundle::didCommitLoadForFrameCallback(
514 WKBundlePageRef page,
515 WKBundleFrameRef frame,
516 WKTypeRef* /*userData*/,
517 const void *clientInfo)
519 LogInfo("didCommitLoadForFrameCallback called");
520 LOG_PROFILE_START("didCommitLoadForFrameCallback");
521 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
523 WKURLRef url = WKBundleFrameCopyURL(frame);
524 WKTypeRef retVal = NULL;
527 LogInfo("url is NULL");
531 if (This->m_willRemoveContext) {
532 PluginModule::unloadFrame(This->m_willRemoveContext);
533 This->m_willRemoveContext = NULL;
536 JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
538 This->m_pageContext[page].insert(context);
540 if (!WKBundleFrameIsMainFrame(frame)) {
541 LogInfo("frame isn't main frame");
543 WrtDB::WidgetDAOReadOnly::getHandle(This->m_widgetTizenId),
546 This->m_encodedBundle.c_str(),
547 This->m_theme.c_str());
548 PluginModule::loadFrame(context);
552 std::string scheme = getScheme(toString(url));
553 std::string result = URICHANGE_PLUGIN_RESTART;
555 if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) {
556 WKStringRef urlStr = WKURLCopyString(url);
557 WKBundlePostSynchronousMessage(This->m_bundle,
558 This->m_uriChangedMessage,
564 result = toString(static_cast<WKStringRef>(retVal));
566 LogInfo("result from UI process : " << result);
568 if (result == URICHANGE_PLUGIN_STOP_ONLY) {
569 PluginModule::stop(context);
570 } else if (result == URICHANGE_PLUGIN_RESTART) {
571 PluginModule::stop(context);
572 This->m_pageGlobalContext[page] = context;
573 LOG_PROFILE_START("PluginModule start");
575 WrtDB::WidgetDAOReadOnly::getHandle(This->m_widgetTizenId),
578 This->m_encodedBundle.c_str(),
579 This->m_theme.c_str() );
580 LOG_PROFILE_STOP("PluginModule start");
582 PluginModule::loadFrame(context);
584 LOG_PROFILE_STOP("didCommitLoadForFrameCallback");
587 WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationActionCallback(
588 WKBundlePageRef page,
589 WKBundleFrameRef frame,
590 WKBundleNavigationActionRef navigationAction,
591 WKURLRequestRef request,
593 const void* clientInfo)
595 LogDebug("pageDecidePolicyForNavigationActionCallback called");
597 Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
599 return This->pageDecidePolicyForNavigationAction(page,
606 WKBundlePagePolicyAction Bundle::pageDecidePolicyForResponseCallback(
607 WKBundlePageRef /* page */,
608 WKBundleFrameRef /* frame */,
609 WKURLResponseRef response,
610 WKURLRequestRef /* request */,
611 WKTypeRef* /* userData */,
612 const void* /* clientInfo */)
614 LogDebug("pageDecidePolicyForResponseCallback called");
617 WKStringRef contentTypeRef = WKURLResponseEflCopyContentType(response);
619 std::string contentType = toString(contentTypeRef);
620 LogDebug("contentTypeRef : " << contentType);
621 WKRelease(contentTypeRef);
623 if (contentType == HTML_MIME) {
624 LogDebug("Accepting HTML_MIME type");
625 return WKBundlePagePolicyActionUse;
627 if (contentType == PHP_MIME) {
628 LogDebug("Accepting php type");
629 return WKBundlePagePolicyActionUse;
632 return WKBundlePagePolicyActionPassThrough;
635 WKURLRequestRef Bundle::willSendRequestForFrame(WKURLRequestRef request)
637 LogDebug("willSendReq got " << toString(request).c_str());
638 WKURLRef url = WKURLRequestCopyURL(request);
639 WKStringRef urlStr = WKURLCopyString(url);
641 bool is_xhr = true; // Webkit should inform if it's XHR
642 DPL::String dplurl = DPL::FromUTF8String(toString(urlStr));
645 DPL::Optional<DPL::String> localizedUrl =
646 BundleURIHandling::localizeURI(dplurl, m_widgetTizenId);
647 bool ret = BundleURIHandling::processURI(
654 LogDebug("Not permitted resource: " << *localizedUrl);
658 LogDebug("URI processing result: " << *localizedUrl);
659 std::string tmpUrlStr = DPL::ToUTF8String(*localizedUrl);
660 WKURLRef tmpUrl = WKURLCreateWithUTF8CString(tmpUrlStr.c_str());
661 std::string scheme = toString(WKURLCopyScheme(url));
663 // Return value must contain details information of input
664 // WKURLRequestRef. Current webkit2 doesn't support api that
665 // copy WKURLRequestRef or change url only. Before webkit2
666 // support api, callback return original WKURLRequestRef in the
667 // case of external scheme
669 // external scheme also need to send message to UI process for
670 // checking roaming and security
671 if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) {
672 LogDebug("external scheme return original WKURLRequestRef");
677 std::string checkUrl = toString(tmpUrl);
681 if (isEncryptedResource(checkUrl, getFileSize)) {
682 std::string decryptString = DecryptResource(checkUrl,
684 if (!decryptString.empty()) {
685 std::string destString = DATA_STRING;
687 std::string mimeString =
689 MimeTypeUtils::identifyFileMimeType(
690 DPL::FromUTF8String(checkUrl)));
692 destString += mimeString;
693 destString += BASE64_STRING;
695 decryptString.insert(0, destString);
698 WKURLCreateWithUTF8CString(decryptString.c_str());
700 WKURLRequestRef req = WKURLRequestCreateWithWKURL(
703 LogDebug("return value " << decryptString << "]]");
708 WKURLRequestRef req = WKURLRequestCreateWithWKURL(tmpUrl);
710 LogDebug("return value " << toString(req).c_str());
715 WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationAction(
716 WKBundlePageRef /* page */,
717 WKBundleFrameRef frame,
718 WKBundleNavigationActionRef /* navigationAction */,
719 WKURLRequestRef request,
720 WKTypeRef* /* userData */)
722 using namespace ViewModule;
723 using namespace ViewModule::SchemeActionMap;
725 char const * const TIZEN_SCHEME = "tizen";
727 std::string request_uri = toString(request);
729 LogInfo("Uri being checked: " << request_uri);
732 if (request_uri == BLANK_PAGE_URL) {
733 return WKBundlePagePolicyActionUse;
737 DPL::String dplUrl = DPL::FromUTF8String(request_uri);
738 DPL::Optional<DPL::String> localizedUrl =
739 BundleURIHandling::localizeURI(dplUrl, m_widgetTizenId);
740 bool ret = BundleURIHandling::processURI(
741 *localizedUrl, true, m_widgetTizenId, m_bundle);
743 std::string blockedUrl = DPL::ToUTF8String(*localizedUrl);
744 LogDebug("URI is blocked: " << blockedUrl);
746 // Send information about blocked URI to UIProcess
747 WKStringRef urlStr = WKStringCreateWithUTF8CString(blockedUrl.c_str());
748 WKTypeRef retVal = NULL;
749 WKStringRef blockMessage = WKStringCreateWithUTF8CString(uriBlockedMessageName);
750 WKBundlePostSynchronousMessage(m_bundle, blockMessage, urlStr, &retVal);
753 WKRelease(blockMessage);
757 std::string request_scheme = getScheme(request_uri);
760 if (request_scheme == TIZEN_SCHEME) {
761 return WKBundlePagePolicyActionPassThrough;
765 Scheme scheme(request_scheme);
766 LogDebug("Scheme: " << request_scheme);
768 Scheme::Type type = scheme.GetType();
769 if (type < Scheme::FILE || type >= Scheme::COUNT) {
770 LogError("Invalid scheme: " << request_scheme);
771 return WKBundlePagePolicyActionPassThrough;
774 bool mainFrame = WKBundleFrameIsMainFrame(frame);
775 NavigationContext ctx = mainFrame ? TOP_LEVEL : FRAME_LEVEL;
777 LogDebug("Scheme type: " << type);
778 LogDebug("Navigation context: " << ctx);
779 LogDebug("Application type: " << m_widgetType.getApptypeToString());
783 if (m_widgetType == WrtDB::APP_TYPE_WAC20) {
784 action = g_wacActionMap[type][ctx];
785 } else if (m_widgetType == WrtDB::APP_TYPE_TIZENWEBAPP) {
786 action = g_tizenActionMap[type][ctx];
788 LogError("Unsupported application type: " << type);
789 return WKBundlePagePolicyActionPassThrough;
792 LogDebug("Uri action: " << action);
794 if (action != URI_ACTION_WRT) {
795 return WKBundlePagePolicyActionPassThrough;
798 return WKBundlePagePolicyActionUse;
801 std::string Bundle::toString(WKStringRef str)
803 if (WKStringIsEmpty(str)) {
804 return std::string();
806 size_t size = WKStringGetMaximumUTF8CStringSize(str);
807 char buffer[size + 1];
808 WKStringGetUTF8CString(str, buffer, size + 1);
812 std::string Bundle::toString(WKURLRef url)
814 WKStringRef urlStr = WKURLCopyString(url);
815 std::string str = toString(urlStr);
820 std::string Bundle::toString(WKURLRequestRef req)
822 WKURLRef reqUrl = WKURLRequestCopyURL(req);
823 std::string str = toString(reqUrl);
828 std::string Bundle::toString(WKErrorRef err)
830 WKStringRef domErr = WKErrorCopyDomain(err);
831 WKStringRef desc = WKErrorCopyLocalizedDescription(err);
832 std::string str = toString(domErr) + "\n" + toString(desc);
838 std::string Bundle::getScheme(std::string uri)
840 std::size_t found = uri.find(':');
843 if (found != std::string::npos) {
844 str = uri.substr(0, found);
850 bool Bundle::isEncryptedResource(std::string Url, int &size)
852 std::string filePath;
854 size_t pos = Url.find_first_not_of(SCHEME_FILE);
855 if (std::string::npos != pos) {
856 filePath = Url.substr(pos - 1);
859 if (m_encryptedFiles.empty()) {
860 WrtDB::WidgetDAOReadOnly(m_widgetTizenId).
861 getEncryptedFileList(m_encryptedFiles);
864 WrtDB::EncryptedFileInfo info;
865 std::set<WrtDB::EncryptedFileInfo>::iterator it;
866 info.fileName = DPL::FromUTF8String(filePath);
868 if ((0 == strncmp(Url.c_str(), SCHEME_FILE, strlen(SCHEME_FILE))) &&
869 (m_encryptedFiles.end() != (it =
870 m_encryptedFiles.find(info))))
872 LogDebug(" info file name : " << it->fileName);
873 LogDebug(" info file size : " << it->fileSize);
880 std::string Bundle::DecryptResource(std::string resource, int size)
882 std::string filePath;
884 size_t pos = resource.find_first_not_of(SCHEME_FILE);
885 if (std::string::npos != pos) {
886 filePath = resource.substr(pos - 1);
890 if (0 == stat(filePath.c_str(), &buf)) {
891 const std::size_t fileSize = buf.st_size;
892 const std::size_t readBufSize = (fileSize > FILE_BUF_MAX_SIZE
893 ? FILE_BUF_MAX_SIZE : fileSize);
895 std::unique_ptr<unsigned char[]> inChunk(new unsigned char[readBufSize]);
897 FILE* fp = fopen(filePath.c_str(), "rb");
899 LogDebug("Couldnot open file : " << filePath);
900 return std::string();
903 std::unique_ptr<unsigned char[]> DecryptedString(new unsigned
908 size_t readSize = fread(inChunk.get(), sizeof(unsigned char),
912 LogDebug("resource is encrypted. decrypting....");
913 using namespace Tizen::Base;
914 ByteBuffer *getBuffer =
915 reinterpret_cast<ByteBuffer*>(DecryptChunkByTrustZone(inChunk.get(),
917 memcpy(DecryptedString.get() + (PLAIN_CHUNK_SIZE * count++),
918 getBuffer->GetPointer(),
919 (readSize < PLAIN_CHUNK_SIZE ? readSize : PLAIN_CHUNK_SIZE));
923 } while( 0 == std::feof(fp));
926 memset(DecryptedString.get() + size, '\n', fileSize - size);
927 LogDebug("resource need to encoding base64");
931 b64 = BIO_new(BIO_f_base64());
932 bmem = BIO_new(BIO_s_mem());
933 b64 = BIO_push(b64, bmem);
934 BIO_write(b64, DecryptedString.get(), fileSize);
936 BIO_get_mem_ptr(b64, &bptr);
938 std::string base64Enc((char *)bptr->data, bptr->length - 1);
943 return std::string();
946 void *Bundle::DecryptChunkByTrustZone(const unsigned char *inBuffer,
949 using namespace Tizen::Base;
950 std::string pkgid(DPL::ToUTF8String(m_widgetTizenId));
952 const byte *b_pkgid = reinterpret_cast<const byte*>(pkgid.c_str());
954 appInfo.Construct(pkgid.length());
955 appInfo.SetArray(b_pkgid, 0, pkgid.length());
958 Tizen::Security::Crypto::_TrustZoneService* pInstance;
959 pInstance = Tizen::Security::Crypto::_TrustZoneService::GetInstance();
962 pBuf.Construct(inBufSize);
963 const byte *pByte = reinterpret_cast<const byte*>(inBuffer);
964 pBuf.SetArray(pByte, 0, inBufSize);
967 ByteBuffer *getBuffer = pInstance->_TrustZoneService::DecryptN(appInfo, pBuf);
968 return reinterpret_cast<void*>(getBuffer);
974 void WKBundleInitialize(WKBundleRef bundle,
977 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-BUNDLE");
978 LogDebug("Bundle initialized");
980 DPL::Event::GetMainEventDispatcherInstance().ResetCrossEventCallHandler();
981 LogDebug("ResetCrossEventCallHandler()");
983 static Bundle s_bundle = Bundle(bundle);
985 WKBundleClient client = {
986 kWKBundleClientCurrentVersion,
988 &Bundle::didCreatePageCallback,
989 &Bundle::willDestroyPageCallback,
990 0, /* didInitializePageGroup */
991 &Bundle::didReceiveMessageCallback
993 WKBundleSetClient(bundle, &client);