From: Dariusz Frankiewicz Date: Mon, 5 Sep 2016 14:08:26 +0000 (+0200) Subject: Progressive web app launching mechanism X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b7ea72c0b6ace2b1c7c1e068518f30e004a612c;p=profile%2Fcommon%2Fapps%2Fweb%2Fbrowser.git Progressive web app launching mechanism [Issue] N/A [Problem] Not implemented PWA launching [Solution] Implement launching browser when browser_shortcut:// url prefix is passed by app_control. Implement PWA parameters parsing and launching browser with fullscreen webpage and with locked rotation. [Verify] Browser should launch by PWA shortct icon. Change-Id: Ib4a95128ffd82cfa10358ad08dd9e102173a8867 --- diff --git a/services/SimpleUI/CMakeLists.txt b/services/SimpleUI/CMakeLists.txt index c2a4ed23..72abfa66 100644 --- a/services/SimpleUI/CMakeLists.txt +++ b/services/SimpleUI/CMakeLists.txt @@ -7,6 +7,7 @@ set(SimpleUI_SRCS NotificationPopup.cpp ViewManager.cpp RadioPopup.cpp + ProgressiveWebApp.cpp ) if (${PROFILE} MATCHES "mobile") diff --git a/services/SimpleUI/ProgressiveWebApp.cpp b/services/SimpleUI/ProgressiveWebApp.cpp new file mode 100644 index 00000000..1ab64033 --- /dev/null +++ b/services/SimpleUI/ProgressiveWebApp.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ProgressiveWebApp.h" + +#include "BrowserLogger.h" + +namespace tizen_browser { +namespace base_ui { + +ProgressiveWebApp::ProgressiveWebApp() + : m_pwaInfoStruct() + , m_uriPartsMap() +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); +} + +ProgressiveWebApp::~ProgressiveWebApp() +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); +} + +void ProgressiveWebApp::preparePWAParameters(const std::string &uri) +{ + parse_uri(uri); + fillPWAstruct(m_uriPartsMap); +} + +void ProgressiveWebApp::parse_uri(const std::string& uri) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + std::string::size_type pos = uri.find("pwa_"); + std::string::size_type prevpos = pos; + m_uriPartsMap["protocol"] = uri.substr(0, pos); + while (pos != std::string::npos) { + prevpos = pos; + pos = uri.find("pwa_", pos+1); + std::string tmp = uri.substr(prevpos, pos-prevpos-1); + std::string::size_type delimiter = tmp.find(":"); + std::string first = tmp.substr(0, delimiter); + std::string second = tmp.substr(delimiter+1, tmp.length()); + m_uriPartsMap[first] = second; + } +} + +void ProgressiveWebApp::fillPWAstruct(const std::map &pwaParametersMap) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + + auto it = pwaParametersMap.find("pwa_id"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.id = it->second; + it = pwaParametersMap.find("pwa_uri"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.uri = it->second; + it = pwaParametersMap.find("pwa_decodedIcon"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.decodedIcon = it->second; + it = pwaParametersMap.find("pwa_name"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.name = it->second; + it = pwaParametersMap.find("pwa_shortName"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.shortName = it->second; + it = pwaParametersMap.find("pwa_orientation"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.orientation = std::stoi(it->second); + it = pwaParametersMap.find("pwa_displayMode"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.displayMode = std::stoi(it->second); + it = pwaParametersMap.find("pwa_themeColor"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.themeColor = std::stol(it->second); + it = pwaParametersMap.find("pwa_backgroundColor"); + if (it != pwaParametersMap.end()) + m_pwaInfoStruct.backgroundColor = std::stol(it->second); +} + +} // namespace tizen_browser +} // namespace base_ui diff --git a/services/SimpleUI/ProgressiveWebApp.h b/services/SimpleUI/ProgressiveWebApp.h new file mode 100644 index 00000000..b19828e1 --- /dev/null +++ b/services/SimpleUI/ProgressiveWebApp.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PROGRESSIVEWEBAPP_H +#define PROGRESSIVEWEBAPP_H + +#include +#include + +namespace tizen_browser { +namespace base_ui { + +//TODO: this is temporaty struct. It will be replaced by enum from engine API when it'll be ready. +struct pwaInfo { + std::string id; + std::string decodedIcon; // needs to src, type, sizes. + std::string uri; + std::string name; + std::string shortName; + int orientation; // needs to portrait-primary, portrait-secondary, landscape-primary, landscape-secondary. + int displayMode; // needs to fullscreen, standalone, minimal-ui, browser, and so on. + long themeColor; + long backgroundColor; +}; + +class ProgressiveWebApp +{ +public: + ProgressiveWebApp(); + ~ProgressiveWebApp(); + void preparePWAParameters(const std::string& uri); + pwaInfo getPWAinfo() {return m_pwaInfoStruct;} + +private: + void parse_uri(const std::string& uri); + void fillPWAstruct(const std::map &pwaParametersMap); + + pwaInfo m_pwaInfoStruct; + std::map m_uriPartsMap; +}; + + +} // namespace tizen_browser +} // namespace base_ui + +#endif // PROGRESSIVEWEBAPP_H diff --git a/services/SimpleUI/SimpleUI.cpp b/services/SimpleUI/SimpleUI.cpp index 85daf464..59e6f7a0 100755 --- a/services/SimpleUI/SimpleUI.cpp +++ b/services/SimpleUI/SimpleUI.cpp @@ -81,6 +81,7 @@ SimpleUI::SimpleUI() , m_tabLimit(0) , m_favoritesLimit(0) , m_wvIMEStatus(false) + , m_pwa() #if PROFILE_MOBILE , m_current_angle(0) , m_temp_angle(0) @@ -108,8 +109,7 @@ SimpleUI::SimpleUI() evas_object_show(main_window); #if PROFILE_MOBILE if (elm_win_wm_rotation_supported_get(main_window)) { - static const int rots[] = {0, 90, 180, 270}; - elm_win_wm_rotation_available_rotations_set(main_window, rots, (sizeof(rots) / sizeof(int))); + rotationType(rotationLock::noLock); evas_object_smart_callback_add(main_window, "wm,rotation,changed", __orientation_changed, this); } else BROWSER_LOGW("[%s:%d] Device does not support rotation.", __PRETTY_FUNCTION__, __LINE__); @@ -174,7 +174,6 @@ int SimpleUI::exec(const std::string& _url, const std::string& _caller) m_tabLimit = boost::any_cast (tizen_browser::config::Config::getInstance().get("TAB_LIMIT")); m_favoritesLimit = boost::any_cast (tizen_browser::config::Config::getInstance().get("FAVORITES_LIMIT")); - loadUIServices(); loadModelServices(); @@ -193,6 +192,21 @@ int SimpleUI::exec(const std::string& _url, const std::string& _caller) #endif } + // Progressive web app + if (!strncmp(url.c_str(), "browser_shortcut:", strlen("browser_shortcut:"))) { + BROWSER_LOGD("Progressive web app"); + m_pwa.preparePWAParameters(url); + url = m_pwa.getPWAinfo().uri; + m_webPageUI->setDisplayMode( + static_cast( + m_pwa.getPWAinfo().displayMode)); + + if (m_pwa.getPWAinfo().orientation == WebPageUI::portrait_primary) + rotationType(rotationLock::portrait); + else if (m_pwa.getPWAinfo().orientation == WebPageUI::landscape_primary) + rotationType(rotationLock::landscape); + } + if (url.empty()) { BROWSER_LOGD("[%s]: restore last session", __func__); @@ -1125,6 +1139,30 @@ int SimpleUI::getRotation() { return elm_win_rotation_get(main_window); } + +void SimpleUI::rotationType(rotationLock lock) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + int *rots; + size_t size = 1; + switch (lock) + { + case rotationLock::portrait: + rots = new int[1] {0}; + break; + case rotationLock::landscape: + rots = new int[1] {90}; + break; + case rotationLock::noLock: + default: + rots = new int[4] {0, 90, 180, 270}; + size = 4; + break; + } + + elm_win_wm_rotation_available_rotations_set( main_window, const_cast(rots), size); +} + #endif Evas_Object* SimpleUI::getMainWindow() diff --git a/services/SimpleUI/SimpleUI.h b/services/SimpleUI/SimpleUI.h index fc6b274e..9af9e8a6 100644 --- a/services/SimpleUI/SimpleUI.h +++ b/services/SimpleUI/SimpleUI.h @@ -64,6 +64,7 @@ #include "WebConfirmation.h" #include "ViewManager.h" #include "MenuButton.h" +#include "ProgressiveWebApp.h" namespace tizen_browser{ namespace base_ui{ @@ -83,8 +84,14 @@ public: virtual std::string getName(); void suspend(); void resume(); - void destroyUI(); + + enum class rotationLock { + noLock = 0, + portrait, + landscape, + }; + private: // setup functions void loadUIServices(); @@ -285,6 +292,7 @@ private: void onRotation(); bool isLandscape(); int getRotation(); + void rotationType(rotationLock lock); void connectSettingsSignals(); static void __orientation_changed(void* data, Evas_Object*, void*); #endif @@ -358,6 +366,7 @@ private: //helper object used to view management ViewManager m_viewManager; Evas_Object *main_window; + ProgressiveWebApp m_pwa; #if PROFILE_MOBILE Evas_Object *m_conformant; int m_current_angle; diff --git a/services/WebPageUI/WebPageUI.cpp b/services/WebPageUI/WebPageUI.cpp index 5d7b979c..d1e178a4 100755 --- a/services/WebPageUI/WebPageUI.cpp +++ b/services/WebPageUI/WebPageUI.cpp @@ -113,6 +113,7 @@ void WebPageUI::showUI() evas_object_show(m_mainLayout); evas_object_show(elm_object_part_content_get(m_mainLayout, "web_view")); + evas_object_show(m_URIEntry->getContent()); evas_object_show(elm_object_part_content_get(m_mainLayout, "bottom_toolbar")); evas_object_show(elm_object_part_content_get(m_mainLayout, "uri_bar_buttons_right")); @@ -538,13 +539,13 @@ void WebPageUI::_cm_add_to_hs_clicked(void* data, Evas_Object*, void* ) webPageUI->m_pwaInfo->uri = uri.c_str(); webPageUI->m_pwaInfo->name = "ProgressiveWebApp"; webPageUI->m_pwaInfo->shortName = "pwa"; - webPageUI->m_pwaInfo->orientation = portrait_secondary; - webPageUI->m_pwaInfo->displayMode = WebDisplayModeMinimalUi; + webPageUI->m_pwaInfo->orientation = landscape_primary; + webPageUI->m_pwaInfo->displayMode = WebDisplayModeFullscreen; webPageUI->m_pwaInfo->themeColor = 1.1; webPageUI->m_pwaInfo->backgroundColor = 2.2; - std::string str = std::string("browser_shortcut:://") - + "pwd_id:" + (webPageUI->m_pwaInfo->id) + "/" + std::string str = std::string("browser_shortcut://") + + "pwa_id:" + (webPageUI->m_pwaInfo->id) + "/" + "pwa_decodedIcon:" + (webPageUI->m_pwaInfo->decodedIcon) + "/" + "pwa_uri:" + (webPageUI->m_pwaInfo->uri) + "/" + "pwa_name:" + (webPageUI->m_pwaInfo->name) + "/" @@ -556,7 +557,7 @@ void WebPageUI::_cm_add_to_hs_clicked(void* data, Evas_Object*, void* ) BROWSER_LOGD("[%s:%d] str : %s", __PRETTY_FUNCTION__, __LINE__, str.c_str()); - if (shortcut_add_to_home("Shortcut", LAUNCH_BY_URI, str.c_str(), NULL, 0, result_cb, NULL) != SHORTCUT_ERROR_NONE) { + if (shortcut_add_to_home("PWA Sample", LAUNCH_BY_URI, str.c_str(), NULL, 0, result_cb, NULL) != SHORTCUT_ERROR_NONE) { BROWSER_LOGE("[%s:%d] Fail to add to homescreen", __PRETTY_FUNCTION__, __LINE__); } } @@ -566,7 +567,6 @@ void WebPageUI::_cm_add_to_hs_clicked(void* data, Evas_Object*, void* ) } int WebPageUI::result_cb(int ret, void *data) { - if (data) { BROWSER_LOGD("[%s:%d] ret : %d, data : %s", __PRETTY_FUNCTION__, __LINE__, ret, data); } @@ -884,6 +884,19 @@ Eina_Bool WebPageUI::_hideDelay(void *data) return ECORE_CALLBACK_CANCEL; } +void WebPageUI::setDisplayMode(WebPageUI::WebDisplayMode mode) +{ + BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); + if (mode == WebDisplayMode::WebDisplayModeFullscreen) + elm_object_signal_emit(m_mainLayout, "webview_fullscreen", "ui"); + else if (mode == WebDisplayMode::WebDisplayModeStandalone) + BROWSER_LOGD("Not implemented"); + else if (mode == WebDisplayMode::WebDisplayModeMinimalUi) + BROWSER_LOGD("Not implemented"); + else if (mode == WebDisplayMode::WebDisplayModeBrowser) + elm_object_signal_emit(m_mainLayout, "webview_default", "ui"); +} + void WebPageUI:: launch_share(const char *uri) { BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__); diff --git a/services/WebPageUI/WebPageUI.h b/services/WebPageUI/WebPageUI.h index db3e375f..235a3283 100755 --- a/services/WebPageUI/WebPageUI.h +++ b/services/WebPageUI/WebPageUI.h @@ -120,6 +120,7 @@ public: static Eina_Bool _hideDelay(void *data); void setDesktopMode(bool desktopMode) {m_desktopMode = desktopMode;} bool getDesktopMode() { return m_desktopMode; } + void setDisplayMode(WebDisplayMode mode); std::string getURI(); diff --git a/services/WebPageUI/edc/WebPageUI.edc b/services/WebPageUI/edc/WebPageUI.edc index 72c14b62..228cfc2b 100644 --- a/services/WebPageUI/edc/WebPageUI.edc +++ b/services/WebPageUI/edc/WebPageUI.edc @@ -304,6 +304,12 @@ collections { base_scale: 2.6; rel1 { relative: 0.0 1.0; to: "uri_bar_bg"; } rel2 { relative: 1.0 0.0; to: "bottom_toolbar"; } } + description { + state: "fullscreen" 0.0; + inherit: "default" 0.0; + rel1 { relative: 0.0 0.0; to: "bg"; } + rel2 { relative: 1.0 1.0; to: "bg"; } + } } part { name: "web_view_dummy_button"; @@ -512,6 +518,20 @@ collections { base_scale: 2.6; target: "uri_bar_bg_color"; target: "bottom_toolbar_bg_color"; } + program { + name: "webview_fullscreen"; + signal: "webview_fullscreen"; + source: "ui"; + action: STATE_SET "fullscreen" 0.0; + target: "web_view"; + } + program { + name: "webview_default"; + signal: "webview_default"; + source: "ui"; + action: STATE_SET "default" 0.0; + target: "web_view"; + } } } }