From: Hwankyu Jhun Date: Thu, 5 Sep 2019 09:25:39 +0000 (+0900) Subject: Support Seamless Effect X-Git-Tag: submit/tizen/20191014.064156~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74c1aee9b1f3c9312a0c0c9de49eaeec8c827c16;p=platform%2Fcore%2Fappfw%2Fwidget-viewer.git Support Seamless Effect Adds: - frame-broker - remote-frame Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/amd/+/212912/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/app-core/+/215390/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/aul-1/+/212287/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/screen-connector/+/212645/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/widget-viewer/+/213445/ Change-Id: I32cc20fdb9cbe42391e8e972aab8120fbba80238 Signed-off-by: Hwankyu Jhun --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 81e1ad22..37e9560c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,16 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) ADD_SUBDIRECTORY(widget_viewer_evas) ADD_SUBDIRECTORY(widget_viewer_sdk) ADD_SUBDIRECTORY(watch-control) +ADD_SUBDIRECTORY(frame-broker) +ADD_SUBDIRECTORY(remote-frame) ADD_SUBDIRECTORY(tool) ADD_SUBDIRECTORY(unittest) ADD_DEPENDENCIES(widget-viewer_unittests widget_viewer_evas) ADD_DEPENDENCIES(widget_viewer_sdk widget_viewer_evas) +ADD_DEPENDENCIES(remote-frame frame-broker) ENABLE_TESTING() SET(WIDGET_VIEWER_UNIT_TESTS widget-viewer_unittests) ADD_TEST(NAME ${WIDGET_VIEWER_UNIT_TESTS} COMMAND ${WIDGET_VIEWER_UNIT_TESTS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest) \ No newline at end of file + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest) diff --git a/frame-broker/CMakeLists.txt b/frame-broker/CMakeLists.txt new file mode 100644 index 00000000..b4f47626 --- /dev/null +++ b/frame-broker/CMakeLists.txt @@ -0,0 +1,62 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(frame-broker C) + +SET(PREFIX "${CMAKE_INSTALL_PREFIX}") +SET(PROJECT_NAME "${PROJECT_NAME}") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(VERSION_MAJOR "${MAJORVER}") +SET(VERSION "${FULLVER}") + +INCLUDE(FindPkgConfig) +pkg_check_modules(frame-broker REQUIRED + aul + capi-appfw-app-control + dlog + elementary + glib-2.0 + screen_connector_launcher_service_evas + uuid + bundle +) + +AUX_SOURCE_DIRECTORY(src SOURCES) + +FOREACH(flag ${frame-broker_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${frame-broker_LDFLAGS}) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc") + +SET(HEADERS_LIB_FRAME_BROKER + frame.h + frame_broker.h + frame_broker_internal.h + frame_context.h + frame_internal.h + frame_types.h + ) + +FOREACH(hfile ${HEADERS_LIB_FRAME_BROKER}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} + DESTINATION include/${PROJECT_NAME}) +ENDFOREACH(hfile) + +INSTALL(TARGETS ${PROJECT_NAME} + DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) diff --git a/frame-broker/frame-broker.pc.in b/frame-broker/frame-broker.pc.in new file mode 100644 index 00000000..51e4a2df --- /dev/null +++ b/frame-broker/frame-broker.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: launcher-service +Description: Support development of the launcher +Version: @VERSION@ +Requires: screen_connector_launcher_service_evas elementary capi-appfw-app-control +Libs: -L${libdir} -lframe-broker +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/frame-broker/include/frame.h b/frame-broker/include/frame.h new file mode 100644 index 00000000..fcf7e39c --- /dev/null +++ b/frame-broker/include/frame.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_H__ +#define __FRAME_H__ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The frame handle. + * @since_tizen 5.5 + */ +typedef struct frame_s *frame_h; + +/** + * @brief Enumeration for the frame type. + * @since_tizen 5.5 + */ +typedef enum { + FRAME_TYPE_REMOTE_SURFACE, /**< The remote surface */ + FRAME_TYPE_SPLASH_SCREEN, /**< The splash screen */ +} frame_type_e; + +/** + * @brief Enumeration for the direction of the frame. + * @since_tizen 5.5 + */ +typedef enum { + FRAME_DIRECTION_FORWARD, /**< The direction that is from the caller to the other application. */ + FRAME_DIRECTION_BACKWARD, /**< The direction that is from the other application to the caller. */ +} frame_direction_e; + +/** + * @brief Gets the raw handle of the frame. + * @since_tizen 5.5 + * @remarks Ths @a raw should not be released. + * + * @param[in] handle The frame handle + * @param[out] raw The evas object + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + */ +int frame_get_raw(frame_h handle, Evas_Object **raw); + +/** + * @brief Gets the type of the frame. + * @since_tizen 5.5 + * + * @param[in] handle The frame handle + * @param[out] type The type + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see frame_type_e + */ +int frame_get_type(frame_h handle, frame_type_e *type); + +/** + * @brief Gets the direction of the frame. + * @since_tizen 5.5 + * + * @param[in] handle The frame handle + * @param[out] direction The direction + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see frame_direction_e + */ +int frame_get_direction(frame_h handle, frame_direction_e *direction); + +/** + * @brief Gets the position X of the frame. + * @since_tizen 5.5 + * + * @param[in] handle The frame handle + * @param[out] x The position X + * @return @c 0 on success, + * otherwise a negative error valuea + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + */ +int frame_get_position_x(frame_h handle, int32_t *x); + +/** + * @brief Gets the position Y of the frame. + * @since_tizen 5.5 + * + * @param[in] handle The frame handle + * @param[out] y The position Y + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + */ +int frame_get_position_y(frame_h handle, int32_t *y); + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_H__ */ diff --git a/frame-broker/include/frame_broker.h b/frame-broker/include/frame_broker.h new file mode 100644 index 00000000..526c83ed --- /dev/null +++ b/frame-broker/include/frame_broker.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_BROKER_H__ +#define __FRAME_BROKER_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The frame broker handle. + * @since_tizen 5.5 + */ +typedef struct frame_broker_s *frame_broker_h; + +/** + * @brief Creates the frame broker handle. + * @since_tizen 5.5 + * @remarks The @a handle should be release using frame_broker_destroy() function. + * + * @param[in] win The evas object + * @param[in] callback The set of callback functions to handle frame context lifecycle events + * @param[in] user_data The user data to be passed to the callback functions + * @param[out] handle The frame broker handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FRAME_BROKER_ERROR_OUT_OF_MEMORY Out of memory + * @retval #FRAME_BROKER_ERROR_IO_ERROR I/O error + * + * @remarks This function is only available for platform level signed applications. + * + * @see frame_broker_destroy() + */ +int frame_broker_create(Evas_Object *win, + frame_context_lifecycle_callback_s *callback, + void *user_data, + frame_broker_h *handle); + +/** + * @brief Destroyes the frame broker handle. + * @since_tizen 5.5 + * + * @param[in] handle The frame broker handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + */ +int frame_broker_destroy(frame_broker_h handle); + +/** + * @brief Sends the launch request asynchronously. + * @since_tizen 5.5 + * + * @privlevel public + * @privilege %http:://tizen.org/privilege/appmanager.launch + * + * @param[in] handle The frame broker handle + * @param[in] app_control The app_control handle + * @param[in] result_cb The callback function to be called when the result is delivered + * @param[in] reply_cb The callback function to be called when the reply is delivered + * @param[in] uset_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_APP_NOT_FOUND The application to run the given launch request is not found + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FRAME_BROKER_ERROR_IO_ERROR I/O error + * @retval #FRAME_BROKER_ERROR_LAUNCH_REJECTED Failed to launch the application + * @retval #FRAME_BROKER_ERROR_PERMISSION_DENIED Permission denied + * + * @see app_control_send_launch_request_async() + * @see app_control_result_cb() + * @see app_control_reply_cb() + */ +int frame_broker_send_launch_request(frame_broker_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_BROKER_H__ */ diff --git a/frame-broker/include/frame_broker_internal.h b/frame-broker/include/frame_broker_internal.h new file mode 100644 index 00000000..7ff1ca4b --- /dev/null +++ b/frame-broker/include/frame_broker_internal.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_BROKER_INTERNAL_H__ +#define __FRAME_BROKER_INTERNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Sends the launch request to get the remote frame. + * @since_tizen 5.5 + * + * @param[in] handle The frame broker handle + * @param[in] app_control The app_control handle + * @param[in] result_cb The callback function to be called when the result is delivered + * @param[in] reply_cb The callback function to be called when the reply is delivered + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_APP_NOT_FOUND The application to run the given launch request is not found + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FRAME_BROKER_ERROR_IO_ERROR I/O error + * @retval #FRAME_BROKER_ERROR_LAUNCH_REJECTED Failed to launch the application + * @retval #FRAME_BROKER_ERROR_PERMISSION_DENIED Permission denied + */ +int frame_broker_send_launch_request_for_remote_frame(frame_broker_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_BROKER_INTERNAL_H__ */ diff --git a/frame-broker/include/frame_context.h b/frame-broker/include/frame_context.h new file mode 100644 index 00000000..f73d6c41 --- /dev/null +++ b/frame-broker/include/frame_context.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_CONTEXT_H__ +#define __FRAME_CONTEXT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The frame context handle. + * @since_tizen 5.5 + */ +typedef struct frame_context_s *frame_context_h; + +/** + * @brief Enumeration for the frame context errors. + * @since_tizen 5.5 + */ +typedef enum { + FRAME_CONTEXT_ERROR_NONE, /**< Successful */ + FRAME_CONTEXT_ERROR_DISQUALIFIED, /**< Disqualified */ + FRAME_CONTEXT_ERROR_WRONG_REQUEST, /**< Wrong request */ +} frame_context_error_e; + +/** + * @brief Called when the frame context is created. + * @since_tizen 5.5 + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] user_data The user data passed from frame_broker_create() function + */ +typedef void (*frame_context_create_cb)(frame_context_h context, + void *user_data); + +/** + * @brief Called when the frame context is resumed. + * @since_tizen 5.5 + * @details When the frame has been prepared, this callback function is called. + * The caller can start animations. To notify that the animation is started, the caller should call frame_context_start_animation() function. + * After the animation is finished, the caller should call frame_context_finish_animation() function to notify. + * @remarks The @a context and the @a frame should not be released. The @a context and the @a frame can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] frame The frame handle + * @param[in] user_data The user data passed from frame_broker_create() function + * + * @see frame_context_start_animation() + * @see frame_context_finish_animation() + */ +typedef void (*frame_context_resume_cb)(frame_context_h context, + frame_h frame, + void *user_data); +/** + * @brief Called when the frame context is paused. + * @since_tizen 5.5 + * @details When the animation has been finished, this callback function is called. + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] user_data The user data passed from frame_broker_create() function + */ +typedef void (*frame_context_pause_cb)(frame_context_h context, + void *user_data); + +/** + * @brief Called when the frame context is destroyed. + * @since_tizen 5.5 + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] user_data The user data passed from frame_broker_create() function + */ +typedef void (*frame_context_destroy_cb)(frame_context_h context, + void *user_data); + +/** + * @brief Called when the error is occurred. + * @since_tizen 5.5 + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] error The error + * @param[in] user_data The user data passed from frame_broker_create() function + * + * @see frame_context_error_e + */ +typedef void (*frame_context_error_cb)(frame_context_h context, + frame_context_error_e error, + void *user_data); + +/** + * @brief Called when the frame context is updated. + * @since_tizen 5.5 + * @details When the frame has been updated, this callback function is called. + * @remarks The @a context and the @a frame should not be released. The @a context and the @a frame can be used only in the callback. + * + * @param[in] context The frame context handle + * @param[in] frame The frame handle + * @param[in] user_data The user data passed from frame_broker_create() function + * + * @see frame_context_resume_cb() + * @see frame_context_start_animation() + * @see frame_context_finish_animation() + */ +typedef void (*frame_context_update_cb)(frame_context_h context, + frame_h frame, + void *user_data); + +/** + * @brief The structure type containing the set of callback functions for lifecycle of a frame context. + * @since_tizen 5.5 + * + * @see frame_broker_create() + * @see frame_context_create_cb() + * @see frame_context_resume_cb() + * @see frame_context_pause_cb() + * @see frame_context_destroy_cb() + * @see frame_context_error_cb() + */ +typedef struct { + frame_context_create_cb create; /**< The callback function called after the frame context is created. */ + frame_context_resume_cb resume; /**< The callback function called when the frame is prepared. */ + frame_context_pause_cb pause; /**< The callback function called when the animation is finished. */ + frame_context_destroy_cb destroy; /**< The callback function called before the frame context is destroyed. */ + frame_context_update_cb update; /**< The callback function called when the frame is updated. */ + frame_context_error_cb error; /**< The callback function called when the error is occurred. */ +} frame_context_lifecycle_callback_s; + +/** + * @brief Notifies that the animation is started. + * @since_tizen 5.5 + * + * @param[in] handle The frame context handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FRAME_BROKER_ERROR_IO_ERROR I/O error + * + * @see frame_context_finish_animation() + */ +int frame_context_start_animation(frame_context_h handle); + +/** + * @brief Notifies that the animation is finished. + * @since_tizen 5.5 + * + * @param[in] handle The frame context handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FRAME_BROKER_ERROR_IO_ERROR I/O error + * + * @see frame_context_start_animation() + */ +int frame_context_finish_animation(frame_context_h handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_CONTEXT_H__ */ diff --git a/frame-broker/include/frame_internal.h b/frame-broker/include/frame_internal.h new file mode 100644 index 00000000..dcb4a5e7 --- /dev/null +++ b/frame-broker/include/frame_internal.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_INTERNAL_H__ +#define __FRAME_INTERNAL_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Gets the extra data of the frame. + * @since_tizen 5.5 + * @remarks The @a extra_data should not be released. + * + * @param[in] handle The frame handle + * @param[out] extra_data The bundle object + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #FRAME_BROKER_ERROR_NONE Successful + * @retval #FRAME_BROKER_ERROR_INVALID_PARAMETER Invalid parameter + */ +int frame_get_extra_data(frame_h handle, bundle **extra_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_INTERNAL_H__ */ diff --git a/frame-broker/include/frame_types.h b/frame-broker/include/frame_types.h new file mode 100644 index 00000000..868f07e6 --- /dev/null +++ b/frame-broker/include/frame_types.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_BROKER_TYPES_H__ +#define __FRAME_BROKER_TYPES_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration for frame broker error. + * @since_tizen 5.5 + */ +typedef enum { + FRAME_BROKER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + FRAME_BROKER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + FRAME_BROKER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + FRAME_BROKER_ERROR_APP_NOT_FOUND = APP_CONTROL_ERROR_APP_NOT_FOUND, /**< The application is not found */ + FRAME_BROKER_ERROR_LAUNCH_REJECTED = APP_CONTROL_ERROR_LAUNCH_REJECTED, /**< Launch rejected */ + FRAME_BROKER_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + FRAME_BROKER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ +} frame_broker_error_e; + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAME_BROKER_TYPES_H__ */ diff --git a/frame-broker/src/frame.c b/frame-broker/src/frame.c new file mode 100644 index 00000000..1fc0aeb9 --- /dev/null +++ b/frame-broker/src/frame.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "frame.h" +#include "frame_internal.h" +#include "frame_private.h" +#include "log_private.h" +#include "private.h" + +struct frame_s { + Evas_Object *raw; + frame_type_e type; + frame_direction_e direction; + int32_t x; + int32_t y; + bundle *extra_data; +}; + +static frame_type_e __convert_type( + screen_connector_launcher_service_evas_image_type_e type) +{ + switch (type) { + case SCREEN_CONNECTOR_LAUNCHER_SERVICE_EVAS_IMAGE_TYPE_REMOTE_SURFACE_TBM: + case SCREEN_CONNECTOR_LAUNCHER_SERVICE_EVAS_IMAGE_TYPE_REMOTE_SURFACE_IMAGE_FILE: + return FRAME_TYPE_REMOTE_SURFACE; + default: + return FRAME_TYPE_SPLASH_SCREEN; + } +} + +static frame_direction_e __convert_direction( + screen_connector_launcher_service_evas_direction_e direction) +{ + if (direction == SCREEN_CONNECTOR_LAUNCHER_SERVICE_EVAS_DIRECTION_FORWARD) + return FRAME_DIRECTION_FORWARD; + + return FRAME_DIRECTION_BACKWARD; +} + +int frame_create(Evas_Object *image, + screen_connector_launcher_service_evas_image_type_e type, + screen_connector_launcher_service_evas_direction_e direction, + int32_t x, + int32_t y, + const char *shared_widget_info, + frame_h *handle) +{ + struct frame_s *frame; + + if (!image || !handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + frame = calloc(1, sizeof(struct frame_s)); + if (!frame) { + _E("Out of memory"); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + _D("shared_widget_info(%s)", shared_widget_info); + if (shared_widget_info && shared_widget_info[0] != '\0' && + strcmp(shared_widget_info, "None") != 0) { + frame->extra_data = bundle_decode( + (bundle_raw *)shared_widget_info, + strlen(shared_widget_info)); + } else { + frame->extra_data = bundle_create(); + } + + if (!frame->extra_data) { + _E("Failed to create extra data"); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + frame->raw = image; + frame->type = __convert_type(type); + frame->direction = __convert_direction(direction); + frame->x = x; + frame->y = y; + + *handle = frame; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_destroy(frame_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + bundle_free(handle->extra_data); + free(handle); + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_raw(frame_h handle, Evas_Object **raw) +{ + if (!handle || !raw) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *raw = handle->raw; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_type(frame_h handle, frame_type_e *type) +{ + if (!handle || !type) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *type = handle->type; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_direction(frame_h handle, frame_direction_e *direction) +{ + if (!handle || !direction) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *direction = handle->direction; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_position_x(frame_h handle, int32_t *x) +{ + if (!handle || !x) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *x = handle->x; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_position_y(frame_h handle, int32_t *y) +{ + if (!handle || !y) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *y = handle->y; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_get_extra_data(frame_h handle, bundle **extra_data) +{ + if (!handle || !extra_data) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *extra_data = handle->extra_data; + + return FRAME_BROKER_ERROR_NONE; +} diff --git a/frame-broker/src/frame_broker.c b/frame-broker/src/frame_broker.c new file mode 100644 index 00000000..5dbb44b1 --- /dev/null +++ b/frame-broker/src/frame_broker.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "frame_broker.h" +#include "frame_broker_internal.h" +#include "frame_broker_private.h" +#include "frame_context_private.h" +#include "frame_private.h" +#include "log_private.h" +#include "private.h" + +struct frame_broker_s { + char *name; + Evas_Object *win; + frame_context_lifecycle_callback_s callback; + void *user_data; + aul_launcher_service_h als; + screen_connector_launcher_service_evas_h scls_evas; + frame_context_h context; +}; + +static GList *__win_list; + +static gint __compare_win(gconstpointer a, gconstpointer b) +{ + Evas_Object *win_a = (Evas_Object *)a; + Evas_Object *win_b = (Evas_Object *)b; + + return win_a != win_b; +} + +static bool __exist_win(Evas_Object *win) +{ + GList *found; + + found = g_list_find_custom(__win_list, win, __compare_win); + if (found) + true; + + return false; +} + +static void __add_win(Evas_Object *win) +{ + __win_list = g_list_append(__win_list, win); +} + +static void __remove_win(Evas_Object *win) +{ + __win_list = g_list_remove(__win_list, win); +} + +static char *__generate_uuid(void) +{ + char uuid[37]; + uuid_t u; + + uuid_generate(u); + uuid_unparse(u, uuid); + return strdup(uuid); +} + +static uint32_t __generate_serial(void) +{ + static gint serial; + + g_atomic_int_inc(&serial); + + return (uint32_t)serial; +} + +static void __aul_launcher_service_cb(const char *app_id, + const char *inst_id, + const int pid, + const uint32_t serial, + void *user_data) +{ + frame_broker_h broker = user_data; + frame_context_h context; + int ret; + + _D("app_id(%s), inst_id(%s), pid(%d), serial(%u)", + app_id, inst_id, pid, serial); + ret = frame_context_create(broker, app_id, inst_id, pid, serial, + &broker->callback, broker->user_data, + &context); + if (ret != FRAME_BROKER_ERROR_NONE) { + _E("Failed to create frame context. error(%d)", ret); + return; + } + + if (broker->context) { + _D("Destroy previous context"); + frame_context_destroy(broker->context); + } + + broker->context = context; + frame_context_on_create(context); +} + +static void __scls_evas_prepare_cb(Evas_Object *image, + screen_connector_launcher_service_evas_image_type_e type, + screen_connector_launcher_service_evas_direction_e direction, + int32_t x, + int32_t y, + const char *shared_widget_info, + uint32_t serial, + void *user_data) +{ + frame_broker_h broker = user_data; + frame_context_h context = broker->context; + frame_h frame; + int ret; + + _D("[__SCLS_EVAS__] Prepare"); + if (context == NULL) { + _E("Invalid context"); + return; + } + + frame_context_set_serial(context, serial); + + ret = frame_create(image, type, direction, x, y, + shared_widget_info, &frame); + if (ret != FRAME_BROKER_ERROR_NONE) { + _E("Failed to create frame. error(%d)", ret); + frame_context_on_error(context, + FRAME_CONTEXT_ERROR_WRONG_REQUEST); + return; + } + + frame_context_on_resume(context, frame); +} + +static void __scls_evas_stop_cb(uint32_t serial, void *user_data) +{ + frame_broker_h broker = user_data; + frame_context_h context = broker->context; + frame_direction_e direction; + frame_h frame; + int ret; + + _D("[__SCLS_EVAS__] Stop"); + if (context == NULL) { + _E("Invalid context"); + return; + } + + frame_context_on_pause(context); + + ret = frame_context_get_frame(context, &frame); + if (ret != FRAME_BROKER_ERROR_NONE) { + _W("Failed to get frame"); + return; + } + + ret = frame_get_direction(frame, &direction); + if ((ret == FRAME_BROKER_ERROR_NONE && + direction == FRAME_DIRECTION_BACKWARD) || + frame == NULL) { + _D("Destroy context"); + frame_context_destroy(context); + } +} + +static frame_context_error_e __convert_error( + screen_connector_launcher_service_evas_error_e error) +{ + switch (error) { + case SCREEN_CONNECTOR_LAUNCHER_SERVICE_EVAS_ERROR_DISQUALIFIED: + return FRAME_CONTEXT_ERROR_DISQUALIFIED; + case SCREEN_CONNECTOR_LAUNCHER_SERVICE_EVAS_ERROR_WRONG_REQUEST: + return FRAME_CONTEXT_ERROR_WRONG_REQUEST; + default: + return FRAME_CONTEXT_ERROR_NONE; + } +} + +static void __scls_evas_error_cb( + screen_connector_launcher_service_evas_error_e error, + uint32_t serial, + void *user_data) +{ + frame_broker_h broker = user_data; + frame_context_h context = broker->context; + + _D("[__SCLS_EVAS__] Error"); + if (context == NULL) { + _E("Invalid context"); + return; + } + + frame_context_on_error(context, __convert_error(error)); +} + +static void __scls_evas_cleanup_cb(uint32_t serial, void *user_data) +{ + _D("[__SCLS_EVAS__] Clean Up"); + __scls_evas_stop_cb(serial, user_data); +} + +API int frame_broker_create(Evas_Object *win, + frame_context_lifecycle_callback_s *callback, + void *user_data, + frame_broker_h *handle) +{ + screen_connector_launcher_service_evas_h scls_evas; + screen_connector_launcher_service_evas_ops ops = { + .prepare = __scls_evas_prepare_cb, + .stop = __scls_evas_stop_cb, + .error = __scls_evas_error_cb, + .cleanup = __scls_evas_cleanup_cb + }; + struct frame_broker_s *broker; + int ret; + + if (!win || !callback || !handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + if (!callback->create || !callback->resume || + !callback->pause || !callback->destroy || + !callback->update || !callback->error) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + if (__exist_win(win)) { + _E("Already exists. win(%p)", win); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + broker = calloc(1, sizeof(struct frame_broker_s)); + if (!broker) { + _E("Out of memory"); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + broker->name = __generate_uuid(); + if (!broker->name) { + _E("Failed to generate uuid"); + frame_broker_destroy(broker); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + ret = aul_launcher_service_create(broker->name, + __aul_launcher_service_cb, + broker, &broker->als); + if (ret != AUL_R_OK) { + _E("Failed to create aul launcher service. error(%d)", ret); + frame_broker_destroy(broker); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + ret = aul_launcher_service_listen(broker->als); + if (ret != AUL_R_OK) { + _E("Failed to listen aul launcher service. error(%d)", ret); + frame_broker_destroy(broker); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + ret = screen_connector_launcher_service_evas_create(win, &scls_evas); + if (ret != 0) { + _E("Failed to create scls evas. error(%d)", ret); + frame_broker_destroy(broker); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + screen_connector_launcher_service_evas_set_ops(scls_evas, &ops, + broker); + + broker->scls_evas = scls_evas; + broker->win = win; + broker->callback = *callback; + broker->user_data = user_data; + + __add_win(win); + + *handle = broker; + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_broker_destroy(frame_broker_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + __remove_win(handle->win); + + if (handle->context) + frame_context_destroy(handle->context); + + screen_connector_launcher_service_evas_destroy(handle->scls_evas); + aul_launcher_service_destroy(handle->als); + free(handle->name); + free(handle); + + return FRAME_BROKER_ERROR_NONE; +} + +static int __send_launch_request(frame_broker_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data, + bool shared_widget) +{ + aul_running_context_h context = NULL; + char buf[12]; + uint32_t serial; + char *app_id; + char *inst_id = NULL; + char *comp_id = NULL; + int pid = -1; + int ret; + + if (!handle || !app_control || !result_cb) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + ret = app_control_get_app_id(app_control, &app_id); + if (ret != APP_CONTROL_ERROR_NONE) { + _E("Failed to get app id. error(%d)", ret); + return ret; + } + + app_control_get_component_id(app_control, &comp_id); + app_control_get_instance_id(app_control, &inst_id); + + ret = aul_running_context_create(app_id, comp_id, inst_id, &context); + if (ret != AUL_R_OK) + _W("Failed to create running context. error(%d)", ret); + + free(comp_id); + free(inst_id); + inst_id = NULL; + + aul_running_context_get_inst_id(context, (const char **)&inst_id); + aul_running_context_get_pid(context, &pid); + + if (shared_widget) { + ret = frame_broker_launch_with_shared_widget(handle, app_id, + inst_id, pid, &serial); + } else { + ret = frame_broker_launch(handle, app_id, inst_id, pid, + &serial); + } + aul_running_context_destroy(context); + free(app_id); + if (ret != FRAME_BROKER_ERROR_NONE) + return ret; + + snprintf(buf, sizeof(buf), "%u", serial); + ret = app_control_add_extra_data(app_control, + AUL_K_LAUNCHER_SERVICE_SERIAL, buf); + if (ret != APP_CONTROL_ERROR_NONE) { + _E("Failed to add extra data. error(%d)", ret); + return ret; + } + + ret = app_control_add_extra_data(app_control, + AUL_K_LAUNCHER_SERVICE, handle->name); + if (ret != APP_CONTROL_ERROR_NONE) { + _E("Failed to add extra data. error(%d)", ret); + return ret; + } + + ret = app_control_send_launch_request_async(app_control, + result_cb, reply_cb, user_data); + if (ret != APP_CONTROL_ERROR_NONE) { + _E("Failed to send launch request. error(%d)", ret); + return ret; + } + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_broker_send_launch_request(frame_broker_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data) +{ + return __send_launch_request(handle, app_control, result_cb, reply_cb, + user_data, false); +} + +API int frame_broker_send_launch_request_for_remote_frame( + frame_broker_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data) +{ + return __send_launch_request(handle, app_control, result_cb, reply_cb, + user_data, true); +} + +void frame_broker_set_frame_context(frame_broker_h handle, + frame_context_h context) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + handle->context = context; +} + +int frame_broker_launch(frame_broker_h handle, const char *app_id, + const char *inst_id, int pid, uint32_t *serial) +{ + int ret; + + if (!handle || !app_id || pid < -1 || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *serial = __generate_serial(); + ret = screen_connector_launcher_service_evas_launch(handle->scls_evas, + app_id, inst_id ? inst_id : "", pid, *serial); + if (ret != 0) { + _E("Failed to launch scls evas. error(%d)", ret); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_broker_launch_with_shared_widget(frame_broker_h handle, + const char *app_id, const char *inst_id, int pid, + uint32_t *serial) +{ + int ret; + + if (!handle || !app_id || pid < -1 || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *serial = __generate_serial(); + ret = screen_connector_launcher_service_evas_launch_with_shared_widget( + handle->scls_evas, app_id, + inst_id ? inst_id : "", pid, *serial); + if (ret != 0) { + _E("Failed to launch scls evas with shared widget. error(%d)", + ret); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_broker_launching(frame_broker_h handle, uint32_t serial) +{ + int ret; + + if (!handle || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + ret = screen_connector_launcher_service_evas_launching( + handle->scls_evas, serial); + if (ret != 0) { + _E("Failed to notify that the animation has been started"); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_broker_launch_cancel(frame_broker_h handle, uint32_t serial) +{ + int ret; + + if (!handle || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + ret = screen_connector_launcher_service_evas_launch_cancel( + handle->scls_evas, serial); + if (ret != 0) { + _E("Failed to notify that the animation has been canceled."); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_broker_launch_done(frame_broker_h handle, uint32_t serial) +{ + int ret; + + if (!handle || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + ret = screen_connector_launcher_service_evas_launch_done( + handle->scls_evas, serial); + if (ret != 0) { + _E("Failed to notify that the animation has been finished."); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} diff --git a/frame-broker/src/frame_broker_private.h b/frame-broker/src/frame_broker_private.h new file mode 100644 index 00000000..285860c8 --- /dev/null +++ b/frame-broker/src/frame_broker_private.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_BROKER_PRIVATE_H__ +#define __FRAME_BROKER_PRIVATE_H__ + +#include + +#include "frame_broker.h" + +void frame_broker_set_frame_context(frame_broker_h handle, + frame_context_h context); + +int frame_broker_launch(frame_broker_h handle, const char *app_id, + const char *inst_id, int pid, uint32_t *serial); + +int frame_broker_launch_with_shared_widget(frame_broker_h handle, + const char *app_id, const char *inst_id, int pid, + uint32_t *serial); + +int frame_broker_launching(frame_broker_h handle, uint32_t serial); + +int frame_broker_launch_cancel(frame_broker_h handle, uint32_t serial); + +int frame_broker_launch_done(frame_broker_h handle, uint32_t serial); + +#endif /* __FRAME_BROKER_PRIVATE_H__ */ diff --git a/frame-broker/src/frame_context.c b/frame-broker/src/frame_context.c new file mode 100644 index 00000000..ba72b841 --- /dev/null +++ b/frame-broker/src/frame_context.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "frame_broker.h" +#include "frame_broker_private.h" +#include "frame_context.h" +#include "frame_context_private.h" +#include "frame_private.h" +#include "log_private.h" +#include "private.h" + +struct frame_context_s { + frame_broker_h broker; + frame_context_state_e state; + frame_context_lifecycle_callback_s callback; + void *user_data; + guint idle_tag; + char *app_id; + char *inst_id; + int pid; + bool started; + uint32_t serial; + frame_h prev_frame; + frame_h curr_frame; +}; + +int frame_context_create(frame_broker_h broker, + const char *app_id, + const char *inst_id, + int pid, + uint32_t serial, + frame_context_lifecycle_callback_s *callback, + void *user_data, + frame_context_h *handle) +{ + struct frame_context_s *context; + + if (!broker || !app_id || !inst_id || pid < 1 || !callback || !handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + context = calloc(1, sizeof(struct frame_context_s)); + if (!context) { + _E("Out of memory"); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + context->app_id = strdup(app_id); + if (!context->app_id) { + _E("Failed to duplicate application ID"); + frame_context_destroy(context); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + context->inst_id = strdup(inst_id); + if (!context->inst_id) { + _E("Failed to duplicate instance ID"); + frame_context_destroy(context); + return FRAME_BROKER_ERROR_OUT_OF_MEMORY; + } + + context->broker = broker; + context->state = FRAME_CONTEXT_STATE_NONE; + context->pid = pid; + context->serial = serial; + context->callback = *callback; + context->user_data = user_data; + + *handle = context; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_destroy(frame_context_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + frame_broker_set_frame_context(handle->broker, NULL); + + if (handle->idle_tag) + g_source_remove(handle->idle_tag); + + frame_context_on_pause(handle); + frame_context_on_destroy(handle); + + if (handle->prev_frame) + frame_destroy(handle->prev_frame); + + if (handle->curr_frame) + frame_destroy(handle->curr_frame); + + free(handle->inst_id); + free(handle->app_id); + free(handle); + + return FRAME_BROKER_ERROR_NONE; +} + +API int frame_context_start_animation(frame_context_h handle) +{ + int ret; + + if (!handle || !handle->serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + if (handle->started) { + _W("Already started"); + return FRAME_BROKER_ERROR_NONE; + } + + ret = frame_broker_launching(handle->broker, handle->serial); + if (ret != 0) { + _E("Failed to notify that the animation is started. error(%d)", + ret); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + handle->started = true; + + return FRAME_BROKER_ERROR_NONE; +} + +static gboolean __context_destroy_cb(gpointer data) +{ + frame_context_h context = data; + + context->idle_tag = 0; + frame_context_destroy(context); + + return G_SOURCE_REMOVE; +} + +static gboolean __context_pause_cb(gpointer data) +{ + frame_context_h context = data; + frame_direction_e direction; + + context->idle_tag = 0; + frame_context_on_pause(context); + + frame_get_direction(context->curr_frame, &direction); + if (direction == FRAME_DIRECTION_BACKWARD) { + _D("frame_context_destroy()"); + frame_context_destroy(context); + } + + return G_SOURCE_REMOVE; +} + +API int frame_context_finish_animation(frame_context_h handle) +{ + int ret = 0; + + if (!handle || !handle->serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + if (handle->started) { + ret = frame_broker_launch_done(handle->broker, handle->serial); + handle->started = false; + if (!handle->idle_tag) { + handle->idle_tag = g_idle_add(__context_pause_cb, + handle); + } + } else { + ret = frame_broker_launch_cancel(handle->broker, + handle->serial); + if (!handle->idle_tag) { + handle->idle_tag = g_idle_add(__context_destroy_cb, + handle); + } + } + + if (ret != 0) { + _E("Failed to notify that the animation is finished. error(%d)", + ret); + return FRAME_BROKER_ERROR_IO_ERROR; + } + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_set_serial(frame_context_h handle, uint32_t serial) +{ + if (!handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + _D("serial(%u) is changed to %u", handle->serial, serial); + handle->serial = serial; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_get_serial(frame_context_h handle, uint32_t *serial) +{ + if (!handle || !serial) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *serial = handle->serial; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_set_frame(frame_context_h handle, frame_h frame) +{ + if (!handle || !frame) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + if (handle->prev_frame) + frame_destroy(handle->prev_frame); + + handle->prev_frame = handle->curr_frame; + handle->curr_frame = frame; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_get_frame(frame_context_h handle, frame_h *frame) +{ + if (!handle || !frame) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *frame = handle->curr_frame; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_set_state(frame_context_h handle, + frame_context_state_e state) +{ + if (!handle) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + handle->state = state; + + return FRAME_BROKER_ERROR_NONE; +} + +int frame_context_get_state(frame_context_h handle, + frame_context_state_e *state) +{ + if (!handle || !state) { + _E("Invalid parameter"); + return FRAME_BROKER_ERROR_INVALID_PARAMETER; + } + + *state = handle->state; + + return FRAME_BROKER_ERROR_NONE; +} + +void frame_context_on_create(frame_context_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + if (handle->state != FRAME_CONTEXT_STATE_NONE) + return; + + handle->callback.create(handle, handle->user_data); + handle->state = FRAME_CONTEXT_STATE_CREATED; +} + +void frame_context_on_resume(frame_context_h handle, frame_h frame) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + frame_context_set_frame(handle, frame); + + if (handle->state == FRAME_CONTEXT_STATE_RESUMED) { + handle->callback.update(handle, frame, handle->user_data); + return; + } + + if (handle->state != FRAME_CONTEXT_STATE_CREATED && + handle->state != FRAME_CONTEXT_STATE_PAUSED) + return; + + handle->callback.resume(handle, frame, handle->user_data); + handle->state = FRAME_CONTEXT_STATE_RESUMED; +} + +void frame_context_on_pause(frame_context_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + if (handle->state != FRAME_CONTEXT_STATE_RESUMED) + return; + + handle->callback.pause(handle, handle->user_data); + handle->state = FRAME_CONTEXT_STATE_PAUSED; +} + +void frame_context_on_destroy(frame_context_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + if (handle->state == FRAME_CONTEXT_STATE_NONE) + return; + + handle->callback.destroy(handle, handle->user_data); + handle->state = FRAME_CONTEXT_STATE_DESTROYED; +} + +void frame_context_on_error(frame_context_h handle, frame_context_error_e error) +{ + if (!handle) { + _E("Invalid parameter"); + return; + } + + handle->callback.error(handle, error, handle->user_data); +} diff --git a/frame-broker/src/frame_context_private.h b/frame-broker/src/frame_context_private.h new file mode 100644 index 00000000..e4e6aef0 --- /dev/null +++ b/frame-broker/src/frame_context_private.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_CONTEXT_INTERNAL_H__ +#define __FRAME_CONTEXT_INTERNAL_H__ + +#include + +#include "frame_broker.h" +#include "frame_context.h" + +typedef enum { + FRAME_CONTEXT_STATE_NONE, + FRAME_CONTEXT_STATE_CREATED, + FRAME_CONTEXT_STATE_RESUMED, + FRAME_CONTEXT_STATE_PAUSED, + FRAME_CONTEXT_STATE_DESTROYED, +} frame_context_state_e; + +int frame_context_create(frame_broker_h broker, + const char *app_id, + const char *inst_id, + int pid, + uint32_t serial, + frame_context_lifecycle_callback_s *callback, + void *user_data, + frame_context_h *handle); + +int frame_context_destroy(frame_context_h handle); + +int frame_context_set_serial(frame_context_h handle, uint32_t serial); + +int frame_context_get_serial(frame_context_h handle, uint32_t *serial); + +int frame_context_set_frame(frame_context_h handle, frame_h frame); + +int frame_context_get_frame(frame_context_h handle, frame_h *frame); + +int frame_context_set_state(frame_context_h handle, + frame_context_state_e state); + +int frame_context_get_state(frame_context_h handle, + frame_context_state_e *state); + +void frame_context_on_create(frame_context_h handle); + +void frame_context_on_resume(frame_context_h handle, frame_h frame); + +void frame_context_on_pause(frame_context_h handle); + +void frame_context_on_destroy(frame_context_h handle); + +void frame_context_on_error(frame_context_h handle, + frame_context_error_e error); + +#endif /* __FRAME_CONTEXT_INTERNAL_H__ */ diff --git a/frame-broker/src/frame_private.h b/frame-broker/src/frame_private.h new file mode 100644 index 00000000..7ec720e3 --- /dev/null +++ b/frame-broker/src/frame_private.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FRAME_INTERNAL_H__ +#define __FRAME_INTERNAL_H__ + +#include + +#include "frame.h" + +int frame_create(Evas_Object *image, + screen_connector_launcher_service_evas_image_type_e type, + screen_connector_launcher_service_evas_direction_e direction, + int32_t x, + int32_t y, + const char *shared_widget_info, + frame_h *handle); + +int frame_destroy(frame_h handle); + +#endif /* __FRAME_INTERNAL_H__ */ diff --git a/frame-broker/src/log_private.h b/frame-broker/src/log_private.h new file mode 100644 index 00000000..add563ce --- /dev/null +++ b/frame-broker/src/log_private.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOG_PRIVATE_H__ +#define __LOG_PRIVATE_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "FRAME_BROKER" + +#ifdef _E +#undef _E +#endif +#define _E LOGE + +#ifdef _W +#undef _W +#endif +#define _W LOGW + +#ifdef _I +#undef _I +#endif +#define _I LOGI + +#ifdef _D +#undef _D +#endif +#define _D LOGD + +#endif /* __LOG_PRIVATE_H__ */ diff --git a/frame-broker/src/private.h b/frame-broker/src/private.h new file mode 100644 index 00000000..67435919 --- /dev/null +++ b/frame-broker/src/private.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PRIVATE_H__ +#define __PRIVATE_H__ + +#ifdef API +#undef API +#endif +#define API __attribute__((visibility("default"))) + +#endif /* __PRIVATE_H__ */ diff --git a/packaging/frame-broker.manifest b/packaging/frame-broker.manifest new file mode 100644 index 00000000..a76fdbae --- /dev/null +++ b/packaging/frame-broker.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libwidget_viewer.spec b/packaging/libwidget_viewer.spec index 8072680c..8a2c519d 100644 --- a/packaging/libwidget_viewer.spec +++ b/packaging/libwidget_viewer.spec @@ -10,6 +10,8 @@ Source0: %{name}-%{version}.tar.gz Source1001: %{name}_evas.manifest Source1003: org.tizen.widget_viewer_sdk.manifest Source1004: watch-control.manifest +Source1005: frame-broker.manifest +Source1006: remote-frame.manifest BuildRequires: cmake, gettext-tools, coreutils, edje-bin BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(aul) @@ -35,6 +37,8 @@ BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(screen_connector_watcher_evas) BuildRequires: pkgconfig(capi-system-device) BuildRequires: pkgconfig(gmock) +BuildRequires: pkgconfig(screen_connector_launcher_service_evas) +BuildRequires: pkgconfig(screen_connector_shared_widget_launch) %if 0%{?gcov:1} BuildRequires: lcov BuildRequires: zip @@ -48,6 +52,8 @@ API for creating a new instance of the widget and managing its life-cycle. cp %{SOURCE1001} . cp %{SOURCE1003} . cp %{SOURCE1004} . +cp %{SOURCE1005} . +cp %{SOURCE1006} . %build %if 0%{?gcov:1} @@ -180,6 +186,55 @@ Header & package configuration of watch-control %post -n watch-control -p /sbin/ldconfig %postun -n watch-control -p /sbin/ldconfig +################################################ +# libframe-broker +################################################ +%package -n frame-broker +Summary: APIs to handle launching images for the launcher +Version: 0.0.1 +License: Apache-2.0 +Group: Applications/Core Applications + +%description -n frame-broker +A set of APIs to handle launching images for the launcher + +%package -n frame-broker-devel +Summary: APIs to handle launching images for the launcher +Group: Development/Libraries +Requires: frame-broker + +%description -n frame-broker-devel +Header & package configuration of launcher service + +%post -n frame-broker -p /sbin/ldconfig +%postun -n frame-broker -p /sbin/ldconfig + +################################################ +# libremote-frame +################################################ +%package -n remote-frame +Summary: APIs to handle launching images for remote frame +Version: 0.0.1 +License: Apache-2.0 +Group: Applications/Core Applications + +%description -n remote-frame +A set of APIs to handle launching images for remote frame + +%package -n remote-frame-devel +Summary: APIs to handle remote frame +Group: Development/Libraries +Requires: remote-frame + +%description -n remote-frame-devel +Header & package configuration for remote frame + +%post -n remote-frame -p /sbin/ldconfig +%postun -n remote-frame -p /sbin/ldconfig + +################################################ +# files +################################################ %files -n %{name}_evas %manifest %{name}_evas.manifest %attr(0644,root,root) %{_libdir}/%{name}_evas.so.* @@ -211,5 +266,22 @@ Header & package configuration of watch-control %{_libdir}/pkgconfig/watch-control.pc %{_libdir}/libwatch-control.so +%files -n frame-broker +%manifest frame-broker.manifest +%{_libdir}/libframe-broker.so.* + +%files -n frame-broker-devel +%{_includedir}/frame-broker/*.h +%{_libdir}/pkgconfig/frame-broker.pc +%{_libdir}/libframe-broker.so + +%files -n remote-frame +%manifest remote-frame.manifest +%{_libdir}/libremote-frame.so.* + +%files -n remote-frame-devel +%{_includedir}/remote-frame/*.h +%{_libdir}/pkgconfig/remote-frame.pc +%{_libdir}/libremote-frame.so # End of a file diff --git a/packaging/remote-frame.manifest b/packaging/remote-frame.manifest new file mode 100644 index 00000000..a76fdbae --- /dev/null +++ b/packaging/remote-frame.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/remote-frame/CMakeLists.txt b/remote-frame/CMakeLists.txt new file mode 100644 index 00000000..1c1b3895 --- /dev/null +++ b/remote-frame/CMakeLists.txt @@ -0,0 +1,61 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(remote-frame C) + +SET(PREFIX "${CMAKE_INSTALL_PREFIX}") +SET(PROJECT_NAME "${PROJECT_NAME}") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(VERSION_MAJOR "${MAJORVER}") +SET(VERSION "${FULLVER}") + +INCLUDE(FindPkgConfig) +pkg_check_modules(remote-frame REQUIRED + aul + bundle + capi-appfw-app-control + dlog + elementary + glib-2.0 + screen_connector_shared_widget_launch +) + +AUX_SOURCE_DIRECTORY(src SOURCES) + +FOREACH(flag ${remote-frame_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../frame-broker/include) + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${remote-frame_LDFLAGS} frame-broker) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc") + +SET(HEADERS_LIB_REMOTE_FRAME + remote_frame.h + remote_frame_consumer.h + remote_frame_context.h + remote_frame_provider.h + remote_frame_types.h + ) + +FOREACH(hfile ${HEADERS_LIB_REMOTE_FRAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} + DESTINATION include/${PROJECT_NAME}) +ENDFOREACH(hfile) + +INSTALL(TARGETS ${PROJECT_NAME} + DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) diff --git a/remote-frame/include/remote_frame.h b/remote-frame/include/remote_frame.h new file mode 100644 index 00000000..1b7ca265 --- /dev/null +++ b/remote-frame/include/remote_frame.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REMOTE_FRAME_H__ +#define __REMOTE_FRAME_H__ + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The remote frame handle. + * @since_tizen 5.5 + */ +typedef void *remote_frame_h; + +/** + * @brief Enumeration for the remote frame type. + * @since_tizen 5.5 + */ +typedef enum { + REMOTE_FRAME_TYPE_REMOTE_SURFACE, /**< The remote surface */ + REMOTE_FRAME_TYPE_SPLASH_SCREEN, /**< The splash screen */ +} remote_frame_type_e; + +/** + * @brief Enumeration for the remote frame direction. + * @since_tizen 5.5 + */ +typedef enum { + REMOTE_FRAME_DIRECTION_FORWARD, /**< The direction that is from the caller to the other application. */ + REMOTE_FRAME_DIRECTION_BACKWARD, /**< The direction that is from the other application to the caller. */ +} remote_frame_direction_e; + +/** + * @brief Gets the raw handle of the remote frame. + * @since_tizen 5.5 + * @remarks The @a raw should not be released. + * + * @param[in] handle The remote frame handle + * @param[out] raw The evas object + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_get_raw(remote_frame_h handle, Evas_Object **raw); + +/** + * @brief Gets the type of the remote frame. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame handle + * @param[out] type The type + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see remote_frame_type_e + */ +int remote_frame_get_type(remote_frame_h handle, remote_frame_type_e *type); + +/** + * @brief Gets the direction of the remote frame. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame handle + * @param[out] direction The direction + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see remote_frame_direction_e + */ +int remote_frame_get_direction(remote_frame_h handle, + remote_frame_direction_e *direction); + +/** + * @brief Gets the position X of the remote frame. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame handle + * @param[out] x The position X + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_get_position_x(remote_frame_h handle, int32_t *x); + +/** + * @brief Gets the position Y of the remote frame. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame handle + * @param[out] y The position Y + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_get_position_y(remote_frame_h handle, int32_t *y); + +/** + * @brief Gets the extra data of the remote frame. + * @since_tizen 5.5 + * @remarks The @a extra_data should not be released. + * + * @param[in] handle The remote frame handle + * @param[out] extra_data The bundle object + * @return @c 0 on success, + * otherwise a negative error value + * + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_get_extra_data(remote_frame_h handle, bundle **extra_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __REMOTE_FRAME_H__ */ diff --git a/remote-frame/include/remote_frame_consumer.h b/remote-frame/include/remote_frame_consumer.h new file mode 100644 index 00000000..ccff372e --- /dev/null +++ b/remote-frame/include/remote_frame_consumer.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REMOTE_FRAME_CONSUMER_H__ +#define __REMOTE_FRAME_CONSUMER_H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The remote frame consumer handle. + * @since_tizen 5.5 + */ +typedef struct remote_frame_consumer_s *remote_frame_consumer_h; + +/** + * @brief Creates the remote frame consumer handle. + * @since_tizen 5.5 + * @remarks The @a handle should be released using remote_frame_consumer_destroy() function. + * + * @param[in] win The evas object + * @param[in] callback The set of callback functions to handle remote frame context lifecycle events + * @param[in] user_data The user data passed to the callback functions + * @param[out] handle The remote frame consumer handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_OUT_OF_MEMORY Out of memory + * @retval #REMOTE_FRAME_ERROR_IO_ERROR I/O error + * + * @see remote_frame_consumer_destroy() + * @see remote_frame_context_lifecycle_callback_s + */ +int remote_frame_consumer_create(Evas_Object *win, + remote_frame_context_lifecycle_callback_s *callback, + void *user_data, + remote_frame_consumer_h *handle); + +/** + * @brief Destroyes the remote frame consumer handle. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame consumer handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_consumer_destroy(remote_frame_consumer_h handle); + +/** + * @brief Sends the launch request asynchronously. + * @since_tizen 5.5 + * + * @privlevel public + * @privilege %http:://tizen.org/privilege/appmanager.launch + * + * @param[in] handle The remote frame consumer handle + * @param[in] app_control The app_control handle + * @param[in] result_cb The callback function to be called when the result is delivered + * @param[in] reply_cb The callback function to be called when the reply is delivered + * @param[in] uset_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_APP_NOT_FOUND The application to run the given launch request is not found + * @retval #REMOTE_FRAME_ERROR_LAUNCH_REJECTED Failed to launch the application + * @retval #REMOTE_FRAME_ERROR_PERMISSION_DENIED Permission denied + * + * @see app_control_send_launch_request_async() + * @see app_control_result_cb() + * @see app_control_reply_cb() + */ +int remote_frame_consumer_send_launch_request(remote_frame_consumer_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __REMOTE_FRAME_VIEWER_H__ */ diff --git a/remote-frame/include/remote_frame_context.h b/remote-frame/include/remote_frame_context.h new file mode 100644 index 00000000..c49387a7 --- /dev/null +++ b/remote-frame/include/remote_frame_context.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REMOTE_FRAME_CONTEXT_H__ +#define __REMOTE_FRAME_CONTEXT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The remote frame context handle. + * @since_tizen 5.5 + */ +typedef void *remote_frame_context_h; + +/** + * @brief Enumeration for errors of the remote frame context. + * @since_tizen 5.5 + */ +typedef enum { + REMOTE_FRAME_CONTEXT_ERROR_NONE, /**< Successful */ + REMOTE_FRAME_CONTEXT_ERROR_DISQUALIFIED, /**< Disqualified */ + REMOTE_FRAME_CONTEXT_ERROR_WRONG_REQUEST, /**< Wrong request */ +} remote_frame_context_error_e; + +/** + * @brief Called when the remote frame context is created. + * @since_tizen 5.5 + * @remarks The @a context should be not released. + * + * @param[in] context The remote frame context handle + * @param[in] user_data The user data passed from remote_frame_viewer_create() function + */ +typedef void (*remote_frame_context_create_cb)(remote_frame_context_h context, + void *user_data); + +/** + * @brief Called when the remote frame context is resumed. + * @since_tizen 5.5 + * @details When the remote frame has been prepared, this callback function is called. + * The caller can start animations. To notify that the animation is started, the caller should call remote_frame_context_start_animation() function. + * After the animation is finished, the caller should call frame_context_finish_animation() function to notify. + * @remarks The @a context and the @frame should not be released. + * The @a context and the @frame can be used only in the callback. + * + * @param[in] context The remote frame context handle + * @param[in] frame The remote frame + * @param[in] user_data The user data passed from remote_frame_viewer_create() function + * + * @see remote_frame_context_start_animation() + * @see remote_frame_context_finish_animation() + */ +typedef void (*remote_frame_context_resume_cb)(remote_frame_context_h context, + remote_frame_h frame, + void *user_data); + +/** + * @brief Called when the remote frame context is paused. + * @since_tizen 5.5 + * @details When the animation has been finished, this callback function is called. + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The remote frame context handle + * @param[in] uset_data The user data passed from remote_frame_viewer_create() function + */ +typedef void (*remote_frame_context_pause_cb)(remote_frame_context_h context, + void *user_data); + +/** + * @brief Called when the remote frame context is destroyed. + * @since_tizen 5.5 + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The remote frame context handle + * @param[in] uset_data The user data passed from remote_frame_viewer_create() function + */ +typedef void (*remote_frame_context_destroy_cb)(remote_frame_context_h context, + void *user_data); + +/** + * @brief Called when the error is occurred. + * @since_tizen 5.5 + * @remarks The @a context should not be released. The @a context can be used only in the callback. + * + * @param[in] context The remote frame context handle + * @param[in] error The error + * @param[in] user_data The user data passed from remote_frame_viewer_create() function + * + * @see remote_frame_context_error_e + */ +typedef void (*remote_frame_context_error_cb)(remote_frame_context_h context, + remote_frame_context_error_e error, + void *user_data); + +/** + * @brief Called when the remote frame context is updated. + * @since_tizen 5.5 + * @details When the remote frame has been updated, this callback function is called. + * @remarks The @a context and the @frame should not be released. + * The @a context and the @frame can be used only in the callback. + * + * @param[in] context The remote frame context handle + * @param[in] frame The remote frame + * @param[in] user_data The user data passed from remote_frame_viewer_create() function + * + * @see remote_frame_context_update_cb() + * @see remote_frame_context_start_animation() + * @see remote_frame_context_finish_animation() + */ +typedef void (*remote_frame_context_update_cb)(remote_frame_context_h context, + remote_frame_h frame, + void *user_data); + +/** + * @brief The structure type containing the set of callback functions for lifecycle of a remote frame context. + * @since_tizen 5.5 + * + * @see remote_frame_viewer_create() + * @see remote_frame_context_create_cb() + * @see remote_frame_context_resume_cb() + * @see remote_frame_context_pause_cb() + * @see remote_frame_context_destroy_cb() + * @see remote_frame_context_error_cb() + */ +typedef struct { + remote_frame_context_create_cb create; /**< The callback function called after the remote frame context is created. */ + remote_frame_context_resume_cb resume; /**< The callback function called when the frame is prepared. */ + remote_frame_context_pause_cb pause; /**< The callback function called when the animation is finished. */ + remote_frame_context_destroy_cb destroy; /**< The callback function called before the remote frame context is destroyed. */ + remote_frame_context_update_cb update; /**< The callback function called when the frame is updated. */ + remote_frame_context_error_cb error; /**< The callback function called when the error is occurred. */ +} remote_frame_context_lifecycle_callback_s; + +/** + * @brief Notifies that the animation is started. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame context handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_IO_ERROR I/O error + * + * @see frame_context_finish_animation() + */ +int remote_frame_context_start_animation(remote_frame_context_h handle); + +/** + * @brief Notifies that the animation is finished. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame context handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_IO_ERROR I/O error + + * @see frame_context_start_animation() + */ +int remote_frame_context_finish_animation(remote_frame_context_h handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __REMOTE_FRAME_CONTEXT_H__ */ diff --git a/remote-frame/include/remote_frame_provider.h b/remote-frame/include/remote_frame_provider.h new file mode 100644 index 00000000..ae3288c5 --- /dev/null +++ b/remote-frame/include/remote_frame_provider.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REMOTE_FRAME_PROVIDER_H__ +#define __REMOTE_FRAME_PROVIDER_H__ + +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The remote frame provider handle. + * @since_tizen 5.5 + */ +typedef struct remote_frame_provider_s *remote_frame_provider_h; + +/** + * @brief Called when the show event is occurred. + * @since_tizen 5.5 + * @details When the provider should show the object to share with the caller, this callback function is called. + * After showing the object, the caller should call remote_frame_provider_notify_show_status() function to notify. + * @remarks The @a handle should not be released. + * + * @param[in] handle The remote frame provider handle + * @param[in] user_data The user data passed from remote_frame_provider_create() function + * + * @see remote_frame_provider_create() + * @see remote_frame_provider_notify_show_status() + */ +typedef void (*remote_frame_provider_show_cb)(remote_frame_provider_h handle, + void *user_data); + +/** + * @brief Called when the hide event is occurred. + * @since_tizen 5.5 + * @details When the provider should hide the object to share with the caller, this callback function is called. + * After hiding the object, the caller should call remote_frame_provider_notify_hide_status() function to notify. + * @remarks The @a handle should not be released. + * + * @param[in] handle The remote frame provider handle + * @param[in] user_data The user data passed from remote_frame_provider_create() function + * + * @see remote_frame_provider_create() + * @see remote_frame_provider_notify_hide_status() + */ +typedef void (*remote_frame_provider_hide_cb)(remote_frame_provider_h handle, + void *user_data); + +/** + * @brief The structure type containing the set of callback functions for events of a remote frame provider. + * @since_tizen 5.5 + * + * @see remote_frame_provider_create() + * @see remote_frame_provider_show_cb() + * @see remote_frame_provider_hide_cb() + */ +typedef struct { + remote_frame_provider_show_cb show; /**< The callback function called when the show event is occurred. */ + remote_frame_provider_hide_cb hide; /**< The callback function called when the hide event is occurred. */ +} remote_frame_provider_event_callback_s; + +/** + * @brief Creates the remote frame provider handle. + * @since_tizen 5.5 + * @remarks The @a handle should be released using remote_frame_provider_destroy(). + * + * @param[in] win The evas object + * @param[in] callback The set of callback functions to handle remote frame provider events + * @param[in] user_data The user data to be passed to the callback functions + * @param[out] handle The remote frame provider handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_OUT_OF_MEMORY Out of memory + * + * @see remote_frame_provider_destroy() + * @see remote_frame_provider_event_callback_s + */ +int remote_frame_provider_create(Evas_Object *win, + remote_frame_provider_event_callback_s *callback, + void *user_data, + remote_frame_provider_h *handle); + +/** + * @brief Destroyes the remote frame provider handle. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame provider handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + */ +int remote_frame_provider_destroy(remote_frame_provider_h handle); + +/** + * @brief Notifies that the object is prepared to show. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame provider handle + * @param[in] extra_data The bundle object + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_INVALID_OPERATION Invalid operation + * @retval #REMOTE_FRAME_ERROR_IO_ERROR I/O error + */ +int remote_frame_provider_notify_show_status(remote_frame_provider_h handle, + bundle *extra_data); + +/** + * @brief Notifies that the object is prepared to hide. + * @since_tizen 5.5 + * + * @param[in] handle The remote frame provider handle + * @param[in] extra_data The bundle object + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #REMOTE_FRAME_ERROR_NONE Successful + * @retval #REMOTE_FRAME_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #REMOTE_FRAME_ERROR_INVALID_OPERATION Invalid operation + * @retval #REMOTE_FRAME_ERROR_IO_ERROR I/O error + */ +int remote_frame_provider_notify_hide_status(remote_frame_provider_h handle, + bundle *extra_data); + +#ifdef __cplusplus +} +#endif + +#endif /* __REMOTE_FRAME_PROVIDER_H__ */ diff --git a/remote-frame/include/remote_frame_types.h b/remote-frame/include/remote_frame_types.h new file mode 100644 index 00000000..8d2c8484 --- /dev/null +++ b/remote-frame/include/remote_frame_types.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REMOTE_FRAME_TYPES_H__ +#define __REMOTE_FRAME_TYPES_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration for remote frame error. + * @since_tizen 5.5 + */ +typedef enum { + REMOTE_FRAME_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + REMOTE_FRAME_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + REMOTE_FRAME_ERROR_APP_NOT_FOUND = APP_CONTROL_ERROR_APP_NOT_FOUND, /**< The application is not found */ + REMOTE_FRAME_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + REMOTE_FRAME_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + REMOTE_FRAME_ERROR_LAUNCH_REJECTED = APP_CONTROL_ERROR_LAUNCH_REJECTED, /**< Launch rejected */ + REMOTE_FRAME_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + REMOTE_FRAME_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ +} remote_frame_error_e; + +#ifdef __cplusplus +} +#endif + +#endif /* __REMOTE_FRAME_TYPES_H__ */ diff --git a/remote-frame/remote-frame.pc.in b/remote-frame/remote-frame.pc.in new file mode 100644 index 00000000..8c48a060 --- /dev/null +++ b/remote-frame/remote-frame.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: remote-frame +Description: Support development of the remote frame +Version: @VERSION@ +Requires: screen_connector_shared_widget_launch elementary frame-broker capi-appfw-app-control bundle +Libs: -L${libdir} -lremote-frame +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/remote-frame/src/log_private.h b/remote-frame/src/log_private.h new file mode 100644 index 00000000..c6e8119f --- /dev/null +++ b/remote-frame/src/log_private.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOG_PRIVATE_H__ +#define __LOG_PRIVATE_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "REMOTE_FRAME" + +#ifdef _E +#undef _E +#endif +#define _E LOGE + +#ifdef _W +#undef _W +#endif +#define _W LOGW + +#ifdef _I +#undef _I +#endif +#define _I LOGI + +#ifdef _D +#undef _D +#endif +#define _D LOGD + +#endif /* __LOG_PRIVATE_H__ */ diff --git a/remote-frame/src/private.h b/remote-frame/src/private.h new file mode 100644 index 00000000..67435919 --- /dev/null +++ b/remote-frame/src/private.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PRIVATE_H__ +#define __PRIVATE_H__ + +#ifdef API +#undef API +#endif +#define API __attribute__((visibility("default"))) + +#endif /* __PRIVATE_H__ */ diff --git a/remote-frame/src/remote_frame.c b/remote-frame/src/remote_frame.c new file mode 100644 index 00000000..837d7c94 --- /dev/null +++ b/remote-frame/src/remote_frame.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "remote_frame.h" +#include "remote_frame_types.h" +#include "log_private.h" +#include "private.h" + +#define HANDLE_TO_FRAME(h) ((frame_h)(remote_frame_h)(h)) + +API int remote_frame_get_raw(remote_frame_h handle, Evas_Object **raw) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + + return frame_get_raw(frame, raw); +} + +static remote_frame_type_e __convert_type(frame_type_e type) +{ + if (type == FRAME_TYPE_REMOTE_SURFACE) + return REMOTE_FRAME_TYPE_REMOTE_SURFACE; + + return REMOTE_FRAME_TYPE_SPLASH_SCREEN; +} + +API int remote_frame_get_type(remote_frame_h handle, remote_frame_type_e *type) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + frame_type_e frame_type; + int ret; + + if (!handle || !type) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + ret = frame_get_type(frame, &frame_type); + if (ret != FRAME_BROKER_ERROR_NONE) + return ret; + + *type = __convert_type(frame_type); + + return REMOTE_FRAME_ERROR_NONE; +} + +static remote_frame_direction_e __convert_direction(frame_direction_e direction) +{ + if (direction == FRAME_DIRECTION_FORWARD) + return REMOTE_FRAME_DIRECTION_FORWARD; + + return REMOTE_FRAME_DIRECTION_BACKWARD; +} + +API int remote_frame_get_direction(remote_frame_h handle, + remote_frame_direction_e *direction) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + frame_direction_e frame_direction; + int ret; + + if (!handle || !direction) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + ret = frame_get_direction(frame, &frame_direction); + if (ret != FRAME_BROKER_ERROR_NONE) + return ret; + + *direction = __convert_direction(frame_direction); + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_get_position_x(remote_frame_h handle, int32_t *x) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + + return frame_get_position_x(frame, x); +} + +API int remote_frame_get_position_y(remote_frame_h handle, int32_t *y) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + + return frame_get_position_y(frame, y); +} + +API int remote_frame_get_extra_data(remote_frame_h handle, bundle **extra_data) +{ + frame_h frame = HANDLE_TO_FRAME(handle); + + return frame_get_extra_data(frame, extra_data); +} diff --git a/remote-frame/src/remote_frame_consumer.c b/remote-frame/src/remote_frame_consumer.c new file mode 100644 index 00000000..c941b8ae --- /dev/null +++ b/remote-frame/src/remote_frame_consumer.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "remote_frame_consumer.h" +#include "remote_frame_context.h" +#include "log_private.h" +#include "private.h" + +struct remote_frame_consumer_s { + frame_broker_h broker; + Evas_Object *win; + remote_frame_context_lifecycle_callback_s callback; + void *user_data; +}; + +static void __frame_context_create_cb(frame_context_h context, void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.create(context, consumer->user_data); +} + +static void __frame_context_resume_cb(frame_context_h context, frame_h frame, + void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.resume(context, frame, consumer->user_data); +} + +static void __frame_context_pause_cb(frame_context_h context, void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.pause(context, consumer->user_data); +} + +static void __frame_context_destroy_cb(frame_context_h context, void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.destroy(context, consumer->user_data); +} + +static void __frame_context_update_cb(frame_context_h context, frame_h frame, + void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.update(context, frame, consumer->user_data); +} + +static remote_frame_context_error_e __convert_error(frame_context_error_e error) +{ + switch (error) { + case FRAME_CONTEXT_ERROR_DISQUALIFIED: + return REMOTE_FRAME_CONTEXT_ERROR_DISQUALIFIED; + case FRAME_CONTEXT_ERROR_WRONG_REQUEST: + return REMOTE_FRAME_CONTEXT_ERROR_WRONG_REQUEST; + default: + return REMOTE_FRAME_CONTEXT_ERROR_NONE; + } +} + +static void __frame_context_error_cb(frame_context_h context, + frame_context_error_e error, + void *user_data) +{ + remote_frame_consumer_h consumer = user_data; + + consumer->callback.error(context, __convert_error(error), + consumer->user_data); +} + +API int remote_frame_consumer_create(Evas_Object *win, + remote_frame_context_lifecycle_callback_s *callback, + void *user_data, + remote_frame_consumer_h *handle) +{ + struct remote_frame_consumer_s *consumer; + frame_context_lifecycle_callback_s cbs = { + .create = __frame_context_create_cb, + .resume = __frame_context_resume_cb, + .pause = __frame_context_pause_cb, + .destroy = __frame_context_destroy_cb, + .update = __frame_context_update_cb, + .error = __frame_context_error_cb + }; + frame_broker_h broker; + int ret; + + if (!win || !callback || !handle) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + if (!callback->create || !callback->resume || + !callback->pause || !callback->destroy || + !callback->update || !callback->error) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + consumer = calloc(1, sizeof(struct remote_frame_consumer_s)); + if (!consumer) { + _E("Out of memory"); + return REMOTE_FRAME_ERROR_OUT_OF_MEMORY; + } + + ret = frame_broker_create(win, &cbs, consumer, &broker); + if (ret != FRAME_BROKER_ERROR_NONE) { + remote_frame_consumer_destroy(consumer); + return ret; + } + + consumer->broker = broker; + consumer->win = win; + consumer->callback = *callback; + consumer->user_data = user_data; + + *handle = consumer; + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_consumer_destroy(remote_frame_consumer_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + frame_broker_destroy(handle->broker); + free(handle); + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_consumer_send_launch_request( + remote_frame_consumer_h handle, + app_control_h app_control, + app_control_result_cb result_cb, + app_control_reply_cb reply_cb, + void *user_data) { + int ret; + + if (!handle || !app_control || !result_cb) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + ret = frame_broker_send_launch_request_for_remote_frame( + handle->broker, app_control, result_cb, reply_cb, + user_data); + if (ret != FRAME_BROKER_ERROR_NONE) { + _E("Failed to send launch request. error(%d)", ret); + return ret; + } + + return REMOTE_FRAME_ERROR_NONE; +} diff --git a/remote-frame/src/remote_frame_context.c b/remote-frame/src/remote_frame_context.c new file mode 100644 index 00000000..cfeaa93e --- /dev/null +++ b/remote-frame/src/remote_frame_context.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "remote_frame_context.h" +#include "remote_frame_types.h" +#include "log_private.h" +#include "private.h" + +#define HANDLE_TO_FRAME_CONTEXT(h) \ + ((frame_context_h)(remote_frame_context_h)(h)) + +API int remote_frame_context_start_animation(remote_frame_context_h handle) +{ + frame_context_h context = HANDLE_TO_FRAME_CONTEXT(handle); + int ret; + + ret = frame_context_start_animation(context); + if (ret != FRAME_BROKER_ERROR_NONE) + return ret; + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_context_finish_animation(remote_frame_context_h handle) +{ + frame_context_h context = HANDLE_TO_FRAME_CONTEXT(handle); + int ret; + + ret = frame_context_finish_animation(context); + if (ret != FRAME_BROKER_ERROR_NONE) + return ret; + + return REMOTE_FRAME_ERROR_NONE; +} diff --git a/remote-frame/src/remote_frame_provider.c b/remote-frame/src/remote_frame_provider.c new file mode 100644 index 00000000..af332591 --- /dev/null +++ b/remote-frame/src/remote_frame_provider.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "remote_frame_provider.h" +#include "remote_frame_types.h" +#include "log_private.h" +#include "private.h" + +struct remote_frame_provider_s { + Evas_Object *win; + screen_connector_shared_widget_launch_h scswl; + screen_connector_shared_widget_launch_prepare_state_e state; + uint32_t serial; + remote_frame_provider_event_callback_s callback; + void *user_data; +}; + +static GList *__win_list; + +static gint __compare_win(gconstpointer a, gconstpointer b) +{ + Evas_Object *win_a = (Evas_Object *)a; + Evas_Object *win_b = (Evas_Object *)b; + + return win_a != win_b; +} + +static bool __exist_win(Evas_Object *win) +{ + GList *found; + + found = g_list_find_custom(__win_list, win, __compare_win); + if (found) + true; + + return false; +} + +static void __add_win(Evas_Object *win) +{ + __win_list = g_list_append(__win_list, win); +} + +static void __remove_win(Evas_Object *win) +{ + __win_list = g_list_remove(__win_list, win); +} + +static void __scswl_prepare_cb( + screen_connector_shared_widget_launch_prepare_state_e state, + uint32_t serial, + void *user_data) +{ + remote_frame_provider_h provider = user_data; + + provider->state = state; + provider->serial = serial; + + if (state == SCREEN_CONNECTOR_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW) + provider->callback.show(provider, provider->user_data); + else + provider->callback.hide(provider, provider->user_data); +} + +API int remote_frame_provider_create(Evas_Object *win, + remote_frame_provider_event_callback_s *callback, + void *user_data, + remote_frame_provider_h *handle) +{ + struct remote_frame_provider_s *provider; + Ecore_Wl2_Window *wl2_win; + int ret; + + if (!win || !callback || !handle) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + if (__exist_win(win)) { + _E("Already exists. win(%p)", win); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + provider = calloc(1, sizeof(struct remote_frame_provider_s)); + if (!provider) { + _E("Out of memory"); + return REMOTE_FRAME_ERROR_OUT_OF_MEMORY; + } + + wl2_win = (Ecore_Wl2_Window *)elm_win_wl_window_get(win); + ret = screen_connector_shared_widget_launch_create(wl2_win, + &provider->scswl); + if (ret != 0) { + _E("Failed to create scswl. error(%d)", ret); + return REMOTE_FRAME_ERROR_OUT_OF_MEMORY; + } + + screen_connector_shared_widget_launch_prepare_cb_set(provider->scswl, + __scswl_prepare_cb, provider); + + provider->win = win; + provider->callback = *callback; + provider->user_data = user_data; + + __add_win(win); + + *handle = provider; + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_provider_destroy(remote_frame_provider_h handle) +{ + if (!handle) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_NONE; + } + + __remove_win(handle->win); + + screen_connector_shared_widget_launch_destroy(handle->scswl); + free(handle); + + return REMOTE_FRAME_ERROR_NONE; +} + +static int __notify_status(remote_frame_provider_h handle, + screen_connector_shared_widget_launch_prepare_state_e state, + bundle *extra_data) +{ + bundle_raw *raw; + int len; + int ret; + + if (!handle || !handle->serial) { + _E("Invalid parameter"); + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + + if (handle->state != state) { + _E("Invalid operation"); + return REMOTE_FRAME_ERROR_INVALID_OPERATION; + } + + if (extra_data) { + ret = bundle_encode(extra_data, &raw, &len); + if (ret != BUNDLE_ERROR_NONE) { + _E("Failed to encode extra data. error(%d)", ret); + if (ret == BUNDLE_ERROR_OUT_OF_MEMORY) + return REMOTE_FRAME_ERROR_OUT_OF_MEMORY; + + return REMOTE_FRAME_ERROR_INVALID_PARAMETER; + } + } else { + raw = (bundle_raw *)strdup("None"); + } + + ret = screen_connector_shared_widget_launch_prepare_done(handle->scswl, + (const char *)raw, state, handle->serial); + free((void *)raw); + if (ret != 0) { + _E("Failed to notify provider status. error(%d)", ret); + return REMOTE_FRAME_ERROR_IO_ERROR; + } + + return REMOTE_FRAME_ERROR_NONE; +} + +API int remote_frame_provider_notify_show_status( + remote_frame_provider_h handle, + bundle *extra_data) +{ + return __notify_status(handle, + SCREEN_CONNECTOR_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW, + extra_data); +} + +API int remote_frame_provider_notify_hide_status( + remote_frame_provider_h handle, + bundle *extra_data) +{ + return __notify_status(handle, + SCREEN_CONNECTOR_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE, + extra_data); +}