From 54da26083a7a08b73fe617b683c3f3c8c895c4a2 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Fri, 9 Jun 2023 14:08:08 +0200 Subject: [PATCH] [agl][cef] Snapshot with all patches needed to enable wam-cef --- CMakeLists.txt | 18 +- src/CMakeLists.txt | 58 ++- src/agl-cef/CMakeLists.txt | 54 +++ src/agl-cef/plugin/CMakeLists.txt | 59 +++ src/agl-cef/plugin/agl_cef_context.cc | 4 + src/agl-cef/plugin/agl_cef_context.h | 42 ++ src/agl-cef/plugin/background_cef_app.cc | 33 ++ src/agl-cef/plugin/background_cef_app.h | 20 + src/agl-cef/plugin/homescreen_cef_app.cc | 25 ++ src/agl-cef/plugin/homescreen_cef_app.h | 15 + src/agl-cef/plugin/regular_cef_app.cc | 11 + src/agl-cef/plugin/regular_cef_app.h | 12 + src/agl-cef/plugin/web_app_factory_agl_cef.cc | 49 +++ src/agl-cef/plugin/web_app_factory_agl_cef.h | 23 ++ src/agl-cef/web_runtime_agl_cef.cc | 63 +++ src/agl-cef/web_runtime_agl_cef.h | 11 + src/agl/web_runtime_agl.cc | 16 +- src/agl/web_runtime_agl.h | 20 +- src/cef/cli/CMakeLists.txt | 17 + src/cef/cli/wam_cli.cc | 171 ++++++++ src/cef/device_info_cef.cc | 104 +++++ src/cef/device_info_cef.h | 38 ++ src/cef/handlers/wam_cef_browser_handler.cc | 31 ++ src/cef/handlers/wam_cef_browser_handler.h | 23 ++ src/cef/handlers/wam_cef_client.cc | 39 ++ src/cef/handlers/wam_cef_client.h | 31 ++ src/cef/handlers/wam_cef_render_handler.cc | 135 +++++++ src/cef/handlers/wam_cef_render_handler.h | 54 +++ src/cef/platform_module_factory_cef.cc | 31 ++ src/cef/platform_module_factory_cef.h | 27 ++ src/cef/plugin/web_app_cef.cc | 172 ++++++++ src/cef/plugin/web_app_cef.h | 95 +++++ src/cef/plugin/web_page_cef.cc | 48 +++ src/cef/plugin/web_page_cef.h | 69 ++++ src/cef/service/CMakeLists.txt | 64 +++ src/cef/service/applauncher.proto | 50 +++ src/cef/service/applauncher_client_grpc.cc | 58 +++ src/cef/service/applauncher_client_grpc.h | 24 ++ src/cef/service/wam_ipc.proto | 22 + .../service/web_app_manager_client_grpc.cc | 42 ++ src/cef/service/web_app_manager_client_grpc.h | 23 ++ .../service/web_app_manager_service_grpc.cc | 382 ++++++++++++++++++ .../service/web_app_manager_service_grpc.h | 85 ++++ src/core/CMakeLists.txt | 4 + src/core/application_description.cc | 37 ++ src/core/application_installation_handler.h | 12 + .../application_installation_handler_stub.cc | 4 + src/core/memory_pressure_level.h | 6 + src/core/web_app_manager.cc | 29 +- src/core/web_app_manager.h | 4 +- src/core/web_app_manager_service.cc | 4 +- src/core/web_app_manager_service.h | 3 +- src/core/web_page_base.h | 6 +- src/core/web_process_manager.h | 1 + src/core/web_runtime.h | 3 +- src/desktop/CMakeLists.txt | 100 +++++ src/desktop/README.md | 102 +++++ src/desktop/web_runtime_desktop.cc | 28 ++ src/desktop/web_runtime_desktop.h | 11 + src/platform/CMakeLists.txt | 23 +- src/platform/web_app_window.h | 6 +- src/util/log_msg_id.h | 2 + src/util/timer.h | 4 +- src/wam_main.cc | 4 +- src/webos/web_app_manager_service_luna.cc | 2 + src/webos/web_runtime_webos.cc | 2 +- src/webos/web_runtime_webos.h | 2 +- 67 files changed, 2693 insertions(+), 74 deletions(-) create mode 100644 src/agl-cef/CMakeLists.txt create mode 100644 src/agl-cef/plugin/CMakeLists.txt create mode 100644 src/agl-cef/plugin/agl_cef_context.cc create mode 100644 src/agl-cef/plugin/agl_cef_context.h create mode 100644 src/agl-cef/plugin/background_cef_app.cc create mode 100644 src/agl-cef/plugin/background_cef_app.h create mode 100644 src/agl-cef/plugin/homescreen_cef_app.cc create mode 100644 src/agl-cef/plugin/homescreen_cef_app.h create mode 100644 src/agl-cef/plugin/regular_cef_app.cc create mode 100644 src/agl-cef/plugin/regular_cef_app.h create mode 100644 src/agl-cef/plugin/web_app_factory_agl_cef.cc create mode 100644 src/agl-cef/plugin/web_app_factory_agl_cef.h create mode 100644 src/agl-cef/web_runtime_agl_cef.cc create mode 100644 src/agl-cef/web_runtime_agl_cef.h create mode 100644 src/cef/cli/CMakeLists.txt create mode 100644 src/cef/cli/wam_cli.cc create mode 100644 src/cef/device_info_cef.cc create mode 100644 src/cef/device_info_cef.h create mode 100644 src/cef/handlers/wam_cef_browser_handler.cc create mode 100644 src/cef/handlers/wam_cef_browser_handler.h create mode 100644 src/cef/handlers/wam_cef_client.cc create mode 100644 src/cef/handlers/wam_cef_client.h create mode 100644 src/cef/handlers/wam_cef_render_handler.cc create mode 100644 src/cef/handlers/wam_cef_render_handler.h create mode 100644 src/cef/platform_module_factory_cef.cc create mode 100644 src/cef/platform_module_factory_cef.h create mode 100644 src/cef/plugin/web_app_cef.cc create mode 100644 src/cef/plugin/web_app_cef.h create mode 100644 src/cef/plugin/web_page_cef.cc create mode 100644 src/cef/plugin/web_page_cef.h create mode 100644 src/cef/service/CMakeLists.txt create mode 100644 src/cef/service/applauncher.proto create mode 100644 src/cef/service/applauncher_client_grpc.cc create mode 100644 src/cef/service/applauncher_client_grpc.h create mode 100644 src/cef/service/wam_ipc.proto create mode 100644 src/cef/service/web_app_manager_client_grpc.cc create mode 100644 src/cef/service/web_app_manager_client_grpc.h create mode 100644 src/cef/service/web_app_manager_service_grpc.cc create mode 100644 src/cef/service/web_app_manager_service_grpc.h create mode 100644 src/core/application_installation_handler.h create mode 100644 src/core/application_installation_handler_stub.cc create mode 100644 src/core/memory_pressure_level.h create mode 100644 src/desktop/CMakeLists.txt create mode 100644 src/desktop/README.md create mode 100644 src/desktop/web_runtime_desktop.cc create mode 100644 src/desktop/web_runtime_desktop.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e9f94f..073e326 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,22 +18,24 @@ cmake_minimum_required(VERSION 3.13.0) project(WebAppMgr VERSION 1.0.0 LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_BUILD_TYPE Release) include(FindPkgConfig) set(OS_WEBOS FALSE) set(OS_AGL FALSE) -set(PLATFORM_NAME "WebOS" CACHE STRING "Target platform name (WebOS, POKY_AGL)") +set(OS_DESKTOP FALSE) +set(WEBENGINE_CEF TRUE) +set(WEBENGINE_CBE FALSE) +set(PLATFORM_NAME "Desktop" CACHE STRING "Target platform name (WebOS, POKY_AGL, Desktop)") string(TOLOWER ${PLATFORM_NAME} PLATFORM) if(${PLATFORM} STREQUAL "webos") set(OS_WEBOS TRUE) elseif(${PLATFORM} MATCHES ".*agl") set(OS_AGL TRUE) else() - message(FATAL_ERROR "Unsupported platform: ${PLATFORM}") + set(OS_DESKTOP TRUE) endif() if(OS_WEBOS) @@ -45,4 +47,12 @@ if(OS_WEBOS) webos_build_system_bus_files(${CMAKE_SOURCE_DIR}/files/sysbus) endif() +message(STATUS "WAM Configuration:") +message(STATUS "OS_WEBOS: ${OS_WEBOS}") +message(STATUS "OS_AGL: ${OS_AGL}") +message(STATUS "OS_DESKTOP: ${OS_DESKTOP}") +message(STATUS "WEBENGINE_CEF: ${WEBENGINE_CEF}") +message(STATUS "WEBENGINE_CBE: ${WEBENGINE_CBE}") +message(STATUS "PLATFORM_NAME: ${PLATFORM_NAME}") + add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cca138..173dafc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,10 +18,12 @@ project(WebAppMgrExec VERSION 1.0.0 DESCRIPTION "WAM") set(WAM_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -if(NOT DEFINED CHROMIUM_SRC_DIR) - message(FATAL_ERROR "CHROMIUM_SRC_DIR was not set") +if (WEBVIEW_CBE) + if(NOT DEFINED CHROMIUM_SRC_DIR) + message(FATAL_ERROR "CHROMIUM_SRC_DIR was not set") + endif() + set(CHROMIUM_LDFLAGS -lcbe) endif() -set(CHROMIUM_LDFLAGS -lcbe) find_package(PkgConfig REQUIRED) find_package(Boost COMPONENTS filesystem REQUIRED) @@ -39,6 +41,8 @@ elseif(OS_AGL) find_package(gRPC REQUIRED) find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) find_package(Threads) +elseif(OS_DESKTOP) + set(DISABLE_PMLOG(true)) endif() if(DISABLE_PMLOG) @@ -58,7 +62,6 @@ set(WAM_COMPILER_FLAGS -fno-rtti -Wall -fpermissive -funwind-tables - -std=c++14 -Wno-psabi -Werror ) @@ -70,29 +73,68 @@ endif() add_link_options(-Wl,--no-as-needed -Wno-psabi -rdynamic) add_subdirectory(core) -add_subdirectory(platform) set(WAM_INCLUDE_DIRS ${GLIB_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR}/util - ${CMAKE_CURRENT_SOURCE_DIR}/webos ) set(WAM_LIBS ${CHROMIUM_LDFLAGS} ${PMLOGLIB_LDFLAGS} - WebAppMgr WebAppMgrCore ) +if(WEBENGINE_CBE) + add_subdirectory(platform) + LIST(APPEND WAM_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/webos + ) + LIST(APPEND WAM_LIBS + WebAppMgr + ) +endif() + +if(OS_DESKTOP OR WEBENGINE_CEF) + if(NOT DEFINED CEF_ROOT) + message(FATAL_ERROR "CEF_ROOT needs to point to the binary distribution directory") + endif() + + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake") + find_package(CEF REQUIRED) + message(STATUS "CEF lib location: ${CEF_LIB_RELEASE}") + print_cef_config() + + add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper) + add_library(libcef_lib SHARED IMPORTED) + set_target_properties(libcef_lib PROPERTIES IMPORTED_LOCATION ${CEF_LIB_RELEASE}) + target_link_libraries(libcef_dll_wrapper libcef_lib) + + LIST(APPEND WAM_LIBS libcef_lib libcef_dll_wrapper) +endif() + +if(OS_DESKTOP) + add_subdirectory(desktop) + add_subdirectory(cef/service) + add_subdirectory(cef/cli) + LIST(APPEND WAM_LIBS WebAppMgrDesktop) +endif() + if(OS_WEBOS) add_subdirectory(plugin) add_subdirectory(tests) add_subdirectory(testplugin) LIST(APPEND WAM_LIBS ${LIBLUNAPREFS_LDFLAGS}) elseif(OS_AGL) - add_subdirectory(agl/plugin) + if(WEBENGINE_CEF) + add_subdirectory(agl-cef) + add_subdirectory(cef/service) + add_subdirectory(cef/cli) + LIST(APPEND WAM_LIBS WebAppMgrAGLCEF) + else() + add_subdirectory(agl/plugin) + endif() LIST(APPEND WAM_INCLUDE_DIRS ${Protobuf_INCLUDE_DIRS} ${gRPC_INCLUDE_DIRS} diff --git a/src/agl-cef/CMakeLists.txt b/src/agl-cef/CMakeLists.txt new file mode 100644 index 0000000..8d29004 --- /dev/null +++ b/src/agl-cef/CMakeLists.txt @@ -0,0 +1,54 @@ +project(WebAppMgrAGLCEF VERSION 1.0.0 DESCRIPTION "Web Application Manager library") + +set(WAM_LIB_LIBS + ${JSONCPP_LDFLAGS} + WebAppMgrCore + WebAppMgrService + libcef_lib + libcef_dll_wrapper +) + +set(SOURCES + web_runtime_agl_cef.cc +) + +set(HEADERS + web_runtime_agl_cef.h +) + +set(WAM_LIB_CEF_DIR ${WAM_ROOT_SOURCE_DIR}/cef) + +set(WAM_LIB_INCLUDE_DIRS + ${JSONCPP_INCLUDE_DIRS} + ${CEF_INCLUDE_PATH} +) + +LIST(APPEND SOURCES + ${WAM_LIB_CEF_DIR}/device_info_cef.cc + ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.cc + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.cc + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.cc + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_render_handler.cc +) +LIST(APPEND HEADERS + ${WAM_LIB_CEF_DIR}/device_info_cef.h + ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.h + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.h + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.h + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_render_handler.cc +) +LIST(APPEND WAM_LIB_INCLUDE_DIRS + ${WAM_LIB_CEF_DIR} + ${WAM_LIB_CEF_DIR}/handlers +) + +add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) +target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_LIB_INCLUDE_DIRS}) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) + +install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/webappmanager) + +target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_LIB_LIBS}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/plugin) diff --git a/src/agl-cef/plugin/CMakeLists.txt b/src/agl-cef/plugin/CMakeLists.txt new file mode 100644 index 0000000..052c94e --- /dev/null +++ b/src/agl-cef/plugin/CMakeLists.txt @@ -0,0 +1,59 @@ +project(webappmgr-default-plugin VERSION 1.0.0 DESCRIPTION "Default WAM plugin") + +set(CEF_PLUGINS_DIR ${WAM_ROOT_SOURCE_DIR}/cef/plugin) +set(CEF_HANDLERS_DIR ${WAM_ROOT_SOURCE_DIR}/cef/handlers) + +set (SOURCES + ${CEF_HANDLERS_DIR}/wam_cef_client.cc + ${CEF_PLUGINS_DIR}/web_app_cef.cc + ${CEF_PLUGINS_DIR}/web_page_cef.cc + agl_cef_context.cc + web_app_factory_agl_cef.cc + background_cef_app.cc + homescreen_cef_app.cc + regular_cef_app.cc +) +set (HEADERS + ${CEF_HANDLERS_DIR}/wam_cef_client.h + ${CEF_PLUGINS_DIR}/web_app_cef.h + ${CEF_PLUGINS_DIR}/web_page_cef.h + agl_cef_context.h + web_app_factory_agl_cef.h + background_cef_app.h + homescreen_cef_app.h + regular_cef_app.h +) +set (WAM_PLUGIN_INCLUDE_DIRS + ${CEF_HANDLERS_DIR} + ${CEF_PLUGINS_DIR} + ${WAM_ROOT_SOURCE_DIR} + ${WAM_ROOT_SOURCE_DIR}/core + ${WAM_ROOT_SOURCE_DIR}/platform + ${WAM_ROOT_SOURCE_DIR}/platform/webengine + ${WAM_ROOT_SOURCE_DIR}/util + ${CEF_INCLUDE_PATH} +) +set(WAM_PLUGIN_LIBS + WebAppMgrService + WebAppMgrService-grpc + libcef_lib + libcef_dll_wrapper +) + +if (OS_DESKTOP) + LIST(APPEND WAM_PLUGIN_LIBS + WebAppMgrDesktop + ) +else() + LIST(APPEND WAM_PLUGIN_LIBS + WebAppMgrAGLCEF + ) +endif() + +add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) +add_dependencies(${PROJECT_NAME} libcef_lib libcef_dll_wrapper) + +target_include_directories(${PROJECT_NAME} PRIVATE ${WAM_PLUGIN_INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${WAM_PLUGIN_LIBS}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/webappmanager/plugins) +install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webappmanager) diff --git a/src/agl-cef/plugin/agl_cef_context.cc b/src/agl-cef/plugin/agl_cef_context.cc new file mode 100644 index 0000000..8c1a390 --- /dev/null +++ b/src/agl-cef/plugin/agl_cef_context.cc @@ -0,0 +1,4 @@ +#include "agl_cef_context.h" + +AglCefContext* AglCefContext::instance_ = nullptr; + diff --git a/src/agl-cef/plugin/agl_cef_context.h b/src/agl-cef/plugin/agl_cef_context.h new file mode 100644 index 0000000..a1e698f --- /dev/null +++ b/src/agl-cef/plugin/agl_cef_context.h @@ -0,0 +1,42 @@ +#ifndef AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H +#define AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H + +#include + +class AglCefContext { + public: + AglCefContext(const AglCefContext&) = delete; + AglCefContext& operator=(const AglCefContext&) = delete; + + static AglCefContext* get() { + if (!instance_) { + instance_ = new AglCefContext(); + } + return instance_; + } + + uint32_t activation_area_width() const { return activation_area_width_; } + void set_activation_area_width(uint32_t activation_area_width) { + activation_area_width_ = activation_area_width; + } + + uint32_t activation_area_height() const { return activation_area_height_; } + void set_activation_area_height(uint32_t activation_area_height) { + activation_area_height_ = activation_area_height; + } + + uint32_t panel_offset() const { return panel_offset_; } + void set_panel_offset(uint32_t panel_offset) { + panel_offset_ = panel_offset; + } + + private: + AglCefContext() = default; + + static AglCefContext* instance_; + uint32_t activation_area_width_ = 0; + uint32_t activation_area_height_ = 0; + uint32_t panel_offset_ = 0; +}; + +#endif // AGL_CEF_PLUGIN_AGL_CEF_CONTEXT_H diff --git a/src/agl-cef/plugin/background_cef_app.cc b/src/agl-cef/plugin/background_cef_app.cc new file mode 100644 index 0000000..c406641 --- /dev/null +++ b/src/agl-cef/plugin/background_cef_app.cc @@ -0,0 +1,33 @@ +#include "background_cef_app.h" + +BackgroundCefApp::BackgroundCefApp(std::shared_ptr app_desc) + : WebAppCEF(app_desc) { + CefRect display_bounds = GetDisplayBounds(); + width_override_ = display_bounds.width; + height_override_ = display_bounds.height; +} + +BackgroundCefApp::~BackgroundCefApp() {} + +void BackgroundCefApp::Init(int width, + int height, + AglShellSurfaceType surface_type, + AglShellPanelEdge panel_type) { + if (!IsReady()) { + return; + } + + /* + // TODO: change when in portrait mode + window_->SetupActivationArea(AglCefContext::get()->panel_offset(), + 0, + AglCefContext::get()->activation_area_width(), + AglCefContext::get()->activation_area_height()); + */ + + WebAppCEF::Init(width, height, surface_type, panel_type); +} + +bool BackgroundCefApp::IsReady() const { + return window_ != nullptr; +} diff --git a/src/agl-cef/plugin/background_cef_app.h b/src/agl-cef/plugin/background_cef_app.h new file mode 100644 index 0000000..6681b5d --- /dev/null +++ b/src/agl-cef/plugin/background_cef_app.h @@ -0,0 +1,20 @@ +#ifndef AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H +#define AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H + +#include "agl_cef_context.h" +#include "web_app_cef.h" + +class BackgroundCefApp : public WebAppCEF { + public: + BackgroundCefApp(std::shared_ptr app_desc); + ~BackgroundCefApp(); + + void Init(int width, + int height, + AglShellSurfaceType surface_type, + AglShellPanelEdge panel_type) override; + + bool IsReady() const override; +}; + +#endif // AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H diff --git a/src/agl-cef/plugin/homescreen_cef_app.cc b/src/agl-cef/plugin/homescreen_cef_app.cc new file mode 100644 index 0000000..cc6af64 --- /dev/null +++ b/src/agl-cef/plugin/homescreen_cef_app.cc @@ -0,0 +1,25 @@ +#include "homescreen_cef_app.h" + +#include "agl_cef_context.h" + +HomescreenCefApp::HomescreenCefApp(std::shared_ptr app_desc) + : WebAppCEF(app_desc) { + CefRect display_bounds = GetDisplayBounds(); + uint32_t panel_offset = app_desc->WidthOverride(); // TODO: height when in portrait mode + uint32_t activation_width = display_bounds.width - panel_offset - 1; + uint32_t activation_height = display_bounds.height; + + // TODO: change when in portrait mode + width_override_ = panel_offset; + height_override_ = activation_height; + + AglCefContext::get()->set_panel_offset(panel_offset); + AglCefContext::get()->set_activation_area_width(activation_width); + AglCefContext::get()->set_activation_area_height(activation_height); +} + +HomescreenCefApp::~HomescreenCefApp() {} + +bool HomescreenCefApp::IsReady() const { + return window_ && window_->IsSurfaceConfigured(); +} diff --git a/src/agl-cef/plugin/homescreen_cef_app.h b/src/agl-cef/plugin/homescreen_cef_app.h new file mode 100644 index 0000000..c4f86ab --- /dev/null +++ b/src/agl-cef/plugin/homescreen_cef_app.h @@ -0,0 +1,15 @@ +#ifndef AGL_CEF_PLUGIN_HOMESCREEN_CEF_APP_H +#define AGL_CEF_PLUGIN_HOMESCREEN_CEF_APP_H + +#include "web_app_cef.h" + +class HomescreenCefApp : public WebAppCEF { + public: + HomescreenCefApp(std::shared_ptr app_desc); + ~HomescreenCefApp(); + + protected: + bool IsReady() const override; +}; + +#endif // AGL_CEF_PLUGIN_BACKGROUND_CEF_APP_H diff --git a/src/agl-cef/plugin/regular_cef_app.cc b/src/agl-cef/plugin/regular_cef_app.cc new file mode 100644 index 0000000..a882314 --- /dev/null +++ b/src/agl-cef/plugin/regular_cef_app.cc @@ -0,0 +1,11 @@ +#include "regular_cef_app.h" + +#include "agl_cef_context.h" + +RegularCefApp::RegularCefApp(std::shared_ptr app_desc) + : WebAppCEF(app_desc) { + width_override_ = AglCefContext::get()->activation_area_width(); + height_override_ = AglCefContext::get()->activation_area_height(); +} + +RegularCefApp::~RegularCefApp() {} diff --git a/src/agl-cef/plugin/regular_cef_app.h b/src/agl-cef/plugin/regular_cef_app.h new file mode 100644 index 0000000..ed4b34d --- /dev/null +++ b/src/agl-cef/plugin/regular_cef_app.h @@ -0,0 +1,12 @@ +#ifndef AGL_CEF_PLUGIN_REGULAR_CEF_APP_H +#define AGL_CEF_PLUGIN_REGULAR_CEF_APP_H + +#include "web_app_cef.h" + +class RegularCefApp : public WebAppCEF { + public: + RegularCefApp(std::shared_ptr app_desc); + ~RegularCefApp(); +}; + +#endif // AGL_CEF_PLUGIN_REGULAR_CEF_APP_H diff --git a/src/agl-cef/plugin/web_app_factory_agl_cef.cc b/src/agl-cef/plugin/web_app_factory_agl_cef.cc new file mode 100644 index 0000000..8ca2ba8 --- /dev/null +++ b/src/agl-cef/plugin/web_app_factory_agl_cef.cc @@ -0,0 +1,49 @@ +#include "web_app_factory_agl_cef.h" + +#include "application_description.h" +#include "plugin_interface.h" + +#include "background_cef_app.h" +#include "homescreen_cef_app.h" +#include "regular_cef_app.h" + +#include "web_page_cef.h" + +#include "wam_cef_client.h" + +const char* kPluginApplicationType = "default"; + +WebAppFactoryInterface* CreateInstance() { + return new WebAppFactoryCEF(); +} + +void DeleteInstance(WebAppFactoryInterface* interface) { + delete interface; +} + +WebAppBase* WebAppFactoryCEF::CreateWebApp( + const std::string&, + std::shared_ptr app_desc) { + std::string app_id = app_desc->Id(); + + if (app_id == "homescreen") { + return new HomescreenCefApp(app_desc); + } else if (app_id == "webapps-html5-background") { + return new BackgroundCefApp(app_desc); + } + return new RegularCefApp(app_desc); +} + +WebAppBase* WebAppFactoryCEF::CreateWebApp( + const std::string& win_type, + WebPageBase*, + std::shared_ptr desc) { + return CreateWebApp(win_type, desc); +} + +WebPageBase* WebAppFactoryCEF::CreateWebPage( + const wam::Url& url, + std::shared_ptr app_desc, + const std::string&) { + return new WebPageCEF(app_desc, url.ToString()); +} diff --git a/src/agl-cef/plugin/web_app_factory_agl_cef.h b/src/agl-cef/plugin/web_app_factory_agl_cef.h new file mode 100644 index 0000000..eb4b7ba --- /dev/null +++ b/src/agl-cef/plugin/web_app_factory_agl_cef.h @@ -0,0 +1,23 @@ +#ifndef AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H +#define AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H + +#include +#include + +#include "web_app_factory_interface.h" + +class WebAppFactoryCEF : public WebAppFactoryInterface { + public: + WebAppBase* CreateWebApp( + const std::string& win_type, + std::shared_ptr desc = 0) override; + WebAppBase* CreateWebApp( + const std::string& win_type, + WebPageBase* page, + std::shared_ptr desc = 0) override; + WebPageBase* CreateWebPage(const wam::Url& url, + std::shared_ptr desc, + const std::string& launchParams = "") override; +}; + +#endif // AGL_CEF_PLUGIN_WEB_APP_FACTORY_CEF_H diff --git a/src/agl-cef/web_runtime_agl_cef.cc b/src/agl-cef/web_runtime_agl_cef.cc new file mode 100644 index 0000000..9bc1bd6 --- /dev/null +++ b/src/agl-cef/web_runtime_agl_cef.cc @@ -0,0 +1,63 @@ +#include "web_runtime_agl_cef.h" + +#include "include/cef_base.h" +#include "include/cef_origin_whitelist.h" + +#include "wam_cef_browser_handler.h" +#include "wam_cef_render_handler.h" + +const char kProcessType[] = "type"; +const char kRendererProcess[] = "renderer"; +const char kZygoteProcess[] = "zygote"; + +class WamCefUtilityHandler : public CefApp { + public: + WamCefUtilityHandler () {} + + private: + IMPLEMENT_REFCOUNTING(WamCefUtilityHandler); + DISALLOW_COPY_AND_ASSIGN(WamCefUtilityHandler); +}; + +int WebRuntimeCEF::Run(int argc, char** argv) { + CefMainArgs main_args(argc, argv); + + CefRefPtr command_line = CefCommandLine::CreateCommandLine(); + command_line->InitFromArgv(main_args.argc, main_args.argv); + + std::string app_id = command_line->GetSwitchValue("appid"); + if (app_id.empty()) { + app_id = "WebAppMgr"; + } + + CefRefPtr app; + if (!command_line->HasSwitch(kProcessType)) { + app = new WamCefBrowserHandler(); + } else { + const std::string& process_type = command_line->GetSwitchValue(kProcessType); + if (process_type == kRendererProcess || process_type == kZygoteProcess) { + app = new WamCefRenderHandler(); + } else { + app = new WamCefUtilityHandler(); + } + } + + auto exit_code = CefExecuteProcess(main_args, app.get(), nullptr); + if (exit_code >= 0) { + return exit_code; + } + + CefSettings settings; + settings.remote_debugging_port = 9998; + CefInitialize(main_args, settings, app.get(), nullptr); + + CefRunMessageLoop(); + + CefShutdown(); + + return 0; +} + +std::unique_ptr WebRuntime::Create() { + return std::make_unique(); +} diff --git a/src/agl-cef/web_runtime_agl_cef.h b/src/agl-cef/web_runtime_agl_cef.h new file mode 100644 index 0000000..049e554 --- /dev/null +++ b/src/agl-cef/web_runtime_agl_cef.h @@ -0,0 +1,11 @@ +#ifndef AGL_CEF_WEB_RUNTIME_AGL_CEF_H_ +#define AGL_CEF_WEB_RUNTIME_AGL_CEF_H_ + +#include "web_runtime.h" + +class WebRuntimeCEF : public WebRuntime { + public: + int Run(int argc, char** argv) override; +}; + +#endif // AGL_CEF_WEB_RUNTIME_CEF_H_ diff --git a/src/agl/web_runtime_agl.cc b/src/agl/web_runtime_agl.cc index ce8525b..c791c70 100644 --- a/src/agl/web_runtime_agl.cc +++ b/src/agl/web_runtime_agl.cc @@ -128,7 +128,7 @@ void SingleBrowserProcessWebAppLauncher::Launch( } int SingleBrowserProcessWebAppLauncher::Loop(int argc, - const char** argv, + char** argv, volatile sig_atomic_t& e_flag) { AGLMainDelegateWAM delegate; webos::WebOSMain webOSMain(&delegate); @@ -154,7 +154,7 @@ void SharedBrowserProcessWebAppLauncher::Launch( } int SharedBrowserProcessWebAppLauncher::Loop(int argc, - const char** argv, + char** argv, volatile sig_atomic_t& e_flag) { // TODO: wait for a pid while (e_flag) @@ -173,7 +173,7 @@ static void AglShellActivateApp(const std::string& app_id) { WebAppManagerServiceAGL::Instance()->SendEvent(kActivateEvent, app_id); } -int WebAppLauncherRuntime::Run(int argc, const char** argv) { +int WebAppLauncherRuntime::Run(int argc, char** argv) { bool is_wait_host_service = IsWaitForHostService(); std::string app_id = IsActivateApp(Args::Instance()); @@ -334,7 +334,7 @@ bool WebAppLauncherRuntime::ParseJsonConfig(const char* path_to_config) { return true; } -int SharedBrowserProcessRuntime::Run(int argc, const char** argv) { +int SharedBrowserProcessRuntime::Run(int argc, char** argv) { if (WebAppManagerServiceAGL::Instance()->InitializeAsHostService()) { AGLMainDelegateWAM delegate; webos::WebOSMain webOSMain(&delegate); @@ -347,7 +347,7 @@ int SharedBrowserProcessRuntime::Run(int argc, const char** argv) { } } -int RenderProcessRuntime::Run(int argc, const char** argv) { +int RenderProcessRuntime::Run(int argc, char** argv) { AGLMainDelegateWAM delegate; webos::WebOSMain webOSMain(&delegate); return webOSMain.Run(argc, argv); @@ -372,7 +372,7 @@ static void print_help(void) { exit(EXIT_FAILURE); } -void Args::parse_args(int argc, const char** argv) { +void Args::parse_args(int argc, char** argv) { int c; int option_index; opterr = 0; @@ -427,7 +427,7 @@ void Args::parse_args(int argc, const char** argv) { } } -void Args::copy_cmdline(int argc, const char** argv) { +void Args::copy_cmdline(int argc, char** argv) { new_argc = argc; new_argv = static_cast(calloc(new_argc + 1, sizeof(*new_argv))); @@ -446,7 +446,7 @@ void Args::clear_cmdline(void) { free(new_argv); } -int WebRuntimeAGL::Run(int argc, const char** argv) { +int WebRuntimeAGL::Run(int argc, char** argv) { int ret; Args::Instance()->parse_args(argc, argv); diff --git a/src/agl/web_runtime_agl.h b/src/agl/web_runtime_agl.h index ad045c2..14bc0ed 100644 --- a/src/agl/web_runtime_agl.h +++ b/src/agl/web_runtime_agl.h @@ -39,7 +39,7 @@ class Args { static Args* args = new Args(); return args; } - void parse_args(int argc, const char** argv); + void parse_args(int argc, char** argv); inline void set_flag(unsigned int flag) { flags |= flag; } @@ -56,7 +56,7 @@ class Args { private: uint32_t flags = FLAG_NONE; - void copy_cmdline(int argc, const char** argv); + void copy_cmdline(int argc, char** argv); char** new_argv; int new_argc; }; @@ -69,9 +69,7 @@ class Launcher { AglShellPanelEdge panel_edge, int width, int height) = 0; - virtual int Loop(int argc, - const char** argv, - volatile sig_atomic_t& e_flag) = 0; + virtual int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) = 0; }; class SharedBrowserProcessWebAppLauncher : public Launcher { @@ -82,7 +80,7 @@ class SharedBrowserProcessWebAppLauncher : public Launcher { AglShellPanelEdge panel_edge, int width, int height) override; - int Loop(int argc, const char** argv, volatile sig_atomic_t& e_flag) override; + int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) override; }; class SingleBrowserProcessWebAppLauncher : public Launcher { @@ -93,12 +91,12 @@ class SingleBrowserProcessWebAppLauncher : public Launcher { AglShellPanelEdge panel_edge, int width, int height) override; - int Loop(int argc, const char** argv, volatile sig_atomic_t& e_flag) override; + int Loop(int argc, char** argv, volatile sig_atomic_t& e_flag) override; }; class WebAppLauncherRuntime : public WebRuntime { public: - int Run(int argc, const char** argv) override; + int Run(int argc, char** argv) override; private: bool Init(Args* args); @@ -127,17 +125,17 @@ class WebAppLauncherRuntime : public WebRuntime { class SharedBrowserProcessRuntime : public WebRuntime { public: - int Run(int argc, const char** argv) override; + int Run(int argc, char** argv) override; }; class RenderProcessRuntime : public WebRuntime { public: - int Run(int argc, const char** argv) override; + int Run(int argc, char** argv) override; }; class WebRuntimeAGL : public WebRuntime { public: - int Run(int argc, const char** argv) override; + int Run(int argc, char** argv) override; private: WebRuntime* runtime_; diff --git a/src/cef/cli/CMakeLists.txt b/src/cef/cli/CMakeLists.txt new file mode 100644 index 0000000..1b5f04a --- /dev/null +++ b/src/cef/cli/CMakeLists.txt @@ -0,0 +1,17 @@ +project(WebAppMgrCli VERSION 1.0.0 DESCRIPTION "Web Application Manager cli helper") + +set(CLI_EXE ${PROJECT_NAME}) +set(CLI_EXE_INCLUDE_DIRS + ${WAM_ROOT_SOURCE_DIR}/util +) + +set(CLI_EXE_LIBS + WebAppMgrCore + WebAppMgrService + WebAppMgrService-grpc +) + +add_executable(${CLI_EXE} wam_cli.cc) +target_include_directories(${CLI_EXE} PUBLIC ${CLI_EXE_INCLUDE_DIRS}) +target_link_libraries(${CLI_EXE} PUBLIC ${CLI_EXE_LIBS}) +install(TARGETS ${CLI_EXE} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/cef/cli/wam_cli.cc b/src/cef/cli/wam_cli.cc new file mode 100644 index 0000000..4775ce4 --- /dev/null +++ b/src/cef/cli/wam_cli.cc @@ -0,0 +1,171 @@ +// Copyright (c) 2018-2022 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include "web_app_manager_client_grpc.h" + +#include "log_manager.h" + +class Args { + public: + enum flags { + FLAG_NONE = 0, + FLAG_APP_TYPE = 1 << 0, + FLAG_ACTIVATE_APP = 1 << 1, + FLAG_HTTP_LINK = 1 << 2, + FLAG_APP_ID = 1 << 3, + FLAG_APP_DIR = 1 << 4, + }; + + static Args* Instance() { + static Args* args = new Args(); + return args; + } + void PrintHelp(void) { + fprintf(stderr, "WAM: Web Application Manager\n"); + fprintf(stderr, + "\t[--activate_app=appid] -- activate application. Interrnal " + "usage.\n\tNot needing for starting applications.\n"); + fprintf(stderr, + "\t[--appid=appid] name of an application id.\n\tRequired if " + "starting a " + "web application.\n"); + fprintf( + stderr, + "\t[--app-install-dir=/path/to/root_index] installation path for web " + "application.\n\tRequired if starting a web application.\n"); + fprintf(stderr, "\t-h -- this help message \n"); + exit(EXIT_FAILURE); + } + + void ParseArgs(int argc, char** argv) { + int c; + int option_index; + opterr = 0; + + CopyCmdLine(argc, argv); + + struct option long_opts[] = {{"help", no_argument, 0, 'h'}, + {"activate-app", required_argument, 0, 'x'}, + {"appid", required_argument, 0, 'a'}, + {"app-install-dir", required_argument, 0, 'd'}, + {0, 0, 0, 0}}; + + while ((c = getopt_long(new_argc, new_argv, "ht:a:i:d:", long_opts, + &option_index)) != -1) { + switch (c) { + case 'h': + PrintHelp(); + break; + case 'x': + activate_app_id_ = optarg; + break; + case 'a': + app_id_ = optarg; + break; + case 'd': + app_dir_ = optarg; + break; + default: + break; + } + } + + if (optind < new_argc) { + // check for 'http://' + int p = optind; + while (p < new_argc) { + if (!strcmp(new_argv[p], "http://")) { + http_link_ = new_argv[p]; + break; + } + p++; + } + } + } + + void ClearCmdLine() { + for (int i = 0; i < new_argc; i++) + free(new_argv[i]); + free(new_argv); + } + + std::string GetAppId() const { + return app_id_.has_value() ? *app_id_ : std::string(); + } + + std::string GetAppUri() const { + if (http_link_.has_value()) + return *http_link_; + else if (app_dir_.has_value()) + return *app_dir_; + return std::string(); + } + + bool HasActivateAppId() const { return activate_app_id_.has_value(); } + std::string GetActivateAppId() const { + return activate_app_id_.has_value() ? *activate_app_id_ : std::string(); + } + + private: + void CopyCmdLine(int argc, char** argv) { + new_argc = argc; + new_argv = static_cast(calloc(new_argc + 1, sizeof(*new_argv))); + + for (int i = 0; i < new_argc; i++) { + size_t len = strlen(argv[i]) + 1; + new_argv[i] = static_cast(calloc(len, sizeof(char))); + memcpy(new_argv[i], argv[i], len); + } + + new_argv[argc] = nullptr; + } + char** new_argv; + int new_argc; + + std::optional activate_app_id_; + std::optional http_link_; + std::optional app_id_; + std::optional app_dir_; +}; + +WebAppManagerClientGRPC* GetGrpcClient() { + static std::unique_ptr grpc_client; + if (!grpc_client) { + grpc_client = std::make_unique(); + } + return grpc_client.get(); +} + +int main(int argc, char** argv) { + auto* args = Args::Instance(); + args->ParseArgs(argc, argv); + + // TODO: handle completed grpc calls + // and get the correct ok() result + if (args->HasActivateAppId()) { + GetGrpcClient()->Activate(args->GetActivateAppId()); + } else { + WebAppManagerClientGRPC::LaunchParams params; + params.app_id = args->GetAppId(); + params.uri = args->GetAppUri(); + GetGrpcClient()->Launch(params); + } + + return 0; +} diff --git a/src/cef/device_info_cef.cc b/src/cef/device_info_cef.cc new file mode 100644 index 0000000..f5fd681 --- /dev/null +++ b/src/cef/device_info_cef.cc @@ -0,0 +1,104 @@ +#include "device_info_cef.h" + +#include + +#include +#include + +#include "log_manager.h" +#include "utils.h" + +DeviceInfoCEF::DeviceInfoCEF() = default; + +void DeviceInfoCEF::Initialize() { + const std::string& json_string = + util::ReadFile("/var/luna/preferences/localeInfo"); + if (json_string.empty()) { + return; + } + + Json::Value locale_json = util::StringToJson(json_string); + if (!locale_json.isObject() || locale_json.empty() || + !locale_json["localeInfo"].isObject() || + !locale_json["localeInfo"]["locales"].isObject() || + !locale_json["localeInfo"]["locales"]["UI"].isString() || + !locale_json["country"].isString() || + !locale_json["smartServiceCountryCode3"].isString()) { + LOG_ERROR(MSGID_LOCALEINFO_READ_FAIL, 1, + PMLOGKS("CONTENT", json_string.c_str()), ""); + return; + } + + Json::Value locale_info = locale_json["localeInfo"]; + + std::string language(locale_info["locales"]["UI"].asString()); + std::string localcountry(locale_json["country"].asString()); + std::string smartservicecountry( + locale_json["smartServiceCountryCode3"].asString()); + + SetSystemLanguage(language.c_str()); + SetDeviceInfo("LocalCountry", localcountry.c_str()); + SetDeviceInfo("SmartServiceCountry", smartservicecountry.c_str()); +} + +void DeviceInfoCEF::InitDisplayInfo() { + // Display information + // -------------------------------------------------------- + float screen_density_ = 1.0f; + int hardware_screen_width = 0; + int hardware_screen_height = 0; + + std::string hardware_screen_width_str; + std::string hardware_screen_height_str; + if (GetDeviceInfo("HardwareScreenWidth", hardware_screen_width_str) && + GetDeviceInfo("HardwareScreenHeight", hardware_screen_height_str)) { + hardware_screen_width = + util::StrToIntWithDefault(hardware_screen_width_str, 0); + hardware_screen_height = + util::StrToIntWithDefault(hardware_screen_height_str, 0); + } else { + GetDisplayWidth(hardware_screen_width); + GetDisplayHeight(hardware_screen_height); + } + + screen_width_ = static_cast(hardware_screen_width / screen_density_); + screen_height_ = static_cast(hardware_screen_height / screen_density_); +} + +void DeviceInfoCEF::InitPlatformInfo() { + // normally like this info + /* + "modelName": "WEBOS1", + "platformVersion": "00.00.00", + "platformVersionDot": 00, + "platformVersionMajor_pos": 00, + "platformVersionMinor": 00, + */ + + std::string value; + if (GetDeviceInfo("ModelName", value)) + model_name_ = value; + if (GetDeviceInfo("FirmwareVersion", value)) + platform_version_ = value; + + size_t major_pos = 0, minor_pos = 0; + major_pos = platform_version_.find_first_of('.'); + if (major_pos != std::string::npos && + major_pos <= platform_version_.size() - 1) + minor_pos = platform_version_.find_first_of('.', major_pos + 1); + if (major_pos == std::string::npos || minor_pos == std::string::npos) { + version_major_ = version_minor_ = version_dot_ = -1; + } else { + version_major_ = + util::StrToIntWithDefault(platform_version_.substr(0, major_pos), 0); + version_minor_ = util::StrToIntWithDefault( + platform_version_.substr(major_pos + 1, minor_pos), 0); + version_dot_ = + util::StrToIntWithDefault(platform_version_.substr(minor_pos + 1), 0); + } +} + +void DeviceInfoCEF::GatherInfo() { + InitDisplayInfo(); + InitPlatformInfo(); +} diff --git a/src/cef/device_info_cef.h b/src/cef/device_info_cef.h new file mode 100644 index 0000000..e2b3712 --- /dev/null +++ b/src/cef/device_info_cef.h @@ -0,0 +1,38 @@ +#ifndef CEF_DEVICE_INFO_CEF_H_ +#define CEF_DEVICE_INFO_CEF_H_ + +#include + +#include "device_info.h" + +class DeviceInfoCEF : public DeviceInfo { + public: + DeviceInfoCEF(); + + void Initialize() override; + + private: + int screen_width_ = 0; + int screen_height_ = 0; + + float screen_density_ = 1.0f; + + std::string model_name_ = "webOS.Open.CEF"; + std::string platform_version_ = "00.00.00"; + + // platform versions are .. + int version_major_ = 0; + int version_minor_ = 0; + int version_dot_ = 0; + + bool support_3d_ = false; + std::string ota_id_; + std::string hardware_version_ = "0x00000001"; + std::string firmware_version_ = "00.00.01"; + + void InitDisplayInfo(); + void InitPlatformInfo(); + void GatherInfo(); +}; + +#endif // CEF_DEVICE_INFO_IMPL_H_ diff --git a/src/cef/handlers/wam_cef_browser_handler.cc b/src/cef/handlers/wam_cef_browser_handler.cc new file mode 100644 index 0000000..0708363 --- /dev/null +++ b/src/cef/handlers/wam_cef_browser_handler.cc @@ -0,0 +1,31 @@ +#include "wam_cef_browser_handler.h" + +#include "log_manager.h" +#include "log_msg_id.h" +#include "platform_module_factory_cef.h" +#include "wam_cef_client.h" +#include "web_app_manager_service_grpc.h" + +WamCefBrowserHandler::WamCefBrowserHandler() : + client_(new WamCefClient()) { + WebAppManager::Instance()->SetPlatformModules( + std::make_unique()); +} + +WamCefBrowserHandler::~WamCefBrowserHandler() {} + +CefRefPtr WamCefBrowserHandler::GetBrowserProcessHandler() { + return this; +} + +CefRefPtr WamCefBrowserHandler::GetDefaultClient() { + return client_; +} + +void WamCefBrowserHandler::OnContextInitialized() { + if (!WebAppManagerServiceGRPC::Instance()->InitializeAsHostService()) { + LOG_ERROR(MSGID_ERROR_CANNOT_LOCK_SERVICE, 0, + "Cannot lock WAM GRPC service IPC"); + } + WebAppManagerServiceGRPC::Instance()->StartService(); +} diff --git a/src/cef/handlers/wam_cef_browser_handler.h b/src/cef/handlers/wam_cef_browser_handler.h new file mode 100644 index 0000000..58c7f20 --- /dev/null +++ b/src/cef/handlers/wam_cef_browser_handler.h @@ -0,0 +1,23 @@ +#ifndef CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H +#define CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H + +#include "include/cef_app.h" +#include "include/cef_browser_process_handler.h" + +#include "wam_cef_client.h" + +class WamCefBrowserHandler : public CefApp, public CefBrowserProcessHandler { + public: + WamCefBrowserHandler(); + virtual ~WamCefBrowserHandler(); + + CefRefPtr GetBrowserProcessHandler() override; + CefRefPtr GetDefaultClient() override; + void OnContextInitialized() override; + + private: + IMPLEMENT_REFCOUNTING(WamCefBrowserHandler); + CefRefPtr client_; +}; + +#endif // CEF_HANDLERS_WAM_CEF_BROWSER_HANDLER_H diff --git a/src/cef/handlers/wam_cef_client.cc b/src/cef/handlers/wam_cef_client.cc new file mode 100644 index 0000000..5ba6201 --- /dev/null +++ b/src/cef/handlers/wam_cef_client.cc @@ -0,0 +1,39 @@ +#include "wam_cef_client.h" + +#include "include/wrapper/cef_helpers.h" + +WamCefClient* g_instance = nullptr; + +WamCefClient::WamCefClient() { + DCHECK(!g_instance); + g_instance = this; +} + +// static +WamCefClient* WamCefClient::GetInstance() { + return g_instance; +} + +bool WamCefClient::OnProcessMessageReceived(CefRefPtr browser, + CefRefPtr frame, + CefProcessId source_process, + CefRefPtr message) { + std::string message_name = message->GetName(); + CefRefPtr args = message->GetArgumentList(); + if (message_name == "start") { + if (args->GetSize() != 1) { + return false; + } + std::string app_id = args->GetString(0); + applauncher_.Start(app_id); + return true; + } else if (message_name == "get_applications") { + if (args->GetSize() != 1) { + return false; + } + bool only_graphical = args->GetBool(0); + applauncher_.GetApplications(browser, only_graphical); + return true; + } + return false; +} diff --git a/src/cef/handlers/wam_cef_client.h b/src/cef/handlers/wam_cef_client.h new file mode 100644 index 0000000..3189c42 --- /dev/null +++ b/src/cef/handlers/wam_cef_client.h @@ -0,0 +1,31 @@ +#ifndef CEF_HANDLERS_WAM_CEF_CLIENT_H +#define CEF_HANDLERS_WAM_CEF_CLIENT_H + +#include "include/cef_client.h" + +#include "applauncher_client_grpc.h" + +class WamCefClient : public CefClient, + public CefLifeSpanHandler { + public: + WamCefClient(); + + static WamCefClient* GetInstance(); + + CefRefPtr GetLifeSpanHandler() override { + return this; + } + + bool OnProcessMessageReceived(CefRefPtr browser, + CefRefPtr frame, + CefProcessId source_process, + CefRefPtr message) override; + + private: + AppLauncherClientGRPC applauncher_; + + IMPLEMENT_REFCOUNTING(WamCefClient); + DISALLOW_COPY_AND_ASSIGN(WamCefClient); +}; + +#endif // CEF_HANDLERS_WAM_CEF_CLIENT_H diff --git a/src/cef/handlers/wam_cef_render_handler.cc b/src/cef/handlers/wam_cef_render_handler.cc new file mode 100644 index 0000000..48c881a --- /dev/null +++ b/src/cef/handlers/wam_cef_render_handler.cc @@ -0,0 +1,135 @@ +#include "wam_cef_render_handler.h" + +#include "include/cef_parser.h" +#include "include/cef_process_message.h" + +WamCefRenderHandler::WamCefRenderHandler() {} + +void WamCefRenderHandler::OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) { + + CefRefPtr app_service = CefV8Value::CreateObject(nullptr, nullptr); + + CefRefPtr start = CefV8Value::CreateFunction("start", this); + app_service->SetValue("start", start, V8_PROPERTY_ATTRIBUTE_NONE); + + CefRefPtr get_applications = CefV8Value::CreateFunction("getApplications", this); + app_service->SetValue("getApplications", get_applications, V8_PROPERTY_ATTRIBUTE_NONE); + + CefRefPtr global = context->GetGlobal(); // window object + CefRefPtr navigator = global->GetValue("navigator"); + + navigator->SetValue("appService", app_service, V8_PROPERTY_ATTRIBUTE_NONE); +} + +void WamCefRenderHandler::OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) { + if (callback_map_.empty()) { + return; + } + + CallbackMap::iterator it = callback_map_.begin(); + for (; it != callback_map_.end();) { + if (it->second.first->IsSame(context)) { + callback_map_.erase(it++); + } else { + ++it; + } + } +} + +void WamCefRenderHandler::Start(const std::string &app_id) { + CefRefPtr message = CefProcessMessage::Create("start"); + CefRefPtr args = message->GetArgumentList(); + args->SetString(0, app_id); + auto context = CefV8Context::GetCurrentContext(); + context->GetFrame()->SendProcessMessage(PID_BROWSER, message); +} + +void WamCefRenderHandler::GetApplications(bool only_graphical, CefRefPtr callback) { + std::string message_name = "get_applications"; + + // store the callback until we receive the browser's response + CefRefPtr context = CefV8Context::GetCurrentContext(); + int browser_id = context->GetBrowser()->GetIdentifier(); + callback_map_.insert( + std::make_pair(std::make_pair(message_name, browser_id), + std::make_pair(context, callback))); + + CefRefPtr message = CefProcessMessage::Create(message_name); + CefRefPtr args = message->GetArgumentList(); + args->SetBool(0, only_graphical); + context->GetFrame()->SendProcessMessage(PID_BROWSER, message); +} + +bool WamCefRenderHandler::Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) { + if (name == "start") { + if (arguments.size() != 1 || !arguments[0]->IsString()) { + return false; + } + std::string app_id = arguments[0]->GetStringValue(); + Start(app_id); + return true; + } else if (name == "getApplications") { + if (arguments.size() != 2 || + !arguments[0]->IsBool() || + !arguments[1]->IsFunction()) { + return false; + } + GetApplications(arguments[0]->GetBoolValue(), arguments[1]); + return true; + } + + return false; +} + +bool WamCefRenderHandler::OnProcessMessageReceived(CefRefPtr browser, + CefRefPtr frame, + CefProcessId source_process, + CefRefPtr message) { + std::string message_name = message->GetName(); + CefRefPtr args = message->GetArgumentList(); + if (message_name == "get_applications") { + CallbackMap::const_iterator it = callback_map_.find( + std::make_pair(message_name, + browser->GetIdentifier())); + if (it == callback_map_.end()) { + return false; + } + + CefRefPtr context = it->second.first; + CefRefPtr callback = it->second.second; + + context->Enter(); + + CefRefPtr apps_list_value = CefParseJSON(args->GetString(0), JSON_PARSER_RFC); + + CefRefPtr list = apps_list_value->GetList(); + int size = list->GetSize(); + CefRefPtr apps_list = CefV8Value::CreateArray(size); + for (int i = 0; i < size; i++) { + CefRefPtr app_info_dict = list->GetDictionary(i); + CefRefPtr dict = CefV8Value::CreateObject(nullptr, nullptr); + dict->SetValue("id", CefV8Value::CreateString(app_info_dict->GetString("id")), V8_PROPERTY_ATTRIBUTE_NONE); + dict->SetValue("name", CefV8Value::CreateString(app_info_dict->GetString("name")), V8_PROPERTY_ATTRIBUTE_NONE); + dict->SetValue("icon", CefV8Value::CreateString(app_info_dict->GetString("icon")), V8_PROPERTY_ATTRIBUTE_NONE); + apps_list->SetValue(i, dict); + } + + CefV8ValueList arguments; + arguments.push_back(apps_list); + callback->ExecuteFunctionWithContext(context, nullptr, arguments); + + context->Exit(); + + return true; + } + + return false; +} diff --git a/src/cef/handlers/wam_cef_render_handler.h b/src/cef/handlers/wam_cef_render_handler.h new file mode 100644 index 0000000..4a05ed6 --- /dev/null +++ b/src/cef/handlers/wam_cef_render_handler.h @@ -0,0 +1,54 @@ +#ifndef CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H +#define CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H + +#include +#include + +#include "include/cef_app.h" +#include "include/cef_render_process_handler.h" +#include "include/cef_v8.h" + +class WamCefRenderHandler : public CefApp, + public CefRenderProcessHandler, + public CefV8Handler { + public: + typedef std::map, + std::pair, CefRefPtr>> CallbackMap; + + WamCefRenderHandler(); + + CefRefPtr GetRenderProcessHandler() override { + return this; + } + + void OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) override; + + + void OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) override; + + bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) override; + + bool OnProcessMessageReceived(CefRefPtr browser, + CefRefPtr frame, + CefProcessId source_process, + CefRefPtr message) override; + + void Start(const std::string &app_id); + void GetApplications(bool only_graphical, CefRefPtr callback); + + private: + IMPLEMENT_REFCOUNTING(WamCefRenderHandler); + DISALLOW_COPY_AND_ASSIGN(WamCefRenderHandler); + + CallbackMap callback_map_; +}; + +#endif // CEF_HANDLERS_WAM_CEF_RENDER_HANDLER_H diff --git a/src/cef/platform_module_factory_cef.cc b/src/cef/platform_module_factory_cef.cc new file mode 100644 index 0000000..e225b9d --- /dev/null +++ b/src/cef/platform_module_factory_cef.cc @@ -0,0 +1,31 @@ +#include "platform_module_factory_cef.h" + +#include "device_info_cef.h" +#include "service_sender.h" +#include "web_app_manager_config.h" +#include "web_process_manager.h" + +PlatformModuleFactoryCEF::PlatformModuleFactoryCEF() { + PrepareRenderingContext(); +} + +std::unique_ptr +PlatformModuleFactoryCEF::CreateServiceSender() { + return nullptr; +} + +std::unique_ptr +PlatformModuleFactoryCEF::CreateWebProcessManager() { + return nullptr; +} + +std::unique_ptr PlatformModuleFactoryCEF::CreateDeviceInfo() { + return std::make_unique(); +} + +std::unique_ptr +PlatformModuleFactoryCEF::CreateWebAppManagerConfig() { + return std::unique_ptr(new WebAppManagerConfig()); +} + +void PlatformModuleFactoryCEF::PrepareRenderingContext() {} diff --git a/src/cef/platform_module_factory_cef.h b/src/cef/platform_module_factory_cef.h new file mode 100644 index 0000000..5015dda --- /dev/null +++ b/src/cef/platform_module_factory_cef.h @@ -0,0 +1,27 @@ +#ifndef CEF_PLATFORM_MODULE_FACTORY_CEF_H_ +#define CEF_PLATFORM_MODULE_FACTORY_CEF_H_ + +#include + +#include "platform_module_factory.h" + +class ServiceSender; +class WebProcessManager; +class DeviceInfo; +class WebAppManagerConfig; + +class PlatformModuleFactoryCEF : public PlatformModuleFactory { + public: + PlatformModuleFactoryCEF(); + + protected: + std::unique_ptr CreateServiceSender() override; + std::unique_ptr CreateWebProcessManager() override; + std::unique_ptr CreateDeviceInfo() override; + std::unique_ptr CreateWebAppManagerConfig() override; + + private: + void PrepareRenderingContext(); +}; + +#endif // CEF_PLATFORM_MODULE_FACTORY_CEF_H_ diff --git a/src/cef/plugin/web_app_cef.cc b/src/cef/plugin/web_app_cef.cc new file mode 100644 index 0000000..f57212b --- /dev/null +++ b/src/cef/plugin/web_app_cef.cc @@ -0,0 +1,172 @@ +#include "web_app_cef.h" + +#include "include/base/cef_callback.h" +#include "include/views/cef_display.h" +#include "include/wrapper/cef_closure_task.h" + +#include "web_page_cef.h" + +WebAppCEF::WebAppCEF(std::shared_ptr app_desc) { + SetAppDescription(app_desc); +} + +WebAppCEF::~WebAppCEF() {} + +void WebAppCEF::Init(int width, + int height, + AglShellSurfaceType surface_type, + AglShellPanelEdge panel_type) { + ApplicationDescription* app_desc = GetAppDescription(); + std::string app_id = app_desc->Id(); + + if (!IsReady()) { + return; + } + + surface_type_ = surface_type; + panel_type_ = panel_type; + + switch (surface_type_) { + case AglShellSurfaceType::kBackground: + window_->AglSetBackGroundApp(); + window_->AglSetAppReady(); + break; + case AglShellSurfaceType::kPanel: + window_->AglSetPanelApp(static_cast(panel_type_)); + break; + case AglShellSurfaceType::kNone: + surface_type_ = AglShellSurfaceType::kNone; + CefPostDelayedTask( + TID_UI, + base::BindOnce(&WebAppCEF::DelayedActivate, this), + 500); + break; + } +} + +void WebAppCEF::TryInitialize() { + ApplicationDescription* app_desc = GetAppDescription(); + + if (!IsReady()) { + CefPostDelayedTask( + TID_UI, + base::BindOnce(&WebAppCEF::TryInitialize, this), + 500); + return; + // TODO: add a maximum number of retries + } + + Init(app_desc->WidthOverride(), + app_desc->HeightOverride(), + app_desc->SurfaceType(), + app_desc->PanelType()); +} + +void WebAppCEF::Attach(WebPageBase* web_page) { + WebAppBase::Attach(web_page); + + WebPageCEF* web_page_cef = static_cast(Page()); + if (!web_page_cef) { + // TODO: handle error + return; + } + web_page_cef->SetWebApp(this); +} + +void WebAppCEF::OnWindowCreated(CefRefPtr window) { + if (!browser_view_) { + return; + } + + window_ = window; + window_->AddChildView(browser_view_); + window_->Show(); + + TryInitialize(); +} + +CefRect WebAppCEF::GetDisplayBounds() const { + CefRefPtr display = CefDisplay::GetPrimaryDisplay(); + CefRect display_bounds; + if (display) { + display_bounds = display->GetBounds(); + } + return display_bounds; +} + +CefSize WebAppCEF::GetPreferredSize(CefRefPtr view) { + return CefSize(width_override_, height_override_); +} + +CefRect WebAppCEF::GetInitialBounds(CefRefPtr window) { + return CefRect(0, 0, width_override_, height_override_); +} + +void WebAppCEF::SendAglReady() { + // Empty because it's called on Init() +} + +void WebAppCEF::SetAglAppId(const char* app_id) { + if (!window_) { + return; + } + window_->SetTitle(app_id); + window_->AglSetAppId(app_id); +} + +void WebAppCEF::SendAglActivate(const char* app_id) { + if (!window_) { + return; + } + window_->AglActivateApp(app_id); +} + +void WebAppCEF::Resize(int width, int height) { + if (!window_) { + return; + } + window_->SetSize(CefSize(width, height)); +} + +bool WebAppCEF::IsReady() const { + return window_ != nullptr; +} + +void WebAppCEF::Hide(bool forced_hide) { + if (!window_) { + return; + } + window_->Hide(); +} + +bool WebAppCEF::HideWindow() { + if (!window_) { + return false; + } + window_->Hide(); + return true; +} + +void WebAppCEF::Raise() { + if (!window_) { + return; + } + window_->BringToTop(); +} + +void WebAppCEF::DelayedActivate() { + ApplicationDescription* app_desc = GetAppDescription(); + SendAglActivate(app_desc->Id().c_str()); +} + +void WebAppCEF::Relaunch(const std::string& args, + const std::string& launching_app_id) { + if (!window_) { + return; + } + + ApplicationDescription* app_desc = GetAppDescription(); + std::string app_id = app_desc->Id(); + + SendAglActivate(app_id.c_str()); +} diff --git a/src/cef/plugin/web_app_cef.h b/src/cef/plugin/web_app_cef.h new file mode 100644 index 0000000..57145cf --- /dev/null +++ b/src/cef/plugin/web_app_cef.h @@ -0,0 +1,95 @@ +#ifndef CEF_PLUGIN_WEB_APP_CEF_H +#define CEF_PLUGIN_WEB_APP_CEF_H + +#include +#include + +#include "web_app_base.h" + +#include "include/views/cef_window.h" +#include "include/views/cef_browser_view.h" +#include "include/views/cef_window_delegate.h" + +#include "application_description.h" + +class WebAppCEF : public WebAppBase, public CefWindowDelegate { + public: + WebAppCEF(std::shared_ptr app_desc); + + ~WebAppCEF(); + + virtual void Init(int width, + int height, + AglShellSurfaceType surface_type, + AglShellPanelEdge panel_type) override; + + void SuspendAppRendering() override {} + void ResumeAppRendering() override {} + bool IsFocused() const override { return false; } + void Resize(int width, int height) override; + bool IsActivated() const override { return false; } + bool IsMinimized() override { return false; } + bool IsNormal() override { return true; } + void OnStageActivated() override {} + void OnStageDeactivated() override {} + void DoAttach() override {} + void ConfigureWindow(const std::string& type) override {} + void SetWindowProperty(const std::string& name, + const std::string& value) override {} + void PlatformBack() override {} + void SetCursor(const std::string& cursor_arg, + int hotspot_x, + int hotspot_y) override {} + void SetInputRegion(const Json::Value& json_doc) override {} + void SetKeyMask(const Json::Value& json_doc) override {} + void Hide(bool forced_hide = false) override; + void Focus() override {} + void Unfocus() override {} + void SetOpacity(float opacity) override {} + void Raise() override; + void GoBackground() override {} + void DoPendingRelaunch() override {} + void DeleteSurfaceGroup() override {} + void DoClose() override {} + void SetUseVirtualKeyboard(const bool enable) override {} + bool HideWindow() override; + + void SendAglReady() override; + void SendAglActivate(const char* app_id) override; + void SetAglAppId(const char* app_id) override; + + void Attach(WebPageBase* web_page) override; + + void Relaunch(const std::string& args, + const std::string& launching_app_id) override; + + void SetBrowserView(CefRefPtr browser_view) { + browser_view_ = browser_view; + } + + virtual bool IsReady() const; + + // CEF overrides + void OnWindowCreated(CefRefPtr window) override; + CefSize GetPreferredSize(CefRefPtr view) override; + CefRect GetInitialBounds(CefRefPtr window) override; + bool IsFrameless(CefRefPtr window) override { return true; } + + protected: + void TryInitialize(); + void DelayedActivate(); + + CefRect GetDisplayBounds() const; + + CefRefPtr browser_view_; + CefRefPtr window_; + AglShellSurfaceType surface_type_; + AglShellPanelEdge panel_type_; + uint32_t width_override_ = 0; + uint32_t height_override_ = 0; + + private: + IMPLEMENT_REFCOUNTING(WebAppCEF); +}; + +#endif // CEF_PLUGIN_WEB_APP_CEF_H diff --git a/src/cef/plugin/web_page_cef.cc b/src/cef/plugin/web_page_cef.cc new file mode 100644 index 0000000..32c6e89 --- /dev/null +++ b/src/cef/plugin/web_page_cef.cc @@ -0,0 +1,48 @@ +#include "web_page_cef.h" +#include "application_description.h" + +#include "include/views/cef_window.h" + +#include "wam_cef_client.h" + +WebPageCEF::WebPageCEF(std::shared_ptr app_desc, const std::string& url) + : url_{url} { + SetApplicationDescription(app_desc); +} + +WebPageCEF::~WebPageCEF() {} + +void WebPageCEF::LoadUrl(const std::string& url) { + CefBrowserSettings browser_settings; + browser_view_ = CefBrowserView::CreateBrowserView( + WamCefClient::GetInstance(), url, browser_settings, nullptr, nullptr, this); + + web_app_->SetBrowserView(browser_view_); + + ApplicationDescription* app_desc = GetAppDescription(); + CefWindow::CreateTopLevelWindowWithId(web_app_, app_desc->Id()); +} + +void WebPageCEF::LoadDefaultUrl() { + LoadUrl(url_); +} + +bool WebPageCEF::HasBeenShown() const { + if (!web_app_) { + return false; + } + + return web_app_->IsReady(); +} + + +void WebPageCEF::EvaluateJavaScript(const std::string& jsCode) { + /*if (!browser_view_) { + return; + } + CefRefPtr browser = browser_view_->GetBrowser(); + if (!browser) { + return; + } + browser->GetMainFrame()->ExecuteJavaScript(jsCode, url_, 0);*/ +} diff --git a/src/cef/plugin/web_page_cef.h b/src/cef/plugin/web_page_cef.h new file mode 100644 index 0000000..f62c223 --- /dev/null +++ b/src/cef/plugin/web_page_cef.h @@ -0,0 +1,69 @@ +#ifndef CEF_PLUGIN_WEB_PAGE_CEF_H +#define CEF_PLUGIN_WEB_PAGE_CEF_H + +#include + +#include "web_page_base.h" +#include "web_app_cef.h" + +#include "include/views/cef_browser_view_delegate.h" + +class WebPageCEF : public WebPageBase, + public CefBrowserViewDelegate { + public: + WebPageCEF(std::shared_ptr app_desc, const std::string& url); + ~WebPageCEF() override; + + void Init() override {} + void* GetWebContents() override { return nullptr; } + + wam::Url Url() const override { return wam::Url(""); } + std::string FailedUrl() const override { return ""; } + void LoadUrl(const std::string& url) override; + int Progress() const override { return 0; } + bool HasBeenShown() const override; + void SetPageProperties() override {} + void SetPreferredLanguages(const std::string& language) override {} + void SetDefaultFont(const std::string& font) override {} + void ReloadDefaultPage() override {} + void Reload() override {} + void SetVisibilityState(WebPageVisibilityState visibility_state) override {} + void SetFocus(bool focus) override {} + std::string Title() override { return ""; } + bool CanGoBack() override { return false; } + void CloseVkb() override {} + void HandleDeviceInfoChanged(const std::string& device_info) override {} + void EvaluateJavaScript(const std::string& jsCode) override; + void EvaluateJavaScriptInAllFrames(const std::string& js_code, + const char* method = {}) override {} + uint32_t GetWebProcessProxyID() override { return 0; } + uint32_t GetWebProcessPID() const override { return 0; } + void CreatePalmSystem(WebAppBase* app) override {} + + void SuspendWebPageAll() override {} + void ResumeWebPageAll() override {} + void SuspendWebPageMedia() override {} + void ResumeWebPageMedia() override {} + void ResumeWebPagePaintingAndJSExecution() override {} + void ForwardEvent(void* event) override {} + + void SuspendWebPagePaintingAndJSExecution() override {} + + void SetWebApp(CefRefPtr web_app) { web_app_ = web_app; } + + protected: + void LoadDefaultUrl() override; + void AddUserScript(const std::string& script) override {} + void AddUserScriptUrl(const wam::Url& url) override {} + void LoadErrorPage(int error_code) override {} + void RecreateWebView() override {} + + private: + IMPLEMENT_REFCOUNTING(WebPageCEF); + + CefRefPtr browser_view_; + CefRefPtr web_app_; + std::string url_; +}; + +#endif // CEF_PLUGIN_WEB_PAGE_CEF_H diff --git a/src/cef/service/CMakeLists.txt b/src/cef/service/CMakeLists.txt new file mode 100644 index 0000000..763b527 --- /dev/null +++ b/src/cef/service/CMakeLists.txt @@ -0,0 +1,64 @@ +project(WebAppMgrService VERSION 1.0.0 DESCRIPTION "Web Application Manager cli helper") + +find_package(gRPC REQUIRED) +find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) +find_package(Protobuf REQUIRED) +find_package(Threads) + +set(WAM_GRPC_LIB_NAME ${PROJECT_NAME}-grpc) +set(APPLAUNCHER_LIB_NAME WamAppLauncher-grpc) + +set(WAM_GRPC_LIBS + protobuf::libprotobuf + gRPC::grpc + gRPC::grpc++ + gRPC::grpc++_reflection +) +set(WAM_SERVICE_LIBS + ${WAM_GRPC_LIBS} + ${WAM_GRPC_LIB_NAME} + ${APPLAUNCHER_LIB_NAME} + libcef_lib + libcef_dll_wrapper +) +set(WAM_GRPC_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) +set(WAM_SERVICE_INCLUDE_DIRS + ${CEF_INCLUDE_PATH} + ${WAM_ROOT_SOURCE_DIR}/core + ${WAM_ROOT_SOURCE_DIR}/util +) +set(SOURCES + applauncher_client_grpc.cc + web_app_manager_client_grpc.cc + web_app_manager_service_grpc.cc +) +set(HEADERS + applauncher_client_grpc.h + web_app_manager_client_grpc.h + web_app_manager_service_grpc.h +) + + +macro(add_wam_grpc_lib target proto) + add_library(${target} SHARED ${proto}) + target_include_directories(${target} PUBLIC ${WAM_GRPC_INCLUDE_DIRS}) + target_link_libraries(${target} PUBLIC ${WAM_GRPC_LIBS}) + set_target_properties(${target} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) + protobuf_generate(TARGET ${target} LANGUAGE cpp APPEND_PATH) + protobuf_generate(TARGET ${target} LANGUAGE grpc APPEND_PATH GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${GRPC_CPP_PLUGIN_EXECUTABLE}") + install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endmacro(add_wam_grpc_lib) + +add_wam_grpc_lib(${WAM_GRPC_LIB_NAME} wam_ipc.proto) +add_wam_grpc_lib(${APPLAUNCHER_LIB_NAME} applauncher.proto) + +add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) +add_dependencies(${PROJECT_NAME} ${WAM_GRPC_LIB_NAME}) +target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_SERVICE_INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_SERVICE_LIBS}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/cef/service/applauncher.proto b/src/cef/service/applauncher.proto new file mode 100644 index 0000000..0b8e0fc --- /dev/null +++ b/src/cef/service/applauncher.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; + +package automotivegradelinux; + +service AppLauncher { + rpc StartApplication(StartRequest) returns (StartResponse) {} + rpc ListApplications(ListRequest) returns (ListResponse) {} + rpc GetStatusEvents(StatusRequest) returns (stream StatusResponse) {} +} + +message StartRequest { + string id = 1; +} + +message StartResponse { + bool status = 1; + string message = 2; +} + +message ListRequest { +} + +message ListResponse { + repeated AppInfo apps = 1; +} + +message AppInfo { + string id = 1; + string name = 2; + string icon_path = 3; +} + +message StatusRequest { +} + +message AppStatus { + string id = 1; + string status = 2; +} + +// Future-proofing for e.g. potentially signaling a list refresh +message LauncherStatus { +} + +message StatusResponse { + oneof status { + AppStatus app = 1; + LauncherStatus launcher = 2; + } +} diff --git a/src/cef/service/applauncher_client_grpc.cc b/src/cef/service/applauncher_client_grpc.cc new file mode 100644 index 0000000..f704742 --- /dev/null +++ b/src/cef/service/applauncher_client_grpc.cc @@ -0,0 +1,58 @@ +#include "applauncher_client_grpc.h" + +#include +#include +#include + +#include "include/cef_parser.h" + +AppLauncherClientGRPC::AppLauncherClientGRPC() + : stub_{MakeStub()} { +} + +std::unique_ptrAppLauncherClientGRPC::MakeStub() const { + return automotivegradelinux::AppLauncher::NewStub(grpc::CreateChannel("localhost:50052", + grpc::InsecureChannelCredentials())); +} + +void AppLauncherClientGRPC::Start(const std::string& app_id) { + automotivegradelinux::StartRequest request; + request.set_id(app_id); + + grpc::ClientContext context; + automotivegradelinux::StartResponse response; + + grpc::Status status = stub_->StartApplication(&context, request, &response); +} + +void AppLauncherClientGRPC::GetApplications(CefRefPtr browser, bool only_graphical) { + automotivegradelinux::ListRequest request; + automotivegradelinux::ListResponse response; + grpc::ClientContext context; + + grpc::Status status = stub_->ListApplications(&context, request, &response); + if (!status.ok()) { + return; + } + + CefRefPtr apps_list = CefListValue::Create(); + for (int i = 0; i < response.apps_size(); i++) { + automotivegradelinux::AppInfo app_info = response.apps(i); + CefRefPtr app_info_dict = CefDictionaryValue::Create(); + app_info_dict->SetString("id", app_info.id()); + app_info_dict->SetString("name", app_info.name()); + app_info_dict->SetString("icon", app_info.icon_path()); + apps_list->SetDictionary(i, app_info_dict); + } + + CefRefPtr apps_list_value = CefValue::Create(); + apps_list_value->SetList(apps_list); + std::string response_string = CefWriteJSON(apps_list_value, JSON_WRITER_DEFAULT); + + // send the response to renderer process + CefRefPtr message = CefProcessMessage::Create("get_applications"); + CefRefPtr args = message->GetArgumentList(); + args->SetString(0, response_string); + browser->GetMainFrame()->SendProcessMessage(PID_RENDERER, message); +} + diff --git a/src/cef/service/applauncher_client_grpc.h b/src/cef/service/applauncher_client_grpc.h new file mode 100644 index 0000000..4a3f289 --- /dev/null +++ b/src/cef/service/applauncher_client_grpc.h @@ -0,0 +1,24 @@ +#ifndef CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H +#define CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H + +#include + +#include "applauncher.grpc.pb.h" + +#include "include/cef_browser.h" + +class AppLauncherClientGRPC { + public: + + AppLauncherClientGRPC(); + + void Start(const std::string& app_id); + void GetApplications(CefRefPtr browser, bool only_graphical); + + private: + std::unique_ptr MakeStub() const; + + std::unique_ptr stub_; +}; + +#endif // CEF_SERVICE_APPLAUNCHER_CLIENT_GRPC_H diff --git a/src/cef/service/wam_ipc.proto b/src/cef/service/wam_ipc.proto new file mode 100644 index 0000000..313de8f --- /dev/null +++ b/src/cef/service/wam_ipc.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +import "google/protobuf/empty.proto"; +package wam_ipc; + +service WebAppManagerService { + rpc Launch(LaunchRequest) returns (google.protobuf.Empty) {} + rpc Activate(ActivateRequest) returns (google.protobuf.Empty) {} + rpc Kill(KillRequest) returns (google.protobuf.Empty) {} +} + +message LaunchRequest { + string app_id = 1; + string uri = 2; +} + +message ActivateRequest { + string app_id = 1; +} + +message KillRequest { + string app_id = 1; +} diff --git a/src/cef/service/web_app_manager_client_grpc.cc b/src/cef/service/web_app_manager_client_grpc.cc new file mode 100644 index 0000000..8529868 --- /dev/null +++ b/src/cef/service/web_app_manager_client_grpc.cc @@ -0,0 +1,42 @@ +#include "web_app_manager_client_grpc.h" + +#include +#include +#include + +const char kDefaultGrpcServiceAddress[] = "127.0.0.1:15000"; + +WebAppManagerClientGRPC::WebAppManagerClientGRPC() { + auto channel = grpc::CreateChannel(kDefaultGrpcServiceAddress, + grpc::InsecureChannelCredentials()); + stub_ = wam_ipc::WebAppManagerService::NewStub(channel); +} + +bool WebAppManagerClientGRPC::Launch(const LaunchParams& params) { + wam_ipc::LaunchRequest request; + request.set_app_id(params.app_id); + request.set_uri(params.uri); + + grpc::ClientContext context; + google::protobuf::Empty reply; + grpc::Status status = stub_->Launch(&context, request, &reply); + return status.ok(); +} + +bool WebAppManagerClientGRPC::Activate(const std::string& app_id) { + grpc::ClientContext context; + google::protobuf::Empty reply; + wam_ipc::ActivateRequest request; + request.set_app_id(app_id); + grpc::Status status = stub_->Activate(&context, request, &reply); + return status.ok(); +} + +bool WebAppManagerClientGRPC::Kill(const std::string& app_id) { + grpc::ClientContext context; + google::protobuf::Empty reply; + wam_ipc::KillRequest request; + request.set_app_id(app_id); + grpc::Status status = stub_->Kill(&context, request, &reply); + return status.ok(); +} diff --git a/src/cef/service/web_app_manager_client_grpc.h b/src/cef/service/web_app_manager_client_grpc.h new file mode 100644 index 0000000..9c4be70 --- /dev/null +++ b/src/cef/service/web_app_manager_client_grpc.h @@ -0,0 +1,23 @@ +#ifndef CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H +#define CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H + +#include "wam_ipc.grpc.pb.h" + +class WebAppManagerClientGRPC { + public: + struct LaunchParams { + std::string app_id; + std::string uri; + }; + + WebAppManagerClientGRPC(); + bool Launch(const LaunchParams& params); + bool Activate(const std::string& app_id); + bool Kill(const std::string& app_id); + + private: + std::unique_ptr stub_; +}; + +#endif // CEF_SERVICE_WEB_APP_MANAGER_CLIENT_GRPC_H + diff --git a/src/cef/service/web_app_manager_service_grpc.cc b/src/cef/service/web_app_manager_service_grpc.cc new file mode 100644 index 0000000..52de924 --- /dev/null +++ b/src/cef/service/web_app_manager_service_grpc.cc @@ -0,0 +1,382 @@ +// Copyright (c) 2018-2022 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "web_app_manager_service_grpc.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log_manager.h" +#include "utils.h" +#include "wam_ipc.grpc.pb.h" +#include "web_app_base.h" +#include "web_app_manager.h" + +namespace { +const char kDefaultGrpcServiceAddress[] = "127.0.0.1:15000"; +} // namespace + +class WamIPCLockFile { + public: + WamIPCLockFile() { + const char* runtime_dir; + if ((runtime_dir = getenv("XDG_RUNTIME_DIR")) == NULL) { + LOG_DEBUG("Failed to retrieve XDG_RUNTIME_DIR, falling back to /tmp"); + runtime_dir = "/tmp"; + } + lock_file_ = std::string(runtime_dir); + lock_file_.append("/wamipc.lock"); + } + + ~WamIPCLockFile() { + if (lock_fd_ != -1) + ReleaseLock(lock_fd_); + if (lock_fd_ != -1) + close(lock_fd_); + } + + bool CreateAndLock() { + lock_fd_ = OpenLockFile(); + if (!AcquireLock(lock_fd_)) { + LOG_DEBUG("Failed to lock file %d", lock_fd_); + return false; + } + return true; + } + + bool OwnsLock() const { return lock_fd_ != -1; } + + bool TryAcquireLock() { + int fd = OpenLockFile(); + if (fd != -1) { + if (AcquireLock(fd)) { + ReleaseLock(fd); + return true; + } + } + return false; + } + + private: + int OpenLockFile() { + int fd = open(lock_file_.c_str(), O_CREAT | O_TRUNC, S_IRWXU); + if (fd == -1) { + LOG_DEBUG("Failed to open lock file descriptor"); + return fd; + } + + int flags = fcntl(fd, F_GETFD); + if (flags == -1) + LOG_DEBUG("Could not get flags for lock file %d", fd); + + flags |= FD_CLOEXEC; + + if (fcntl(fd, F_SETFD, flags) == -1) + LOG_DEBUG("Could not set flags for lock file %d", fd); + + return fd; + } + + bool AcquireLock(int fd) { + if (flock(fd, LOCK_EX | LOCK_NB) != 0) + return false; + return true; + } + + void ReleaseLock(int fd) { flock(fd, LOCK_UN); } + + std::string lock_file_; + int lock_fd_ = -1; +}; + +class GrpcServiceImpl final + : public wam_ipc::WebAppManagerService::CallbackService { + grpc::ServerUnaryReactor* Launch(grpc::CallbackServerContext* context, + const ::wam_ipc::LaunchRequest* request, + google::protobuf::Empty* /*response*/) { + WebAppManagerServiceGRPC::LaunchParams launch_params; + launch_params.app_id = request->app_id(); + launch_params.uri = request->uri(); + launch_params.width = 0; + launch_params.height = 0; + + WebAppManagerServiceGRPC::Instance()->LaunchOnIdle(launch_params); + + grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); + reactor->Finish(grpc::Status::OK); + return reactor; + } + grpc::ServerUnaryReactor* Activate(grpc::CallbackServerContext* context, + const ::wam_ipc::ActivateRequest* request, + google::protobuf::Empty* /*response*/) { + WebAppManagerServiceGRPC::Instance()->SendEventOnIdle(kActivateEvent, + request->app_id()); + grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); + reactor->Finish(grpc::Status::OK); + return reactor; + } + grpc::ServerUnaryReactor* Kill(grpc::CallbackServerContext* context, + const ::wam_ipc::KillRequest* request, + google::protobuf::Empty* /*response*/) { + WebAppManagerServiceGRPC::Instance()->SendEventOnIdle(kKilledApp, + request->app_id()); + grpc::ServerUnaryReactor* reactor = context->DefaultReactor(); + reactor->Finish(grpc::Status::OK); + return reactor; + } +}; + +WebAppManagerServiceGRPC::WebAppManagerServiceGRPC() + : lock_file_(std::make_unique()) {} + +WebAppManagerServiceGRPC* WebAppManagerServiceGRPC::Instance() { + static WebAppManagerServiceGRPC* srv = new WebAppManagerServiceGRPC(); + return srv; +} + +bool WebAppManagerServiceGRPC::InitializeAsHostService() { + return lock_file_->CreateAndLock(); +} + +bool WebAppManagerServiceGRPC::IsHostServiceRunning() { + return !lock_file_->TryAcquireLock(); +} + +void* RunGrpcService(void*) { + std::string server_address(kDefaultGrpcServiceAddress); + GrpcServiceImpl service; + + grpc::EnableDefaultHealthCheckService(true); + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + + grpc::ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + server->Wait(); + + return nullptr; +} + +bool WebAppManagerServiceGRPC::StartService() { + if (lock_file_->OwnsLock()) { + pthread_t thread_id; + if (pthread_create(&thread_id, nullptr, RunGrpcService, nullptr) < 0) { + perror("Could not create thread"); + LOG_DEBUG("Could not create thread..."); + return false; + } + } + + return true; +} + +void WebAppManagerServiceGRPC::LaunchOnIdle(const LaunchParams& params) { + auto launch_params = std::make_unique(params); + + auto* timer = + new OneShotTimerWithData(); + timer->Start(0, this, &WebAppManagerServiceGRPC::OnLaunchApp, + std::move(launch_params)); +} + +void WebAppManagerServiceGRPC::SendEventOnIdle(const std::string& event, + const std::string& app_id) { + auto event_data = std::make_unique(); + event_data->app_id = app_id; + auto* timer = new OneShotTimerWithData(); + if (event == kActivateEvent) + timer->Start(0, this, &WebAppManagerServiceGRPC::OnActivateEvent, + std::move(event_data)); + else if (event == kDeactivateEvent) + timer->Start(0, this, &WebAppManagerServiceGRPC::OnDeactivateEvent, + std::move(event_data)); + else if (event == kKilledApp) + timer->Start(1000, this, &WebAppManagerServiceGRPC::OnKillEvent, + std::move(event_data)); +} + +void WebAppManagerServiceGRPC::OnLaunchApp(LaunchParams* params) { + LOG_DEBUG("Triggering app start: %s", params->uri.c_str()); + if (!params->uri.empty()) { + if (params->uri.find("http://") == 0) { + LaunchStartupAppFromURL(params); + } else { + LaunchStartupAppFromJsonConfig(params); + } + } +} + +void WebAppManagerServiceGRPC::LaunchStartupAppFromJsonConfig( + LaunchParams* params) { + std::string configfile; + configfile.append(params->uri); + configfile.append("/appinfo.json"); + + Json::Value root; + Json::CharReaderBuilder builder; + JSONCPP_STRING errs; + + std::ifstream ifs; + ifs.open(configfile.c_str()); + + if (!parseFromStream(builder, ifs, &root, &errs)) { + LOG_DEBUG("Failed to parse %s configuration file", configfile.c_str()); + } + + root["folderPath"] = params->uri.c_str(); + + auto surface_obj = root["surface"]; + auto surface_type = surface_obj["type"].asString(); + if (surface_type == "background") { + root["surface_type"] = 1; // AglShellSurfaceType::kBackground; + } else if (surface_type == "panel") { + root["surface_type"] = 2; // AglShellSurfaceType::kPanel; + } else { + root["surface_type"] = 0; // AglShellSurfaceType::kNone; + } + + std::string app_desc = util::JsonToString(root); + std::string empty_params = "{}"; + std::string app_id = root["id"].asString(); + int err_code = 0; + std::string err_msg; + WebAppManagerService::OnLaunch(app_desc, empty_params, app_id, err_code, + err_msg); +} + +void WebAppManagerServiceGRPC::LaunchStartupAppFromURL(LaunchParams* params) { + LOG_DEBUG("WebAppManagerServiceGRPC::LaunchStartupAppFromURL"); + LOG_DEBUG(" url: %s", params->uri.c_str()); + Json::Value obj(Json::objectValue); + obj["id"] = params->app_id; + obj["version"] = "1.0"; + obj["vendor"] = "some vendor"; + obj["type"] = "web"; + obj["main"] = params->uri; + obj["title"] = "webapp"; + obj["uiRevision"] = "2"; + + obj["widthOverride"] = params->width; + obj["heightOverride"] = params->height; + + std::string app_desc = util::JsonToString(obj); + std::string app_id = params->app_id; + int err_code = 0; + std::string empty_params = "{}"; + std::string err_msg; + + LOG_DEBUG("Launching with appDesc=[%s]", app_desc.c_str()); + + WebAppManagerService::OnLaunch(app_desc, empty_params, app_id, err_code, + err_msg); + LOG_DEBUG("onLaunch: Done."); +} + +Json::Value WebAppManagerServiceGRPC::launchApp(const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::killApp(const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::pauseApp(const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::logControl(const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::setInspectorEnable( + const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::closeAllApps(const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::discardCodeCache( + const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::listRunningApps( + const Json::Value& request, + bool subscribed) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::getWebProcessSize( + const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::clearBrowsingData( + const Json::Value& request) { + return Json::Value(Json::objectValue); +} + +Json::Value WebAppManagerServiceGRPC::webProcessCreated( + const Json::Value& request, + bool subscribed) { + return Json::Value(Json::objectValue); +} + +void WebAppManagerServiceGRPC::OnActivateEvent(EventData* event_data) { + LOG_DEBUG("Activate app=%s", event_data->app_id.c_str()); + WebAppBase* web_app = + WebAppManager::Instance()->FindAppById(event_data->app_id); + if (web_app) { + web_app->OnStageActivated(); + web_app->SendAglActivate(event_data->app_id.c_str()); + } else { + LOG_DEBUG("Not found app=%s running", event_data->app_id.c_str()); + } +} + +void WebAppManagerServiceGRPC::OnDeactivateEvent(EventData* event_data) { + LOG_DEBUG("Dectivate app=%s", event_data->app_id.c_str()); + WebAppBase* web_app = + WebAppManager::Instance()->FindAppById(event_data->app_id); + if (web_app) + web_app->OnStageDeactivated(); +} + +void WebAppManagerServiceGRPC::OnKillEvent(EventData* event_data) { + LOG_DEBUG("Kill app=%s", event_data->app_id.c_str()); + WebAppManager::Instance()->OnKillApp(event_data->app_id, event_data->app_id); +} diff --git a/src/cef/service/web_app_manager_service_grpc.h b/src/cef/service/web_app_manager_service_grpc.h new file mode 100644 index 0000000..69ea0ed --- /dev/null +++ b/src/cef/service/web_app_manager_service_grpc.h @@ -0,0 +1,85 @@ +// Copyright (c) 2018-2022 LG Electronics, Inc. +// +// 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. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H +#define CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H + +#include + +#include "timer.h" +#include "web_app_manager_service.h" + +constexpr char kStartApp[] = "start-app"; +constexpr char kKilledApp[] = "killed-app"; +constexpr char kActivateEvent[] = "activate-event"; +constexpr char kDeactivateEvent[] = "deactivate-event"; + +class GrpcClient; +class WamIPCLockFile; + +class WebAppManagerServiceGRPC : public WebAppManagerService, + public TimerReceiver { + public: + struct LaunchParams { + std::string app_id; + std::string uri; + int width = 0; + int height = 0; + }; + + static WebAppManagerServiceGRPC* Instance(); + + bool InitializeAsHostService(); + bool IsHostServiceRunning(); + + void LaunchOnIdle(const LaunchParams& params); + void SendEventOnIdle(const std::string& event, const std::string& app_id); + + // WebAppManagerService + bool StartService() override; + Json::Value launchApp(const Json::Value& request) override; + Json::Value killApp(const Json::Value& request) override; + Json::Value pauseApp(const Json::Value& request) override; + Json::Value logControl(const Json::Value& request) override; + Json::Value setInspectorEnable(const Json::Value& request) override; + Json::Value closeAllApps(const Json::Value& request) override; + Json::Value discardCodeCache(const Json::Value& request) override; + Json::Value listRunningApps(const Json::Value& request, + bool subscribed) override; + Json::Value getWebProcessSize(const Json::Value& request) override; + Json::Value clearBrowsingData(const Json::Value& request) override; + Json::Value webProcessCreated(const Json::Value& request, + bool subscribed) override; + + void TriggerStartupApp(); + + private: + WebAppManagerServiceGRPC(); + + void OnLaunchApp(LaunchParams* launch_data); + void LaunchStartupAppFromJsonConfig(LaunchParams*); + void LaunchStartupAppFromURL(LaunchParams*); + struct EventData { + std::string app_id; + }; + void OnActivateEvent(EventData* event_data); + void OnDeactivateEvent(EventData* event_data); + void OnKillEvent(EventData* event_data); + + std::unique_ptr lock_file_; +}; + +#endif // CEF_SERVICE_WEB_APP_MANAGER_SERVICE_GRPC_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 182f96a..41871b9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,6 +18,7 @@ project(WebAppMgrCore VERSION 1.0.0 DESCRIPTION "Core of the Web Application Man set(SOURCES application_description.cc + application_installation_handler_stub.cc device_info.cc palm_system_base.cc plugin_service.cc @@ -44,7 +45,9 @@ set(SOURCES set(HEADERS agl_shell_types.h application_description.h + application_installation_handler.h device_info.h + memory_pressure_level.h palm_system_base.h platform_module_factory.h plugin_service.h @@ -95,6 +98,7 @@ set(CORE_INCLUDE_DIRS set(CORE_LIBS ${CHROMIUM_LDFLAGS} ${GLIB_LDFLAGS} + ${JSONCPP_LDFLAGS} ${PMLOGLIB_LDFLAGS} Boost::filesystem dl diff --git a/src/core/application_description.cc b/src/core/application_description.cc index 9b494fc..adbb7d8 100644 --- a/src/core/application_description.cc +++ b/src/core/application_description.cc @@ -144,12 +144,49 @@ std::unique_ptr ApplicationDescription::FromJsonString( auto app_desc = std::unique_ptr(new ApplicationDescription()); + app_desc->surface_type_ = static_cast(json_obj["surface_type"].asInt()); app_desc->panel_type_ = static_cast(json_obj["panel_type"].asInt()); app_desc->width_override_ = json_obj["widthOverride"].asInt(); app_desc->height_override_ = json_obj["heightOverride"].asInt(); + + // override previous values if the json config file contains + // a "surface" object with nested data + auto surface_obj = json_obj["surface"]; + if (!surface_obj.empty()) { + std::string surface_type = surface_obj["type"].asString(); + if (surface_type == "background") { + app_desc->surface_type_ = AglShellSurfaceType::kBackground; + } else if (surface_type == "panel") { + app_desc->surface_type_ = AglShellSurfaceType::kPanel; + } else { + app_desc->surface_type_ = AglShellSurfaceType::kNone; + } + + std::string panel_edge = surface_obj["panel_edge"].asString(); + if (panel_edge == "left") { + app_desc->panel_type_ = AglShellPanelEdge::kLeft; + } else if (panel_edge == "right") { + app_desc->panel_type_ = AglShellPanelEdge::kRight; + } else if (panel_edge == "top") { + app_desc->panel_type_ = AglShellPanelEdge::kTop; + } else if (panel_edge == "bottom") { + app_desc->panel_type_ = AglShellPanelEdge::kBottom; + } + + int width = 0; + if (!surface_obj["width"].empty()) + util::StrToInt(surface_obj["width"].asString(), width); + app_desc->width_override_ = width; + + int height = 0; + if (!surface_obj["height"].empty()) + util::StrToInt(surface_obj["height"].asString(), height); + app_desc->height_override_ = height; + } + app_desc->transparency_ = json_obj["transparent"].asBool(); auto vendor_extension = json_obj.get("vendorExtension", Json::Value(Json::objectValue)); diff --git a/src/core/application_installation_handler.h b/src/core/application_installation_handler.h new file mode 100644 index 0000000..054bc9d --- /dev/null +++ b/src/core/application_installation_handler.h @@ -0,0 +1,12 @@ +#ifndef CORE_APPLICATION_INSTALLATION_HANDLER_H_ +#define CORE_APPLICATION_INSTALLATION_HANDLER_H_ + +#include + +class ApplicationInstallationHandler { + public: + static void OnAppInstalled(const std::string& app_id); + static void OnAppRemoved(const std::string& app_id); +}; + +#endif // CORE_APPLICATION_INSTALLATION_HANDLER_H_ \ No newline at end of file diff --git a/src/core/application_installation_handler_stub.cc b/src/core/application_installation_handler_stub.cc new file mode 100644 index 0000000..016c7d2 --- /dev/null +++ b/src/core/application_installation_handler_stub.cc @@ -0,0 +1,4 @@ +#include "application_installation_handler.h" + +void ApplicationInstallationHandler::OnAppInstalled(const std::string&) {} +void ApplicationInstallationHandler::OnAppRemoved(const std::string&) {} \ No newline at end of file diff --git a/src/core/memory_pressure_level.h b/src/core/memory_pressure_level.h new file mode 100644 index 0000000..01c9316 --- /dev/null +++ b/src/core/memory_pressure_level.h @@ -0,0 +1,6 @@ +#ifndef CORE_MEMORY_PRESSURE_LEVEL_H_ +#define CORE_MEMORY_PRESSURE_LEVEL_H_ + +enum class MemoryPressureLevel { kNone, kLow, kCritical }; + +#endif // CORE_MEMORY_PRESSURE_LEVEL_H_ \ No newline at end of file diff --git a/src/core/web_app_manager.cc b/src/core/web_app_manager.cc index ca64ef1..42e8be7 100644 --- a/src/core/web_app_manager.cc +++ b/src/core/web_app_manager.cc @@ -22,10 +22,9 @@ #include #include -#include "webos/application_installation_handler.h" -#include "webos/public/runtime.h" #include "application_description.h" +#include "application_installation_handler.h" #include "base_check.h" #include "device_info.h" #include "log_manager.h" @@ -63,8 +62,7 @@ WebAppManager::~WebAppManager() { device_info_->Terminate(); } -void WebAppManager::NotifyMemoryPressure( - webos::WebViewBase::MemoryPressureLevel level) { +void WebAppManager::NotifyMemoryPressure(MemoryPressureLevel level) { std::list app_list = RunningApps(); for (auto it = app_list.begin(); it != app_list.end(); ++it) { const WebAppBase* app = *it; @@ -72,15 +70,14 @@ void WebAppManager::NotifyMemoryPressure( // critical (when system is on low or critical) because they will be killed // anyway if (app->IsActivated() && - (!app->Page()->IsPreload() || - level != webos::WebViewBase::MEMORY_PRESSURE_CRITICAL)) + (!app->Page()->IsPreload() || level != MemoryPressureLevel::kCritical)) app->Page()->NotifyMemoryPressure(level); else { LOG_DEBUG( "Skipping memory pressure handler for" " instanceId(%s) appId(%s) isActivated(%d) isPreload(%d) Level(%d)", app->InstanceId().c_str(), app->AppId().c_str(), app->IsActivated(), - app->Page()->IsPreload(), level); + app->Page()->IsPreload(), static_cast(level)); } } } @@ -341,8 +338,10 @@ WebAppBase* WebAppManager::OnLaunchUrl( WebPageAdded(page); /* if the surface role is a background send ready to display them */ - if (app_desc->SurfaceType() == AglShellSurfaceType::kBackground) + if (app_desc->SurfaceType() == AglShellSurfaceType::kBackground) { + LOG_DEBUG("Sending agl_ready from app %s", app_desc->Id().c_str()); app->SendAglReady(); + } app_list_.push_back(app); @@ -831,8 +830,10 @@ void WebAppManager::UpdateNetworkStatus(const Json::Value& object) { NetworkStatus status; status.FromJsonObject(object); +#if defined(OS_WEBOS) webos::Runtime::GetInstance()->SetNetworkConnected( status.IsInternetConnectionAvailable()); +#endif network_status_manager_->UpdateNetworkStatus(status); if (status.IsInternetConnectionAvailable()) { @@ -867,16 +868,12 @@ int WebAppManager::MaskForBrowsingDataType(const char* type) { void WebAppManager::AppInstalled(const std::string& app_id) { LOG_INFO(MSGID_WAM_DEBUG, 0, "App installed; id=%s", app_id.c_str()); - auto p = webos::ApplicationInstallationHandler::GetInstance(); - if (p) - p->OnAppInstalled(app_id); + ApplicationInstallationHandler::OnAppInstalled(app_id); } void WebAppManager::AppRemoved(const std::string& app_id) { LOG_INFO(MSGID_WAM_DEBUG, 0, "App removed; id=%s", app_id.c_str()); - auto p = webos::ApplicationInstallationHandler::GetInstance(); - if (p) - p->OnAppRemoved(app_id); + ApplicationInstallationHandler::OnAppRemoved(app_id); } std::string WebAppManager::IdentifierForSecurityOrigin( @@ -889,5 +886,9 @@ std::string WebAppManager::IdentifierForSecurityOrigin( LOG_WARNING(MSGID_APPID_HAS_UPPERCASE, 0, "Application id should not contain capital letters"); } +#if defined(OS_WEBOS) return (lowcase_identifier + webos::WebViewBase::kSecurityOriginPostfix); +#else + return lowcase_identifier; +#endif } diff --git a/src/core/web_app_manager.h b/src/core/web_app_manager.h index b10f53d..0f30a85 100644 --- a/src/core/web_app_manager.h +++ b/src/core/web_app_manager.h @@ -24,7 +24,7 @@ #include #include -#include "webos/webview_base.h" +#include "memory_pressure_level.h" class ApplicationDescription; class DeviceInfo; @@ -150,7 +150,7 @@ class WebAppManager { const std::string& payload, const std::string& app_id); void UpdateNetworkStatus(const Json::Value& object); - void NotifyMemoryPressure(webos::WebViewBase::MemoryPressureLevel level); + void NotifyMemoryPressure(MemoryPressureLevel level); bool IsEnyoApp(const std::string& app_id); diff --git a/src/core/web_app_manager_service.cc b/src/core/web_app_manager_service.cc index 1770d02..90b880f 100644 --- a/src/core/web_app_manager_service.cc +++ b/src/core/web_app_manager_service.cc @@ -19,6 +19,7 @@ #include #include "log_manager.h" +#include "memory_pressure_level.h" #include "web_app_base.h" #include "web_app_manager_tracer.h" @@ -158,8 +159,7 @@ void WebAppManagerService::UpdateNetworkStatus(const Json::Value& object) { WebAppManager::Instance()->UpdateNetworkStatus(object); } -void WebAppManagerService::NotifyMemoryPressure( - webos::WebViewBase::MemoryPressureLevel level) { +void WebAppManagerService::NotifyMemoryPressure(MemoryPressureLevel level) { WebAppManager::Instance()->NotifyMemoryPressure(level); } diff --git a/src/core/web_app_manager_service.h b/src/core/web_app_manager_service.h index 7ead117..c294e50 100644 --- a/src/core/web_app_manager_service.h +++ b/src/core/web_app_manager_service.h @@ -22,7 +22,6 @@ #include #include "web_app_manager.h" -#include "webos/webview_base.h" namespace Json { class Value; @@ -114,7 +113,7 @@ class WebAppManagerService { void KillCustomPluginProcess(const std::string& app_base_path); void RequestKillWebProcess(uint32_t pid); void UpdateNetworkStatus(const Json::Value& object); - void NotifyMemoryPressure(webos::WebViewBase::MemoryPressureLevel level); + void NotifyMemoryPressure(MemoryPressureLevel level); void SetAccessibilityEnabled(bool enable); uint32_t GetWebProcessId(const std::string& app_id, const std::string& instance_id); diff --git a/src/core/web_page_base.h b/src/core/web_page_base.h index 7bbca84..8a689a7 100644 --- a/src/core/web_page_base.h +++ b/src/core/web_page_base.h @@ -20,8 +20,7 @@ #include #include -#include "webos/webview_base.h" - +#include "memory_pressure_level.h" #include "observer_list.h" #include "util/url.h" @@ -58,8 +57,7 @@ class WebPageBase { virtual void Init() = 0; virtual void* GetWebContents() = 0; virtual void SetLaunchParams(const std::string& params); - virtual void NotifyMemoryPressure( - webos::WebViewBase::MemoryPressureLevel level) {} + virtual void NotifyMemoryPressure(MemoryPressureLevel level) {} virtual std::string GetIdentifier() const; virtual wam::Url Url() const = 0; diff --git a/src/core/web_process_manager.h b/src/core/web_process_manager.h index b63d270..c7ffde1 100644 --- a/src/core/web_process_manager.h +++ b/src/core/web_process_manager.h @@ -17,6 +17,7 @@ #ifndef CORE_WEB_PROCESS_MANAGER_H_ #define CORE_WEB_PROCESS_MANAGER_H_ +#include #include #include #include diff --git a/src/core/web_runtime.h b/src/core/web_runtime.h index 69bc204..1ae6ca9 100644 --- a/src/core/web_runtime.h +++ b/src/core/web_runtime.h @@ -21,8 +21,9 @@ class WebRuntime { public: + virtual ~WebRuntime() = default; static std::unique_ptr Create(); - virtual int Run(int argc, const char** argv) = 0; + virtual int Run(int argc, char** argv) = 0; }; #endif // CORE_WEB_RUNTIME_H_ diff --git a/src/desktop/CMakeLists.txt b/src/desktop/CMakeLists.txt new file mode 100644 index 0000000..06078da --- /dev/null +++ b/src/desktop/CMakeLists.txt @@ -0,0 +1,100 @@ +project(WebAppMgrDesktop VERSION 1.0.0 DESCRIPTION "Web Application Manager library") + +find_package(gRPC REQUIRED) +find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) +find_package(Protobuf REQUIRED) +find_package(Threads) + +set(WAM_IPC_LIB_NAME ${PROJECT_NAME}IPC) +set(WAM_IPC_PROTO_FILES ${WAM_ROOT_SOURCE_DIR}/cef/ipc/wam_ipc.proto) +set(WAM_IPC_LIBS + protobuf::libprotobuf + gRPC::grpc + gRPC::grpc++ + gRPC::grpc++_reflection +) +set(WAM_IPC_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR} +) + +set(WAM_LIB_LIBS + ${JSONCPP_LDFLAGS} + WebAppMgrCore + ${WAM_IPC_LIB_NAME} + libcef_lib + libcef_dll_wrapper +) + +set(SOURCES + web_runtime_desktop.cc +) + +set(HEADERS + web_runtime_desktop.h +) + +set(WAM_LIB_CEF_DIR ${WAM_ROOT_SOURCE_DIR}/cef) + + +set(WAM_LIB_INCLUDE_DIRS + ${JSONCPP_INCLUDE_DIRS} + ${CEF_INCLUDE_PATH} +) + +add_library(${WAM_IPC_LIB_NAME} SHARED ${WAM_IPC_PROTO_FILES}) +target_include_directories(${WAM_IPC_LIB_NAME} PUBLIC ${WAM_IPC_INCLUDE_DIRS}) +target_link_libraries(${WAM_IPC_LIB_NAME} PUBLIC ${WAM_IPC_LIBS}) +set_target_properties(${WAM_IPC_LIB_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) +protobuf_generate(TARGET ${WAM_IPC_LIB_NAME} LANGUAGE cpp APPEND_PATH) +protobuf_generate(TARGET ${WAM_IPC_LIB_NAME} LANGUAGE grpc APPEND_PATH GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${GRPC_CPP_PLUGIN_EXECUTABLE}") +install(TARGETS ${WAM_IPC_LIB_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) + + +LIST(APPEND SOURCES + ${WAM_LIB_CEF_DIR}/device_info_cef.cc + ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.cc + ${WAM_LIB_CEF_DIR}/ipc/web_app_manager_service_grpc.cc + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.cc + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.cc +) +LIST(APPEND HEADERS + ${WAM_LIB_CEF_DIR}/device_info_cef.h + ${WAM_LIB_CEF_DIR}/platform_module_factory_cef.h + ${WAM_LIB_CEF_DIR}/ipc/web_app_manager_service_grpc.h + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_browser_handler.h + ${WAM_LIB_CEF_DIR}/handlers/wam_cef_client.h +) +LIST(APPEND WAM_LIB_INCLUDE_DIRS + ${WAM_LIB_CEF_DIR} + ${WAM_LIB_CEF_DIR}/ipc + ${WAM_LIB_CEF_DIR}/webapp +) + +add_library(${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES}) +target_include_directories(${PROJECT_NAME} PUBLIC ${WAM_LIB_INCLUDE_DIRS}) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 1.0) + +install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/webappmanager) + +macro(INSTALL_CEF_FILES file_list source_dir target_dir) + foreach(FILENAME ${file_list}) + set(source_file ${source_dir}/${FILENAME}) + + # Remove the target file path component. + get_filename_component(target_name ${FILENAME} NAME) + set(target_file ${target_dir}/${target_name}) + + if (IS_DIRECTORY ${source_file}) + install(DIRECTORY ${source_file} DESTINATION ${target_dir}) + else() + install(FILES ${source_file} DESTINATION ${target_dir}) + endif() + endforeach() +endmacro() + +# Copy CEF dependencies +install_cef_files("${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CMAKE_INSTALL_PREFIX}") +install_cef_files("${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CMAKE_INSTALL_PREFIX}") + +target_link_libraries(${PROJECT_NAME} PUBLIC ${WAM_LIB_LIBS}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/desktop/README.md b/src/desktop/README.md new file mode 100644 index 0000000..2d32b39 --- /dev/null +++ b/src/desktop/README.md @@ -0,0 +1,102 @@ +# CEF backend + +This is an experimental CEF backend for WAM. + +## Compilation + +### Preparations + +First prepare a workspace: +``` +mkdir wam-cef +cd wam-cef +``` + +Now clone WAM repository: +``` +git clone ssh://git@gitlab.igalia.com:4429/dape/wam.git +``` + +Fetch latest stable CEF binary distribution (standard) for your system, from [CEF binary download](https://cef-builds.spotifycdn.com/index.html). Then uncompress the tarball: +``` +tar xvf ...path...to...binary/cef_binary...tar.bz2 +``` + +### Compilation of CEF DLL wrapper + +Create a folder to compile the CEF DLL wrapper `.a` file: +``` +mkdir build-cef-dll +cd build-cef-dll +``` + +Prepare compilation scripts: +``` +cmake ../cef_binary_... +``` + +Then compile the DLL wrapper: +``` +make libcef_dll_wrapper +``` + +Finally go back to the top directory: +``` +cd .. +``` + +After this, you can see the wrapper at `build-cef-dll/libcef_dll_wrapper/libcef_dll_wrapper.a`. + +### Test applications + +You can just use webOS `test-apps` repository: +``` +git clone https://github.com/webosose/test-apps.git +``` + +### Compilation of WAM + +Prepare build folder: + +``` +mkdir build-wam +cd build-wam +mkdir wam-install +``` + +Then call *CMake* to generate the compilation scripts. You will need to pass several variables: +* `CEF_ROOT`: full path to the CEF dist directory. +* `CMAKE_INSTALL_PREFIX`: base install directory. +* `CMAKE_INSTALL_BINDIR`: where executables will go. +* `CMAKE_INSTALL_LIBDIR`: libraries. +* `CMAKE_INSTALL_INCLUDEDIR`: path for includes. + +You can also use `CMAKE_BUILD_TYPE` to set `Debug` or `Release` builds. + +An example of the *CMake* invokation: +``` +cmake -DCMAKE_INSTALL_PREFIX=$PWD/wam-install -DCMAKE_INSTALL_BINDIR=$PWD/wam-install/bin -DCMAKE_INSTALL_LIBDIR=$PWD/wam-install/lib -DCMAKE_INSTALL_INCLUDEDIR=$PWD/wam-install/include -DCEF_ROOT=$WAM_BASE_PATH/cef_binary_114.2.10+g398e3c3+chromium-114.0.5735.110_linux64/Debug/ -DCMAKE_BUILD_TYPE=Debug +``` + +And finally compilation of WAM: +``` +make +``` + +And installation: +``` +make install +``` + +## Running + +To run the daemon, you can do: +``` +cd wam-install/bin +WEBAPPFACTORY_PLUGIN_PATH=../lib/webappmanager/plugins/ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib:$WAM_BASE_PATH/cef_binary_114.2.10+g398e3c3+chromium-114.0.5735.110_linux64/Release/ ./WebAppMgr & +``` + +Then, you can launch an application: +``` +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib ../WebAppMgrDesktopCli --app-id=bareapp --app-install-dir=$WAM_BASE_PATH/test-apps/bareapp/ +``` diff --git a/src/desktop/web_runtime_desktop.cc b/src/desktop/web_runtime_desktop.cc new file mode 100644 index 0000000..49d1914 --- /dev/null +++ b/src/desktop/web_runtime_desktop.cc @@ -0,0 +1,28 @@ +#include "web_runtime_desktop.h" + +#include "include/cef_base.h" + +#include "wam_cef_browser_handler.h" + +int WebRuntimeDesktop::Run(int argc, char** argv) { + CefMainArgs main_args(argc, argv); + + CefRefPtr app = new WamCefBrowserHandler; + auto exit_code = CefExecuteProcess(main_args, app.get(), nullptr); + if (exit_code >= 0) { + return exit_code; + } + + CefSettings settings; + CefInitialize(main_args, settings, app.get(), nullptr); + + CefRunMessageLoop(); + + CefShutdown(); + + return 0; +} + +std::unique_ptr WebRuntime::Create() { + return std::make_unique(); +} diff --git a/src/desktop/web_runtime_desktop.h b/src/desktop/web_runtime_desktop.h new file mode 100644 index 0000000..e65f738 --- /dev/null +++ b/src/desktop/web_runtime_desktop.h @@ -0,0 +1,11 @@ +#ifndef DESKTOP_WEB_RUNTIME_CEF_H_ +#define DESKTOP_WEB_RUNTIME_CEF_H_ + +#include "web_runtime.h" + +class WebRuntimeDesktop : public WebRuntime { + public: + int Run(int argc, char** argv) override; +}; + +#endif // DESKTOP_WEB_RUNTIME_CEF_H_ diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 876921b..b401dca 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -17,10 +17,6 @@ project(WebAppMgr VERSION 1.0.0 DESCRIPTION "Web Application Manager library") set(SOURCES - palm_system_webos.cc - web_app_wayland.cc - web_app_wayland_window.cc - web_app_window_impl.cc webengine/blink_web_process_manager.cc webengine/blink_web_view.cc webengine/blink_web_view_profile_helper.cc @@ -32,12 +28,8 @@ set(SOURCES ) set(HEADERS - palm_system_webos.h - web_app_wayland.h - web_app_wayland_window.h web_app_window.h web_app_window_factory.h - web_app_window_impl.h webengine/blink_web_process_manager.h webengine/blink_web_view.h webengine/blink_web_view_profile_helper.h @@ -67,6 +59,21 @@ set(WAM_LIB_LIBS WebAppMgrCore ) +if (WEBENGINE_CBE) + LIST(APPEND SOURCES + web_app_window_impl.h + web_app_wayland_window.cc + palm_system_webos.cc + web_app_wayland.cc + ) + LIST(APPEND HEADERS + palm_system_webos.h + web_app_wayland.h + web_app_wayland_window.h + web_app_window_impl.h + ) +endif() + if (OS_WEBOS) LIST(APPEND SOURCES ${WAM_ROOT_SOURCE_DIR}/webos/palm_service_base.cc diff --git a/src/platform/web_app_window.h b/src/platform/web_app_window.h index 7381b0c..a90127f 100644 --- a/src/platform/web_app_window.h +++ b/src/platform/web_app_window.h @@ -20,8 +20,6 @@ #include #include -#include "webos/webapp_window_base.h" - class WebAppWayland; class WebAppWindow { @@ -32,12 +30,14 @@ class WebAppWindow { virtual int DisplayWidth() = 0; virtual int DisplayHeight() = 0; virtual void InitWindow(int width, int height) = 0; - virtual void SetLocationHint(webos::WebAppWindowBase::LocationHint value) = 0; + virtual void SetLocationHint(const std::string& value) = 0; virtual webos::NativeWindowState GetWindowHostState() const = 0; +#if defined(OS_WEBOS) virtual void CreateWindowGroup( const webos::WindowGroupConfiguration& config) = 0; virtual void AttachToWindowGroup(const std::string& name, const std::string& layer) = 0; +#endif virtual bool IsKeyboardVisible() = 0; virtual void SetKeyMask(webos::WebOSKeyMask key_mask) = 0; virtual void SetKeyMask(webos::WebOSKeyMask key_mask, bool set) = 0; diff --git a/src/util/log_msg_id.h b/src/util/log_msg_id.h index 7d114cf..71d9621 100644 --- a/src/util/log_msg_id.h +++ b/src/util/log_msg_id.h @@ -150,6 +150,8 @@ #define MSGID_DL_ERROR "DL_ERROR" /** Dinamic load library error **/ +#define MSGID_ERROR_CANNOT_LOCK_SERVICE "MSGID_CANNOT_LOCK_SERVICE" /** Cannot lock the GRPC IPC lock **/ + // clang-format on #endif // LOGMSGID_H diff --git a/src/util/timer.h b/src/util/timer.h index 795a38c..6824fb8 100644 --- a/src/util/timer.h +++ b/src/util/timer.h @@ -30,12 +30,12 @@ class Timer { : source_id_(0), is_running_(false), is_repeating_(is_repeating) {} virtual ~Timer() {} - // Timer virtual void HandleCallback() = 0; - virtual void Start(int delay_in_milli_seconds); bool IsRunning() { return is_running_; } bool IsRepeating() { return is_repeating_; } + + void Start(int delay_in_milli_seconds); void Stop(); protected: diff --git a/src/wam_main.cc b/src/wam_main.cc index 0c04a40..d559ee4 100644 --- a/src/wam_main.cc +++ b/src/wam_main.cc @@ -14,11 +14,9 @@ // // SPDX-License-Identifier: Apache-2.0 -#include - #include "web_runtime.h" -int main(int argc, const char** argv) { +int main(int argc, char** argv) { std::unique_ptr web_runtime(WebRuntime::Create()); return web_runtime->Run(argc, argv); } diff --git a/src/webos/web_app_manager_service_luna.cc b/src/webos/web_app_manager_service_luna.cc index 627cf31..b69635f 100644 --- a/src/webos/web_app_manager_service_luna.cc +++ b/src/webos/web_app_manager_service_luna.cc @@ -632,6 +632,7 @@ void WebAppManagerServiceLuna::GetForegroundAppInfoCallback( if (cleared_cache_) cleared_cache_ = false; +#if defined(OS_WEBOS) if (reply["returnValue"] == true) { if (reply.isMember("appId") && reply["appId"].isString()) { std::string appId = reply["appId"].asString(); @@ -639,6 +640,7 @@ void WebAppManagerServiceLuna::GetForegroundAppInfoCallback( WebAppManagerService::IsEnyoApp(appId.c_str())); } } +#endif } void WebAppManagerServiceLuna::BootdConnectCallback(const Json::Value& reply) { diff --git a/src/webos/web_runtime_webos.cc b/src/webos/web_runtime_webos.cc index 9dd2f72..cab7e5a 100644 --- a/src/webos/web_runtime_webos.cc +++ b/src/webos/web_runtime_webos.cc @@ -70,7 +70,7 @@ class WebOSMainDelegateWAM : public webos::WebOSMainDelegate { void AboutToCreateContentBrowserClient() override { StartWebAppManager(); } }; -int WebRuntimeWebOS::Run(int argc, const char** argv) { +int WebRuntimeWebOS::Run(int argc, char** argv) { WebOSMainDelegateWAM delegate; webos::WebOSMain webos_main(&delegate); return webOSMain.Run(argc, argv); diff --git a/src/webos/web_runtime_webos.h b/src/webos/web_runtime_webos.h index eb52348..fa031a2 100644 --- a/src/webos/web_runtime_webos.h +++ b/src/webos/web_runtime_webos.h @@ -21,7 +21,7 @@ class WebRuntimeWebOS : public WebRuntime { public: - int Run(int argc, const char** argv) override; + int Run(int argc, char** argv) override; }; #endif // WEBOS_WEB_RUNTIME_WEBOS_H_ -- 2.39.2