In this lesson we'll look at the application manager, to find out what information about the application you can get by using it. Also we will make changes to the application by replacing a package manager with an application manager.
The application manager provides information about installed and running applications. It provides a set of functions to get the application name, the absolute path to the application's public folder, and so on. To use functions and data types of the application manager, include following header file in the application:
#include <app_manager.h>
It is necessary to distinguish the application manager from the package manager; the difference is that in application manager several applications can be placed in one package. So, the package is a larger entity. You can create 3 applications: ui-, widget- and service application, and then merge them into one package, which will be downloaded to the application store.
If you want to use the functions for getting information about the running applications without using the application manager functions, you have to include in the project the following header file:
#include <app_context.h>
The most commonly used function is the function to get all, running on the device, applications:
int app_manager_foreach_app_context(app_manager_app_context_cb callback, void *user_data);
The first parameter is a pointer to the application selection handler; the second parameter is a pointer to user data. The function returns code 0 in case of success, and a negative number in case of an error.
Let's look at the declarations of the application handler:
typedef bool (*app_manager_app_context_cb) (app_context_h app_context, void *user_data);
The first parameter is an object for obtaining information about the application context; the second parameter is a pointer to user data. The function returns a logical indicator to continue enumeration of running applications (true) or stop it (false).
When you receive a pointer to the application context, you may consider the most frequently used functions for obtaining information. To obtain the application identifier, use the following function:
int app_context_get_app_id(app_context_h app_context, char **app_id);
The first parameter is an object containing the context of the running application; the second parameter is a double pointer to the application identifier that will be filed inside the function. The function returns code 0 in case of success, and a negative number in case of an error. Note that after the function is called and the work with the line containing the application identifier is completed, it is necessary to release the memory allocated for it.
Consider the function for obtaining the application process ID:
int app_context_get_pid(app_context_h app_context, pid_t *pid);
The first parameter is an object containing the context of the running application; the second parameter is a pointer to the process identifier that will be filed inside the function. The function returns code 0 in case of success, and a negative number in case of an error.
There is a list of several more functions for getting information about the running applications.
To get information about the package to which the running application belongs, call the following function:
int app_context_get_package(app_context_h app_context, char **package);
The first parameter is an object containing the context of the running application; the second parameter is a double pointer to the package identifier that will be filled inside the function. The function returns code 0 in case of success, and a negative number in case of an error. It is also necessary to release allocated memory after the work completion.
Use the following function, if you need to check whether the application is allowed to work:
int app_context_is_terminated(app_context_h app_context, bool *terminated);
The first parameter is an object containing the context of the application; the second parameter is a pointer to the logical indicator of the application termination that will be filed inside the function.The function returns code 0 in case of success, and a negative number in case of an error.
Note that, since this function is used during the application operation, and if the pointer to the context is received in the iterator handler (it means that outside the callback this data can be deleted by the system), clone it by calling the following function:
int app_context_clone(app_context_h *clone, app_context_h app_context);
The first parameter is a pointer to the object, into which the context of the running application will be copied; the second parameter is the object to be copied. The function returns code 0 in case of success, and a negative number in case of an error.
To delete the copied context object of the running application, use the following function:
int app_context_destroy(app_context_h app_context);
The function takes a single parameter - the object that should be deleted.
The function returns code 0 in case of success, and a negative number in case of an error.
If you are going to use the functions for getting information about installed applications without using package manager functionality, include the following header file in the project:
#include <app_info.h>
The number of functions for getting information about installed applications is slightly larger than amount of function for getting information about running applications. Let's look at the main ones.
To iterate all installed applications on the device, consider the following function:
int app_manager_foreach_app_info(app_manager_app_info_cb callback, void *user_data);
The first parameter is a pointer to the application selection handler; the second parameter is a pointer to user data. Let's consider the declaration of the iterator handler:
typedef bool (*app_manager_app_info_cb) (app_info_h app_info, void *user_data);
The first parameter is the object required for obtaining information about the application; the second parameter is a pointer to the user data that was set during handler registration. The function returns a logical indicator to continue processing installed applications or not.
Now let's list the most useful functions for getting information about the application. Since the set and the types of parameters in these functions are the same, the description of the parameters will be explained below after listing all the functions.
The following function is required to obtain the application identifier:
int app_info_get_app_id(app_info_h app_info, char **app_id);
The following function is required to obtain the application name:
int app_info_get_label(app_info_h app_info, char **label);
The function for getting the absolute path to the application icon:
int app_info_get_icon(app_info_h app_info, char **path);
The following function is required to obtain the name of the package to which the application belongs:
int app_info_get_package(app_info_h app_info, char **package);
The following function is required to obtain an application type (native or web application):
int app_info_get_type(app_info_h app_info, char **type);
The first parameter of the listed functions is the object for obtaining information about the application; the second parameter is a double pointer to the string that will be filled in the function. Don’t forget to delete the selected strings. Now let’s list the functions that include logical information about the application. The following function is required to verify whether the application has a graphical user interface:
int app_info_is_nodisplay(app_info_h app_info, bool *nodisplay);
This function is required to check whether the application is preinstalled:
int app_info_is_preload(app_info_h app_info, bool *preload);
The first parameter of the listed functions is a pointer to the structure of the application; the second parameter is a pointer to a Boolean variable.
Let's move on to the practical part by adding the above listed functions to the application and displaying the result of their work in the log window.
To use the functions and data types of the application manager, add following header file to the project.
#include <app_manager.h>
Add a call of function for registering the handler for iterator of running applications instead of the package_manager_foreach_package_info() function, created in the previous tutorial.
static bool
_app_create_cb(void *data)
{
...
app_manager_foreach_app_context(_app_manager_app_context_cb, NULL);
...
}
Implement the handler of the running applications iterator and call there the functions to get both application and the process identifiers.
static bool
_app_manager_app_context_cb(app_context_h app_context, void *user_data)
{
char *app_id = NULL;
pid_t pid;
app_context_get_app_id(app_context, &app_id);
app_context_get_pid(app_context, &pid);
dlog_print(DLOG_INFO, "lesson26", "Applications ID: %s", app_id);
dlog_print(DLOG_INFO, "lesson26", "Process ID: %d", pid);
free(app_id);
return true;
}
Run the application and open the logging window. You will see a list of the running applications IDs and the process IDs.
Now add to the project the above mentioned functions for getting information about applications. Delete all the functions and handlers, added in the last lesson, which connected with the package manager as well as the functions added above, related to the running applications. Add information only about the installed applications.
Change the name of the structure, containing information about the application, and add one field with the application ID (you will need it in the next lesson).
In the structure it is necessary, to delete char *version field, containing the package version, and also in the _app_terminate_cb() function, remove the memory deallocation for this already not existing field.
typedef struct _Application_Info {
char *label;
char *path_icon;
char *app_id;
} Application_Info;
For successful compilation, in the whole project replace the name of the Install_Package_Info structure with Application_Info.
Now, instead of the function of iterating the running applications, we will call the function to register the iteration of the installed applications.
static bool
_app_create_cb(void *data)
{
...
app_manager_foreach_app_info(_app_manager_app_info_cb, ui);
...
}
Remove the previous handler _app_manager_app_context_cb() to avoid warning about unused functions from the compiler.
Now implement the application iteration handler. Inside the handler, output to the log the application name, application ID, absolute path to the icon, and package ID. But at the same time, add to the list only those applications that have a user graphical interface (ui-applications).
static bool
_app_manager_app_info_cb(app_info_h app_info, void *user_data)
{
UIData *ui = user_data;
Application_Info *application_info = calloc(1, sizeof(Application_Info));
if (!application_info) return false;
memset(application_info, 0x0, sizeof(Application_Info));
app_info_get_app_id(app_info, &(application_info->app_id));
app_info_get_label(app_info, &(application_info->label));
app_info_get_icon(app_info, &(application_info->path_icon));
bool is_nodisplay = false;
app_info_is_nodisplay(app_info, &is_nodisplay);
if (!is_nodisplay)
ui->list_package = eina_list_append(ui->list_package, application_info);
char *str_app_info = NULL;
app_info_get_type(app_info, &str_app_info);
dlog_print(DLOG_INFO, "lesson26", " Application type: %s", str_app_info);
free(str_app_info);
str_app_info = NULL;
app_info_get_package(app_info, &str_app_info);
dlog_print(DLOG_INFO, "lesson26", " Package ID: %s", str_app_info);
free(str_app_info);
dlog_print(DLOG_INFO, "lesson26", "Name: %s", application_info->label);
dlog_print(DLOG_INFO, "lesson26", "Path to the icon: %s", application_info->path_icon);
dlog_print(DLOG_INFO, "lesson26", "Application ID: %s", application_info->app_id);
return true;
}
And the last thing that needs to be done to successfully launch the application is to remove the function call for setting the version string as additional text to the element in the rotary selector creation function.
Delete the following call:
eext_rotary_selector_item_part_text_set(item,
"selector,sub_text",
install_package_info->version);
Run the application.
On the Samsung Gear S3 it is looks like this.
As you can see, installed applications with a graphical interface displayed as widget elements, and if you open the logging window, you will see a large list of all installed applications and information about them.
Let’s consider the list of the application manager the most useful features, on which you should pay attention.
The following function is required to obtain the application identifier, using the ID of the running process:
int app_manager_get_app_id(pid_t pid, char **app_id);
The first parameter is a process identifier (obtained in one of two ways: using a function with the context of a running application or using a call of a system function), the second parameter is a double pointer to a string, containing the application identifier that should be released. The function returns code 0 in case of success, and a negative number in case of an error.
To get the absolute path to the subdirectories of the public application directory, consider the following functions.
Next function is necessary to get the absolute path to the public directory with data (shared/data) of your project:
int app_manager_get_shared_data_path(const char *app_id, char **path);
The following function is required to get the absolute path to the public directory with shared/res resources of your project:
int app_manager_get_shared_resource_path(const char *app_id, char **path);
The following function is necessary to get the absolute path to the shared/trusted directory of your project:
int app_manager_get_shared_trusted_path(const char *app_id, char **path);
The first parameter is a pointer to a string containing the application identifier; the second parameter is a double pointer to the absolute path to the requested directory, note that memory allocated for the string, supposed to be released. The function returns code 0 in case of success, and a negative number in case of an error.
In order to check if the application is running, by using its identifier, call the following function:
int app_manager_is_running(const char *app_id, bool *running);
The first parameter is a pointer to the application identifier; the second is a pointer to the Boolean variable containing the application status. The function returns code 0 in case of success, and a negative number in case of an error.
There are a number of important functions as well. The first of them is for resuming the application:
int app_manager_resume_app(app_context_h app_context);
The input parameter of this function is an object containing the context of the running application. The function returns code 0 in case of success, and a negative number in case of an error.
The second function opens an application by the specified identifier:
int app_manager_open_app(const char *app_id);
The input parameter is a pointer to a string containing the unique identifier of the application. The function returns code 0 in case of success, and a negative number in case of an error.
The full source code of the lesson is available here WearLesson026.