From: Jiwoong Im Date: Mon, 3 Aug 2015 08:32:26 +0000 (+0900) Subject: add async launch request result X-Git-Tag: accepted/tizen/4.0/unified/20170816.011601~6^2~107 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=418edbf80d9f655f6305b2c41585807f03a10459;p=platform%2Fcore%2Fapi%2Fapp-control.git add async launch request result add app_control_enable_launch_result_event() api Change-Id: I0bf5904c1e119765d8f8e6bad1583d239f3dd989 Signed-off-by: Jiwoong Im --- diff --git a/app_control/app_control.c b/app_control/app_control.c index 33c2352..dfe1af2 100644 --- a/app_control/app_control.c +++ b/app_control/app_control.c @@ -73,7 +73,7 @@ typedef struct app_control_request_context_s { 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) @@ -113,6 +113,9 @@ 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"; } @@ -126,7 +129,7 @@ int app_control_error(app_control_error_e error, const char* function, const cha } 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); @@ -353,6 +356,12 @@ int app_control_destroy(app_control_h 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 && + 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); @@ -743,6 +752,65 @@ int app_control_get_launch_mode(app_control_h 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; @@ -838,6 +906,24 @@ int app_control_send_launch_request(app_control_h app_control, app_control_reply } 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; } @@ -850,7 +936,7 @@ int app_control_send_terminate_request(app_control_h 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) + if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0) { return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); } @@ -907,6 +993,11 @@ int app_control_reply_to_launch_request(app_control_h reply, app_control_h reque 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"); @@ -1133,7 +1224,7 @@ int app_control_is_extra_data_array(app_control_h app_control, const char *key, 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)) { @@ -1378,7 +1469,6 @@ int app_control_export_as_bundle(app_control_h app_control, bundle **data) 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; @@ -1398,3 +1488,21 @@ int app_control_request_transient_app(app_control_h app_control, unsigned int ca 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; +} diff --git a/include/app_control.h b/include/app_control.h index be6427e..b39fe84 100644 --- a/include/app_control.h +++ b/include/app_control.h @@ -67,13 +67,15 @@ typedef enum /** * @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; /** @@ -81,8 +83,8 @@ typedef enum * @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; /** @@ -288,8 +290,12 @@ typedef enum { * @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); @@ -725,9 +731,10 @@ int app_control_foreach_app_matched(app_control_h app_control, app_control_app_m * @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); @@ -735,6 +742,9 @@ int app_control_send_launch_request(app_control_h app_control, app_control_reply /** * @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, @@ -743,6 +753,7 @@ int app_control_send_launch_request(app_control_h app_control, app_control_reply * @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); @@ -752,6 +763,7 @@ 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 @@ -821,6 +833,11 @@ int app_control_is_reply_requested(app_control_h app_control, bool *requested); /** * @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 @@ -849,6 +866,22 @@ int app_control_set_launch_mode(app_control_h app_control, */ 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); /** * @} */