1 From 2e731255404e0efb0df1ede8d0b0a32ac011b420 Mon Sep 17 00:00:00 2001
2 From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
3 Date: Sat, 16 Jul 2016 02:53:25 -0400
4 Subject: [PATCH] ivi-shell: Add autolaunch and launch rules functionality
6 Add ability to select application for autolaunch.
7 Also launch rules settings are added.
9 Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
10 Signed-off-by: Karthik Ramanan <a0393906@ti.com>
12 ivi-shell/ivi-layout-controller-ti.c | 293 +++++++++++++++++++++++++++++++----
13 1 file changed, 259 insertions(+), 34 deletions(-)
15 diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
16 index b7cf436..4a2d648 100644
17 --- a/ivi-shell/ivi-layout-controller-ti.c
18 +++ b/ivi-shell/ivi-layout-controller-ti.c
26 #include "ivi-layout-export.h"
29 @@ -56,13 +59,24 @@ if (__dl__ & debug_level) \
30 #define pr_wrn(...) __print_log(DL_WRN, "W: " __VA_ARGS__)
31 #define TRACE() __print_log(DL_DBG, "TR: %s - %d\n", __func__, __LINE__)
34 -#define WINDOWS_TITLE_HEIGHT 30
35 #define DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP 0x80000000
37 /*****************************************************************************
39 ****************************************************************************/
41 +struct hmi_launch_rule {
42 +#define MAX_APP_NAME_LEN 64
43 + char app_name[MAX_APP_NAME_LEN];
48 + int32_t src_rect[4];
49 + int32_t dest_rect[4];
50 + int32_t crop_rect[4];
53 struct hmi_controller_layer {
54 struct ivi_layout_layer *ivilayer;
56 @@ -75,6 +89,7 @@ struct hmi_controller_layer {
58 struct wl_list screen_link;
59 struct wl_list surfaces_list;
60 + struct hmi_launch_rule *rule;
63 struct hmi_controller_surface {
64 @@ -82,6 +97,7 @@ struct hmi_controller_surface {
67 struct wl_listener destroy_listener;
71 struct hmi_controller_screen {
72 @@ -93,6 +109,8 @@ struct hmi_server_setting {
73 uint32_t base_layer_id;
76 + char *homescreen_app;
77 + struct wl_array rules;
80 struct hmi_controller {
81 @@ -108,6 +126,7 @@ struct hmi_controller {
82 struct wl_listener destroy_listener;
83 struct wl_client *user_interface;
84 struct wl_list layers_list;
88 const struct ivi_controller_interface *ivi_controller_interface;
89 @@ -143,6 +162,42 @@ mem_alloc(size_t size, char *file, int32_t line)
91 #define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
94 +get_process_name_by_pid(pid_t pid, char *name, int size)
96 + char proc_name[256] = "/proc/";
100 + sprintf(&proc_name[strlen(proc_name)], "%d/exe", (int)pid);
103 + || access(proc_name, R_OK)
104 + || (readlink(proc_name, n, sizeof(n)) <= 0)) {
109 + _n = strrchr(n, '/');
110 + strncpy(name, _n ? (_n + 1) : n, size);
115 +static struct hmi_launch_rule
116 +*get_rule(struct wl_array *arr, const char *app_name)
118 + struct hmi_launch_rule *rule = NULL;
120 + wl_array_for_each(rule, arr) {
121 + if (!strcmp(app_name, rule->app_name))
130 * Internal method to create ivi_layer with hmi_controller_layer and
131 * add to a ivi_screen
132 @@ -177,6 +232,42 @@ create_layer(struct ivi_layout_screen *iviscrn,
137 +register_layer_on_screen(struct hmi_controller *hmi_ctrl,
139 + struct hmi_controller_layer *nlayer)
141 + unsigned cnt, j = 0;
142 + struct hmi_controller_layer *layer = NULL;
143 + struct ivi_layout_layer **layers;
145 + if (nlayer->rule && nlayer->rule->order == 0) {
146 + wl_list_insert(&hmi_ctrl->screens[i].layers_list, &nlayer->screen_link);
148 + wl_list_for_each(layer, &hmi_ctrl->screens[i].layers_list, screen_link) {
149 + if (layer->rule && (layer->rule->order == 0))
154 + wl_list_insert(layer->screen_link.prev, &nlayer->screen_link);
157 + cnt = wl_list_length(&hmi_ctrl->screens[i].layers_list);
159 + layers = calloc(cnt, sizeof(*layers));
161 + wl_list_for_each_reverse(layer, &hmi_ctrl->screens[i].layers_list, screen_link) {
162 + layers[j++] = layer->ivilayer;
165 + ivi_controller_interface->screen_set_render_order(hmi_ctrl->screens[i].iviscrn, layers, cnt);
169 + ivi_controller_interface->commit_changes();
172 static struct hmi_controller_layer
173 *get_layer_for_surface(struct hmi_controller *hmi_ctrl
174 , struct ivi_layout_surface *ivisurf
175 @@ -188,6 +279,9 @@ static struct hmi_controller_layer
176 struct wl_client *client;
177 struct ivi_layout_screen *iviscrn = NULL;
178 struct weston_output *output = NULL;
179 + char proc_name[256];
180 + struct hmi_launch_rule *rule;
185 @@ -213,13 +307,21 @@ static struct hmi_controller_layer
187 pr_dbg("Existed layer for PID=%d was not found. Creating new\n", pid);
190 - if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
191 - (i == (hmi_ctrl->screens_count - 1)))
194 + get_process_name_by_pid(pid, proc_name, sizeof(proc_name));
196 - iviscrn = hmi_ctrl->screens[i].iviscrn;
197 + rule = get_rule(&hmi_ctrl->hmi_setting->rules, proc_name);
199 + if (rule && (rule->screen_id >= 0) && (rule->screen_id < hmi_ctrl->screens_count)) {
200 + iviscrn = hmi_ctrl->screens[rule->screen_id].iviscrn;
201 + i = rule->screen_id;
204 + if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
205 + (i == (hmi_ctrl->screens_count - 1)))
208 + iviscrn = hmi_ctrl->screens[i].iviscrn;
211 layer = calloc(1, sizeof *layer);
213 @@ -230,14 +332,16 @@ static struct hmi_controller_layer
214 wl_list_init(&layer->surfaces_list);
216 layer->width = output->width;
217 - layer->height = output->height + WINDOWS_TITLE_HEIGHT;
218 + layer->height = output->height;
219 layer->id_layer = hmi_ctrl->hmi_setting->base_layer_id++;
221 + layer->rule = rule;
223 create_layer(iviscrn, layer);
225 wl_list_insert(&hmi_ctrl->layers_list, &layer->link);
226 - wl_list_insert(&hmi_ctrl->screens[i].layers_list, &layer->screen_link);
228 + register_layer_on_screen(hmi_ctrl, i, layer);
232 @@ -350,41 +454,77 @@ set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
233 struct hmi_controller_layer *hmi_ctrl_layer = NULL;
234 struct weston_surface *surface;
235 struct hmi_controller_surface *hmi_ctrl_surf = NULL;
236 + int src_rect[4] = {0};
237 + int dest_rect[4] = {0};
239 wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
240 wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
241 if (hmi_ctrl_surf->ivisurf == ivisurf) {
242 - pr_dbg("Surface was already configured. Skip add to list\n");
248 - hmi_ctrl_layer = NULL;
251 surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
255 - ivi_controller_interface->surface_set_source_rectangle(
256 - ivisurf, 0, WINDOWS_TITLE_HEIGHT, surface->width,
260 - ivi_controller_interface->surface_set_destination_rectangle(
261 - ivisurf, 0, 0, surface->width, surface->height);
263 - if (hmi_ctrl_layer) {
264 - ivi_controller_interface->surface_set_destination_rectangle(
265 - ivisurf, 0, 0, hmi_ctrl_layer->width, hmi_ctrl_layer->height);
267 - ivi_controller_interface->surface_set_destination_rectangle(
268 - ivisurf, 0, 0, surface->width, surface->height);
272 + src_rect[2] = dest_rect[2] = surface->width;
273 + src_rect[3] = dest_rect[3] = surface->height;
275 + if (hmi_ctrl_layer && hmi_ctrl_layer->rule) {
277 + if (hmi_ctrl_layer->rule->mode >= 0) {
278 + switch (hmi_ctrl_layer->rule->mode) {
280 + dest_rect[2] = hmi_ctrl_layer->width;
281 + dest_rect[3] = hmi_ctrl_layer->height;
285 + /* No changes, using requested size */
290 + if (hmi_ctrl_layer->rule->crop_rect[0] >= 0) {
291 + src_rect[0] += hmi_ctrl_layer->rule->crop_rect[0];
292 + src_rect[1] += hmi_ctrl_layer->rule->crop_rect[1];
293 + src_rect[2] -= (hmi_ctrl_layer->rule->crop_rect[0]
294 + + hmi_ctrl_layer->rule->crop_rect[2]);
295 + src_rect[3] -= (hmi_ctrl_layer->rule->crop_rect[1]
296 + + hmi_ctrl_layer->rule->crop_rect[3]);
299 + if (hmi_ctrl_layer->rule->dest_rect[0] >= 0 ||
300 + hmi_ctrl_layer->rule->dest_rect[1] >= 0 ||
301 + hmi_ctrl_layer->rule->dest_rect[2] >= 0 ||
302 + hmi_ctrl_layer->rule->dest_rect[3] >= 0) {
304 + dest_rect[0] = hmi_ctrl_layer->rule->dest_rect[0];
305 + dest_rect[1] = hmi_ctrl_layer->rule->dest_rect[1];
306 + dest_rect[2] = hmi_ctrl_layer->rule->dest_rect[2] > 0 ?
307 + hmi_ctrl_layer->rule->dest_rect[2] : dest_rect[2] ;
308 + dest_rect[3] = hmi_ctrl_layer->rule->dest_rect[3] > 0 ?
309 + hmi_ctrl_layer->rule->dest_rect[3] : dest_rect[3] ;
312 - ivi_controller_interface->surface_set_visibility(ivisurf, true);
313 - ivi_controller_interface->commit_changes();
316 + ivi_controller_interface->surface_set_source_rectangle(ivisurf
317 + , src_rect[0], src_rect[1]
318 + , src_rect[2], src_rect[3]);
320 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf
321 + , dest_rect[0], dest_rect[1]
322 + , dest_rect[2], dest_rect[3]);
324 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
325 + ivi_controller_interface->commit_changes();
327 + hmi_ctrl_surf->conf_num++;
330 static struct hmi_server_setting *
331 @@ -393,6 +533,9 @@ hmi_server_setting_create(struct weston_compositor *ec)
332 struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
333 struct weston_config *config = ec->config;
334 struct weston_config_section *shell_section = NULL;
335 + const char *name = NULL;
337 + setting->panel_height = 30;
339 shell_section = weston_config_get_section(config, "ivi-shell",
341 @@ -400,7 +543,78 @@ hmi_server_setting_create(struct weston_compositor *ec)
342 weston_config_section_get_uint(shell_section, "base-layer-id",
343 &setting->base_layer_id, 1000);
345 - setting->panel_height = 30;
346 + if ((shell_section = weston_config_get_section(config, "ivi-autolaunch",
348 + weston_config_section_get_string(shell_section, "path",
349 + &setting->homescreen_app, NULL);
353 + wl_array_init(&setting->rules);
355 + while (weston_config_next_section(config, &shell_section, &name)) {
360 + int crop_rect[4] = {-1, -1, -1, -1};
361 + int src_rect[4] = {-1, -1, -1, -1};
362 + int dest_rect[4] = {-1, -1, -1, -1};
365 + struct hmi_launch_rule *rule = NULL;
367 + if (0 != strcmp(name, "ivi-layout-rule"))
370 + if (0 != weston_config_section_get_string(shell_section, "application",
374 + weston_config_section_get_int(shell_section, "order", &order, -1);
375 + weston_config_section_get_int(shell_section, "mode", &mode, -1);
376 + weston_config_section_get_int(shell_section, "focus_on", &focus_on, -1);
377 + weston_config_section_get_int(shell_section, "screen", &screen_id, -1);
379 + if (0 == weston_config_section_get_string(shell_section, "crop_rect",
381 + sscanf(buff, "%d,%d,%d,%d", crop_rect + 0,
387 + if (0 == weston_config_section_get_string(shell_section, "src_rect",
389 + sscanf(buff, "%d,%d,%d,%d", src_rect + 0,
395 + if (0 == weston_config_section_get_string(shell_section, "dest_rect",
397 + sscanf(buff, "%d,%d,%d,%d", dest_rect + 0,
403 + rule = wl_array_add(&setting->rules, sizeof(*rule));
406 + rule->screen_id = screen_id;
407 + rule->order = order;
409 + rule->autofocus = focus_on;
411 + strncpy(rule->app_name, app_name, sizeof(rule->app_name));
413 + memcpy(rule->src_rect, src_rect, sizeof(rule->src_rect));
414 + memcpy(rule->dest_rect, dest_rect, sizeof(rule->dest_rect));
415 + memcpy(rule->crop_rect, crop_rect, sizeof(rule->crop_rect));
421 @@ -415,6 +629,15 @@ hmi_controller_destroy(struct wl_listener *listener, void *data)
425 +static void hmi_controller_launch_homescreen(struct hmi_controller *hmi_ctrl)
427 + if (hmi_ctrl->hmi_setting->homescreen_app) {
428 + if(system(hmi_ctrl->hmi_setting->homescreen_app)) {
434 static struct hmi_controller *
435 hmi_controller_create(struct weston_compositor *ec)
437 @@ -429,9 +652,10 @@ hmi_controller_create(struct weston_compositor *ec)
439 ivi_controller_interface->get_screens(&screen_length, &pp_screen);
441 - for (i = screen_length; i-- ; j++) {
442 + for (i = screen_length; i--;) {
444 iviscrn = pp_screen[i];
445 + j = ivi_controller_interface->get_id_of_screen(iviscrn);
446 hmi_ctrl->screens[j].iviscrn = iviscrn;
447 wl_list_init(&hmi_ctrl->screens[i].layers_list);
449 @@ -506,7 +730,6 @@ controller_module_init(struct weston_compositor *ec,
451 struct hmi_controller *hmi_ctrl = NULL;
454 if (interface_version < sizeof(struct ivi_controller_interface)) {
455 weston_log("ivi-layout-controller-ti: version mismatch of controller interface");
457 @@ -528,5 +751,7 @@ controller_module_init(struct weston_compositor *ec,
459 weston_log("ivi-layout-controller-ti: Successfully started.");
461 + hmi_controller_launch_homescreen(hmi_ctrl);