From 6d87542b832f9ba2ae1558aea34694311b3e7548 Mon Sep 17 00:00:00 2001 From: Seungkeun Lee Date: Mon, 7 Sep 2015 15:29:46 +0900 Subject: [PATCH] Implement Scheme to Appcontrol request - Well-known scheme was converted to AppControl request - Except (http(s), file, app, data, blob), all custom scheme was send to AppControl request Change-Id: Id4fe074cdec87bd8812519f555dea31f28be60ea --- common/app_control.cc | 66 ++++++++++++++++++++++++++++++++++++++ common/app_control.h | 3 ++ runtime/browser/web_application.cc | 28 ++++++++++++++-- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/common/app_control.cc b/common/app_control.cc index 799af8b..5818b8f 100755 --- a/common/app_control.cc +++ b/common/app_control.cc @@ -21,8 +21,14 @@ #include #include +#include +#include +#include // NOLINT +#include #include "common/logger.h" +#include "common/string_utils.h" +#include "common/file_utils.h" namespace common { @@ -57,6 +63,46 @@ static bool BundleAddDataArray(bundle* target, const std::string& key, } } +static const std::string GetOperationFromScheme(const std::string& scheme) { + static std::map table = { + {"sms", APP_CONTROL_OPERATION_COMPOSE}, + {"mmsto", APP_CONTROL_OPERATION_COMPOSE}, + {"mailto", APP_CONTROL_OPERATION_COMPOSE}, + {"tel", APP_CONTROL_OPERATION_CALL} + }; + auto found = table.find(scheme); + if (found == table.end()) { + // default operation + return APP_CONTROL_OPERATION_VIEW; + } + return found->second; +} + +static void AppendExtraDatafromUrl(AppControl* request, + const std::string& url) { + static std::vector > patterns = { + {".*[?&]body=([^&]+).*", APP_CONTROL_DATA_TEXT}, + {".*[?&]cc=([^&]+).*", APP_CONTROL_DATA_CC}, + {".*[?&]bcc=([^&]+).*", APP_CONTROL_DATA_BCC}, + {".*[?&]subject=([^&]+).*", APP_CONTROL_DATA_SUBJECT}, + {".*[?&]to=([^&]+).*", APP_CONTROL_DATA_TO}, + {"sms:([^?&]+).*", APP_CONTROL_DATA_TO}, + {"mmsto:([^?&]+).*", APP_CONTROL_DATA_TO}, + {"mailto:([^?&]+).*", APP_CONTROL_DATA_TO} + }; + + for (auto& param : patterns) { + std::regex pattern(param.first, std::regex_constants::icase); + std::smatch result; + if (std::regex_match(url, result, pattern) && result.size() >= 2) { + std::string extra_data = result[1].str(); + request->AddData( + param.second, + utils::UrlDecode(extra_data)); + } + } +} + } // namespace @@ -210,4 +256,24 @@ bool AppControl::LaunchRequest() { APP_CONTROL_ERROR_NONE); } +std::unique_ptr AppControl::MakeAppcontrolFromURL( + const std::string& url) { + std::string smsto_scheme("smsto"); + + std::string request_url(url); + std::string scheme = utils::SchemeName(request_url); + // smsto: does not supported by platform. change to sms: + if (scheme == smsto_scheme) { + request_url = "sms" + request_url.substr(smsto_scheme.length()); + scheme = "sms"; + } + + std::unique_ptr request(new AppControl()); + request->set_uri(request_url); + request->set_operation(GetOperationFromScheme(scheme)); + AppendExtraDatafromUrl(request.get(), request_url); + + return std::move(request); +} + } // namespace common diff --git a/common/app_control.h b/common/app_control.h index 00fcedb..e59de11 100755 --- a/common/app_control.h +++ b/common/app_control.h @@ -22,11 +22,14 @@ #include #include #include +#include namespace common { class AppControl { public: + static std::unique_ptr MakeAppcontrolFromURL( + const std::string& url); explicit AppControl(app_control_h app_control); AppControl(); ~AppControl(); diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 3733a91..7b8cb82 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -184,6 +184,28 @@ static bool ClearCookie(Ewk_Context* ewk_context) { return true; } +static bool ProcessWellKnownScheme(const std::string& url) { + if (utils::StartsWith(url, "file:") || + utils::StartsWith(url, "app:") || + utils::StartsWith(url, "data:") || + utils::StartsWith(url, "http:") || + utils::StartsWith(url, "https:") || + utils::StartsWith(url, "widget:") || + utils::StartsWith(url, "about:") || + utils::StartsWith(url, "blob:")) { + return false; + } + + std::unique_ptr request(AppControl::MakeAppcontrolFromURL(url)); + if (request.get() == NULL || !request->LaunchRequest()) { + LOGGER(ERROR) << "Fail to send appcontrol request"; + SLoggerE("Fail to send appcontrol request [%s]", url.c_str()); + } + + // Should return true, to stop the WebEngine progress step about this URL + return true; +} + } // namespace WebApplication::WebApplication( @@ -666,9 +688,11 @@ void WebApplication::SetupWebView(WebView* view) { bool WebApplication::OnDidNavigation(WebView* /*view*/, const std::string& url) { - // TODO(sngn.lee): scheme handling + // scheme handling // except(file , http, https, app) pass to appcontrol and return false - + if (ProcessWellKnownScheme(url)) { + return false; + } return resource_manager_->AllowNavigation(url); } -- 2.7.4