Progressive web app launching mechanism 45/86945/9
authorDariusz Frankiewicz <d.frankiewic@samsung.com>
Mon, 5 Sep 2016 14:08:26 +0000 (16:08 +0200)
committerHye Kyoung Hwang <cookie@samsung.com>
Mon, 12 Sep 2016 01:30:12 +0000 (18:30 -0700)
[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

services/SimpleUI/CMakeLists.txt
services/SimpleUI/ProgressiveWebApp.cpp [new file with mode: 0644]
services/SimpleUI/ProgressiveWebApp.h [new file with mode: 0644]
services/SimpleUI/SimpleUI.cpp
services/SimpleUI/SimpleUI.h
services/WebPageUI/WebPageUI.cpp
services/WebPageUI/WebPageUI.h
services/WebPageUI/edc/WebPageUI.edc

index c2a4ed2300a5b67a6112b74cd2d9ce433925d866..72abfa66dfa3ab117d0fbba60df86248c3fd42bf 100644 (file)
@@ -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 (file)
index 0000000..1ab6403
--- /dev/null
@@ -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<std::string, std::string> &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 (file)
index 0000000..b19828e
--- /dev/null
@@ -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 <string>
+#include <map>
+
+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<std::string, std::string> &pwaParametersMap);
+
+    pwaInfo m_pwaInfoStruct;
+    std::map<std::string, std::string> m_uriPartsMap;
+};
+
+
+}   // namespace tizen_browser
+}   // namespace base_ui
+
+#endif // PROGRESSIVEWEBAPP_H
index 85daf464f6f2b235dd43567c4566f9dd809b1bcd..59e6f7a0980767020aa80a23ce9b3ad59fb5f274 100755 (executable)
@@ -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 <int> (tizen_browser::config::Config::getInstance().get("TAB_LIMIT"));
             m_favoritesLimit = boost::any_cast <int> (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<WebPageUI::WebDisplayMode>(
+                    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<const int*>(rots), size);
+}
+
 #endif
 
 Evas_Object* SimpleUI::getMainWindow()
index fc6b274ee17a96ea946b154f0f1f28627fd64394..9af9e8a619cd9d0568191467c0b144eedc17e722 100644 (file)
@@ -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;
index 5d7b979ce94ba3ee3df7ec3ddbad7c537c94ea36..d1e178a45b6b341696e20ce710ff62ce4e13eee0 100755 (executable)
@@ -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__);
index db3e375f611a27a0a6586d393962053da70d4d4e..235a3283773932ff7ba7e79462a60dea0210cd63 100755 (executable)
@@ -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();
 
index 72c14b62f97c28ee790144ea4f75e93c147780f6..228cfc2bf995b8ff2f762c81e11be4415ddd6e36 100644 (file)
@@ -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";
+            }
         }
     }
 }