The following Web API are supported.
- tizen.appwidget.reload();
- tizen.appwidget.launchBrowser(url);
And if needed, other Web API for livebox will be added
[Issue#] N/A
[Problem] Content of box or pd can't request some tasks to web-provider like reloading box, launching browser
[Cause] There was no way for content of box or pd to request specific tasks to web-provider
[Solution] Additional js objects for livebox device api are defined,
and this objects are injected before loading real resources of box or pd.
Change-Id: Ida0c6513a9b83215772feb7ce50071a17b90ca20
<smack request="ail::db" type="rwxat"/>
<smack request="sys-assert::core" type="rwxat"/>
<smack request="webkit2-efl" type="rwxat"/>
+ <smack request="app-svc" type="rwxat"/>
<!-- <smack request="immvibed" type="rwxa"/> -->
</request>
<permit>
BuildRequires: pkgconfig(livebox-service)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(json-glib-1.0)
+BuildRequires: pkgconfig(capi-appfw-application)
# requires for smack
Requires(post): sys-assert
#include "BoxState.h"
#include "Util/ITimer.h"
#include "BoxUpdateTimer.h"
+#include "BoxSchemeHandler.h"
#include "Box.h"
// This is used for informing context of box to web content as value of url parameter
boxInfo->period,
Box::updateCallback,
this);
+ BoxSchemeHandler::Instance()->registerBox(boxInfo->instanceId, this);
+
// TODO code regarding state needs more testing
//m_state = BoxInitState::create(
// IBoxContextPtr(dynamic_cast<IBoxContext*>(this)));
Box::~Box()
{
LogD("enter");
+ BoxSchemeHandler::Instance()->unregisterBox(m_boxInfo->instanceId);
}
bool Box::show()
return true;
}
+void Box::update()
+{
+ LogD("enter");
+
+ m_boxBuffer->startCanvasUpdate();
+ RenderInfoPtr renderInfo = makeRenderInfo(renderTypeUpdate);
+ m_view->showBox(renderInfo);
+}
+
RenderInfoPtr Box::makeRenderInfo(const std::string& renderType) const
{
RenderInfoPtr renderInfo(new RenderInfo);
LogD("enter");
Box* This = static_cast<Box*>(data);
- This->m_boxBuffer->startCanvasUpdate();
- RenderInfoPtr renderInfo = This->makeRenderInfo(renderTypeUpdate);
- This->m_view->showBox(renderInfo);
-
+ This->update();
return ECORE_CALLBACK_RENEW;
}
bool pause();
bool openPd(int width, int height);
bool closePd();
+ void update();
~Box();
private:
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+/**
+ * @file BoxSchemeHandler.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string.h>
+#include "Box.h"
+#include "Service/AppControl.h"
+#include "Util/Log.h"
+#include "BoxSchemeHandler.h"
+
+static const std::string BOX_SCHEME("box://");
+static const std::string BOX_SCHEME_RELOAD("box://reload");
+static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
+static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
+
+static const std::string HTTP_SCHEME("http://");
+static const std::string HTTPS_SCHEME("https://");
+
+// static variable intialization
+BoxSchemeHandler* BoxSchemeHandler::s_instance = NULL;
+
+BoxSchemeHandler::BoxSchemeHandler()
+ : m_boxMap()
+{
+ LogD("enter");
+}
+
+BoxSchemeHandler::~BoxSchemeHandler()
+{
+ LogD("enter");
+}
+
+BoxSchemeHandler* BoxSchemeHandler::Instance()
+{
+ LogD("enter");
+ if (!s_instance) {
+ s_instance = new BoxSchemeHandler();
+ }
+
+ return s_instance;
+}
+
+void BoxSchemeHandler::registerBox(std::string& instanceId, Box* box)
+{
+ LogD("enter");
+
+ if (getBox(instanceId)) {
+ LogD("already registered");
+ return;
+ }
+
+ m_boxMap.insert(BoxMapPair(instanceId, box));
+}
+
+void BoxSchemeHandler::unregisterBox(std::string& instanceId)
+{
+ LogD("enter");
+ m_boxMap.erase(instanceId);
+}
+
+bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
+{
+ LogD("enter");
+
+ if (!isBoxScheme(uri)) {
+ return false;
+ }
+
+ if (!uri.compare(BOX_SCHEME_RELOAD)) {
+ return handleReload(instanceId);
+ }
+
+ if (!uri.compare(BOX_SCHEME_CHANGE_PERIOD)) {
+ return handleChangePeriod(instanceId);
+ }
+
+ if (!uri.compare(
+ 0,
+ BOX_SCHEME_LAUNCH_BROWSER.size(),
+ BOX_SCHEME_LAUNCH_BROWSER))
+ {
+ std::string key("url");
+ std::string url = parse(uri, key);
+ return handleLaunchBrowser(instanceId, url);
+ }
+
+ LogD("unknown box scheme protocol");
+ return false;
+}
+
+bool BoxSchemeHandler::isBoxScheme(std::string& uri)
+{
+ LogD("enter");
+ if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
+ return true;
+ }
+
+ return false;
+}
+
+Box* BoxSchemeHandler::getBox(std::string& instanceId)
+{
+ LogD("enter");
+
+ auto it = m_boxMap.find(instanceId);
+ if (it != m_boxMap.end()) {
+ LogD("registered: %s (%p)", it->first.c_str(), it->second);
+ return it->second;
+ }
+
+ return NULL;
+}
+
+bool BoxSchemeHandler::handleReload(std::string& instanceId)
+{
+ LogD("enter");
+ Box* box = getBox(instanceId);
+ if (!box) {
+ LogD("unregistered instance");
+ return false;
+ }
+
+ box->update();
+ return true;
+}
+
+bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId)
+{
+ LogD("enter");
+ // TODO show special efl window for this
+ return true;
+}
+
+bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
+{
+ LogD("enter");
+ if(!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
+ !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
+ {
+ return Service::AppControl::launchBrowser(url);
+ }
+
+ return false;
+}
+
+std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
+{
+ LogD("enter");
+
+ // TODO url parameter SHOULD be parsed using std::regex, not manually
+ std::string value("");
+
+ unsigned found = uri.find_first_of("?");
+ if (found == std::string::npos) {
+ LogD("no query");
+ return value;
+ }
+
+ std::string query = std::string(uri, found + 1);
+ found = 0;
+ do {
+ LogD("enter\n");
+ unsigned seperator = query.find_first_of("=", found + 1);
+ if (seperator == std::string::npos) {
+ LogD("no '=' character\n");
+ break;
+ }
+
+ unsigned next = query.find_first_of("&", found + 1);
+ if (!query.compare(found, key.size(), key)) {
+ LogD("key matched!\n");
+ value = std::string(query, seperator + 1, next - seperator);
+ break;
+ }
+
+ found = next + 1;
+ } while (found && found != std::string::npos);
+
+ LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
+ return value;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+/**
+ * @file BoxSchemeHandler.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+#ifndef BOX_SCHEME_HANDLER_H
+#define BOX_SCHEME_HANDLER_H
+
+#include <string>
+#include <map>
+
+class Box;
+
+#define EXPORT_CLASS __attribute__ ((visibility("default"))
+
+class EXPORT_CLASS BoxSchemeHandler {
+ public:
+ static BoxSchemeHandler* Instance();
+ void registerBox(std::string& instanceId, Box* box);
+ void unregisterBox(std::string& instanceId);
+ bool process(std::string& instanceId, std::string& uri);
+ bool isBoxScheme(std::string& uri);
+
+ private:
+ Box* getBox(std::string& instanceId);
+ bool handleReload(std::string& instanceId);
+ bool handleChangePeriod(std::string& instanceId);
+ bool handleLaunchBrowser(std::string& instanceId, std::string& url);
+ std::string parse(std::string& uri, std::string& key);
+
+ BoxSchemeHandler();
+ ~BoxSchemeHandler();
+
+ // members
+ typedef std::map<std::string, Box*> BoxMap;
+ typedef std::pair<std::string, Box*> BoxMapPair;
+ BoxMap m_boxMap;
+ static BoxSchemeHandler* s_instance;
+};
+
+#endif // BOX_SCHEME_HANDLER_H
+
RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
evas_data_argb_unpremul(static_cast<unsigned int*>(buffer->m_bufferAddr), buffer->getWidth() * buffer->getHeight());
+#ifdef RENDER_BUFFER_VERIFY_SHOT
{
FILE *fp;
static int idx = 0;
LogD("Failed to open a file: %s", filename);
}
}
+#endif
if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
provider_buffer_sync(buffer->m_bufferInfo);
SET(TARGET_NAME ${TARGET_CORE})
SET(TARGET_CORE_BUFFER web-provider-core-buffer)
SET(TARGET_CORE_VIEW web-provider-core-view)
+SET(TARGET_CORE_SERVICE web-provider-core-service)
SET(TARGET_CORE_UTIL web-provider-core-util)
SET(DEPS ${TARGET_NAME}_DEPS)
${CMAKE_CURRENT_SOURCE_DIR}/BoxManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/BoxState.cpp
${CMAKE_CURRENT_SOURCE_DIR}/BoxUpdateTimer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/BoxSchemeHandler.cpp
)
SET(HEADERS
"-Wl,--whole-archive"
${TARGET_CORE_VIEW}
${TARGET_CORE_BUFFER}
+ ${TARGET_CORE_SERVICE}
${TARGET_CORE_UTIL}
"-Wl,--no-whole-archive"
)
ADD_SUBDIRECTORY(Buffer)
ADD_SUBDIRECTORY(View)
+ADD_SUBDIRECTORY(Service)
ADD_SUBDIRECTORY(Util)
INSTALL(TARGETS ${TARGET_NAME}
INSTALL_FILE(BoxData.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
INSTALL_FILE(IBoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
INSTALL_FILE(BoxManager.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
+INSTALL_FILE(BoxSchemeHandler.h include/${PROJECT_NAME}/${CURRENT_DIR_NAME})
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+/**
+ * @file LaunchBrowser.cpp
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <app_service.h>
+#include <Core/Util/Log.h>
+#include "AppControl.h"
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_VIEW);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set operation");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_set_uri(handle, url.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set url");
+ service_destroy(handle);
+ return false;
+ }
+
+ ret = service_send_launch_request(handle, NULL, NULL);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to request launch");
+ service_destroy(handle);
+ return false;
+ }
+
+ LogD("success to launch browser: %s", url.c_str());
+ service_destroy(handle);
+
+ return true;
+}
+
+} // AppControl
+} // Service
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+/**
+ * @file LaunchBrowser.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+
+namespace Service {
+namespace AppControl {
+
+bool launchBrowser(std::string& url);
+
+}
+} // Service
--- /dev/null
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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.
+#
+# @author Yunchan Cho (yunchan.cho@samsung.com)
+
+SET(TARGET_NAME ${TARGET_CORE_SERVICE})
+SET(DEPS ${TARGET_NAME}_DEPS)
+
+PKG_CHECK_MODULES(${DEPS}
+ dlog
+ capi-appfw-application
+ REQUIRED
+)
+ADD_DEFINITIONS(${${DEPS}_CFLAGS})
+
+SET(SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/AppControl.cpp
+)
+
+SET(HEADERS
+ ${${DEPS}_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+INCLUDE_DIRECTORIES(${HEADERS})
+
+ADD_LIBRARY(${TARGET_NAME} STATIC ${SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ COMPILE_FLAGS -fPIC
+ LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both"
+)
+
+SET_TARGET_PROPERTIES(${TARGET_NAME}
+ PROPERTIES
+ SOVERSION ${CMAKE_PROJECT_API_VERSION}
+ VERSION ${CMAKE_PROJECT_VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${${DEPS}_LIBRARIES}
+)
+
+GET_FILENAME_COMPONENT(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+GET_FILENAME_COMPONENT(PARENT_DIR_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
+GET_FILENAME_COMPONENT(PARENT_DIR_NAME ${PARENT_DIR_ABSOLUTE_PATH} NAME)
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+/**
+ * @file InjectedScript.h
+ * @author Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#define INJECTED_SCRIPT \
+ " \
+ function reload() { \
+ window.location.href=\"box://reload\"; \
+ } \
+ function changePeriod() { \
+ window.location.href=\"box://change-period\"; \
+ } \
+ function launchBrowser(url) { \
+ window.location.href=\"box://launch-browser?url=\" + url; \
+ } \
+ window.tizen = new Object(); \
+ window.tizen.appwidget = new Object(); \
+ window.tizen.appwidget.reload = reload; \
+ window.tizen.appwidget.changePeriod = changePeriod; \
+ window.tizen.appwidget.launchBrowser = launchBrowser; \
+ "
#include <ewk_context.h>
#include <ewk_view.h>
#include <Core/Util/Log.h>
+#include "InjectedScript.h"
#include "WebView.h"
std::map<const std::string, const Evas_Smart_Cb> WebView::m_smartCallbacksMap =
{"load,started", WebView::loadStartedCallback},
{"load,finished", WebView::loadFinishedCallback},
{"title,changed", WebView::titleChangedCallback},
+ {"uri,changed", WebView::uriChangedCallback},
{"load,progress", WebView::loadProgressCallback},
{"load,progress,finished", WebView::loadProgressFinishedCallback},
{"process,crashed", WebView::processCrashedCallback},
// set orientation
ewk_view_orientation_lock_callback_set(
webview, orientationLockCallback, this);
+
+ evas_object_color_set(webview, 0, 0, 0, 0);
return true;
}
LogD("enter");
WebView* This = static_cast<WebView*>(data);
+ const char* injectedScript = INJECTED_SCRIPT;
+ ewk_view_script_execute(obj, injectedScript, executeScriptCallback, This);
This->didLoadStarted(obj);
}
This->didTitleChanged(obj, eventInfo);
}
+void WebView::uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+
+ WebView* This = static_cast<WebView*>(data);
+ This->didUriChanged(obj, eventInfo);
+}
+
void WebView::loadProgressCallback(
void* data, Evas_Object* obj, void* eventInfo)
{
// This Will be implemented by derived class
}
+void WebView::didUriChanged(Evas_Object* obj, void* eventInfo)
+{
+ LogD("enter");
+ // This Will be implemented by derived class
+}
+
void WebView::didLoadProgress(Evas_Object* obj, void* eventInfo)
{
LogD("enter");
LogD("enter");
return EINA_TRUE;
}
+
+void WebView::executeScriptCallback(
+ Evas_Object* obj, const char* result, void* data)
+{
+ LogD("enter");
+}
+
void* data, Evas_Object* obj, void* eventInfo);
static void titleChangedCallback(
void* data, Evas_Object* obj, void* eventInfo);
+ static void uriChangedCallback(
+ void* data, Evas_Object* obj, void* eventInfo);
static void loadProgressCallback(
void* data, Evas_Object* obj, void* eventInfo);
static void loadProgressFinishedCallback(
virtual void didLoadStarted(Evas_Object* obj);
virtual void didLoadFinished(Evas_Object* obj);
virtual void didTitleChanged(Evas_Object* obj, void* eventInfo);
+ virtual void didUriChanged(Evas_Object* obj, void* eventInfo);
virtual void didLoadProgress(Evas_Object* obj, void* eventInfo);
virtual void didLoadProgressFinished(Evas_Object* obj);
virtual void didProcessCrashed(Evas_Object* obj);
// orientation lock
static Eina_Bool orientationLockCallback(
Evas_Object* obj, Eina_Bool needLock, int orientation, void* data);
+ static void executeScriptCallback(Evas_Object* obj, const char* result, void* data);
static std::map<const std::string, const Evas_Smart_Cb> m_smartCallbacksMap;