summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSangyoon Jang <s89.jang@samsung.com>2014-12-19 16:49:40 +0900
committerSangyoon Jang <s89.jang@samsung.com>2014-12-22 19:23:45 +0900
commite3907ebfb0e5f2a9db74df2741402b5c84e05731 (patch)
tree2be1fe9cd6436e8fa54aade9c4ad83a2ab965711
parent4383609dbe3f4b43240030d392bb1b81aef22b0f (diff)
downloadapplication-e3907ebfb0e5f2a9db74df2741402b5c84e05731.tar.gz
application-e3907ebfb0e5f2a9db74df2741402b5c84e05731.tar.bz2
application-e3907ebfb0e5f2a9db74df2741402b5c84e05731.zip
Add app_control source from tizen_2.3
app_control is renamed from service api(for consistent with web api) service api will be deprecated Change-Id: I18d09e692075f8a4349064206172beae5a0b5953 Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
-rwxr-xr-xinclude/app.h1
-rwxr-xr-xinclude/app_control.h876
-rw-r--r--include/app_control_internal.h95
-rwxr-xr-xsrc/app_control.c1335
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;
+}
+