<smack request="app-svc" type="rwxat"/>
<smack request="app-svc::db" type="rwxat"/>
<smack request="svi-data" type="rwxat"/>
- <smack request="mobileprint" type="rwxat"/>
<smack request="sound_server" type="rwxat"/>
<smack request="pkgmgr::db" type="rwxat"/>
<!-- <smack request="immvibed" type="rwxa"/> -->
+#git:framework/web/web-provider
Name: livebox.web-provider
Summary: web framework for livebox
-Version: 1.22.1
+Version: 1.28
Release: 1
Group: main/app
License: Flora License, Version 1.1
static const std::string jsonMemberPath("path");
static const std::string jsonMemberBoxId("service_boxid");
static const std::string jsonMemberBoxScrollable("box_scrollable");
+static const std::string jsonMemberBoxSize("supported_size");
static const std::string jsonValueBoolTrue("true");
static const std::string jsonValueBoolFalse("false");
static const std::string jsonFileExtension(".json");
+static const std::string mendatoryBoxSize("1x1");
web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count)
{
static_cast<const char*>(
json_object_get_string_member(object, jsonMemberPath.c_str()));
- if (!type || !path) {
+ JsonArray* size =
+ json_object_get_array_member(object, jsonMemberBoxSize.c_str());
+ int sizeCount = static_cast<int>(json_array_get_length(size));
+
+ if (!type || !path || !sizeCount) {
LogD("mandatory members don't exist");
g_error_free(error);
g_object_unref(parser);
info->type = strdup(type);
info->path = strdup(path);
+ info->box_size = static_cast<char**>(malloc(sizeof(char*) * sizeCount));
+
+ for (int i = 0; i < sizeCount; i++) {
+ info->box_size[i] =
+ strdup(static_cast<const char*>(json_array_get_string_element(size, i)));
+ }
+ info->box_size_count = sizeCount;
gboolean hasBoxId = json_object_has_member(object, jsonMemberBoxId.c_str());
if (hasBoxId == TRUE) {
g_error_free(error);
g_object_unref(parser);
- return info;
+ return info;
}
bool web_provider_plugin_release_info(web_provider_plugin_info* info)
delete info->type;
delete info->path;
delete info->service_boxid;
+ for(int i = 0; i < info->box_size_count; i++) {
+ delete[] info->box_size[i];
+ }
delete info;
return true;
}
+
+int web_provider_plugin_check_supported_size(
+ const char* plugin_type, char** size, int sizeCount)
+{
+ bool mendatoryChk = false;
+
+ // read plugin directory and store plugin config path
+ std::string configPath;
+ configPath = installedPluginDirPath;
+ configPath += plugin_type;
+ configPath += jsonFileExtension;
+
+ // get the json datas
+ web_provider_plugin_info* jsonData = get_parsed_json_data(configPath);
+ if (!jsonData) {
+ LogD("failed to get the json file");
+ return false;
+ }
+
+ // compare the parsed config data with the parsed json data
+ for (int configCnt = 0; configCnt < sizeCount; configCnt++) {
+ bool supportedSizeChk = false;
+
+ for (int jsonCnt = 0; jsonCnt < jsonData->box_size_count; jsonCnt++) {
+
+ // check mendatory size
+ if (!strcmp(mendatoryBoxSize.c_str(), size[configCnt])) {
+ mendatoryChk = true;
+ }
+
+ // check supported size
+ if (!strcmp(jsonData->box_size[jsonCnt], size[configCnt])) {
+ supportedSizeChk = true;
+ break;
+ }
+ }
+
+ if (!supportedSizeChk) {
+ LogD("Not supported size: %s", size[configCnt]);
+ return false;
+ }
+ }
+
+ if (!mendatoryChk) {
+ LogD("Mandatory members don't exist ");
+ return false;
+ }
+
+ return true;
+}
const char* type;
const char* path;
const char* service_boxid;
+ char** box_size;
int box_scrollable;
+ int box_size_count;
};
typedef _web_provider_plugin_info web_provider_plugin_info;
web_provider_plugin_info** info_list,
int count);
EXPORT_API int web_provider_plugin_get_box_scrollable(const char* plugin_type);
-
+EXPORT_API int web_provider_plugin_check_supported_size(const char* plugin_type, char** size, int sizeCount);
#ifdef __cplusplus
}
#endif
* @author Yunchan Cho (yunchan.cho@samsung.com)
*/
#include <string>
+#include <Ecore.h>
#include <Plugin/IBoxPluginFactory.h>
#include "Buffer/IRenderBuffer.h"
+#include "Buffer/RenderBuffer.h"
#include "Buffer/RenderBufferFactory.h"
#include "Util/Log.h"
#include "BoxData.h"
: m_boxInfo(boxInfo)
, m_factory(factory)
, m_currentTab(true)
+ , m_paused(false)
+ , m_updateNeeded(false)
{
LogD("enter");
try {
try {
m_updateTimer->start();
- m_boxBuffer->startCanvasUpdate();
RenderInfoPtr renderInfo = makeRenderInfo(renderTypeCreate);
+ m_boxBuffer->stopCanvasUpdate();
m_view->showBox(renderInfo);
+ ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_boxBuffer.get());
} catch (...) {
return false;
}
try {
m_currentTab = true;
- m_updateTimer->resume();
- m_view->resumeBox();
+ m_paused = false;
+
+ if (m_updateNeeded) {
+ m_updateNeeded = false;
+ return update();
+ } else {
+ m_view->resumeBox();
+ }
} catch (...) {
return false;
}
if (!background) {
m_currentTab = false;
}
- m_updateTimer->pause();
+ m_paused = true;
m_view->pauseBox();
} catch (...) {
return false;
m_boxInfo->pdHeight);
m_pdBuffer->allocate();
RenderInfoPtr renderInfo = makeRenderInfo(renderTypeOpenPd);
+ m_pdBuffer->stopCanvasUpdate();
m_view->showPd(m_pdBuffer->getWindow(), renderInfo);
+ ecore_idler_add(startUpdateRenderBufferIdlerCallback, m_pdBuffer.get());
} catch (...) {
return false;
}
try {
m_view->hidePd();
m_pdBuffer->free();
- m_updateTimer->start();
+ m_updateTimer->restart();
} catch (...) {
return false;
}
{
LogD("enter");
+ if (m_paused) {
+ // update is dalayed until this box goes to current tab
+ m_updateNeeded = true;
+ return true;
+ }
+
m_boxBuffer->startCanvasUpdate();
RenderInfoPtr renderInfo = makeRenderInfo(renderTypeUpdate);
m_view->showBox(renderInfo);
return ECORE_CALLBACK_RENEW;
}
+Eina_Bool Box::startUpdateRenderBufferIdlerCallback(void* data)
+{
+ LogD("enter");
+ RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
+ if (!buffer) {
+ LogD("no buffer");
+ } else {
+ buffer->startCanvasUpdate();
+ }
+
+ return ECORE_CALLBACK_CANCEL;
+}
// static callbacks
static Eina_Bool updateCallback(void* data);
+ static Eina_Bool startUpdateRenderBufferIdlerCallback(void* data);
// constructor
explicit Box(
IRenderBufferPtr m_pdBuffer;
IRenderViewPtr m_view;
ITimerPtr m_updateTimer;
+ // flag for knowing this box is on current tab
bool m_currentTab;
+ // flag for knowing this box has been already paused
+ bool m_paused;
+ // flag for knowing this box should be updated when the box is resumed
+ bool m_updateNeeded;
//IBoxStatePtr m_state;
friend class BoxSchemeHandler;
* @file BoxManager.cpp
* @author Yunchan Cho (yunchan.cho@samsung.com)
*/
+#include <string>
#include <map>
#include <ewk_context.h>
#include <Plugin/IBoxPluginFactory.h>
result = requestChangePeriod(boxInfo->instanceId, boxInfo->period);
break;
case REQUEST_CMD_UPDATE_BOX:
- result = requestUpdateBox(boxInfo->instanceId);
+ result = requestUpdateBox(boxInfo->boxId);
break;
default:
LogD("not available request type");
return box->changePeriod(period);
}
-bool BoxManager::requestUpdateBox(std::string& instanceId)
+bool BoxManager::requestUpdateBox(std::string& boxId)
{
LogD("enter");
- IBoxPtr box = searchBoxMap(instanceId);
- if (!box) {
- return false;
+
+ IBoxPtr box;
+ box.reset();
+ for (auto it = m_boxMap.begin(); it != m_boxMap.end(); ++it) {
+ if (it->first.find(boxId) == std::string::npos) {
+ continue;
+ }
+ box = it->second;
+ box->update();
}
- return box->update();
+ return true;
}
void BoxManager::insertBoxMap(std::string& instanceId, IBoxPtr box)
LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
Evas* e = ecore_evas_get(ee);
+ evas_image_cache_flush(e);
Evas_Object *eo = evas_object_rectangle_add(e);
evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_color_set(eo, 0, 0, 0, 0);
provider_buffer_sync(m_bufferInfo);
updateBuffer();
} else {
- provider_buffer_pre_render(m_bufferInfo);
+ preRenderCallback(this, m_canvas, NULL);
memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
- provider_buffer_post_render(m_bufferInfo);
- updateBuffer();
+ postRenderCallback(this, m_canvas, NULL);
}
}
bool reallocate(int width, int height);
bool free();
Evas_Object* getWindow();
+ void startCanvasUpdate();
+ void stopCanvasUpdate();
static void preRenderCallback(void* data, Evas* canvas, void* eventInfo);
static void postRenderCallback(void* data, Evas* canvas, void* eventInfo);
virtual ~RenderBuffer();
protected:
- void startCanvasUpdate();
- void stopCanvasUpdate();
void paintColor(unsigned int color);
Evas* getCanvas();
Evas_Object* getSnapshot();
return true;
}
+bool launchDownloader(std::string& url, std::string& cookie)
+{
+ LogD("enter");
+
+ service_h handle = NULL;
+ int ret = SERVICE_ERROR_NONE;
+
+ if (url.empty()) {
+ LogD("invalid arguments");
+ return false;
+ }
+
+ ret = service_create(&handle);
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to create service");
+ return false;
+ }
+
+ ret = service_set_operation(handle, SERVICE_OPERATION_DOWNLOAD);
+ 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;
+ }
+
+ if (!cookie.empty()) {
+ ret = service_add_extra_data(handle, "cookie", cookie.c_str());
+ if (ret != SERVICE_ERROR_NONE) {
+ LogD("failed to set cookie");
+ 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 downloader");
+ service_destroy(handle);
+
+ return true;
+}
+
} // AppControl
} // Service
namespace AppControl {
bool launchBrowser(std::string& url);
+bool launchDownloader(std::string& url, std::string& cookie);
}
} // Service
ecore-x
elementary
provider
+ ecore
REQUIRED
)
ADD_DEFINITIONS(${${DEPS}_CFLAGS})
#include <string>
#include <Evas.h>
#include <Ecore_X.h>
+#include <Ecore.h>
#include <Elementary.h>
#include <livebox-service.h>
#include <Core/Util/Log.h>
Evas_Object* window = createWindow();
Evas_Object* periodList = elm_list_add(window);
- Evas_Object* radio;
if (!periodList) {
LogD("failed to add elm_list_add");
setPopupListData();
// TODO Language ID should be used, not static string
for(int i = 0 ; i < sizeof(m_hour) / sizeof(PopupListData); i++) {
- radio = elm_radio_add(periodList);
- elm_radio_state_value_set(radio,
+ m_hour[i].radio = elm_radio_add(periodList);
+ elm_radio_state_value_set(m_hour[i].radio,
m_currentPeriod == m_hour[i].newPeriod ? EINA_FALSE : EINA_TRUE);
elm_list_item_append(periodList,
m_hour[i].period,
- radio,
+ m_hour[i].radio,
NULL,
selectPeriodCallback, &m_hour[i]);
}
LogD("Update period is set to %f", popupData->newPeriod);
popupData->periodChanger->requestToPlatform(popupData->newPeriod);
- popupData->periodChanger->destroyPeriodPopup(obj);
+ ecore_idler_add(popupDestroyIdlerCallback, popupData);
}
void PeriodChanger::cancelButtonCallback(void *data, Evas_Object *obj, void *event_info)
This->destroyPeriodPopup(obj);
}
+Eina_Bool PeriodChanger::popupDestroyIdlerCallback(void *data)
+{
+ LogD("enter");
+ PopupListData* popupData = static_cast<PopupListData*>(data);
+ popupData->periodChanger->destroyPeriodPopup(popupData->radio);
+ return ECORE_CALLBACK_CANCEL;
+}
} // Service
static void selectPeriodCallback(void *data, Evas_Object *obj, void *event_info);
static void cancelButtonCallback(void *data, Evas_Object *obj, void *event_info);
+ static Eina_Bool popupDestroyIdlerCallback(void *data);
PeriodChanger(
std::string& boxId, std::string& instanceId,
PeriodChanger* periodChanger;
float newPeriod;
const char* period;
+ Evas_Object* radio;
};
PopupListData m_hour[5];
#include <Eina.h>
#include <ewk_context.h>
#include <ewk_view.h>
+#include <ewk_policy_decision.h>
#include <Core/Util/Log.h>
+#include <Core/Service/AppControl.h>
#include "WebView.h"
// injection javascript file regarding creating js object used by box and pd
{
LogD("enter");
+ Ewk_Policy_Decision *policyDecision = static_cast<Ewk_Policy_Decision *>(eventInfo);
+ Ewk_Policy_Decision_Type policyType = ewk_policy_decision_type_get(policyDecision);
+ std::string url(ewk_policy_decision_url_get(policyDecision));
+ std::string cookie(ewk_policy_decision_cookie_get(policyDecision));
+ const char* contentType = ewk_policy_decision_response_mime_get(policyDecision);
+
+ switch (policyType) {
+ case EWK_POLICY_DECISION_USE:
+ LogD("policy use");
+ ewk_policy_decision_use(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_DOWNLOAD:
+ LogD("policy download: %s, %s, %s", url.c_str(), cookie.c_str(), contentType);
+ ewk_policy_decision_suspend(policyDecision);
+ Service::AppControl::launchDownloader(url, cookie);
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+
+ case EWK_POLICY_DECISION_IGNORE:
+ default:
+ LogD("policy ignore");
+ ewk_policy_decision_ignore(policyDecision);
+ break;
+ }
+
+ if (policyType == EWK_POLICY_DECISION_DOWNLOAD) {
+ if (ewk_view_back_possible(obj)) {
+ ewk_view_back(obj);
+ } else {
+ // TODO Add handling code in case that new window is opened
+ //ecore_idler_add(windowCloseIdlerCallback, data);
+ }
+ }
+
WebView* This = static_cast<WebView*>(data);
This->didPageResponseDecide(obj);
}
// set javascript objects for Web APIs of Tizen appwidget
+var appTizenObject = 0;
if (typeof window.tizen == 'undefined') {
- console.log("window.tizen object not exists");
window.tizen = new Object();
window.tizen.appwidget = new Object();
+} else {
+ appTizenObject = 1;
}
// For future, only window.appwidget will be used
window.appwidget.reload = function() {
window.location.href = "box://reload";
-}
+};
window.appwidget.changePeriod = function(period) {
switch (arguments.length) {
window.location.href = "box://change-period";
break;
}
-}
+};
window.appwidget.launchBrowser = function(url) {
window.location.href = "box://launch-browser?url=" + url;
-}
+};
window.appwidget.scrollStart = function() {
window.location.href = "box://scroll-start";
-}
+};
window.appwidget.scrollStop = function() {
window.location.href = "box://scroll-stop";
-}
+};
window.appwidget.sendMessageToBox = function(message) {
window.location.href = "box://send-message-to-box?message=" + message;
-}
+};
window.appwidget.sendMessageToPd = function(message) {
window.location.href = "box://send-message-to-pd?message=" + message;
-}
+};
var webprovider = {
// define specific function for registering appwidget event
console.log("unknown appwidget event: " + event);
}
},
-}
+};
// register custom events for appwidget
webprovider.registerAppWidgetEvent("pdmessage");
webprovider.registerAppWidgetEvent("boxmessage");
// These objects will be deprecated soon
-window.tizen.appwidget.reload = window.appwidget.reload;
-window.tizen.appwidget.changePeriod = window.appwidget.changePeriod;
-window.tizen.appwidget.launchBrowser = window.appwidget.launchBrowser;
-window.tizen.appwidget.scrollStart = window.appwidget.scrollStart;
-window.tizen.appwidget.scrollStop = window.appwidget.scrollStop;
+if (!appTizenObject) {
+ window.tizen.appwidget.reload = window.appwidget.reload;
+ window.tizen.appwidget.changePeriod = window.appwidget.changePeriod;
+ window.tizen.appwidget.launchBrowser = window.appwidget.launchBrowser;
+ window.tizen.appwidget.scrollStart = window.appwidget.scrollStart;
+ window.tizen.appwidget.scrollStop = window.appwidget.scrollStop;
+}
+
+// If every functionalities of appwidget are initialized, fire appwidget ready event
+var readyevent = document.createEvent("CustomEvent");
+readyevent.initCustomEvent("appwidgetready", true, true);
+document.dispatchEvent(readyevent);
{
LogD("enter");
+ // stop updating render buffer
+ m_renderBuffer->stopCanvasUpdate();
+ clearSnapShot();
+
// delete already running timer
deleteRenderTimer();
std::string boxStartUrl = getStartUrl(URL_TYPE_BOX, renderInfo->defaultUrlParams);
if (m_boxWrt) {
LogD("existing wrt core is removed");
- destroyWrtCore(m_boxWrt);
+ destroyBoxWrtCore();
}
m_boxWrt = createWrtCore(boxStartUrl, m_boxWin, m_ewkContext);
// To support transparent background
evas_object_color_set(wrt->GetCurrentWebview(), 0, 0, 0, 0);
- evas_object_layer_set(wrt->GetCurrentWebview(), EVAS_LAYER_MAX);
+ //evas_object_layer_set(wrt->GetCurrentWebview(), EVAS_LAYER_MAX);
+
+ // To know starting point for updating buffer
+ evas_object_smart_callback_add(
+ wrt->GetCurrentWebview(),
+ "load,nonemptylayout,finished",
+ //"frame,rendered",
+ loadNonEmptyLayoutFinishedCallback,
+ this);
return wrt;
}
{
LogD("enter");
if (m_snapshot) {
- evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
- //evas_object_hide(m_snapshot);
+ //evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
evas_object_del(m_snapshot);
m_snapshot = NULL;
}
void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
{
LogD("enter");
- m_renderBuffer->startCanvasUpdate();
// execute injection for creating js objects
std::ifstream jsFile(injectionFile);
std::string script((std::istreambuf_iterator<char>(jsFile)),
ewk_shutdown();
elm_exit();
}
+
+void AppBoxRenderView::loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo)
+{
+ LogD("enter");
+
+ // start to update render buffer!
+ AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+ This->m_renderBuffer->startCanvasUpdate();
+}
// ewk view callback
static void executeScriptCallback(
Evas_Object* webview, const char* result, void* data);
+ static void loadNonEmptyLayoutFinishedCallback(
+ void* data, Evas_Object* webview, void* eventInfo);
// user Callbacks of RunnableWidgetObject
void startLoadCallback(Evas_Object* webview);
{
"type" : "app",
- "path" : "/usr/lib/web-provider/libweb-provider-plugin-app.so"
+ "path" : "/usr/lib/web-provider/libweb-provider-plugin-app.so",
+ "supported_size" : ["1x1","2x1","2x2"]
}