diff options
-rwxr-xr-x | include/app.h | 1 | ||||
-rwxr-xr-x | include/app_control.h | 876 | ||||
-rw-r--r-- | include/app_control_internal.h | 95 | ||||
-rwxr-xr-x | src/app_control.c | 1335 |
4 files changed, 2307 insertions, 0 deletions
diff --git a/include/app.h b/include/app.h index 362178b..df123b6 100755 --- a/include/app.h +++ b/include/app.h @@ -20,6 +20,7 @@ #include <tizen.h> #include <app_service.h> +#include <app_control.h> #include <app_alarm.h> #include <app_preference.h> #include <app_storage.h> diff --git a/include/app_control.h b/include/app_control.h new file mode 100755 index 0000000..dea3a07 --- /dev/null +++ b/include/app_control.h @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_APP_CONTROL_H__ +#define __TIZEN_APPFW_APP_CONTROL_H__ + +#include <tizen.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file app_control.h + */ + +/** + * @addtogroup CAPI_APP_CONTROL_MODULE + * @{ + */ + + +typedef struct _bundle_t bundle; + + +/** + * @brief App Control handle. + * @since_tizen 2.3 + */ +typedef struct app_control_s* app_control_h; + + +/** + * @brief Enumeration for App Control Error. + * @since_tizen 2.3 + */ +typedef enum +{ + APP_CONTROL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + APP_CONTROL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + APP_CONTROL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + APP_CONTROL_ERROR_APP_NOT_FOUND = TIZEN_ERROR_APPLICATION_CLASS | 0x21, /**< The application is not found */ + APP_CONTROL_ERROR_KEY_NOT_FOUND = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Specified key is not found */ + APP_CONTROL_ERROR_KEY_REJECTED = TIZEN_ERROR_KEY_REJECTED, /**< Key is not available */ + APP_CONTROL_ERROR_INVALID_DATA_TYPE = TIZEN_ERROR_APPLICATION_CLASS | 0x22, /**< Invalid data type */ + APP_CONTROL_ERROR_LAUNCH_REJECTED = TIZEN_ERROR_APPLICATION_CLASS | 0x23, /**< The application cannot be launched now*/ + APP_CONTROL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + APP_CONTROL_ERROR_LAUNCH_FAILED = TIZEN_ERROR_APPLICATION_CLASS | 0x24, /**< Internal launch error */ + APP_CONTROL_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT /**< Time out */ +} app_control_error_e; + + +/** + * @brief Enumeration for App Control Result. + * @since_tizen 2.3 + */ +typedef enum +{ + APP_CONTROL_RESULT_SUCCEEDED = 0, /**< Operation succeeded */ + APP_CONTROL_RESULT_FAILED = -1, /**< Operation failed by the callee */ + APP_CONTROL_RESULT_CANCELED = -2, /**< Operation canceled by the framework */ +} app_control_result_e; + + +/** + * @brief Definition for the app_control operation: main operation for an explicit launch. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_MAIN "http://tizen.org/appcontrol/operation/main" + + +/** + * @brief Definition for the app_control operation: default operation for an explicit launch. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_DEFAULT "http://tizen.org/appcontrol/operation/default" + + +/** + * @brief Definition for the app_control operation: provides an explicit editable access to the given data. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_EDIT "http://tizen.org/appcontrol/operation/edit" + + +/** + * @brief Definition for the app_control operation: displays the data. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_VIEW "http://tizen.org/appcontrol/operation/view" + + +/** + * @brief Definition for the app_control operation: picks an item from the data, returning what is selected. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_PICK "http://tizen.org/appcontrol/operation/pick" + + +/** + * @brief Definition for the app_control operation: creates content, returning what is created. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_CREATE_CONTENT "http://tizen.org/appcontrol/operation/create_content" + + +/** + * @brief Definition for the app_control operation: performs a call to someone specified by the data. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/call + * @remarks When you request this operation, you must declare this privilege. + */ +#define APP_CONTROL_OPERATION_CALL "http://tizen.org/appcontrol/operation/call" + + +/** + * @brief Definition for the app_control operation: delivers some data to someone else. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_SEND "http://tizen.org/appcontrol/operation/send" + + +/** + * @brief Definition for the app_control operation: delivers text data to someone else. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_SEND_TEXT "http://tizen.org/appcontrol/operation/send_text" + + +/** + * @brief Definition for the app_control operation: shares an item with someone else. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_SHARE "http://tizen.org/appcontrol/operation/share" + + +/** + * @brief Definition for the app_control operation: shares multiple items with someone else. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_MULTI_SHARE "http://tizen.org/appcontrol/operation/multi_share" + + +/** + * @brief Definition for the app_control operation: shares text data with someone else. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_SHARE_TEXT "http://tizen.org/appcontrol/operation/share_text" + + +/** + * @brief Definition for the app_control operation: dials a number as specified by the data. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_DIAL "http://tizen.org/appcontrol/operation/dial" + + +/** + * @brief Definition for the app_control operation: performs a search. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_SEARCH "http://tizen.org/appcontrol/operation/search" + + +/** + * @brief Definition for the app_control operation: downloads an item. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_DOWNLOAD "http://tizen.org/appcontrol/operation/download" + + +/** + * @brief Definition for the app_control operation: prints content. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_PRINT "http://tizen.org/appcontrol/operation/print" + +/** + * @brief Definition for the app_control operation: composes. + * @since_tizen 2.3 + */ +#define APP_CONTROL_OPERATION_COMPOSE "http://tizen.org/appcontrol/operation/compose" + +/** + * @brief Definition for app_control optional data: the subject of a message. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_SUBJECT "http://tizen.org/appcontrol/data/subject" + + +/** + * @brief Definition for app_control optional data: e-mail addresses. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_TO "http://tizen.org/appcontrol/data/to" + + +/** + * @brief Definition for app_control optional data: e-mail addresses that should be carbon copied. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_CC "http://tizen.org/appcontrol/data/cc" + + +/** + * @brief Definition for app_control optional data: e-mail addresses that should be blind carbon copied. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_BCC "http://tizen.org/appcontrol/data/bcc" + + +/** + * @brief Definition for app_control optional data: the content of the data is associated with #APP_CONTROL_OPERATION_SEND. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_TEXT "http://tizen.org/appcontrol/data/text" + + +/** + * @brief Definition for app_control optional data: the title of the data. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_TITLE "http://tizen.org/appcontrol/data/title" + + +/** + * @brief Definition for app_control optional data: the path of a selected item. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_SELECTED "http://tizen.org/appcontrol/data/selected" + + +/** + * @brief Definition for app_control optional data: multiple item path to deliver. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_PATH "http://tizen.org/appcontrol/data/path" + + +/** + * @brief Definition for app_control optional data: the selection type. + * @since_tizen 2.3 + */ +#define APP_CONTROL_DATA_SELECTION_MODE "http://tizen.org/appcontrol/data/selection_mode" + + +/** + * @brief Called when the reply of the launch request is delivered. + * + * @since_tizen 2.3 + * + * @remarks The @a request and @a reply must not be deallocated by the application. + * + * @param[in] request The app_control handle of the launch request that has been sent + * @param[in] reply The app_control handle in which the results of the callee are contained + * @param[in] result The result code of the launch request + * @param[in] user_data The user data passed from the callback registration function + * @pre When the callee replies to the launch request, this callback will be invoked. + * @see app_control_send_launch_request() + * @see app_control_reply_to_launch_request() + */ +typedef void (*app_control_reply_cb) (app_control_h request, app_control_h reply, app_control_result_e result, void *user_data); + + +/** + * @brief Called to retrieve the extra data contained in the app_control. + * + * @since_tizen 2.3 + * + * @remarks The @a key must not be deallocated by the application. + * + * @param[in] app_control The app_control handle + * @param[in] key The key of the value contained in the app_control + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre app_control_foreach_extra_data() will invoke this callback. + * @see app_control_foreach_extra_data() + */ +typedef bool (*app_control_extra_data_cb)(app_control_h app_control, const char *key, void *user_data); + + +/** + * @brief Called once for each matched application that can be launched to handle the given app_control request. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] package The package name of the application that can handle the launch request of the given app_control + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre app_control_foreach_app_matched() will invoke this callback. + * @see app_control_foreach_app_matched() + */ +typedef bool (*app_control_app_matched_cb)(app_control_h app_control, const char *appid, void *user_data); + + +typedef int (*app_control_host_res_fn)(void *data); + +/** + * @brief Creates an app_control handle. + * + * @since_tizen 2.3 + * @remarks The @a app_control must be released using app_control_destroy(). + * @param[out] app_control The app_control handle to be newly created on success + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_destroy() + */ +int app_control_create(app_control_h *app_control); + + +/** + * @brief Destroys the app_control handle and releases all its resources. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_create() + */ +int app_control_destroy(app_control_h app_control); + + +/** + * @internal + * @brief Converts the app_control handle to bundle data. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[out] data The bundle data on success + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + */ +int app_control_to_bundle(app_control_h app_control, bundle **data); + +/** + * @brief Sets the operation to be performed. + * + * @details The @a operation is the mandatory information for the launch request. + * If the operation is not specified, #APP_CONTROL_OPERATION_DEFAULT is used for the launch request. + * If the operation is #APP_CONTROL_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application. + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] operation The operation to be performed (if the @a operation is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_operation() + * @see APP_CONTROL_OPERATION_DEFAULT + * @see APP_CONTROL_OPERATION_EDIT + * @see APP_CONTROL_OPERATION_VIEW + * @see APP_CONTROL_OPERATION_PICK + * @see APP_CONTROL_OPERATION_CREATE_CONTENT + * @see APP_CONTROL_OPERATION_CALL + * @see APP_CONTROL_OPERATION_SEND + * @see APP_CONTROL_OPERATION_SEND_TEXT + * @see APP_CONTROL_OPERATION_DIAL + * @see APP_CONTROL_OPERATION_SEARCH + */ +int app_control_set_operation(app_control_h app_control, const char *operation); + + +/** + * @brief Gets the operation to be performed. + * + * @since_tizen 2.3 + * @remarks The @a operation must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] operation The operation to be performed + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_operation() + */ +int app_control_get_operation(app_control_h app_control, char **operation); + + +/** + * @brief Sets the URI of the data. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] uri The URI of the data this app_control is operating on (if the @a uri is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_uri() + */ +int app_control_set_uri(app_control_h app_control, const char *uri); + + +/** + * @brief Gets the URI of the data. + * + * @since_tizen 2.3 + * @remarks The @a uri must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] uri The URI of the data this app_control is operating on + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_uri() + */ +int app_control_get_uri(app_control_h app_control, char **uri); + + +/** + * @brief Sets the explicit MIME type of the data. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] mime The explicit MIME type of the data this app_control is operating on (if the @a mime is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_mime() + */ +int app_control_set_mime(app_control_h app_control, const char *mime); + + +/** + * @brief Gets the explicit MIME type of the data. + * + * @since_tizen 2.3 + * @remarks The @a uri must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] mime The explicit MIME type of the data this app_control is operating on + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_mime() + */ +int app_control_get_mime(app_control_h app_control, char **mime); + + +/** + * @brief Sets the explicit category. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] category The explicit category (if the @a category is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_category() + */ +int app_control_set_category(app_control_h app_control, const char *category); + + +/** + * @brief Gets the explicit category. + * + * @since_tizen 2.3 + * @remarks The @a category must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] category The explicit category + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_category() + */ +int app_control_get_category(app_control_h app_control, char **category); + + +/** + * @brief Sets the ID of the application to explicitly launch. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] app_id The ID of the application to explicitly launch (if the @a app_id is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_get_app_id() + */ +int app_control_set_app_id(app_control_h app_control, const char *app_id); + + +/** + * @brief Gets the ID of the application to explicitly launch. + * + * @since_tizen 2.3 + * @remarks The @a app_id must be released with free(). + * @param[in] app_control The app_control handle + * @param[out] app_id The ID of the application to explicitly launch + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_app_id() + */ +int app_control_get_app_id(app_control_h app_control, char **app_id); + +/** + * @internal + * @brief Sets the window ID of the application. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] id The window ID of the caller application (if the @a id is not positive, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_get_window() + */ +int app_control_set_window(app_control_h app_control, unsigned int id); + + +/** + * @internal + * @brief Gets the window ID of the application. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[out] id The window ID of the caller application + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_app_id() +*/ +int app_control_get_window(app_control_h app_control, unsigned int *id); + + +/** + * @brief Adds extra data to the app_control. + * + * @since_tizen 2.3 + * @remarks The function replaces any existing value for the given key. + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if @a key or @a value is a zero-length string. + * @remarks The function returns #APP_CONTROL_ERROR_KEY_REJECTED if the application tries to use the same key with system-defined key. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[in] value The value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_REJECTED Key not available + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_get_extra_data() + */ +int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value); + + +/** + * @brief Adds the extra data array to the app_control. + * + * @since_tizen 2.3 + * @remarks The function replaces any existing value for the given key. + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if @a key is a zero-length string. + * @remarks The function returns #APP_CONTROL_ERROR_KEY_REJECTED if the application tries to use the same key with system-defined key. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[in] value The array value associated with the given key + * @param[in] length The length of the array + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_REJECTED Key not available + * @see app_control_add_extra_data() + * @see app_control_remove_extra_data() + * @see app_control_get_extra_data() + */ +int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length); + + +/** + * @brief Removes the extra data from the app_control. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_get_extra_data() + */ +int app_control_remove_extra_data(app_control_h app_control, const char *key); + + +/** + * @brief Gets the extra data from the app_control. + * + * @since_tizen 2.3 + * @remarks The @a value must be released using free(). + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_DATA_TYPE if @a value is of array data type. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] value The value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_INVALID_DATA_TYPE Invalid data type + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_get_extra_data() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_get_extra_data(app_control_h app_control, const char *key, char **value); + + +/** + * @brief Gets the extra data array from the app_control. + * + * @since_tizen 2.3 + * @remarks The @a value must be released using free(). + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_DATA_TYPE if @a value is not of array data type. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] value The array value associated with the given key + * @param[out] length The length of the array + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_INVALID_DATA_TYPE Invalid data type + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length); + + +/** + * @brief Checks whether the extra data associated with the given @a key is of array data type. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] array If @c true the extra data is of array data type, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array); + + +/** + * @brief Retrieves all extra data contained in app_control. + * @details This function calls app_control_extra_data_cb() once for each key-value pair for extra data contained in app_control. \n + * If the app_control_extra_data_cb() callback function returns @c false, then iteration will be finished. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] callback The iteration callback function + * @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 #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @post This function invokes app_control_extra_data_cb(). + * @see app_control_extra_data_cb() + */ +int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data); + + +/** + * @brief Retrieves all applications that can be launched to handle the given app_control request. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @param[in] callback The iteration callback function + * @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 #APP_CONTROL_ERROR_NONE Success + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @post This function invokes app_control_app_matched_cb(). + * @see app_control_app_matched_cb() + */ +int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data); + + +/** + * @brief Sends the launch request. + * + * @details The operation is mandatory information for the launch request. \n + * If the operation is not specified, #APP_CONTROL_OPERATION_DEFAULT is used by default. + * If the operation is #APP_CONTROL_OPERATION_DEFAULT, the application ID is mandatory to explicitly launch the application. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/appmanager.launch + * @param[in] app_control The app_control handle + * @param[in] callback 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 #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_APP_NOT_FOUND The application to run the given launch request is not found + * @retval #APP_CONTROL_ERROR_LAUNCH_REJECTED The application cannot be launched in current context + * @retval #APP_CONTROL_ERROR_LAUNCH_FAILED Failed to launch the application + * @retval #APP_CONTROL_ERROR_TIMED_OUT Failed due to timeout. The application that handles @a app_control may be busy + * @retval #APP_CONTROL_ERROR_PERMISSION_DENIED Permission denied + * @post If the launch request is sent for the result, the result will come back through app_control_reply_cb() from the callee application. + * @see app_control_reply_to_launch_request() + * @see app_control_reply_cb() + */ +int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data); + + +/** + * @brief Sends the terminate request to the application that is launched by app_control. This API is only effective for some applications that are provided by default for handling platform default app_controls. You are not allowed to terminate other general applications using this API. + * + * @since_tizen 2.3 + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_PERMISSION_DENIED Permission denied + * @see app_control_send_launch_request() + */ +int app_control_send_terminate_request(app_control_h app_control); + + +/** + * @brief Replies to the launch request sent by the caller. + * @details If the caller application sent the launch request to receive the result, the callee application can return the result back to the caller. + * + * @since_tizen 2.3 + * @param[in] reply The app_control handle in which the results of the callee are contained + * @param[in] request The app_control handle sent by the caller + * @param[in] result The result code of the launch request + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_send_launch_request() + */ +int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result); + + +/** + * @brief Creates and returns a copy of the given app_control handle. + * + * @since_tizen 2.3 + * @remarks A newly created app_control should be destroyed by calling app_control_destroy() if it is no longer needed. + * + * @param[out] clone If successful, a newly created app_control handle will be returned + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_destroy() + */ +int app_control_clone(app_control_h *clone, app_control_h app_control); + + +/** + * @brief Gets the application ID of the caller from the launch request. + * + * @since_tizen 2.3 + * @remarks The @a app_control must be the launch request from app_control_cb(). + * @remarks This function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if the given app_control is not the launch request. + * @remarks The @a id must be released using free(). + * @param[in] app_control The app_control handle from app_control_cb() + * @param[out] id The application ID of the caller + * @return @a 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_control_get_caller(app_control_h app_control, char **id); + + +/** + * @brief Checks whether the caller is requesting a reply from the launch request. + * + * @since_tizen 2.3 + * @remarks The @a app_control must be the launch request from app_control_cb(). + * @remarks This function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if the given app_control is not the launch request. + * @param[in] app_control The app_control handle from app_control_cb() + * @param[out] requested If @c true a reply is requested by the caller, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_control_is_reply_requested(app_control_h app_control, bool *requested); + +/** + * @internal + * @brief Requests the specified callee window to be transient for the caller window. + * + * @since_tizen 2.3 + * @remarks The @a callee_id window is transient for the top-level caller window and should be handled accordingly. + * @param[in] app_control The app_control handle + * @param[in] callee_id The callee window ID + * @param[in] cbfunc The callback function to be called when the transient is requested + * @param[in] data A data pointer to pass to the callback function + * @return @c 0 on success, + * otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + */ +int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_APP_CONTROL_H__ */ diff --git a/include/app_control_internal.h b/include/app_control_internal.h new file mode 100644 index 0000000..3daa86b --- /dev/null +++ b/include/app_control_internal.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ +#define __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ + +#include <bundle.h> + +#include <app_control.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file app_control_internal.h + */ + +/** + * @addtogroup CAPI_APP_CONTROL_MODULE + * @{ + */ + +/** + * @brief Replaces all data in the app_control with the bundle + * + * @remarks This function clears all data in the app_control and adds all key-value pairs in the bundle into the app_control + * @param [in] app_control The app_control handle + * @param [in] data The bundle handle + * @return 0 on success, otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_export_as_bundle() + * @code + * + * #include <bundle.h> + * #include <app_control.h> + * + * app_control_h app_control = NULL; + * app_control_create(&app_control); + * app_control_import_from_bundle(app_control, b); + * + * @endcode + * + */ +int app_control_import_from_bundle(app_control_h app_control, bundle *data); + +/** + * @brief Returns a new bundle containing all data contained int the app_control + * + * @remarks The @a data must be released with bundle_free() by you. + * @param [in] app_control The app_control handle + * @param [out] data The bundle handle + * @return 0 on success, otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_import_from_bundle() + * @code + * + * #include <bundle.h> + * #include <app_control.h> + * + * bundle* b = NULL; + * app_control_export_as_bundle(app_control, &b); + * + * @endcode + */ +int app_control_export_as_bundle(app_control_h app_control, bundle **data); + +int app_control_create_request(bundle *data, app_control_h *app_control); + +int app_control_create_event(bundle *data, app_control_h *app_control); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ */ diff --git a/src/app_control.c b/src/app_control.c new file mode 100755 index 0000000..9603792 --- /dev/null +++ b/src/app_control.c @@ -0,0 +1,1335 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <bundle.h> +#include <aul.h> +#include <appsvc.h> +#include <dlog.h> + +#include <app_control.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "CAPI_APPFW_APP_CONTROL" + +#ifndef TIZEN_PATH_MAX +#define TIZEN_PATH_MAX 1024 +#endif + +#define BUNDLE_KEY_PREFIX_AUL "__AUL_" +#define BUNDLE_KEY_PREFIX_SERVICE "__APP_SVC_" + +#define BUNDLE_KEY_OPERATION "__APP_SVC_OP_TYPE__" +#define BUNDLE_KEY_URI "__APP_SVC_URI__" +#define BUNDLE_KEY_MIME "__APP_SVC_MIME_TYPE__" +#define BUNDLE_KEY_DATA "__APP_SVC_DATA__" +#define BUNDLE_KEY_PACKAGE "__APP_SVC_PKG_NAME__" +#define BUNDLE_KEY_WINDOW "__APP_SVC_K_WIN_ID__" +#define BUNDLE_KEY_CATEGORY "__APP_SVC_CATEGORY__" + +typedef enum { + APP_CONTROL_TYPE_REQUEST, + APP_CONTROL_TYPE_EVENT, + APP_CONTROL_TYPE_REPLY, +} app_control_type_e; + +struct app_control_s { + int id; + app_control_type_e type; + bundle *data; + int launch_pid; +}; + +typedef struct app_control_request_context_s { + app_control_h app_control; + app_control_reply_cb reply_cb; + void *user_data; +} *app_control_request_context_h; + +extern int appsvc_allow_transient_app(bundle *b, unsigned int id); +extern int appsvc_request_transient_app(bundle *b, unsigned int callee_id, appsvc_host_res_fn cbfunc, void *data); + +static int app_control_create_reply(bundle *data, struct app_control_s **app_control); + +static const char* app_control_error_to_string(app_control_error_e error) +{ + switch (error) + { + case APP_CONTROL_ERROR_NONE: + return "NONE"; + + case APP_CONTROL_ERROR_INVALID_PARAMETER: + return "INVALID_PARAMETER"; + + case APP_CONTROL_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + + case APP_CONTROL_ERROR_APP_NOT_FOUND: + return "APP_NOT_FOUND"; + + case APP_CONTROL_ERROR_KEY_NOT_FOUND: + return "KEY_NOT_FOUND"; + + case APP_CONTROL_ERROR_KEY_REJECTED: + return "KEY_REJECTED"; + + case APP_CONTROL_ERROR_INVALID_DATA_TYPE: + return "INVALID_DATA_TYPE"; + + case APP_CONTROL_ERROR_LAUNCH_REJECTED: + return "LAUNCH_REJECTED"; + + case APP_CONTROL_ERROR_PERMISSION_DENIED: + return "PERMISSION_DENIED"; + + case APP_CONTROL_ERROR_LAUNCH_FAILED: + return "LAUNCH_FAILED"; + + case APP_CONTROL_ERROR_TIMED_OUT: + return "TIMED_OUT"; + + default : + return "UNKNOWN"; + } +} + +int app_control_error(app_control_error_e error, const char* function, const char *description) +{ + if (description) + { + LOGE("[%s] %s(0x%08x) : %s", function, app_control_error_to_string(error), error, description); + } + else + { + if(error == APP_CONTROL_ERROR_KEY_NOT_FOUND) + LOGW("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error); + else + LOGE("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error); + } + + return error; +} + +static int app_control_validate_extra_data(const char *data) +{ + if (data == NULL || data[0] == '\0') + { + return APP_CONTROL_ERROR_INVALID_PARAMETER; + } + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_validate(app_control_h app_control) +{ + if (app_control == NULL || app_control->data == NULL) + { + return APP_CONTROL_ERROR_INVALID_PARAMETER; + } + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_new_id() +{ + static int sid = 0; + return sid++; +} + +int app_control_validate_internal_key(const char *key) +{ + if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0) + { + return -1; + } + + if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0) + { + return -1; + } + + return 0; +} + +static void app_control_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data) +{ + app_control_request_context_h request_context; + app_control_h request; + app_control_h reply = NULL; + app_control_result_e result; + void *user_data; + app_control_reply_cb reply_cb; + + if (appsvc_data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control reply"); + return; + } + + if (app_control_create_reply(appsvc_bundle, &reply) != 0) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control reply"); + return; + } + + request_context = appsvc_data; + request = request_context->app_control; + + switch (appsvc_result) + { + case APPSVC_RES_OK: + result = APP_CONTROL_RESULT_SUCCEEDED; + break; + + case APPSVC_RES_NOT_OK: + result = APP_CONTROL_RESULT_FAILED; + break; + + case APPSVC_RES_CANCEL: + result = APP_CONTROL_RESULT_CANCELED; + break; + + default: + result = APP_CONTROL_RESULT_CANCELED; + break; + } + + user_data = request_context->user_data; + reply_cb = request_context->reply_cb; + + if (reply_cb != NULL) + { + reply_cb(request, reply, result, user_data); + } + else + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback "); + } + + app_control_destroy(reply); + + if (request_context->app_control != NULL) + { + app_control_destroy(request_context->app_control); + } + + free(request_context); +} + +int app_control_create_request(bundle *data, app_control_h *app_control) +{ + struct app_control_s *app_control_request; + + if (app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_request = malloc(sizeof(struct app_control_s)); + + if (app_control_request == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_request->type = APP_CONTROL_TYPE_REQUEST; + + if (data != NULL) + { + app_control_request->data = bundle_dup(data); + } + else + { + app_control_request->data = bundle_create(); + } + + if (app_control_request->data == NULL) + { + free(app_control_request); + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle"); + } + + app_control_request->id = app_control_new_id(); + app_control_request->launch_pid = -1; + + *app_control = app_control_request; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_create(app_control_h *app_control) +{ + return app_control_create_request(NULL, app_control); +} + +int app_control_create_event(bundle *data, struct app_control_s **app_control) +{ + struct app_control_s *app_control_event; + + const char *operation; + + if (data == NULL || app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_event = malloc(sizeof(struct app_control_s)); + + if (app_control_event == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_event->type = APP_CONTROL_TYPE_EVENT; + app_control_event->data = bundle_dup(data); + app_control_event->id = app_control_new_id(); + + operation = appsvc_get_operation(app_control_event->data); + + if (operation == NULL) + { + appsvc_set_operation(app_control_event->data, APP_CONTROL_OPERATION_DEFAULT); + } + + *app_control = app_control_event; + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_create_reply(bundle *data, struct app_control_s **app_control) +{ + struct app_control_s *app_control_reply; + + if (data == NULL || app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_reply = malloc(sizeof(struct app_control_s)); + + if (app_control_reply == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_reply->type = APP_CONTROL_TYPE_REPLY; + app_control_reply->data = bundle_dup(data); + app_control_reply->id = app_control_new_id(); + + *app_control = app_control_reply; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_destroy(app_control_h app_control) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + bundle_free(app_control->data); + app_control->data = NULL; + free(app_control); + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_to_bundle(app_control_h app_control, bundle **data) +{ + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + *data = app_control->data; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_set_operation(app_control_h app_control, const char *operation) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (operation != NULL) + { + if (appsvc_set_operation(app_control->data, operation) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_OPERATION); + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_get_operation(app_control_h app_control, char **operation) +{ + const char *operation_value; + + if (app_control_validate(app_control) || operation == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + operation_value = appsvc_get_operation(app_control->data); + + if (operation_value != NULL) + { + *operation = strdup(operation_value); + } + else + { + *operation = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_uri(app_control_h app_control, const char *uri) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (uri != NULL) + { + if (appsvc_set_uri(app_control->data, uri) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_URI); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_uri(app_control_h app_control, char **uri) +{ + const char *uri_value; + + if (app_control_validate(app_control) || uri == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + uri_value = appsvc_get_uri(app_control->data); + + if (uri_value != NULL) + { + *uri = strdup(uri_value); + } + else + { + *uri = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_mime(app_control_h app_control, const char *mime) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (mime != NULL) + { + if (appsvc_set_mime(app_control->data, mime) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_MIME); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_mime(app_control_h app_control, char **mime) +{ + const char *mime_value; + + if (app_control_validate(app_control) || mime == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + mime_value = appsvc_get_mime(app_control->data); + + if (mime_value != NULL) + { + *mime = strdup(mime_value); + } + else + { + *mime = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_category(app_control_h app_control, const char *category) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (category != NULL) + { + if (appsvc_set_category(app_control->data, category) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_CATEGORY); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_category(app_control_h app_control, char **category) +{ + const char *category_value; + + if (app_control_validate(app_control) || category == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + category_value = appsvc_get_category(app_control->data); + + if (category_value != NULL) + { + *category = strdup(category_value); + } + else + { + *category = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_package(app_control_h app_control, const char *package) +{ + // TODO: this function must be deprecated + return app_control_set_app_id(app_control, package); +} + +int app_control_get_package(app_control_h app_control, char **package) +{ + // TODO: this function must be deprecated + return app_control_get_app_id(app_control, package); +} + + +int app_control_set_app_id(app_control_h app_control, const char *app_id) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_id != NULL) + { + if (appsvc_set_appid(app_control->data, app_id) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_PACKAGE); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_app_id(app_control_h app_control, char **app_id) +{ + const char *app_id_value; + + if (app_control_validate(app_control) || app_id == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_id_value = appsvc_get_appid(app_control->data); + + if (app_id_value != NULL) + { + *app_id = strdup(app_id_value); + } + else + { + *app_id = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_set_window(app_control_h app_control, unsigned int id) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (id > 0) + { + if (appsvc_allow_transient_app(app_control->data, id) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_WINDOW); + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_get_window(app_control_h app_control, unsigned int *id) +{ + const char *window_id; + + if (app_control_validate(app_control) || id == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW); + + if (window_id != NULL) + { + *id = atoi(window_id); + } + else + { + *id = 0; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_clone(app_control_h *clone, app_control_h app_control) +{ + app_control_h app_control_clone; + + if (app_control_validate(app_control) || clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_clone = malloc(sizeof(struct app_control_s)); + + if (app_control_clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_clone->id = app_control_new_id(); + app_control_clone->type = app_control->type; + app_control_clone->data = bundle_dup(app_control->data); + + *clone = app_control_clone; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data) +{ + const char *operation; + + bool implicit_default_operation = false; + int launch_pid; + + app_control_request_context_h request_context = NULL; + + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + operation = appsvc_get_operation(app_control->data); + if (operation == NULL) + { + implicit_default_operation = true; + operation = APP_CONTROL_OPERATION_DEFAULT; + } + + // TODO: Check the privilege for call operation + + // operation : default + if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) + { + const char *appid = appsvc_get_appid(app_control->data); + if (appid == NULL) + { + return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value"); + } + } + + if (callback != NULL) + { + app_control_h request_clone = NULL; + + request_context = calloc(1, sizeof(struct app_control_request_context_s)); + + if (request_context == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + request_context->reply_cb = callback; + + if (app_control_clone(&request_clone, app_control) != APP_CONTROL_ERROR_NONE) + { + free(request_context); + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the app_control request handle"); + } + + request_context->app_control = request_clone; + request_context->user_data = user_data; + } + + if (implicit_default_operation == true) + { + appsvc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT); + } + + launch_pid = appsvc_run_service(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context); + + if (implicit_default_operation == true) + { + bundle_del(app_control->data, BUNDLE_KEY_OPERATION); + } + + if (launch_pid < 0) + { + if (launch_pid == APPSVC_RET_ENOMATCH) + { + return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL); + } + else if (launch_pid == APPSVC_RET_EILLACC) + { + return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); + } + else if (launch_pid == APPSVC_RET_EINVAL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL); + } + } + + app_control->launch_pid = launch_pid; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_send_terminate_request(app_control_h app_control) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if(app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + appsvc_subapp_terminate_request_pid(app_control->launch_pid); + + return APP_CONTROL_ERROR_NONE; +} + +static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data) +{ + bundle *reply_data = user_data; + char *value = NULL; + char **value_array = NULL; + int value_array_length = 0; + int value_array_index = 0; + + if (reply_data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return false; + } + + if (appsvc_data_is_array(app_control->data, key)) + { + app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length); + appsvc_add_data_array(reply_data, key, (const char**)value_array, value_array_length); + + for (value_array_index=0; value_array_index < value_array_length; value_array_index++) + { + free(value_array[value_array_index]); + } + + free(value_array); + } + else + { + app_control_get_extra_data(app_control, key, &value); + appsvc_add_data(reply_data, key, value); + free(value); + } + + return true; +} + +int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result) +{ + bundle *reply_data; + int appsvc_result; + int ret = 0; + + if (app_control_validate(reply) || app_control_validate(request)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (appsvc_create_result_bundle(request->data, &reply_data) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle"); + } + + app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data); + + switch (result) + { + case APP_CONTROL_RESULT_SUCCEEDED: + appsvc_result = APPSVC_RES_OK; + break; + + case APP_CONTROL_RESULT_FAILED: + appsvc_result = APPSVC_RES_NOT_OK; + break; + + case APP_CONTROL_RESULT_CANCELED: + appsvc_result = APPSVC_RES_CANCEL; + break; + + default: + appsvc_result = APPSVC_RES_CANCEL; + break; + } + + ret = appsvc_send_result(reply_data, appsvc_result); + if (ret < 0) + { + if (ret == APPSVC_RET_EINVAL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL); + } + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (appsvc_get_data(app_control->data, key) != NULL) + { + // overwrite any existing value + bundle_del(app_control->data, key); + } + + if (appsvc_add_data(app_control->data, key, value) != 0) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle"); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (value == NULL || length <= 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array"); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (appsvc_get_data_array(app_control->data, key, NULL) != NULL) + { + // overwrite any existing value + bundle_del(app_control->data,key); + } + + if (appsvc_add_data_array(app_control->data, key, value, length) != 0) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle"); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_remove_extra_data(app_control_h app_control, const char *key) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (bundle_del(app_control->data, key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_extra_data(app_control_h app_control, const char *key, char **value) +{ + const char *data_value; + + if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + data_value = appsvc_get_data(app_control->data, key); + + if (data_value == NULL) + { + if (errno == ENOTSUP) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + } + + *value = strdup(data_value); + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length) +{ + const char **array_data; + int array_data_length; + char **array_data_clone; + int i; + + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (value == NULL || length == 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + array_data = appsvc_get_data_array(app_control->data, key, &array_data_length); + + if (array_data == NULL) + { + if (errno == ENOTSUP) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + } + + array_data_clone = calloc(array_data_length, sizeof(char*)); + + if (array_data_clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + for (i=0; i<array_data_length; i++) + { + if (array_data[i] != NULL) + { + array_data_clone[i] = strdup(array_data[i]); + } + } + + *value = array_data_clone; + *length = array_data_length; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key) || array == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); +
} + + if (!appsvc_data_is_array(app_control->data, key)) + { + *array = false; + } + else + { + *array = true; + } + + return APP_CONTROL_ERROR_NONE; +} + + +typedef struct { + app_control_h app_control; + app_control_extra_data_cb callback; + void* user_data; + bool foreach_break; +} foreach_context_extra_data_t; + +static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data) +{ + foreach_context_extra_data_t* foreach_context = NULL; + app_control_extra_data_cb extra_data_cb; + + if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY)) + { + return; + } + + foreach_context = (foreach_context_extra_data_t*)user_data; + + if (foreach_context->foreach_break == true) + { + return; + } + + if (app_control_validate_internal_key(key)) + { + return; + } + + extra_data_cb = foreach_context->callback; + + if (extra_data_cb != NULL) + { + bool stop_foreach = false; + + stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data); + + foreach_context->foreach_break = stop_foreach; + } + +} + + +int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data) +{ + foreach_context_extra_data_t foreach_context = { + .app_control = app_control, + .callback = callback, + .user_data = user_data, + .foreach_break = false + }; + + if (app_control_validate(app_control) || callback == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context); + + return APP_CONTROL_ERROR_NONE; +} + +typedef struct { + app_control_h app_control; + app_control_app_matched_cb callback; + void* user_data; + bool foreach_break; +} foreach_context_launchable_app_t; + +int app_control_cb_broker_foreach_app_matched(const char *package, void *data) +{ + foreach_context_launchable_app_t *foreach_context; + app_control_app_matched_cb app_matched_cb; + + if (package == NULL || data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return -1; + } + + foreach_context = (foreach_context_launchable_app_t*)data; + + if (foreach_context->foreach_break == true) + { + return -1; + } + + app_matched_cb = foreach_context->callback; + + if (app_matched_cb != NULL) + { + bool stop_foreach = false; + + stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data); + + foreach_context->foreach_break = stop_foreach; + } + + return 0; +} + +int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data) +{ + foreach_context_launchable_app_t foreach_context = { + .app_control = app_control, + .callback = callback, + .user_data = user_data, + .foreach_break = false + }; + + if (app_control_validate(app_control) || callback == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + appsvc_get_list(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context); + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_caller(app_control_h app_control, char **package) +{ + const char *bundle_value; + char *package_dup; + + if (app_control_validate(app_control) || package == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control->type != APP_CONTROL_TYPE_EVENT) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type"); + } + + bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID); + if (bundle_value == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller"); + } + + package_dup = strdup(bundle_value); + + if (package_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + *package = package_dup; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_is_reply_requested(app_control_h app_control, bool *requested) +{ + const char *bundle_value; + + if (app_control_validate(app_control) || requested == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control->type != APP_CONTROL_TYPE_EVENT) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type"); + } + + bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT); + + if (bundle_value != NULL) + { + *requested = true; + } + else + { + *requested = false; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_import_from_bundle(app_control_h app_control, bundle *data) +{ + bundle *data_dup = NULL; + + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + data_dup = bundle_dup(data); + + if (data_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); + } + + if (app_control->data != NULL) + { + bundle_free(app_control->data); + } + + app_control->data = data_dup; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_export_as_bundle(app_control_h app_control, bundle **data) +{ + bundle *data_dup = NULL; + + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + data_dup = bundle_dup(app_control->data); + + if (data_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); + } + + *data = data_dup; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data) +{ + int ret; + + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + ret = appsvc_request_transient_app(app_control->data, callee_id, (appsvc_host_res_fn)cbfunc, data); + + if (ret < 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + return APP_CONTROL_ERROR_NONE; +} + |