/**
* Prepare data for PWA.
*/
- virtual void setPWAData() = 0;
+ virtual void AddToHomescreen() = 0;
/**
* @return title of page opened in current tab.
Tools/CapiWebErrorCodes.cpp
Tools/StringTools.cpp
Tools/GengridWrapper.cpp
+ Tools/PWAHandler.cpp
)
if(${PROFILE} MATCHES "mobile")
--- /dev/null
+#include "PWAHandler.h"
+
+#include <curl/curl.h>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <fcntl.h>
+#include <shortcut_manager.h>
+
+#include "BrowserLogger.h"
+
+using namespace std;
+
+namespace
+{
+string shortcutString;
+string pwaName;
+string iconPath;
+
+const string DOWNLOAD_PATH = app_get_shared_data_path();
+
+void MakeShortcut(const string& name, const string& pwaData, const string& icon)
+{
+ if (shortcut_add_to_home(name.c_str(), LAUNCH_BY_URI, pwaData.c_str(),
+ icon.c_str(), 0, PWAHandler::OnDidMakeShortcutCb, nullptr) != SHORTCUT_ERROR_NONE) {
+ BROWSER_LOGE("[%s:%d] Fail to add to homescreen", __PRETTY_FUNCTION__, __LINE__);
+ } else {
+ BROWSER_LOGE("[%s:%d] Success to add to homescreen", __PRETTY_FUNCTION__, __LINE__);
+ }
+}
+
+void SoupSessionCb(SoupSession *session, SoupMessage *msg, gpointer data)
+{
+ BROWSER_LOGD("[%s:%d] session : %s", __PRETTY_FUNCTION__, __LINE__, session);
+
+ if (data) {
+ DownloadRequest *request = static_cast<DownloadRequest *>(data);
+ SoupBuffer *body = soup_message_body_flatten(msg->response_body);
+ int fd = 0;
+ int oflags = O_CREAT | O_WRONLY;
+ int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ const char* filePath = request->filePath.c_str();
+
+ if (body->data && (body->length > 0) && ((fd = open(filePath, oflags, mode)) >= 0)) {
+ unsigned int write_len = write(fd, body->data, body->length);
+ close(fd);
+ if (write_len == body->length)
+ request->cb(filePath);
+ else
+ unlink(filePath);
+ }
+ g_object_unref(msg);
+ soup_buffer_free(body);
+ delete request;
+ }
+ MakeShortcut(pwaName, shortcutString, iconPath);
+}
+
+void OnDidDownloadCb(const char *filePath)
+{
+ BROWSER_LOGD("[%s:%d] filePath = [%s]", __PRETTY_FUNCTION__, __LINE__, filePath);
+ BROWSER_LOGD("[%s:%d] complete !", __PRETTY_FUNCTION__, __LINE__);
+}
+
+} // anonymous namespace
+
+int PWAHandler::OnDidMakeShortcutCb(int ret, void *data)
+{
+ if (data)
+ BROWSER_LOGD("[%s:%d] ret : %d, data : %s", __PRETTY_FUNCTION__, __LINE__, ret, data);
+ else
+ BROWSER_LOGW("[%s] result_cb_data = nullptr", __PRETTY_FUNCTION__);
+
+ return 0;
+}
+
+void PWAHandler::ConnectWebView(Evas_Object *webView)
+{
+ ewk_view_app_installation_request_callback_set(
+ webView, OnDidGetInstallationRequestCb, this);
+}
+
+void PWAHandler::OnDidGetInstallationRequestCb(Evas_Object* ewkView, Ewk_App_Installation_Request* request, void* userData)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (!ewkView) {
+ BROWSER_LOGD("View no longer exists!");
+ return;
+ }
+ auto pwaHandler = static_cast<PWAHandler*>(userData);
+ Ewk_View_Request_Manifest* manifest = ewk_app_installation_request_manifest_get(request);
+ ManifestData manifestData = pwaHandler->GetManifestData(manifest);
+
+ const char* tmp = ewk_app_installation_request_service_worker_url_get(request);
+ manifestData.serviceWorkerURL = (tmp) ? tmp : "";
+ pwaHandler->TriggerPWAInstallation(manifestData);
+}
+
+ManifestData PWAHandler::GetManifestData(Ewk_View_Request_Manifest *manifest)
+{
+ ManifestData data;
+ const char *tmp;
+ data.pushId = ((tmp = ewk_manifest_push_sender_id_get(manifest)) ? tmp : "");
+ if (data.pushId.empty())
+ BROWSER_LOGW("[%s:%d] unknown Push ID value!", __PRETTY_FUNCTION__, __LINE__);
+
+ data.shortName = ((tmp = ewk_manifest_short_name_get(manifest)) ? tmp : "");
+ data.name = ((tmp = ewk_manifest_name_get(manifest)) ? tmp : "");
+ data.startUrl = ((tmp = ewk_manifest_start_url_get(manifest)) ? tmp : "");
+ data.orientationType = ewk_manifest_orientation_type_get(manifest);
+ data.webDisplayMode = ewk_manifest_web_display_mode_get(manifest);
+ data.themeColor.colorExist = ewk_manifest_theme_color_get(
+ manifest, &data.themeColor.r,
+ &data.themeColor.g,
+ &data.themeColor.b,
+ &data.themeColor.a);
+ data.backgroundColor.colorExist = ewk_manifest_background_color_get(
+ manifest,
+ &data.backgroundColor.r,
+ &data.backgroundColor.g,
+ &data.backgroundColor.b,
+ &data.backgroundColor.a);
+ data.iconsCount = ewk_manifest_icons_count_get(manifest);
+ for (size_t iconNumber = 0; iconNumber < data.iconsCount; iconNumber++)
+ {
+ ManifestData::Icon icon;
+ icon.src = ((tmp = ewk_manifest_icons_src_get(manifest, iconNumber)) ? tmp : "");
+ icon.type = ((tmp = ewk_manifest_icons_type_get(manifest, iconNumber)) ? tmp : "");
+ icon.sizesCount = ewk_manifest_icons_sizes_count_get(manifest, iconNumber);
+ for (size_t sizeNumber = 0; sizeNumber < icon.sizesCount; sizeNumber++)
+ {
+ ManifestData::Icon::Size size;
+ size.width = ewk_manifest_icons_width_get(manifest, iconNumber, sizeNumber);
+ size.height = ewk_manifest_icons_height_get(manifest, iconNumber, sizeNumber);
+ icon.sizes.push_back(size);
+ }
+ data.icons.push_back(icon);
+ }
+ return data;
+}
+
+void OnDidGetInstallationRequestCb(Evas_Object* ewkView, Ewk_App_Installation_Request* request, void* userData)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (!ewkView) {
+ BROWSER_LOGD("View no longer exists!");
+ return;
+ }
+ auto pwaHandler = static_cast<PWAHandler*>(userData);
+ Ewk_View_Request_Manifest* manifest = ewk_app_installation_request_manifest_get(request);
+ ManifestData manifestData = pwaHandler->GetManifestData(manifest);
+
+ const char* tmp = ewk_app_installation_request_service_worker_url_get(request);
+ manifestData.serviceWorkerURL = (tmp) ? tmp : "";
+ pwaHandler->TriggerPWAInstallation(manifestData);
+}
+
+void PWAHandler::TriggerPWAInstallation(ManifestData manifest)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+
+ if (manifest.name.empty() || manifest.startUrl.empty()) {
+ BROWSER_LOGW("No Name and url in manifest!");
+ return;
+ }
+
+ pwaName = manifest.name;
+
+ CURL *curl = curl_easy_init();
+ char *text;
+ if (!curl) {
+ BROWSER_LOGE("[%s:%d] CURL not initialized", __PRETTY_FUNCTION__, __LINE__);
+ return;
+ }
+
+ iconPath = DOWNLOAD_PATH + boost::uuids::to_string(boost::uuids::random_generator()());
+ RequestFileDownload(manifest.icons.begin()->src, iconPath, OnDidDownloadCb);
+
+ auto id = installPWA(manifest.name, manifest.pushId, manifest.shortName);
+ if (!id) {
+ BROWSER_LOGE("[%s:%d] unknown installPWA value!", __PRETTY_FUNCTION__, __LINE__);
+ curl_easy_cleanup(curl);
+ return;
+ }
+
+ string retVal("multi-instance-shortcut://tizen.org/shortcut/multi-instance?");
+ retVal += "id=" + manifest.shortName + to_string(*id)
+ + "&icon=" + string(text = curl_easy_escape(curl, iconPath.c_str(), iconPath.length()));
+ curl_free(text);
+ retVal += "&name=" + manifest.name + "&uri=" + string(text = curl_easy_escape(curl, manifest.startUrl.c_str(),
+ manifest.startUrl.length()));
+ curl_free(text);
+ retVal += "&pwa_shortName=" + manifest.shortName
+ + "&pwa_name=" + manifest.name
+ + "&pwa_uri=" + string(text = curl_easy_escape(curl, manifest.startUrl.c_str(),
+ manifest.startUrl.length()));
+ curl_free(text);
+ retVal += "&pwa_orientation=" + to_string(static_cast<int>(manifest.orientationType))
+ + "&pwa_displayMode=" + to_string(static_cast<int>(manifest.webDisplayMode))
+ + "&pwa_themeColor=" + to_string(manifest.themeColor.colorExist)
+ + "&pwa_theme_r=" + to_string(manifest.themeColor.r)
+ + "&pwa_theme_g=" + to_string(manifest.themeColor.g)
+ + "&pwa_theme_b=" + to_string(manifest.themeColor.b)
+ + "&pwa_theme_a=" + to_string(manifest.themeColor.a)
+ + "&pwa_backgroundColor=" + to_string(manifest.backgroundColor.colorExist)
+ + "&pwa_bg_r=" + to_string(manifest.backgroundColor.r)
+ + "&pwa_bg_g=" + to_string(manifest.backgroundColor.g)
+ + "&pwa_bg_b=" + to_string(manifest.backgroundColor.b)
+ + "&pwa_bg_a=" + to_string(manifest.backgroundColor.a)
+ + "&pwa_icon_count=" + to_string(manifest.iconsCount)
+ + "&pwa_icon_src=" + string(text = curl_easy_escape(curl,
+ manifest.icons.begin()->src.c_str(), manifest.icons.begin()->src.length()));
+ if (!manifest.serviceWorkerURL.empty())
+ retVal += "&pwa_serviceWorkerUri=" + manifest.serviceWorkerURL;
+
+ curl_free(text);
+ curl_easy_cleanup(curl);
+
+ BROWSER_LOGD("[%s:%d] retVal : %s", __PRETTY_FUNCTION__, __LINE__, retVal.c_str());
+ storePWAShortcut(*id, retVal);
+
+ shortcutString = retVal;
+}
+
+void PWAHandler::RequestFileDownload(const string &uri, const string &filePath, DownloadRequest::DownloadFinishCb cb)
+{
+ BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
+ BROWSER_LOGD("uri = [%s], filePath = [%s]", uri.c_str(), filePath.c_str());
+
+ SoupSession *soupSession = soup_session_async_new();
+ SoupMessage *soupMsg = soup_message_new("GET", uri.c_str());
+ g_object_set(soupSession, SOUP_SESSION_TIMEOUT, 15, nullptr);
+
+ DownloadRequest *request = new (nothrow) DownloadRequest(filePath, cb);
+ soup_session_queue_message(soupSession, soupMsg, SoupSessionCb, static_cast<void *>(request));
+
+ g_object_unref(soupSession);
+}
\ No newline at end of file
--- /dev/null
+#ifndef PWAHANDLER_H_
+#define PWAHANDLER_H_
+
+#include <app.h>
+#include <boost/signals2/signal.hpp>
+#include <cstddef>
+#include <EWebKit_internal.h>
+#include <libsoup/soup.h>
+#include <string>
+#include <vector>
+
+struct DownloadRequest
+{
+ using DownloadFinishCb = void (*)(const char* filePath);
+
+ DownloadRequest(const std::string &filePath, DownloadFinishCb cb = nullptr)
+ : filePath(filePath), cb(cb) {}
+
+ std::string filePath;
+ DownloadFinishCb cb;
+};
+
+struct ManifestData
+{
+ std::string shortName;
+ std::string name;
+ std::string startUrl;
+ Ewk_View_Orientation_Type orientationType;
+ Ewk_View_Web_Display_Mode webDisplayMode;
+ struct Color
+ {
+ unsigned colorExist;
+ uint8_t r, g, b, a;
+ } themeColor, backgroundColor;
+
+ size_t iconsCount;
+ struct Icon
+ {
+ std::string src;
+ std::string type;
+ size_t sizesCount;
+ struct Size
+ {
+ int width;
+ int height;
+ };
+ std::vector<Size> sizes;
+ };
+ std::vector<Icon> icons;
+ std::string pushId;
+ std::string serviceWorkerURL;
+};
+
+class PWAHandler
+{
+ public:
+ void TriggerPWAInstallation(ManifestData manifest);
+ ManifestData GetManifestData(Ewk_View_Request_Manifest *manifest);
+ void ConnectWebView(Evas_Object *webView);
+
+ boost::signals2::signal<unsigned(const std::string &, const std::string &, const std::string &)> installPWA;
+ boost::signals2::signal<void(const unsigned &, const std::string &)> storePWAShortcut;
+
+ static int OnDidMakeShortcutCb(int ret, void *data);
+
+ private:
+ static void OnDidGetInstallationRequestCb(Evas_Object* ewkView, Ewk_App_Installation_Request* request, void* userData);
+ void RequestFileDownload(const std::string &uri, const std::string &filePath, DownloadRequest::DownloadFinishCb cb);
+};
+
+#endif /* PWAHANDLER_H_ */
\ No newline at end of file
m_webPageUI->requestCurrentPageForWebPageUI.connect(
[this] {return requestSettingsCurrentPage();});
m_webPageUI->pwaRequestManifest.connect(
- [this] {m_webEngine->setPWAData();});
+ [this] {m_webEngine->AddToHomescreen();});
m_webPageUI->getCountCheckSignal.connect(
[this] {return this->countCheckUrl();});
m_webPageUI->isMostVisited.connect(
m_webEngine->changeUIColor.connect([this](int r, int g, int b, int a) {
m_webPageUI->changeUIColor(r, g, b, a);
});
- m_webEngine->installPWA.connect(
- [this](const std::string& s, const std::string& p, const std::string& sn) {
- return m_storageService->getPWAStorage().installPWAItem(s, p, sn);
- });
+ m_webEngine->installPWA.connect([this](const std::string &name,
+ const std::string &push_id,
+ const std::string &short_name) {
+ return m_storageService->getPWAStorage().installPWAItem(name, push_id,
+ short_name);
+ });
m_webEngine->storePWAShortcut.connect(
[this](const unsigned& id, const std::string& shortcut) {
return m_storageService->getPWAStorage().storePWAShortcut(id, shortcut);
[this](const int& id, const bool& state) {
return m_storageService->getPWAStorage().updatePermissionState(id, state);
});
+ m_webEngine->installPWA.connect(
+ [this](const std::string& s, const std::string& p, const std::string& sn) {
+ return m_storageService->getPWAStorage().installPWAItem(s, p, sn);
+ });
+ m_webEngine->storePWAShortcut.connect(
+ [this](const unsigned& id, const std::string& shortcut) {
+ return m_storageService->getPWAStorage().storePWAShortcut(id, shortcut);
+ });
m_webEngine->windowCreated.connect([this] {switchViewToWebPage();});
m_webEngine->getPermissionsMap.connect([this] {
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
switch (button) {
case OK:
BROWSER_LOGD("[%s:%d] pwaPopup OK !", __PRETTY_FUNCTION__, __LINE__);
- m_webEngine->setPWAData();
+ m_webEngine->AddToHomescreen();
m_storageService->getPWAStorage().addPWAItem(uri, 1, 0);
break;
case CANCEL:
m_downloadControl(std::make_shared<DownloadControl>()),
m_policyCounter(0)
{
+ m_pwaHandler.reset(new PWAHandler);
+ m_pwaHandler->installPWA.connect(
+ [this](const std::string& s, const std::string& p, const std::string& sn) { return *installPWA(s, p, sn); });
+ m_pwaHandler->storePWAShortcut.connect(
+ [this](const unsigned& id, const std::string& shortcut) { storePWAShortcut(id, shortcut); });
}
WebEngineMin::~WebEngineMin()
#if PWE_SHUB
evas_object_smart_callback_add(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this);
#endif
+ m_pwaHandler->ConnectWebView(m_ewkView);
+
auto permissions = *getPermissionsMap();
Eina_List* permList = nullptr;
for (const auto& it : permissions) {
#include <boost/noncopyable.hpp>
#include <Evas.h>
#include <EWebKit_internal.h>
+#include <memory>
#include "AbstractWebEngine/AbstractWebEngine.h"
#include "DownloadControl/DownloadControl.h"
+#include "PWAHandler.h"
#include "service_macros.h"
namespace tizen_browser {
#if !DUMMY_BUTTON
Evas_Object* getWidget() override { }
#endif
- void setPWAData() override { }
+ void AddToHomescreen() override { }
void setUserAgent(const std::string&) override { }
void languageChanged() override { }
void stopLoading() override { }
Evas_Object* m_ewkView;
Ewk_Context* m_ewkContext;
std::string m_loadingURL;
+ std::unique_ptr<PWAHandler> m_pwaHandler;
std::shared_ptr<DownloadControl> m_downloadControl;
#if PWE_SHUB
std::map<CertificateConfirmationPtr, Ewk_Certificate_Policy_Decision *> m_confirmationCertificatenMap;
[this](const int& r, const int& g, const int& b, const int& a){
this->changeUIColor(r, g, b, a);
});
- webView->installPWA.connect(
+ webView->GetPWAHandler()->installPWA.connect(
[this](const std::string& str, const std::string& id, const std::string& sn) { return *installPWA(str, id, sn); });
- webView->storePWAShortcut.connect(
+ webView->GetPWAHandler()->storePWAShortcut.connect(
[this](const unsigned& id, const std::string& shortcut){this->storePWAShortcut(id, shortcut);});
webView->pushSignal.connect(
[this](const char* sender, const char* push_data) {
webView->findOnPage.disconnect(boost::bind(&WebEngineService::_findOnPage, this, _1));
webView->searchInNewTab.disconnect_all_slots();
webView->changeUIColor.disconnect_all_slots();
- webView->installPWA.disconnect_all_slots();
- webView->storePWAShortcut.disconnect_all_slots();
+ webView->GetPWAHandler()->installPWA.disconnect_all_slots();
+ webView->GetPWAHandler()->storePWAShortcut.disconnect_all_slots();
webView->storePermission.disconnect_all_slots();
webView->getPermissionId.disconnect_all_slots();
webView->updatePermissionState.disconnect_all_slots();
return std::string("");
}
-void WebEngineService::setPWAData()
+void WebEngineService::AddToHomescreen()
{
- m_currentWebView->addManifestTypeToHandle(ManifestType::PWA_MANIFEST);
- if (!m_currentWebView->isManifestReady())
- m_currentWebView->requestManifest();
- else
- m_currentWebView->handleManifest();
+ m_currentWebView->requestManifest();
}
bool WebEngineService::isLoadError() const
void init(Evas_Object* guiParent);
void setURI(const std::string &);
std::string getURI(void) const;
- void setPWAData();
+ void AddToHomescreen();
std::string getTitle(void) const;
TabOrigin getOrigin(void) const;
std::string getUserAgent(void) const;
namespace webengine_service {
const std::string WebView::COOKIES_PATH = "cookies";
-std::string WebView::s_pwaData = "";
-std::string WebView::s_name = "";
-std::string WebView::s_icon = "";
-const std::string WebView::DOWNLOAD_PATH = app_get_shared_data_path();
struct SnapshotItemData {
WebView* web_view;
, m_suspended(false)
, m_private(incognitoMode)
, m_fullscreen(false)
- , m_manifestData()
- , m_manifestReady(false)
, m_downloadControl(nullptr)
, m_policyCounter(0)
, m_imeState(false)
, m_themeColor()
{
- m_manifestData.orientation_type = static_cast<Ewk_View_Orientation_Type>(0);
- m_manifestData.web_display_mode = static_cast<Ewk_View_Web_Display_Mode>(0);
- m_manifestData.theme_color.colorExist = 0;
- m_manifestData.theme_color.r = 0;
- m_manifestData.theme_color.g = 0;
- m_manifestData.theme_color.b = 0;
- m_manifestData.theme_color.a = 0;
- m_manifestData.background_color.colorExist = 0;
- m_manifestData.background_color.r = 0;
- m_manifestData.background_color.g = 0;
- m_manifestData.background_color.b = 0;
- m_manifestData.background_color.a = 0;
- m_manifestData.icons_count = 0;
+ m_pwaHandler.reset(new PWAHandler());
}
WebView::~WebView()
BROWSER_LOGD("[%s:%d] Set permissions", __PRETTY_FUNCTION__, __LINE__);
ewk_notification_cached_permissions_set(permList);
}
-
+ m_pwaHandler->ConnectWebView(m_ewkView);
resume();
}
evas_object_smart_callback_add(m_ewkView, "notification,permission,reply", __notification_reply_cb, this);
ewk_view_did_change_theme_color_callback_set(m_ewkView, __theme_color_changed, this);
-#if PWE_SHUB
- ewk_view_app_installation_request_callback_set(m_ewkView, __install_pwa_request_cb, this);
-#endif
}
void WebView::unregisterCallbacks()
void WebView::requestManifest(void)
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
- ewk_view_request_manifest(m_ewkView, __setManifestData, this);
-}
-
-void WebView::handleManifest()
-{
- BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
- for (const auto &type : m_manifestVector) {
- switch (type) {
- case ManifestType::QUICKACCESS_MANIFEST:
- BROWSER_LOGD("Quickaccess manifest - not implemented");
- break;
- case ManifestType::THEME_MANIFEST:
- BROWSER_LOGD("Quickaccess manifest - not implemented");
- break;
- case ManifestType::PWA_MANIFEST:
- setPWAData();
- break;
- default:
- BROWSER_LOGD("Bad manifest type");
- break;
- }
- }
- m_manifestVector.clear();
-}
-
-void WebView::setPWAData(const std::string& serviceWorkerURL)
-{
- BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
- s_name = m_manifestData.name;
-
- CURL *curl = curl_easy_init();
- char* text;
- if (!curl) {
- BROWSER_LOGE("[%s:%d] CURL not initialized", __PRETTY_FUNCTION__, __LINE__);
- return;
- }
-
- std::string str_icon_src = m_manifestData.icons.begin()->src;
- s_icon = DOWNLOAD_PATH + boost::uuids::to_string(boost::uuids::random_generator()());
- request_file_download(m_manifestData.icons.begin()->src, s_icon, __download_result_cb, nullptr);
-
- if (m_manifestData.m_push_id.empty())
- BROWSER_LOGW("[%s:%d] unknown Push ID value!", __PRETTY_FUNCTION__, __LINE__);
-
- auto id = installPWA(m_manifestData.name, m_manifestData.m_push_id, m_manifestData.short_name);
- if (!id) {
- BROWSER_LOGE("[%s:%d] unknown installPWA value!", __PRETTY_FUNCTION__, __LINE__);
- curl_easy_cleanup(curl);
- return;
- }
-
- std::string retVal("multi-instance-shortcut://tizen.org/shortcut/multi-instance?");
- retVal += "id=" + m_manifestData.short_name + std::to_string(*id)
- + "&icon=" + std::string(text = curl_easy_escape(curl, s_icon.c_str(), s_icon.length()));
- curl_free(text);
- retVal += "&name=" + s_name
- + "&uri=" + std::string(text = curl_easy_escape(curl, m_manifestData.start_url.c_str(),
- m_manifestData.start_url.length()));
- curl_free(text);
- retVal += "&pwa_shortName=" + m_manifestData.short_name
- + "&pwa_name=" + m_manifestData.name
- + "&pwa_uri=" + std::string(text = curl_easy_escape(curl, m_manifestData.start_url.c_str(),
- m_manifestData.start_url.length()));
- curl_free(text);
- retVal += "&pwa_orientation=" + std::to_string(static_cast<int>(m_manifestData.orientation_type))
- + "&pwa_displayMode=" + std::to_string(static_cast<int>(m_manifestData.web_display_mode))
- + "&pwa_themeColor=" + std::to_string(m_manifestData.theme_color.colorExist)
- + "&pwa_theme_r=" + std::to_string(m_manifestData.theme_color.r)
- + "&pwa_theme_g=" + std::to_string(m_manifestData.theme_color.g)
- + "&pwa_theme_b=" + std::to_string(m_manifestData.theme_color.b)
- + "&pwa_theme_a=" + std::to_string(m_manifestData.theme_color.a)
- + "&pwa_backgroundColor=" + std::to_string(m_manifestData.background_color.colorExist)
- + "&pwa_bg_r=" + std::to_string(m_manifestData.background_color.r)
- + "&pwa_bg_g=" + std::to_string(m_manifestData.background_color.g)
- + "&pwa_bg_b=" + std::to_string(m_manifestData.background_color.b)
- + "&pwa_bg_a=" + std::to_string(m_manifestData.background_color.a)
- + "&pwa_icon_count=" + std::to_string(m_manifestData.icons_count)
- + "&pwa_icon_src=" + std::string(text = curl_easy_escape(curl, s_icon.c_str(), s_icon.length()));
-#if PWE_SHUB
- if (!serviceWorkerURL.empty())
- retVal += "&pwa_serviceWorkerUri=" + serviceWorkerURL;
-#endif
- curl_free(text);
- curl_easy_cleanup(curl);
-
- BROWSER_LOGD("[%s:%d] retVal : %s", __PRETTY_FUNCTION__, __LINE__, retVal.c_str());
- storePWAShortcut(*id, retVal);
- s_pwaData = retVal;
-}
-
-void WebView::makeShortcut(const std::string& name, const std::string& pwaData, const std::string& icon)
-{
- if (shortcut_add_to_home(name.c_str(), LAUNCH_BY_URI, pwaData.c_str(),
- icon.c_str(), 0, result_cb, nullptr) != SHORTCUT_ERROR_NONE)
- BROWSER_LOGE("[%s:%d] Fail to add to homescreen", __PRETTY_FUNCTION__, __LINE__);
- else
- BROWSER_LOGE("[%s:%d] Success to add to homescreen", __PRETTY_FUNCTION__, __LINE__);
-}
-
-int WebView::result_cb(int ret, void *data) {
- if (data) {
- BROWSER_LOGD("[%s:%d] ret : %d, data : %s", __PRETTY_FUNCTION__, __LINE__, ret, data);
- } else {
- BROWSER_LOGW("[%s] result_cb_data = nullptr", __PRETTY_FUNCTION__);
- }
- return 0;
-}
-
-void WebView::request_file_download(const std::string& uri, const std::string& file_path, download_finish_callback cb, void *data)
-{
- BROWSER_LOGD("[%s:%d]", __PRETTY_FUNCTION__, __LINE__);
- BROWSER_LOGD("uri = [%s], file_path = [%s]", uri.c_str(), file_path.c_str());
-
- SoupSession *soup_session = nullptr;
- SoupMessage *soup_msg = nullptr;
- char *s_filePath = strdup(file_path.c_str());
-
- soup_session = soup_session_async_new();
- g_object_set(soup_session, SOUP_SESSION_TIMEOUT, 15, nullptr);
-
- soup_msg = soup_message_new("GET", uri.c_str());
- download_request *request = new(std::nothrow) download_request(s_filePath, cb, data);
- soup_session_queue_message(soup_session, soup_msg, __file_download_finished_cb, static_cast<void*>(request));
-
- g_object_unref(soup_session);
- free(s_filePath);
-}
-
-void WebView::__file_download_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data)
-{
- BROWSER_LOGD("[%s:%d] session : %s", __PRETTY_FUNCTION__, __LINE__, session);
-
- if (data) {
- download_request *request = static_cast<download_request*>(data);
- SoupBuffer *body = soup_message_body_flatten(msg->response_body);
- int fd = 0;
- if (body->data && (body->length > 0) && ((fd = open(request->file_path.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0)) {
- unsigned int write_len = write(fd, body->data, body->length);
- close(fd);
- if (write_len == body->length)
- request->cb(request->file_path.c_str(), request->data);
- else
- unlink(request->file_path.c_str());
- }
- g_object_unref(msg);
- soup_buffer_free(body);
- delete request;
- }
- makeShortcut(s_name, s_pwaData, s_icon);
-}
-
-void WebView::__download_result_cb(const std::string& file_path, void *data)
-{
- BROWSER_LOGD("[%s:%d] file_path = [%s], data = [%s]", file_path.c_str(), data);
- BROWSER_LOGD("[%s:%d] complete !", __PRETTY_FUNCTION__, __LINE__);
+ ewk_view_request_manifest(m_ewkView, OnDidGetManifestCb, this);
}
std::string WebView::getTitle(void)
m_webEngine->closeTab(self->getTabId());
}
-void WebView::__setManifestData(Evas_Object *view, Ewk_View_Request_Manifest *manifest, void *data)
+void WebView::OnDidGetManifestCb(Evas_Object *view, Ewk_View_Request_Manifest *manifest, void *data)
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
-
- if (view && data) {
- WebView *self = reinterpret_cast<WebView *>(data);
-
- if (manifest) {
- const char *tmp;
- self->m_manifestData.m_push_id = ((tmp = ewk_manifest_push_sender_id_get(manifest)) ? tmp : "");
- self->m_manifestData.short_name = ((tmp = ewk_manifest_short_name_get(manifest)) ? tmp : "");
- self->m_manifestData.name = ((tmp = ewk_manifest_name_get(manifest)) ? tmp : "");
- self->m_manifestData.start_url = ((tmp = ewk_manifest_start_url_get(manifest)) ? tmp : "");
- self->m_manifestData.orientation_type = ewk_manifest_orientation_type_get(manifest);
- self->m_manifestData.web_display_mode = ewk_manifest_web_display_mode_get(manifest);
- self->m_manifestData.theme_color.colorExist = ewk_manifest_theme_color_get(
- manifest,
- &self->m_manifestData.theme_color.r,
- &self->m_manifestData.theme_color.g,
- &self->m_manifestData.theme_color.b,
- &self->m_manifestData.theme_color.a);
- self->m_manifestData.background_color.colorExist = ewk_manifest_background_color_get(
- manifest,
- &self->m_manifestData.background_color.r,
- &self->m_manifestData.background_color.g,
- &self->m_manifestData.background_color.b,
- &self->m_manifestData.background_color.a);
-
- self->m_manifestData.icons_count = ewk_manifest_icons_count_get(manifest);
- self->m_manifestData.icons.clear();
- for (size_t iconNumber = 0; iconNumber < self->m_manifestData.icons_count; iconNumber++) {
- ManifestData::_icon icon;
- icon.src = ((tmp = ewk_manifest_icons_src_get(manifest, iconNumber)) ? tmp : "");
- icon.type = ((tmp = ewk_manifest_icons_type_get(manifest, iconNumber)) ? tmp : "");
- icon.sizes_count = ewk_manifest_icons_sizes_count_get(manifest, iconNumber);
- for (size_t sizeNumber = 0; sizeNumber < icon.sizes_count; sizeNumber++) {
- ManifestData::_icon::_size size;
- size.width = ewk_manifest_icons_width_get(manifest, iconNumber, sizeNumber);
- size.height = ewk_manifest_icons_height_get(manifest, iconNumber, sizeNumber);
- icon.sizes.push_back(size);
- }
- self->m_manifestData.icons.push_back(icon);
- }
-
- if (!self->m_manifestData.name.empty() && !self->m_manifestData.start_url.empty()) {
- self->m_manifestReady = true;
- self->handleManifest();
- } else {
- BROWSER_LOGW("No Name and url in manifest!");
- }
-
- } else {
- BROWSER_LOGW("No manifest for webview!");
- std::string uri = self->getURI();
- shortcut_add_to_home(self->m_title.c_str(), LAUNCH_BY_URI, uri.c_str(), nullptr, 0, result_cb, nullptr);
- }
- } else {
+ auto self = static_cast<WebView*>(data);
+ if (!view || !data) {
BROWSER_LOGW("No View or data!");
+ return;
}
+
+ if (!manifest) {
+ BROWSER_LOGW("No manifest for webview!");
+ std::string uri = self->getURI();
+ shortcut_add_to_home(self->m_title.c_str(), LAUNCH_BY_URI, uri.c_str(),
+ nullptr, 0, PWAHandler::OnDidMakeShortcutCb, nullptr);
+ return;
+ }
+
+ ManifestData manifest_data = self->m_pwaHandler->GetManifestData(manifest);
+ self->m_pwaHandler->TriggerPWAInstallation(manifest_data);
}
void WebView::__loadStarted(void * data, Evas_Object * /* obj */, void * /* event_info */)
WebView * self = reinterpret_cast<WebView *>(data);
BROWSER_LOGD("URL changed for tab: %s", self->getTabId().toString().c_str());
self->uriChanged(self->getURI());
- self->m_manifestReady = false;
}
void WebView::__backForwardListChanged(void * data, Evas_Object * /* obj */, void * /* event_info */)
ewk_policy_decision_use(policy_decision);
}
-#if PWE_SHUB
-void WebView::__install_pwa_request_cb(Evas_Object* ewk_view, Ewk_App_Installation_Request* request, void* user_data)
-{
- BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
- auto webView = static_cast<WebView*>(user_data);
- Ewk_View_Request_Manifest* manifest = ewk_app_installation_request_manifest_get(request);
- webView->__setManifestData(ewk_view, manifest, user_data);
- const char* tmp = ewk_app_installation_request_service_worker_url_get(request);
- std::string serviceWorkerURL = (tmp) ? tmp : "";
- // Trigger installation
- webView->setPWAData(serviceWorkerURL);
-}
-#endif
-
} /* namespace webengine_service */
} /* end of basic_webengine */
} /* end of tizen_browser */
#define WEBVIEW_H_
#include <boost/signals2/signal.hpp>
+#include <memory>
#include <string>
#include <vector>
#include <Evas.h>
#include "AbstractWebEngine/WebConfirmation.h"
#include "AbstractWebEngine.h"
#include "GeneralTools.h"
+#include "PWAHandler.h"
#include <app_control.h>
#include <app.h>
class BrowserImage;
}
-enum class ManifestType {
- PWA_MANIFEST,
- QUICKACCESS_MANIFEST,
- THEME_MANIFEST
-};
-
-struct ManifestData {
- ManifestData() = default;
- std::string short_name;
- std::string name;
- std::string start_url;
- Ewk_View_Orientation_Type orientation_type;
- Ewk_View_Web_Display_Mode web_display_mode;
- struct _color {
- _color() = default;
- unsigned colorExist;
- uint8_t r, g, b, a;
- } theme_color, background_color;
- size_t icons_count;
- struct _icon {
- _icon() = default;
- std::string src;
- std::string type;
- size_t sizes_count;
- struct _size {
- _size() = default;
- int width;
- int height;
- };
- std::vector<_size> sizes;
- };
- std::vector<_icon> icons;
- std::string m_push_id;
-};
-
namespace basic_webengine {
class TabOrigin;
namespace webengine_service {
-using download_finish_callback = void (*)(const std::string& file_path, void *data);
-using ManifestTypesVector = std::vector<ManifestType>;
-
class WebView
: public tizen_browser::interfaces::AbstractRotatable
{
bool isLoadError() const;
void requestManifest(void);
- bool isManifestReady() { return m_manifestReady; }
- void handleManifest();
- void addManifestTypeToHandle(const ManifestType &type) { m_manifestVector.push_back(type); }
-
- void setPWAData(const std::string& serviceWorkerURL = "");
-
- void request_file_download(const std::string& uri, const std::string& file_path, download_finish_callback cb, void *data);
-
- struct download_request
- {
- public:
- download_request(char* file_path_ = nullptr, download_finish_callback cb_ = nullptr, void* data_ = nullptr)
- : file_path(file_path_)
- , cb(cb_)
- , data(data_)
- {}
-
- ~download_request() {}
-
- std::string file_path;
- download_finish_callback cb;
- void *data;
-
- private:
- download_request& operator=(const download_request&);
- download_request(const download_request&);
- };
std::map<std::string, std::vector<std::string> > parse_uri(const char *uriToParse);
#endif
void confirmationResult(WebConfirmationPtr);
+ PWAHandler* GetPWAHandler() { return m_pwaHandler.get(); }
+
std::shared_ptr<tizen_browser::tools::BrowserImage> captureSnapshot(int width, int height, bool async,
tizen_browser::tools::SnapshotType snapshot_type);
boost::signals2::signal<void(int,int,int,int)> changeUIColor;
- boost::signals2::signal<unsigned(const std::string&, const std::string&, const std::string&)> installPWA;
- boost::signals2::signal<void(const unsigned&,const std::string&)> storePWAShortcut;
boost::signals2::signal<std::string(const char*, const char* )> pushSignal;
boost::signals2::signal<unsigned(const std::string&, const bool&)> storePermission;
boost::signals2::signal<unsigned(const std::string&)> getPermissionId;
static void __newWindowRequest(void * data, Evas_Object *, void *out);
static void __closeWindowRequest(void * data, Evas_Object *, void *);
- static void __setManifestData(Evas_Object* view, Ewk_View_Request_Manifest* manifest, void *data);
+ static void OnDidGetManifestCb(Evas_Object* view, Ewk_View_Request_Manifest* manifest, void *data);
- static int result_cb(int ret, void *data);
- static void makeShortcut(const std::string& name, const std::string& pwaData, const std::string& icon);
- static void __file_download_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data);
- static void __download_result_cb(const std::string& file_path, void *data);
static void _push_cb(const char *sender_id, const char *, void *data);
context_menu_type _get_menu_type(Ewk_Context_Menu *menu);
// Screenshot capture
static void __screenshotCaptured(Evas_Object* image, void* user_data);
-#if PWE_SHUB
- static void __install_pwa_request_cb(Evas_Object* /*ewk_view*/, Ewk_App_Installation_Request* request, void* user_data);
-#endif
-
Evas_Object * m_parent;
TabId m_tabId;
Evas_Object * m_ewkView;
TabOrigin m_origin;
std::map<CertificateConfirmationPtr, Ewk_Certificate_Policy_Decision *> m_confirmationCertificatenMap;
- ManifestData m_manifestData;
- bool m_manifestReady;
- ManifestTypesVector m_manifestVector;
static const std::string COOKIES_PATH;
- static std::string s_pwaData;
- static std::string s_name;
- static std::string s_start_url;
- static std::string s_icon;
- static const std::string DOWNLOAD_PATH;
+ std::unique_ptr<PWAHandler> m_pwaHandler;
DownloadControl* m_downloadControl;
int m_policyCounter;
bool m_imeState;