From: Kichan Kwon Date: Thu, 18 May 2017 06:22:39 +0000 (+0900) Subject: Add new APIs getting all apps' memory/CPU usage X-Git-Tag: submit/tizen/20170614.044733~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6102a348e7b27c029bf9eb96f694cbb2e4cfc3f5;p=platform%2Fcore%2Fapi%2Fruntime-info.git Add new APIs getting all apps' memory/CPU usage 1) runtime_info_app_usage_destroy - Free app usage handle 2) runtime_info_app_usage_get_count - Get the count of handle 3) runtime_info_app_usage_get_appid - Get app's ID from handle 4) runtime_info_app_usage_get_usage - Get app's resource usage from handle 5) runtime_info_get_all_apps_memory_usage - Get handle storing each app's memory usage(KB) 6) runtime_info_get_all_apps_cpu_rate - Get handle storing each app's CPU rate(%) - To get information, it requests to resourced via D-Bus Change-Id: Ib3fc4b91475600c071a6a6e18b6998bfbcee4e4d Signed-off-by: Kichan Kwon --- diff --git a/include/runtime_info.h b/include/runtime_info.h index 446ccea..cd5a0ae 100644 --- a/include/runtime_info.h +++ b/include/runtime_info.h @@ -391,6 +391,172 @@ int runtime_info_get_processor_max_frequency(int core_idx, int *cpu_freq); */ int runtime_info_get_physical_memory_size(int *size); + +/** + * @brief Handle for app usage information. + * @since_tizen 4.0 + */ +typedef struct app_usages_s *app_usage_h; + + +/** + * @brief Frees an app usage handle. + * @since_tizen 4.0 + * + * @param[in] handle App usage handle to free + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + */ +int runtime_info_app_usage_destroy(app_usage_h handle); + + +/** + * @brief Gets the app count from an app usage handle. + * @since_tizen 4.0 + * + * @param[in] handle The app usage handle + * @param[out] count The number of apps on the app list + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see runtime_info_get_all_apps_memory_usage() + * @see runtime_info_get_all_apps_cpu_rate() + */ +int runtime_info_app_usage_get_count(app_usage_h handle, unsigned int *count); + + +/** + * @brief Gets the app ID from an app usage handle. + * @since_tizen 4.0 + * + * @remarks You must release @a appid using free(). + * + * @param[in] handle The app usage handle + * @param[in] index The index in the app list; should be between 0 and @a count - 1 (inclusive), \n + * where @a count is provided by runtime_info_app_usage_get_count() + * @param[out] appid The app ID + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see runtime_info_get_all_apps_memory_usage() + * @see runtime_info_get_all_apps_cpu_rate() + */ +int runtime_info_app_usage_get_appid(app_usage_h handle, int index, char **appid); + + +/** + * @brief Gets resource usage from an app usage handle. + * @since_tizen 4.0 + * + * @remarks The meaning of @a usage depends on which function was used to create @a handle. + * + * @param[in] handle The app usage handle + * @param[in] index The index in the app list; should be between 0 and @a count - 1 (inclusive), \n + * where @a count is provided by runtime_info_app_usage_get_count() + * @param[out] usage Resource usage + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see runtime_info_get_all_apps_memory_usage() + * @see runtime_info_get_all_apps_cpu_rate() + */ +int runtime_info_app_usage_get_usage(app_usage_h handle, int index, unsigned int *usage); + + +/** + * @brief Gets memory usage of all apps. + * @since_tizen 4.0 + * + * @privilege %http://tizen.org/privilege/systemmonitor + * @remarks You must release @a usage using runtime_info_app_usage_destroy(). + * + * @param[out] usage An array of each app's memory usage (KB) + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #RUNTIME_INFO_ERROR_OUT_OF_MEMORY Not able to allocate memory (for output param/other operations) + * @retval #RUNTIME_INFO_ERROR_REMOTE_IO Call to resource daemon failed (dbus errors/resource daemon errors) + * @retval #RUNTIME_INFO_ERROR_IO_ERROR An I/O error during dbus message operations + * @retval #RUNTIME_INFO_ERROR_PERMISSION_DENIED Process not authorized to request app usage info + * + * @code + * #include + * + * void print_memory_usage(void) + * { + * int i; + * unsigned int count; + * app_usage_h mem_usage_handle; + * char *appid; + * unsigned int usage; + * + * runtime_info_get_all_apps_memory_usage(&mem_usage_handle); + * runtime_info_app_usage_get_count(mem_usage_handle, &count); + * + * for (i = 0; i < count; i++) { + * runtime_info_app_usage_get_appid(mem_usage_handle, i, &appid); + * runtime_info_app_usage_get_usage(mem_usage_handle, i, &usage); + * printf("appid = %s, usage = %u KB\n", appid, usage); + * free(appid); + * } + * + * runtime_info_app_usage_destroy(mem_usage_handle); + * + * } + * @endcode + */ +int runtime_info_get_all_apps_memory_usage(app_usage_h *usage); + + +/** + * @brief Gets CPU rate of all apps. + * @since_tizen 4.0 + * + * @privilege %http://tizen.org/privilege/systemmonitor + * @remarks You must release @a rate using runtime_info_app_usage_destroy(). + * + * @param[out] rate An array of each app's CPU usage rate (%), the values are rounded down. + * + * @retval #RUNTIME_INFO_ERROR_NONE Successful + * @retval #RUNTIME_INFO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #RUNTIME_INFO_ERROR_OUT_OF_MEMORY Not able to allocate memory (for output param/other operations) + * @retval #RUNTIME_INFO_ERROR_REMOTE_IO Call to resource daemon failed (dbus errors/resource daemon errors) + * @retval #RUNTIME_INFO_ERROR_IO_ERROR An I/O error during dbus message operations + * @retval #RUNTIME_INFO_ERROR_PERMISSION_DENIED Process not authorized to request app usage info + * + * @code + * #include + * + * void print_cpu_usage(void) + * { + * int i; + * unsigned int count; + * app_usage_h cpu_rate_handle; + * char *appid; + * unsigned int rate; + * + * runtime_info_get_all_apps_cpu_rate(&cpu_rate_handle); + * runtime_info_app_usage_get_count(cpu_rate_handle, &count); + * + * for (i = 0; i < count; i++) { + * runtime_info_app_usage_get_appid(cpu_rate_handle, i, &appid); + * runtime_info_app_usage_get_usage(cpu_rate_handle, i, &rate); + * printf("appid = %s, rate = %u %%\n", appid, rate); + * free(appid); + * } + * + * runtime_info_app_usage_destroy(cpu_rate_handle); + * + * } + * @endcode + */ +int runtime_info_get_all_apps_cpu_rate(app_usage_h *rate); + + /** * @} */ diff --git a/include/runtime_info_private.h b/include/runtime_info_private.h index be5eab7..6486d94 100644 --- a/include/runtime_info_private.h +++ b/include/runtime_info_private.h @@ -54,6 +54,16 @@ typedef union { typedef runtime_info_value_u * runtime_info_value_h; +struct app_usage_s { + char *appid; + unsigned int usage; +}; + +struct app_usages_s { + unsigned int len; + struct app_usage_s *list; +}; + typedef int (*runtime_info_func_get_value) (runtime_info_value_h value); typedef int (*runtime_info_func_set_event_cb) (void); typedef void (*runtime_info_func_unset_event_cb) (void); diff --git a/src/runtime_info_usage.c b/src/runtime_info_usage.c index b8e1c5e..bb63755 100644 --- a/src/runtime_info_usage.c +++ b/src/runtime_info_usage.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -35,6 +36,8 @@ typedef enum { USAGE_TYPE_PROCESS_MEMORY, USAGE_TYPE_PROCESS_CPU, + USAGE_TYPE_APP_MEMORY, + USAGE_TYPE_APP_CPU, } runtime_info_usage_type_e; typedef struct { @@ -46,6 +49,8 @@ typedef struct { static const runtime_info_dbus_info_s dbus_info[] = { { "ProcMemoryUsage", "process memory" }, { "ProcCpuUsage", "process cpu" }, + { "GetMemoryList", "all apps memory" }, + { "GetCpuList", "all apps cpu" }, }; #define kBtoKiB(val) ((val) <= 0) ? 0 : (int)MIN((((long long)(val) << 10) / 1000), INT_MAX) @@ -83,18 +88,30 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e GVariant *usage; /* Check parameter */ - if (!pid || !error) { - //LCOV_EXCL_START : system error - _E("INVALID_PARAMETER(0x%08x): pid list and error params cannot be null"); - if (error) - *error = RUNTIME_INFO_ERROR_INVALID_PARAMETER; - return NULL; - //LCOV_EXCL_STOP - } - - if (type != USAGE_TYPE_PROCESS_MEMORY && type != USAGE_TYPE_PROCESS_CPU) { + switch (type) { + case USAGE_TYPE_PROCESS_MEMORY: + case USAGE_TYPE_PROCESS_CPU: + if (!pid || size <= 0) { + //LCOV_EXCL_START : system error + _E("INVALID_PARAMETER(0x%08x): pid list cannot be null"); + if (error) + *error = RUNTIME_INFO_ERROR_INVALID_PARAMETER; + return NULL; + //LCOV_EXCL_STOP + } + /* Fall through */ + case USAGE_TYPE_APP_MEMORY: + case USAGE_TYPE_APP_CPU: + if (!error) { + //LCOV_EXCL_START : system error + _E("INVALID_PARAMETER(0x%08x): error parameter cannot be null"); + return NULL; + //LCOV_EXCL_STOP + } + break; + default: //LCOV_EXCL_START : system error - _E("INVALID_PARAMETER(0x%08x): invalid info parameter", + _E("INVALID_PARAMETER(0x%08x): invalid type parameter", RUNTIME_INFO_ERROR_INVALID_PARAMETER); *error = RUNTIME_INFO_ERROR_INVALID_PARAMETER; return NULL; @@ -102,16 +119,26 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e } /* Make argument for requesting */ - _D("Process %d: received query to get %s usage of %d processes", - getpid(), dbus_info[type].caption, size); - - args_in = runtime_info_append_args(pid, size); - if (!args_in) { - //LCOV_EXCL_START : system error - _E("DBUS_METHOD_CALL: not able to append pid array to message"); - *error = RUNTIME_INFO_ERROR_IO_ERROR; - return NULL; - //LCOV_EXCL_STOP + switch (type) { + case USAGE_TYPE_PROCESS_MEMORY: + case USAGE_TYPE_PROCESS_CPU: + _D("Process %d: received query to get %s usage of %d processes", + getpid(), dbus_info[type].caption, size); + args_in = runtime_info_append_args(pid, size); + if (!args_in) { + //LCOV_EXCL_START : system error + _E("DBUS_METHOD_CALL: not able to append pid array to message"); + *error = RUNTIME_INFO_ERROR_IO_ERROR; + return NULL; + //LCOV_EXCL_STOP + } + break; + case USAGE_TYPE_APP_MEMORY: + case USAGE_TYPE_APP_CPU: + _D("Process %d: received query to get %s usage of all apps", + getpid(), dbus_info[type].caption); + args_in = NULL; + break; } /* Send message to resourced and receive reply */ @@ -120,7 +147,8 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e if (!conn) { //LCOV_EXCL_START : system error _E("Failed to get dbus connection : %s", err->message); - g_variant_unref(args_in); + if (args_in) + g_variant_unref(args_in); return NULL; //LCOV_EXCL_STOP } @@ -142,12 +170,14 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e *error = RUNTIME_INFO_ERROR_PERMISSION_DENIED; else *error = RUNTIME_INFO_ERROR_REMOTE_IO; - g_variant_unref(args_in); + if (args_in) + g_variant_unref(args_in); return NULL; //LCOV_EXCL_STOP } - g_variant_unref(args_in); + if (args_in) + g_variant_unref(args_in); usage = g_variant_get_child_value(args_out, 0); g_variant_unref(args_out); @@ -155,6 +185,70 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e return usage; } +static int runtime_info_get_all_apps_usage(runtime_info_usage_type_e type, + app_usage_h *handle) +{ + int i; + int error; + unsigned int len; + struct app_usages_s *usages; + GVariant *reply; + GVariantIter iter; + + if (!handle) { + _E("INVALID_PARAMETER(0x%08x) : invalid output param", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + reply = runtime_info_dbus_request_usage_info(type, NULL, 0, &error); + if (!reply) { + //LCOV_EXCL_START : system error + _E("DBUS_METHOD_CALL: call to resourced not successful"); + return error; + //LCOV_EXCL_STOP + } + + /* Check whether the received usage has expected format or not */ + if (g_strcmp0(g_variant_get_type_string(reply), "a(su)")) { + //LCOV_EXCL_START : system error + _E("DBUS_METHOD_CALL: received dbus message is not in expected format"); + g_variant_unref(reply); + return RUNTIME_INFO_ERROR_REMOTE_IO; + //LCOV_EXCL_STOP + } + + /* Populate the entries of info array using the data received from resourced */ + len = g_variant_n_children(reply); + + usages = calloc(1, sizeof(struct app_usages_s)); + if (!usages) { + _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY); + g_variant_unref(reply); + return RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + } + + usages->len = len; + + usages->list = calloc(len, sizeof(struct app_usage_s)); + if (!usages->list) { + _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY); + free(usages); + g_variant_unref(reply); + return RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + } + + g_variant_iter_init(&iter, reply); + for (i = 0; i < len; i++) + g_variant_iter_next(&iter, "(su)", + &(usages->list[i].appid), &(usages->list[i].usage)); + g_variant_unref(reply); + + *handle = usages; + + return RUNTIME_INFO_ERROR_NONE; +} + API int runtime_info_get_system_memory_info(runtime_memory_info_s *info) { FILE *fp; @@ -516,3 +610,101 @@ API int runtime_info_get_physical_memory_size(int *size) return RUNTIME_INFO_ERROR_NONE; } + +API int runtime_info_app_usage_destroy(app_usage_h handle) +{ + int i; + struct app_usage_s *list; + struct app_usages_s *usages = handle; + + if (!usages) { + _E("INVALID PARAMETER(0x%08x) : invalid input parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + list = usages->list; + if (list) { + for (i = 0; i < usages->len; i++) + if (list[i].appid) + free(list[i].appid); + } + + free(list); + free(usages); + + return RUNTIME_INFO_ERROR_NONE; +} + +API int runtime_info_app_usage_get_count(app_usage_h handle, unsigned int *count) +{ + struct app_usages_s *usages = handle; + + if (!usages) { + _E("INVALID PARAMETER(0x%08x) : invalid input parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + if (!count) { + _E("INVALID PARAMETER(0x%08x) : invalid output parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + *count = usages->len; + + return RUNTIME_INFO_ERROR_NONE; +} + +API int runtime_info_app_usage_get_appid(app_usage_h handle, int index, char **appid) +{ + struct app_usages_s *usages = handle; + + if (!usages || index < 0 || index >= usages->len) { + _E("INVALID PARAMETER(0x%08x) : invalid input parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + if (!appid) { + _E("INVALID PARAMETER(0x%08x) : invalid output parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + *appid = strndup(usages->list[index].appid, strlen(usages->list[index].appid)); + + return RUNTIME_INFO_ERROR_NONE; +} + +API int runtime_info_app_usage_get_usage(app_usage_h handle, int index, unsigned int *usage) +{ + struct app_usages_s *usages = handle; + + if (!usages || index < 0 || index >= usages->len) { + _E("INVALID PARAMETER(0x%08x) : invalid input parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + if (!usage) { + _E("INVALID PARAMETER(0x%08x) : invalid output parameter", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + *usage = usages->list[index].usage; + + return RUNTIME_INFO_ERROR_NONE; +} + +API int runtime_info_get_all_apps_memory_usage(app_usage_h *usage) +{ + return runtime_info_get_all_apps_usage(USAGE_TYPE_APP_MEMORY, usage); +} + +API int runtime_info_get_all_apps_cpu_rate(app_usage_h *rate) +{ + return runtime_info_get_all_apps_usage(USAGE_TYPE_APP_CPU, rate); +}