Add new functions for listening app lifecycle state 30/251730/3
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 19 Jan 2021 03:44:01 +0000 (12:44 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 25 Jan 2021 01:05:54 +0000 (10:05 +0900)
Adds:
 - aul_app_lifecycle_register_state_changed_cb()
 - aul_app_lifecycle_deregister_state_changed_cb()
 - aul_app_lifecycle_update_state()

Change-Id: Idc1f822aebe4a0cdad014f13ed23ecfafab71bf5
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
aul/api/aul_app_lifecycle.cc [new file with mode: 0644]
aul/api/aul_app_lifecycle.h [new file with mode: 0644]
aul/common/exception.hh
include/aul_cmd.h
include/aul_key.h
src/aul_cmd.c
tool/aul_test/CMakeLists.txt
tool/aul_test/aul_test.c

diff --git a/aul/api/aul_app_lifecycle.cc b/aul/api/aul_app_lifecycle.cc
new file mode 100644 (file)
index 0000000..cc33eba
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2021 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 <bundle_cpp.h>
+
+#include "aul/api/aul_app_lifecycle.h"
+#include "aul/common/api.hh"
+#include "aul/common/exception.hh"
+#include "aul/socket/client.hh"
+#include "include/aul.h"
+#include "include/aul_app_com.h"
+#include "include/aul_cmd.h"
+#include "include/aul_error.h"
+#include "include/aul_sock.h"
+
+namespace {
+
+class EventListener {
+ public:
+  EventListener() {
+  }
+
+  ~EventListener() {
+    Deregister();
+  }
+
+  int Register(aul_app_lifecycle_state_changed_cb cb, void* user_data) {
+    cb_ = cb;
+    user_data_ = user_data;
+
+    if (conn_ != nullptr)
+      return AUL_R_OK;
+
+    int ret = aul_app_com_create_async("app_lifecycle_state_change", nullptr,
+        AppComMessageCb, this, &conn_);
+    if (ret != AUL_R_OK) {
+      _E("aul_app_com_create_async() is failed. error(%d)", ret);
+      return ret;
+    }
+
+    return AUL_R_OK;
+  }
+
+  int Deregister() {
+    if (conn_ == nullptr)
+      return AUL_R_OK;
+
+    aul_app_com_leave(conn_);
+    conn_ = nullptr;
+    return AUL_R_OK;
+  }
+
+ private:
+  static int AppComMessageCb(const char* endpoint, aul_app_com_result_e res,
+      bundle* envelope, void* user_data) {
+    tizen_base::Bundle b(envelope, false, false);
+    std::string app_id = b.GetString(AUL_K_APPID);
+    pid_t pid = std::stoi(b.GetString(AUL_K_PID));
+    int state = std::stoi(b.GetString(AUL_K_STATE));
+    std::string has_focus = b.GetString(AUL_K_HAS_FOCUS);
+
+    auto* handle = static_cast<EventListener*>(user_data);
+    if (handle->cb_) {
+      handle->cb_(app_id.c_str(), pid,
+          static_cast<aul_app_lifecycle_state_e>(state),
+          has_focus == "true" ? true : false,
+          handle->user_data_);
+    }
+
+    return 0;
+  }
+
+ private:
+  aul_app_com_connection_h conn_ = nullptr;
+  aul_app_lifecycle_state_changed_cb cb_ = nullptr;
+  void* user_data_ = nullptr;
+};
+
+EventListener listener;
+
+}  // namespace
+
+extern "C" API int aul_app_lifecycle_register_state_changed_cb(
+    aul_app_lifecycle_state_changed_cb callback, void *user_data) {
+  if (callback == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return listener.Register(callback, user_data);
+}
+
+extern "C" API int aul_app_lifecycle_deregister_state_changed_cb(void) {
+ return listener.Deregister();
+}
+
+extern "C" int aul_app_lifecycle_update_state(aul_app_lifecycle_state_e state) {
+  tizen_base::Bundle b;
+  b.Add(AUL_K_STATE, std::to_string(static_cast<int>(state)));
+  aul::Packet packet(APP_LIFECYCLE_UPDATE_STATE,
+      AUL_SOCK_NOREPLY | AUL_SOCK_BUNDLE, b);
+  try {
+    aul::Client client(aul::PATH_AMD_SOCK);
+    int ret = client.Send(packet);
+    if (ret < 0)
+      return aul_error_convert(ret);
+  } catch (aul::Exception& e) {
+    return aul_error_convert(e.GetErrorCode());
+  }
+
+  return AUL_R_OK;
+}
diff --git a/aul/api/aul_app_lifecycle.h b/aul/api/aul_app_lifecycle.h
new file mode 100644 (file)
index 0000000..96a6196
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2021 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 AUL_API_AUL_APP_LIFECYCLE_H_
+#define AUL_API_AUL_APP_LIFECYCLE_H_
+
+#include <stdbool.h>
+#include <aul.h>
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Enumeration for application lifecycle state.
+ * @since_tizen 6.5
+ */
+typedef enum {
+       AUL_APP_LIFECYCLE_STATE_INITIALIZED,    /**< The application is initialized. */
+       AUL_APP_LIFECYCLE_STATE_CREATED,        /**< The application is created. */
+       AUL_APP_LIFECYCLE_STATE_RESUMED,        /**< The application is resumed. */
+       AUL_APP_LIFECYCLE_STATE_PAUSED,         /**< The application is paused. */
+       AUL_APP_LIFECYCLE_STATE_DESTROYED,      /**< The application is terminated. */
+} aul_app_lifecycle_state_e;
+
+/**
+ * @brief Called when the state of the application is changed.
+ * @since_tizen 6.5
+ * @param[in]   app_id          The application ID
+ * @param[in]   pid             The process ID
+ * @param[in]   state           The state of the application lifecycle
+ * @param[in]   has_focus       If it's true, the application has focus
+ * @param[in]   user_data       The user data passed from the registration function
+ * @see aul_app_lifecycle_register_state_changed_cb()
+ * @see aul_app_lifecycle_deregister_state_changed_cb()
+ */
+typedef void (*aul_app_lifecycle_state_changed_cb)(const char *app_id, pid_t pid, aul_app_lifecycle_state_e state, bool has_focus, void *user_data);
+
+/**
+ * @breif Registers a callback function to be invoked when the state of the application is changed.
+ * @details To deregister the callback function, you have to call aul_app_lifecycle_deregister_state_changed_cb().
+ * @since_tizen 6.5
+ * @param[in]   callback        The 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
+ * @see aul_app_lifecycle_state_changed_cb()
+ * @see aul_app_lifecycle_deregister_state_changed_cb()
+ */
+int aul_app_lifecycle_register_state_changed_cb(aul_app_lifecycle_state_changed_cb callback, void *user_data);
+
+/**
+ * @brief Deregister the callback function.
+ * @since_tizen 6.5
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ * @see aul_app_lifecycle_register_state_changed_cb()
+ */
+int aul_app_lifecycle_deregister_state_changed_cb(void);
+
+/**
+ * @breif Updates the state of the application lifecycle.
+ * @since_tizen 6.5
+ * @param[in]   state           The state of the application lifecycle
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ * @see #aul_app_lifecycle_state_e
+ */
+int aul_app_lifecycle_update_state(aul_app_lifecycle_state_e state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // AUL_API_AUL_APP_LIFECYCLE_HH_
index 37f54c9..4d7fa1c 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "aul/common/log_private.hh"
 
-#define THROW(error_code) throw Exception(error_code)
+#define THROW(error_code) throw Exception(error_code, __FUNCTION__, __LINE__)
 
 namespace aul {
 
index 5e07d86..ee316bb 100644 (file)
@@ -193,6 +193,7 @@ enum app_cmd {
        COMP_PORT_EXIST = 152,
        COMP_PORT_CREATE = 153,
        COMP_PORT_DESTROY = 154,
+       APP_LIFECYCLE_UPDATE_STATE = 155,
 
        APP_CMD_MAX
 };
index c441ef9..efde117 100644 (file)
  * @since_tizen 6.5
  */
 #define AUL_K_RESULT                    "__AUL_RESULT__"
+
+/**
+ * @brief Definition for AUL: The flag if it's 'true', the application has focus.
+ * @since_tizen 6.5
+ */
+#define AUL_K_HAS_FOCUS                 "__AUL_HAS_FOCUS__"
+
+/**
+ * @brief Definition for AUL: The state of the application lifecycle.
+ * @since_tizen 6.5
+ */
+#define AUL_K_STATE                     "__AUL_STATE__"
index 7cca83f..e9e98fb 100755 (executable)
@@ -195,6 +195,7 @@ API const char *aul_cmd_convert_to_string(int cmd)
                "COMP_PORT_EXIST",
                "COMP_PORT_CREATE",
                "COMP_PORT_DESTROY",
+               "APP_LIFECYCLE_UPDATE_STATE",
 
                "CUSTOM_COMMAND"
        };
index f7c5f2f..baa2569 100644 (file)
@@ -7,5 +7,7 @@ TARGET_LINK_LIBRARIES(${TARGET_AUL_TEST} PRIVATE ${TARGET_AUL})
 
 TARGET_INCLUDE_DIRECTORIES(${TARGET_AUL_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../src)
 TARGET_INCLUDE_DIRECTORIES(${TARGET_AUL_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AUL_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AUL_TEST} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../aul/api)
 
 INSTALL(TARGETS ${TARGET_AUL_TEST} DESTINATION bin)
index 3320a5b..b4ee278 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "menu_db_util.h"
 #include "aul.h"
+#include "aul/api/aul_app_lifecycle.h"
 
 #define MAX_LOCAL_BUFSZ 128
 #define QUERY_LEN      10240
@@ -703,6 +704,37 @@ static int listen_app_status_for_uid_test(void)
        return aul_listen_app_status_for_uid(gargv[2], app_status_handler, NULL, &listen_handle, apn_pid);
 }
 
+static const char *__app_lifecycle_state_to_string(aul_app_lifecycle_state_e state)
+{
+       switch (state) {
+       case AUL_APP_LIFECYCLE_STATE_INITIALIZED:
+               return "INITIALIZED";
+       case AUL_APP_LIFECYCLE_STATE_CREATED:
+               return "CREATED";
+       case AUL_APP_LIFECYCLE_STATE_RESUMED:
+               return "RESUMED";
+       case AUL_APP_LIFECYCLE_STATE_PAUSED:
+               return "PAUSED";
+       default:
+               return "DESTROYED";
+       }
+}
+
+static void app_lifecycle_state_changed_cb(const char *app_id, pid_t pid, aul_app_lifecycle_state_e state, bool has_focus, void *user_data)
+{
+       printf("app_id(%s), pid(%d), state(%s), has_focus(%s)\n",
+                       app_id, pid, __app_lifecycle_state_to_string(state),
+                       has_focus ? "true" : "false");
+}
+
+static int listen_app_lifecycle_test(void)
+{
+       static int num;
+
+       printf("aul_app_lifecycle_register_state_changed_cb %d test]\n", num++);
+       return aul_app_lifecycle_register_state_changed_cb(app_lifecycle_state_changed_cb, NULL);
+}
+
 static int test_regex()
 {
        char *token;
@@ -843,6 +875,8 @@ static test_func_t test_func[] = {
                "[usage] listen_app_status <appid>"},
        {"listen_app_status_for_uid", listen_app_status_for_uid_test, "aul_listen_app_status_for_uid",
                "[usage] listen_app_status_for_uid <appid> <uid>"},
+       {"listen_app_lifecycle", listen_app_lifecycle_test, "aul_app_lifecycle_register_state_changed_cb",
+               "[usafe] listen_app_lifecycle"},
 };
 
 int callfunc(char *testname)
@@ -895,11 +929,13 @@ static gboolean run_func(void *data)
 {
        callfunc(cmd);
 
-       if (strcmp(cmd, "launch_res") == 0 || strcmp(cmd, "all") == 0
-           || strcmp(cmd, "dbuslaunch") == 0
-           || strcmp(cmd, "listen_app_status") == 0
-           || strcmp(cmd, "open_svc_res") == 0 ||
-           strcmp(cmd, "listen_app_status") == 0)
+       if (strcmp(cmd, "launch_res") == 0 ||
+                       strcmp(cmd, "all") == 0 ||
+                       strcmp(cmd, "dbuslaunch") == 0 ||
+                       strcmp(cmd, "listen_app_status") == 0 ||
+                       strcmp(cmd, "open_svc_res") == 0 ||
+                       strcmp(cmd, "listen_app_status") == 0 ||
+                       strcmp(cmd, "listen_app_lifecycle") == 0)
                return 0;
        else
                g_main_loop_quit(mainloop);