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);
-
+extern int aul_invoke_caller_cb(int launch_pid);
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)
case APP_CONTROL_ERROR_TIMED_OUT:
return "TIMED_OUT";
+ case APP_CONTROL_ERROR_IO_ERROR:
+ return "IO ERROR";
+
default :
return "UNKNOWN";
}
}
else
{
- if(error == APP_CONTROL_ERROR_KEY_NOT_FOUND)
+ 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 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
}
+ if (app_control->type == APP_CONTROL_TYPE_REQUEST && app_control->launch_pid > 0 &&
+ bundle_get_val(app_control->data, APPSVC_K_LAUNCH_RESULT_APP_STARTED) == NULL)
+ {
+ aul_remove_caller_cb(app_control->launch_pid);
+ }
+
bundle_free(app_control->data);
app_control->data = NULL;
free(app_control);
return APP_CONTROL_ERROR_NONE;
}
+static void __update_launch_pid(int launched_pid, void *data)
+{
+ app_control_h app_control;
+
+ if (data == NULL)
+ return;
+
+ app_control = data;
+
+ app_control->launch_pid = launched_pid;
+}
+
+static void __handle_launch_result(int launched_pid, void *data)
+{
+ app_control_request_context_h request_context;
+ app_control_h reply = NULL;
+ app_control_h request;
+ app_control_result_e result;
+ app_control_reply_cb reply_cb;
+ void *user_data;
+ char callee[255] = {0, };
+ int ret = 0;
+
+ if (data == NULL)
+ return;
+
+ request_context = (app_control_request_context_h)data;
+
+ if (app_control_create_event(request_context->app_control->data, &reply) != 0)
+ {
+ app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control event");
+ return;
+ }
+
+ ret = aul_app_get_appid_bypid(launched_pid, callee, sizeof(callee));
+ if (ret < 0) {
+ LOGE("aul_app_get_appid_bypid failed: %d", launched_pid);
+ }
+
+ app_control_set_app_id(reply, callee);
+ LOGI("app control async result callback callee pid:%d", launched_pid);
+
+ result = APP_CONTROL_RESULT_APP_STARTED;
+ request = request_context->app_control;
+ 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);
+}
+
int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
{
const char *operation;
}
app_control->launch_pid = launch_pid;
+ /* app_control_enable_app_started_result_event called */
+ if (bundle_get_val(app_control->data, APPSVC_K_LAUNCH_RESULT_APP_STARTED)) {
+ char callee[255] = {0,};
+ if (aul_app_get_appid_bypid(launch_pid, callee, sizeof(callee)) != AUL_R_OK)
+ LOGE("aul_app_get_appid_bypid failed: %d", launch_pid);
+
+ if (request_context && request_context->app_control)
+ request_context->app_control->launch_pid = launch_pid;
+
+ aul_add_caller_cb(launch_pid, __handle_launch_result, request_context);
+
+ /* launched without app selector */
+ if (strncmp(callee, APP_SELECTOR, strlen(APP_SELECTOR)) != 0)
+ aul_invoke_caller_cb(launch_pid);
+
+ } else { /* default case */
+ aul_add_caller_cb(launch_pid, __update_launch_pid, app_control);
+ }
return APP_CONTROL_ERROR_NONE;
}
return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
}
- if(app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
+ if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
{
return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
}
return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
}
+ if (result == APP_CONTROL_RESULT_APP_STARTED)
+ {
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "APP_CONTROL_RESULT_APP_STARTED is not allowed to use");
+ }
+
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");
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");
-\r }
+ }
if (!appsvc_data_is_array(app_control->data, key))
{
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;
return APP_CONTROL_ERROR_NONE;
}
+int app_control_enable_app_started_result_event(app_control_h app_control)
+{
+ int ret;
+
+ if (app_control_validate(app_control))
+ {
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ ret = aul_svc_subscribe_launch_result(app_control->data, APPSVC_K_LAUNCH_RESULT_APP_STARTED);
+
+ if (ret < 0)
+ {
+ return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ return APP_CONTROL_ERROR_NONE;
+}
/**
* @brief Enumeration for App Control Result.
+ * @see app_control_enable_app_started_result_event()
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
typedef enum
{
+ APP_CONTROL_RESULT_APP_STARTED = 1, /**< Callee application launched actually (Since 2.4) */
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_CANCELED = -2, /**< Operation canceled by the platform */
} app_control_result_e;
/**
* @since_tizen 2.4
*/
typedef enum {
- APP_CONTROL_LAUNCH_MODE_SINGLE = 0,
- APP_CONTROL_LAUNCH_MODE_GROUP,
+ APP_CONTROL_LAUNCH_MODE_SINGLE = 0, /**< Prefer to launch an application as single mode */
+ APP_CONTROL_LAUNCH_MODE_GROUP, /**< Prefer to launch an application as group mode */
} app_control_launch_mode_e;
/**
* @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.
+ * @pre Since 2.4, if #APP_CONTROL_RESULT_APP_STARTED event is enabled,
+ * this callback also will be invoked when the callee app actually launched.
* @see app_control_send_launch_request()
* @see app_control_reply_to_launch_request()
+ * @see app_control_enable_app_started_result_event()
+ * @see #APP_CONTROL_RESULT_APP_STARTED
*/
typedef void (*app_control_reply_cb) (app_control_h request, app_control_h reply, app_control_result_e result, void *user_data);
* @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.
+ * @post If the launch request is sent for the result, the result will come back through app_control_reply_cb() from the callee application. Additional replies may be delivered on app_control_enable_app_started_result_event() called.
* @see app_control_reply_to_launch_request()
* @see app_control_reply_cb()
+ * @see app_control_enable_app_started_result_event()
*/
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.
*
+ * @remarks Since Tizen 2.4, this API can be used to terminate sub-applications which were launched as group mode by caller application.
+ * Once callee application is being terminated by this API, other applications which were launched by callee application as group mode will be terminated as well.
+ *
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @param[in] app_control The app_control handle
* @return @c 0 on success,
* @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #APP_CONTROL_ERROR_PERMISSION_DENIED Permission denied
* @see app_control_send_launch_request()
+ * @see app_control_set_launch_mode()
*/
int app_control_send_terminate_request(app_control_h app_control);
* @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 @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @remarks The function is not allowed to send reply #APP_CONTROL_RESULT_APP_STARTED as @a result which is reserved for platform developers.
* @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
/**
* @brief Sets the launch mode of the application.
*
+ * @details This function allows callee application to be launched as group or single mode.
+ * @remarks Although launch_mode were set as #APP_CONTROL_LAUNCH_MODE_GROUP, callee application would be launched as single mode if the manifest file of callee application defined the launch mode as "single".
+ * This function can just set the preference of caller application to launch an application.
+ * @remarks Sub-applications which were launched as group mode always have own process.
+ *
* @since_tizen 2.4
* @param[in] app_control The app_control handle
* @param[in] launch_mode The launch mode of app
*/
int app_control_get_launch_mode(app_control_h app_control,
app_control_launch_mode_e *mode);
+
+/**
+ * @brief Enables additional launch result event on launch request.
+ *
+ * @details The function allows to receive #APP_CONTROL_RESULT_APP_STARTED event on\n
+ * application get launched by app_control.
+ * @remarks app_control_reply_cb() will be called on APP_CONTROL_RESULT_APP_STARTED event received.
+ * @since_tizen 2.4
+ * @param[in] app_control The app_control 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_send_launch_request()
+ * @see #APP_CONTROL_RESULT_APP_STARTED
+ */
+int app_control_enable_app_started_result_event(app_control_h app_control);
/**
* @}
*/