The status API is implmented using C++ language.
Change-Id: Ia1930ea1565b7710e266a224f02826486df54bb6
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
int aul_app_get_status_for_uid(const char *appid, uid_t uid);
/**
+ * @brief Called when the status is changed.
+ * @remarks If @c is a negative error value,
+ * the registered callback function will be deregistered.
+ * @param[in] status The status
+ * @param[in] user_data The user data passed from the registration function
+ * @return @c 0 to continue with the next iteration of the loop,
+ * otherwise a negative error value to break out of the loop
+ * @see aul_add_status_local_cb()
+ * @see aul_remove_status_local_cb();
+ */
+typedef int (*aul_status_local_cb)(int status, void *user_data);
+
+/**
* @par Description
* This API sets callback function that on application status changed.
* @par Purpose:
* the caller process. In general, a library that required to release resource on
* application's status may use this API.
*
- * @param[in] func callback function
- * @param[in] data user data
+ * @param[in] callback callback function
+ * @param[in] data user data
* @return 0 if success, negative value if fail
* @retval AUL_R_OK - success
* @retval AUL_R_ERROR - general error
* This API is only available in User Session.
*
*/
-int aul_add_status_local_cb(int (*func) (int, void *), void *data);
+int aul_add_status_local_cb(aul_status_local_cb callback, void *data);
/**
* @par Description
* This API's purpose is to remove callback that added by
* aul_add_status_local_cb.
*
- * @param[in] func callback function
- * @param[in] data user data
+ * @param[in] callback callback function
+ * @param[in] data user data
* @return 0 if success, negative value if fail
* @retval AUL_R_OK - success
* @retval AUL_R_ERROR - general error
* This API is only available in User Session.
*
*/
-int aul_remove_status_local_cb(int (*func) (int, void *), void *data);
+int aul_remove_status_local_cb(aul_status_local_cb callback, void *data);
/*
* This API is only for appfw internally.
+++ /dev/null
-/*
- * Copyright (c) 2000 - 2015 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-
-#include "aul_util.h"
-#include "aul_sock.h"
-#include "aul_api.h"
-#include "launch.h"
-#include "aul_app_com.h"
-#include "aul_error.h"
-
-typedef struct _app_status_cb_info_t {
- int (*handler)(int status, void *data);
- void *data;
-} app_status_cb_info_t;
-
-struct status_listen_s {
- aul_app_com_connection_h conn;
- app_status_cb callback;
- void *user_data;
-};
-
-static int app_status = STATUS_LAUNCHING;
-static GList *app_status_cb_list;
-
-API int aul_status_update(int status)
-{
- int ret;
- app_status_cb_info_t *cb;
- GList *iter;
-
- if (app_status == status)
- return 0;
-
- app_status = status;
-
- ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(), APP_STATUS_UPDATE,
- (unsigned char *)&status, sizeof(status), AUL_SOCK_NOREPLY);
-
- if (!ret) {
- iter = g_list_first(app_status_cb_list);
- while (iter) {
- cb = (app_status_cb_info_t *)iter->data;
- iter = g_list_next(iter);
- if (cb && cb->handler) {
- if (cb->handler(app_status, cb->data) < 0) {
- app_status_cb_list = g_list_remove(
- app_status_cb_list, cb);
- free(cb);
- }
- }
- }
- }
-
- return ret;
-}
-
-API int aul_app_get_status_bypid(int pid)
-{
- return aul_app_get_status_bypid_for_uid(pid, getuid());
-}
-
-API int aul_app_get_status_bypid_for_uid(int pid, uid_t uid)
-{
- int ret;
- char buf[MAX_PID_STR_BUFSZ];
- bundle *b;
-
- if (pid == getpid())
- return app_status;
-
- b = bundle_create();
- if (b == NULL) {
- _E("out of memory");
- return AUL_R_ERROR;
- }
-
- snprintf(buf, sizeof(buf), "%d", pid);
- bundle_add(b, AUL_K_PID, buf);
- snprintf(buf, sizeof(buf), "%d", uid);
- bundle_add(b, AUL_K_TARGET_UID, buf);
-
- ret = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_STATUS,
- b, AUL_SOCK_NONE);
- bundle_free(b);
-
- return ret;
-}
-
-API int aul_app_get_status(const char *appid)
-{
- return aul_app_get_status_for_uid(appid, getuid());
-}
-
-API int aul_app_get_status_for_uid(const char *appid, uid_t uid)
-{
- int ret;
- bundle *kb;
- char buf[MAX_PID_STR_BUFSZ];
-
- if (appid == NULL)
- return AUL_R_EINVAL;
-
- kb = bundle_create();
- if (kb == NULL) {
- _E("out of memory");
- return AUL_R_ERROR;
- }
-
- snprintf(buf, sizeof(buf), "%d", uid);
- bundle_add(kb, AUL_K_APPID, appid);
- bundle_add(kb, AUL_K_TARGET_UID, buf);
- ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid,
- APP_GET_STATUS_BY_APPID, kb);
- bundle_free(kb);
-
- return ret;
-}
-
-API int aul_add_status_local_cb(int (*func)(int status, void *data), void *data)
-{
- app_status_cb_info_t *cb;
- GList *iter;
-
- if (func == NULL)
- return -1;
-
- iter = g_list_first(app_status_cb_list);
- while (iter) {
- cb = (app_status_cb_info_t *)iter->data;
- if (cb && cb->handler == func && cb->data == data) {
- _D("Already exists");
- return 0;
- }
-
- iter = g_list_next(iter);
- }
-
- cb = (app_status_cb_info_t *)malloc(sizeof(app_status_cb_info_t));
- if (cb == NULL) {
- _E("out of memory");
- return -1;
- }
-
- cb->handler = func;
- cb->data = data;
-
- app_status_cb_list = g_list_append(app_status_cb_list, cb);
-
- return 0;
-}
-
-API int aul_remove_status_local_cb(int (*func)(int status, void *data), void *data)
-{
- app_status_cb_info_t *cb;
- GList *iter;
-
- iter = g_list_first(app_status_cb_list);
- while (iter) {
- cb = (app_status_cb_info_t *)iter->data;
- iter = g_list_next(iter);
- if (cb && cb->handler == func && cb->data == data) {
- app_status_cb_list = g_list_remove(app_status_cb_list, cb);
- free(cb);
- return 0;
- }
- }
-
- return -1;
-}
-
-API int aul_invoke_status_local_cb(int status)
-{
- app_status_cb_info_t *cb;
- GList *iter;
-
- iter = g_list_first(app_status_cb_list);
- while (iter) {
- cb = (app_status_cb_info_t *)iter->data;
- iter = g_list_next(iter);
- if (cb && cb->handler) {
- if (cb->handler(status, cb->data) < 0) {
- app_status_cb_list = g_list_remove(
- app_status_cb_list, cb);
- free(cb);
- }
- }
- }
-
- return 0;
-}
-
-API int aul_set_process_group(int owner_pid, int child_pid)
-{
- int ret = -1;
- bundle *kb = NULL;
- char pid_buf[MAX_PID_STR_BUFSZ] = {0,};
-
- kb = bundle_create();
-
- if (kb == NULL)
- return -1;
-
- snprintf(pid_buf, MAX_PID_STR_BUFSZ, "%d", owner_pid);
- bundle_add(kb, AUL_K_OWNER_PID, pid_buf);
- snprintf(pid_buf, MAX_PID_STR_BUFSZ, "%d", child_pid);
- bundle_add(kb, AUL_K_CHILD_PID, pid_buf);
- ret = app_send_cmd(AUL_UTIL_PID, APP_SET_PROCESS_GROUP, kb);
- bundle_free(kb);
-
- return ret;
-}
-
-static int __app_status_event_cb(const char *endpoint, aul_app_com_result_e res,
- bundle *envelope, void *user_data)
-{
- struct status_listen_s *listen = (struct status_listen_s *)user_data;
- aul_app_info app_info = { 0, };
- const char *val;
- int context_status;
-
- if (listen == NULL) {
- _E("Critical error");
- return -1;
- }
-
- bundle_get_str(envelope, AUL_K_APPID, &app_info.appid);
- if (app_info.appid == NULL) {
- _E("Failed to get application id");
- return -1;
- }
-
- bundle_get_str(envelope, AUL_K_PKGID, &app_info.pkgid);
- if (app_info.pkgid == NULL) {
- _E("Failed to get package id");
- return -1;
- }
-
- bundle_get_str(envelope, AUL_K_EXEC, &app_info.app_path);
- if (app_info.app_path == NULL) {
- _E("Failed to get app path");
- return -1;
- }
-
- bundle_get_str(envelope, AUL_K_INSTANCE_ID, &app_info.instance_id);
-
- val = bundle_get_val(envelope, AUL_K_PID);
- if (val == NULL) {
- _E("Failed to get pid");
- return -1;
- }
- app_info.pid = atoi(val);
-
- val = bundle_get_val(envelope, AUL_K_STATUS);
- if (val == NULL) {
- _E("Failed to get status");
- return -1;
- }
- app_info.status = atoi(val);
-
- val = bundle_get_val(envelope, AUL_K_IS_SUBAPP);
- if (val == NULL) {
- _E("Failed to get is_subapp");
- return -1;
- }
- app_info.is_sub_app = atoi(val);
-
- val = bundle_get_val(envelope, "__CONTEXT_STATUS__");
- if (val == NULL) {
- _E("Failed to get context status");
- return -1;
- }
- context_status = atoi(val);
-
- listen->callback(&app_info, context_status, listen->user_data);
-
- return 0;
-}
-
-API int aul_listen_app_status_for_uid(const char *appid, app_status_cb callback,
- void *data, status_listen_h *handle, uid_t uid)
-{
- struct status_listen_s *listen;
- char endpoint[128];
-
- if (appid == NULL || callback == NULL || handle == NULL) {
- _E("Invalid parameter");
- return AUL_R_EINVAL;
- }
-
- listen = calloc(1, sizeof(struct status_listen_s));
- if (listen == NULL) {
- _E("Out of memory");
- return AUL_R_ERROR;
- }
-
- if (uid < REGULAR_UID_MIN) {
- snprintf(endpoint, sizeof(endpoint),
- "app_status_event:%s", appid);
- } else {
- snprintf(endpoint, sizeof(endpoint),
- "app_status_event:%s:%d", appid, uid);
- }
-
- aul_app_com_create(endpoint, NULL, __app_status_event_cb,
- listen, &listen->conn);
- if (listen->conn == NULL) {
- _E("Failed to create app com");
- free(listen);
- return AUL_R_ERROR;
- }
-
- listen->callback = callback;
- listen->user_data = data;
-
- *handle = listen;
-
- return AUL_R_OK;
-}
-
-API int aul_listen_app_status(const char *appid, app_status_cb callback,
- void *data, status_listen_h *handle)
-{
- return aul_listen_app_status_for_uid(appid, callback, data, handle,
- getuid());
-}
-
-API int aul_ignore_app_status(status_listen_h handle)
-{
- if (handle == NULL)
- return AUL_R_EINVAL;
-
- if (handle->conn)
- aul_app_com_leave(handle->conn);
- free(handle);
-
- return AUL_R_OK;
-}
-
-API int aul_notify_exit(void)
-{
- return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
- APP_NOTIFY_EXIT, NULL, 0, AUL_SOCK_NOREPLY);
-}
-
-API int aul_notify_start(void)
-{
- int r;
-
- r = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
- APP_NOTIFY_START, NULL, 0, AUL_SOCK_NOREPLY);
- return r;
-}
-
-API const char *aul_app_status_convert_to_string(int status)
-{
- switch (status) {
- case STATUS_LAUNCHING:
- return "STATUS_LAUNCHING";
- case STATUS_CREATED:
- return "STATUS_CREATED";
- case STATUS_FOCUS:
- return "STATUS_FOCUS";
- case STATUS_VISIBLE:
- return "STATUS_VISIBLE";
- case STATUS_BG:
- return "STATUS_BG";
- case STATUS_DYING:
- return "STATUS_DYING";
- case STATUS_HOME:
- return "STATUS_HOME";
- case STATUS_NORESTART:
- return "STATUS_NORESTART";
- case STATUS_SERVICE:
- return "STATUS_SERVICE";
- case STATUS_TERMINATE:
- return "STATUS_TERMINATE";
- default:
- return "Unknown status";
- }
-}
-
-API int aul_status_update_v2(int status)
-{
- char buf[12];
- bundle *b;
- int ret;
-
- if (status < 0) {
- _E("Invalid parameter");
- return AUL_R_EINVAL;
- }
-
- if (app_status == status)
- return AUL_R_OK;
-
- app_status = status;
-
- b = bundle_create();
- if (!b) {
- _E("Out of memory");
- return AUL_R_ENOMEM;
- }
-
- snprintf(buf, sizeof(buf), "%d", status);
- bundle_add(b, AUL_K_STATUS, buf);
-
- ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_STATUS_UPDATE_V2,
- b, AUL_SOCK_NONE);
- bundle_free(b);
- if (ret != 0) {
- _E("Failed to update app status. error(%d)", ret);
- return aul_error_convert(ret);
- } else {
- aul_invoke_status_local_cb(status);
- }
-
- return AUL_R_OK;
-}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2022 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 "include/aul.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <bundle_cpp.h>
+
+#include <list>
+#include <memory>
+#include <mutex>
+
+#include "aul_api.h"
+#include "aul_util.h"
+#include "include/aul_app_com.h"
+#include "include/aul_error.h"
+#include "include/aul_sock.h"
+#include "launch.h"
+
+#include "app_request.h"
+#include "aul/common/exception.hh"
+
+using namespace aul::internal;
+
+struct status_listen_s {
+ void* dummy;
+};
+
+namespace {
+using namespace aul;
+
+class AppStatusEvent {
+ public:
+ AppStatusEvent(std::string appid, uid_t uid, app_status_cb cb,
+ void* user_data)
+ : appid_(std::move(appid)),
+ uid_(uid),
+ cb_(cb),
+ user_data_(user_data) {
+ std::string endpoint = "app_status_event:" + appid_;
+ if (uid_ < REGULAR_UID_MIN)
+ endpoint += ":" + std::to_string(uid_);
+
+ int ret = aul_app_com_create(endpoint.c_str(), nullptr, OnAppComCb, this,
+ &connection_);
+ if (ret != AUL_R_OK) {
+ _E("aul_app_com_create() is failed. endpoint(%s), error(%d)",
+ endpoint.c_str(), ret);
+ THROW(ret);
+ }
+ }
+
+ ~AppStatusEvent() {
+ if (connection_ != nullptr)
+ aul_app_com_leave(connection_);
+ }
+
+ private:
+ static int OnAppComCb(const char* endpoint, aul_app_com_result_e res,
+ bundle* envelope, void* user_data) {
+ tizen_base::Bundle b(envelope);
+ aul_app_info app_info = { 0, };
+ app_info.appid = const_cast<char*>(b.GetString(AUL_K_APPID).c_str());
+ app_info.pkgid = const_cast<char*>(b.GetString(AUL_K_PKGID).c_str());
+ app_info.app_path = const_cast<char*>(b.GetString(AUL_K_EXEC).c_str());
+ app_info.instance_id = const_cast<char*>(
+ b.GetString(AUL_K_INSTANCE_ID).c_str());
+ app_info.pid = std::stoi(b.GetString(AUL_K_PID));
+ app_info.status = std::stoi(b.GetString(AUL_K_STATUS));
+ app_info.is_sub_app = std::stoi(b.GetString(AUL_K_IS_SUBAPP));
+ int context_status = std::stoi(b.GetString("__CONTEXT_STATUS__"));
+
+ auto* event = static_cast<AppStatusEvent*>(user_data);
+ event->cb_(&app_info, context_status, event->user_data_);
+ return 0;
+ }
+
+ private:
+ std::string appid_;
+ uid_t uid_;
+ app_status_cb cb_;
+ void* user_data_;
+ aul_app_com_connection_h connection_ = nullptr;
+};
+
+class StatusLocalCb {
+ public:
+ StatusLocalCb(aul_status_local_cb cb, void* user_data)
+ : cb_(cb), user_data_(user_data) {
+ }
+
+ aul_status_local_cb GetCb() const {
+ return cb_;
+ }
+
+ void* GetUserData() const {
+ return user_data_;
+ }
+
+ int Invoke(int status) {
+ if (cb_ != nullptr)
+ return cb_(status, user_data_);
+
+ return 0;
+ }
+
+ private:
+ aul_status_local_cb cb_;
+ void* user_data_;
+};
+
+class Context {
+ public:
+ Context() = default;
+
+ int GetStatus() const {
+ return status_;
+ }
+
+ void SetStatus(int status) {
+ status_ = status;
+ }
+
+ void AddLocalCb(aul_status_local_cb cb, void* user_data) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ cbs_.emplace_back(new StatusLocalCb(cb, user_data));
+ }
+
+ std::size_t RemoveLocalCb(aul_status_local_cb cb, void* user_data) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto count = cbs_.size();
+ cbs_.remove_if([&](const std::unique_ptr<StatusLocalCb>& local_cb) {
+ return local_cb->GetCb() == cb &&
+ local_cb->GetUserData() == user_data;
+ });
+ return count - cbs_.size();
+ }
+
+ void InvokeLocalCb(int status) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto iter = cbs_.begin();
+ while (iter != cbs_.end()) {
+ if ((*iter)->Invoke(status) < 0)
+ iter = cbs_.erase(iter);
+ else
+ iter++;
+ }
+ }
+
+ private:
+ int status_ = STATUS_LAUNCHING;
+ std::list<std::unique_ptr<StatusLocalCb>> cbs_;
+ std::recursive_mutex mutex_;
+};
+
+Context context;
+
+} // namespace
+
+extern "C" API int aul_status_update(int status) {
+ if (status < STATUS_LAUNCHING || status > STATUS_TERMINATE) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (context.GetStatus() == status)
+ return AUL_R_OK;
+
+ context.SetStatus(status);
+
+ int ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(), APP_STATUS_UPDATE,
+ reinterpret_cast<unsigned char*>(&status), sizeof(status),
+ AUL_SOCK_NOREPLY);
+ if (ret == 0)
+ context.InvokeLocalCb(status);
+ else
+ ret = aul_error_convert(ret);
+
+ return ret;
+}
+
+extern "C" API int aul_app_get_status_bypid(int pid) {
+ return aul_app_get_status_bypid_for_uid(pid, getuid());
+}
+
+extern "C" API int aul_app_get_status_bypid_for_uid(int pid, uid_t uid) {
+ if (pid < 0) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (pid == getpid())
+ return context.GetStatus();
+
+ return AppRequest(APP_GET_STATUS, uid)
+ .SetPid(pid)
+ .SendSimply();
+}
+
+extern "C" API int aul_app_get_status(const char* appid) {
+ return aul_app_get_status_for_uid(appid, getuid());
+}
+
+extern "C" API int aul_app_get_status_for_uid(const char* appid, uid_t uid) {
+ if (appid == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ return AppRequest(APP_GET_STATUS_BY_APPID, uid)
+ .SetAppId(appid)
+ .SendSimply();
+}
+
+extern "C" API int aul_add_status_local_cb(aul_status_local_cb callback,
+ void* user_data) {
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_ERROR;
+ }
+
+ context.RemoveLocalCb(callback, user_data);
+ context.AddLocalCb(callback, user_data);
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_remove_status_local_cb(aul_status_local_cb callback,
+ void* user_data) {
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_ERROR;
+ }
+
+ if (context.RemoveLocalCb(callback, user_data) > 0)
+ return AUL_R_OK;
+
+ return AUL_R_EINVAL;
+}
+
+extern "C" API int aul_invoke_status_local_cb(int status) {
+ if (status < STATUS_LAUNCHING || status > STATUS_TERMINATE) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ context.InvokeLocalCb(status);
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_set_process_group(int owner_pid, int child_pid) {
+ if (owner_pid < 1 || child_pid < 1) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ tizen_base::Bundle b {
+ { AUL_K_OWNER_PID, std::to_string(owner_pid) },
+ { AUL_K_CHILD_PID, std::to_string(child_pid) }
+ };
+
+ return AppRequest(APP_SET_PROCESS_GROUP, getuid())
+ .With(std::move(b))
+ .SendSimply();
+}
+
+extern "C" API int aul_listen_app_status(const char* appid,
+ app_status_cb callback, void* user_data, status_listen_h* handle) {
+ return aul_listen_app_status_for_uid(appid, callback, user_data, handle,
+ getuid());
+}
+
+extern "C" API int aul_listen_app_status_for_uid(const char* appid,
+ app_status_cb callback, void* user_data, status_listen_h* handle,
+ uid_t uid) {
+ if (appid == nullptr || callback == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ try {
+ auto* event = new (std::nothrow) AppStatusEvent(
+ appid, uid, callback, user_data);
+ if (event == nullptr) {
+ _E("Out of memory");
+ return AUL_R_ENOMEM;
+ }
+
+ *handle = reinterpret_cast<status_listen_h>(event);
+ } catch (const Exception& e) {
+ _E("Exception occurs. error(%s)", e.what());
+ return e.GetErrorCode();
+ }
+
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_ignore_app_status(status_listen_h handle) {
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ auto* event = reinterpret_cast<AppStatusEvent*>(handle);
+ delete event;
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_notify_exit(void) {
+ return AppRequest(APP_NOTIFY_EXIT, getuid())
+ .SendCmdOnly(AUL_SOCK_NOREPLY);
+}
+
+extern "C" API int aul_notify_start(void) {
+ return AppRequest(APP_NOTIFY_START, getuid())
+ .SendCmdOnly(AUL_SOCK_NOREPLY);
+}
+
+extern "C" API const char* aul_app_status_convert_to_string(int status) {
+ switch (status) {
+ case STATUS_LAUNCHING:
+ return "STATUS_LAUNCHING";
+ case STATUS_CREATED:
+ return "STATUS_CREATED";
+ case STATUS_FOCUS:
+ return "STATUS_FOCUS";
+ case STATUS_VISIBLE:
+ return "STATUS_VISIBLE";
+ case STATUS_BG:
+ return "STATUS_BG";
+ case STATUS_DYING:
+ return "STATUS_DYING";
+ case STATUS_HOME:
+ return "STATUS_HOME";
+ case STATUS_NORESTART:
+ return "STATUS_NORESTART";
+ case STATUS_SERVICE:
+ return "STATUS_SERVICE";
+ case STATUS_TERMINATE:
+ return "STATUS_TERMINATE";
+ default:
+ return "Unknown status";
+ }
+}
+
+extern "C" API int aul_status_update_v2(int status) {
+ if (status < STATUS_LAUNCHING || status > STATUS_TERMINATE) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (context.GetStatus() == status)
+ return AUL_R_OK;
+
+ context.SetStatus(status);
+
+ tizen_base::Bundle b { { AUL_K_STATUS, std::to_string(status) } };
+ int ret = AppRequest(APP_STATUS_UPDATE_V2, getuid())
+ .With(std::move(b))
+ .SendSimply();
+ if (ret != 0) {
+ _E("Failed to update app status. error(%d)", ret);
+ return ret;
+ }
+
+ context.InvokeLocalCb(status);
+ return AUL_R_OK;
+}