Merge lp:~charlesk/indicator-session/lp-1256590-j-random-user into lp:indicator-session/14.04

Proposed by Charles Kerr
Status: Merged
Approved by: Ted Gould
Approved revision: 446
Merged at revision: 443
Proposed branch: lp:~charlesk/indicator-session/lp-1256590-j-random-user
Merge into: lp:indicator-session/14.04
Diff against target: 365 lines (+266/-10)
5 files modified
debian/control (+1/-0)
src/CMakeLists.txt (+2/-0)
src/recoverable-problem.c (+167/-0)
src/recoverable-problem.h (+26/-0)
src/service.c (+70/-10)
To merge this branch: bzr merge lp:~charlesk/indicator-session/lp-1256590-j-random-user
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Ted Gould (community) Approve
Review via email: mp+213353@code.launchpad.net

Commit message

Fix the phantom "J Random User" menuitem that shows up under some conditions.

Description of the change

This patch skips creating menuitems for users that don't have a username.

Sometimes org.freedesktop.login1 gives us a user without a username. Multiple users have reported this happens when running "Remmina Remote Desktop Client."

So we pass a NULL label to glib when we create the menuitem, and when the label property is NULL for an x-canonical-type of "indicator.user-menu-item", the default text of "J Random User" is used.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
445. By Charles Kerr

copy recoverable-problem.[ch] from url-dispatcher 0.1+14.04.20140331.1-0ubuntu1

446. By Charles Kerr

if we encounter a user for whom we can't find a name, report it to apport as a recoverable error.

Revision history for this message
Ted Gould (ted) wrote :

+1

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2014-03-05 20:12:45 +0000
+++ debian/control 2014-04-02 15:03:28 +0000
@@ -32,6 +32,7 @@
32 unity-control-center | gnome-control-center,32 unity-control-center | gnome-control-center,
33 unity-control-center-signon | gnome-control-center-signon33 unity-control-center-signon | gnome-control-center-signon
34Suggests: lightdm,34Suggests: lightdm,
35 apport,
35 zenity36 zenity
36Description: indicator showing session management, status and user switching37Description: indicator showing session management, status and user switching
37 This indicator is designed to be placed on the right side of a panel and38 This indicator is designed to be placed on the right side of a panel and
3839
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2013-07-02 02:00:17 +0000
+++ src/CMakeLists.txt 2014-04-02 15:03:28 +0000
@@ -5,6 +5,8 @@
5 actions.h5 actions.h
6 guest.c6 guest.c
7 guest.h7 guest.h
8 recoverable-problem.c
9 recoverable-problem.h
8 service.c10 service.c
9 service.h11 service.h
10 users.c12 users.c
1113
=== added file 'src/recoverable-problem.c'
--- src/recoverable-problem.c 1970-01-01 00:00:00 +0000
+++ src/recoverable-problem.c 2014-04-02 15:03:28 +0000
@@ -0,0 +1,167 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Ted Gould <ted.gould@canonical.com>
18 */
19
20#include "recoverable-problem.h"
21#include <glib/gstdio.h>
22#include <string.h>
23#include <errno.h>
24
25/* Helpers to ensure we write nicely */
26static void
27write_string (int fd,
28 const gchar *string)
29{
30 int res;
31 do
32 res = write (fd, string, strlen (string));
33 while (G_UNLIKELY (res == -1 && errno == EINTR));
34}
35
36/* Make NULLs fast and fun! */
37static void
38write_null (int fd)
39{
40 int res;
41 do
42 res = write (fd, "", 1);
43 while (G_UNLIKELY (res == -1 && errno == EINTR));
44}
45
46/* Child watcher */
47static gboolean
48apport_child_watch (GPid pid G_GNUC_UNUSED, gint status G_GNUC_UNUSED, gpointer user_data)
49{
50 g_main_loop_quit((GMainLoop *)user_data);
51 return FALSE;
52}
53
54static gboolean
55apport_child_timeout (gpointer user_data)
56{
57 g_warning("Recoverable Error Reporter Timeout");
58 g_main_loop_quit((GMainLoop *)user_data);
59 return FALSE;
60}
61
62/* Code to report an error */
63void
64report_recoverable_problem (const gchar * signature, GPid report_pid, gboolean wait, gchar * additional_properties[])
65{
66 GSpawnFlags flags;
67 gboolean first;
68 GError * error = NULL;
69 gint error_stdin = 0;
70 GPid pid = 0;
71 gchar * pid_str = NULL;
72 gchar ** argv = NULL;
73 gchar * argv_nopid[2] = {
74 "/usr/share/apport/recoverable_problem",
75 NULL
76 };
77 gchar * argv_pid[4] = {
78 "/usr/share/apport/recoverable_problem",
79 "-p",
80 NULL, /* put pid_str when allocated here */
81 NULL
82 };
83
84
85 argv = (gchar **)argv_nopid;
86
87 if (report_pid != 0) {
88 pid_str = g_strdup_printf("%d", report_pid);
89 argv_pid[2] = pid_str;
90 argv = (gchar**)argv_pid;
91 }
92
93 flags = G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
94 if (wait) {
95 flags |= G_SPAWN_DO_NOT_REAP_CHILD;
96 }
97
98 g_spawn_async_with_pipes(NULL, /* cwd */
99 argv,
100 NULL, /* envp */
101 flags,
102 NULL, NULL, /* child setup func */
103 &pid,
104 &error_stdin,
105 NULL, /* stdout */
106 NULL, /* stderr */
107 &error);
108
109 if (error != NULL) {
110 g_warning("Unable to report a recoverable error: %s", error->message);
111 g_error_free(error);
112 }
113
114 first = TRUE;
115
116 if (error_stdin != 0 && signature != NULL) {
117 write_string(error_stdin, "DuplicateSignature");
118 write_null(error_stdin);
119 write_string(error_stdin, signature);
120
121 first = FALSE;
122 }
123
124 if (error_stdin != 0 && additional_properties != NULL) {
125 gint i;
126 for (i = 0; additional_properties[i] != NULL; i++) {
127 if (!first) {
128 write_null(error_stdin);
129 } else {
130 first = FALSE;
131 }
132
133 write_string(error_stdin, additional_properties[i]);
134 }
135 }
136
137 if (error_stdin != 0) {
138 close(error_stdin);
139 }
140
141 if (wait && pid != 0) {
142 GSource * child_source, * timeout_source;
143 GMainContext * context = g_main_context_new();
144 GMainLoop * loop = g_main_loop_new(context, FALSE);
145
146 child_source = g_child_watch_source_new(pid);
147 g_source_attach(child_source, context);
148 g_source_set_callback(child_source, (GSourceFunc)apport_child_watch, loop, NULL);
149
150 timeout_source = g_timeout_source_new_seconds(5);
151 g_source_attach(timeout_source, context);
152 g_source_set_callback(timeout_source, apport_child_timeout, loop, NULL);
153
154 g_main_loop_run(loop);
155
156 g_source_destroy(timeout_source);
157 g_source_destroy(child_source);
158 g_main_loop_unref(loop);
159 g_main_context_unref(context);
160
161 g_spawn_close_pid(pid);
162 }
163
164 g_free(pid_str);
165
166 return;
167}
0168
=== added file 'src/recoverable-problem.h'
--- src/recoverable-problem.h 1970-01-01 00:00:00 +0000
+++ src/recoverable-problem.h 2014-04-02 15:03:28 +0000
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Ted Gould <ted.gould@canonical.com>
18 */
19
20#include <gio/gio.h>
21
22void report_recoverable_problem (const gchar * signature,
23 GPid report_pid,
24 gboolean wait,
25 gchar * additional_properties[]);
26
027
=== modified file 'src/service.c'
--- src/service.c 2014-03-24 10:19:00 +0000
+++ src/service.c 2014-04-02 15:03:28 +0000
@@ -21,6 +21,7 @@
21#include <gio/gio.h>21#include <gio/gio.h>
2222
23#include "backend.h"23#include "backend.h"
24#include "recoverable-problem.h"
24#include "service.h"25#include "service.h"
2526
26#define BUS_NAME "com.canonical.indicator.session"27#define BUS_NAME "com.canonical.indicator.session"
@@ -104,6 +105,7 @@
104 GSimpleAction * user_switcher_action;105 GSimpleAction * user_switcher_action;
105 GSimpleAction * guest_switcher_action;106 GSimpleAction * guest_switcher_action;
106 GHashTable * users;107 GHashTable * users;
108 GHashTable * reported_users;
107 guint rebuild_id;109 guint rebuild_id;
108 int rebuild_flags;110 int rebuild_flags;
109 GDBusConnection * conn;111 GDBusConnection * conn;
@@ -250,15 +252,15 @@
250static void252static void
251maybe_add_users (IndicatorSessionService * self)253maybe_add_users (IndicatorSessionService * self)
252{254{
253 if (!show_user_list (self))255 if (show_user_list (self))
254 return;256 {
255257 GList * uids, * l;
256 GList * uids, * l;258
257259 uids = indicator_session_users_get_uids (self->priv->backend_users);
258 uids = indicator_session_users_get_uids (self->priv->backend_users);260 for (l=uids; l!=NULL; l=l->next)
259 for (l=uids; l!=NULL; l=l->next)261 add_user (self, GPOINTER_TO_UINT(l->data));
260 add_user (self, GPOINTER_TO_UINT(l->data));262 g_list_free (uids);
261 g_list_free (uids);263 }
262}264}
263265
264266
@@ -488,6 +490,49 @@
488 return serialized_icon;490 return serialized_icon;
489}491}
490492
493static void
494report_unusable_user (IndicatorSessionService * self, const IndicatorSessionUser * u)
495{
496 const priv_t * const p = self->priv;
497 gpointer key;
498
499 g_return_if_fail(u != NULL);
500
501 key = GUINT_TO_POINTER(u->uid);
502
503 if (!g_hash_table_contains (p->reported_users, key))
504 {
505 gchar * uid_str;
506 GPtrArray * additional;
507 const gchar * const error_name = "indicator-session-unknown-user-error";
508
509 /* don't spam apport with duplicates */
510 g_hash_table_add (p->reported_users, key);
511
512 uid_str = g_strdup_printf("%u", u->uid);
513
514 additional = g_ptr_array_new (); /* null-terminated key/value pair strs */
515 g_ptr_array_add (additional, "uid");
516 g_ptr_array_add (additional, uid_str);
517 g_ptr_array_add (additional, "icon_file");
518 g_ptr_array_add (additional, u->icon_file ? u->icon_file : "(null)");
519 g_ptr_array_add (additional, "is_current_user");
520 g_ptr_array_add (additional, u->is_current_user ? "true" : "false");
521 g_ptr_array_add (additional, "is_logged_in");
522 g_ptr_array_add (additional, u->is_logged_in ? "true" : "false");
523 g_ptr_array_add (additional, "real_name");
524 g_ptr_array_add (additional, u->real_name ? u->real_name : "(null)");
525 g_ptr_array_add (additional, "user_name");
526 g_ptr_array_add (additional, u->user_name ? u->user_name : "(null)");
527 g_ptr_array_add (additional, NULL); /* null termination */
528 report_recoverable_problem(error_name, (GPid)0, FALSE, (gchar**)additional->pdata);
529
530 /* cleanup */
531 g_free (uid_str);
532 g_ptr_array_free (additional, TRUE);
533 }
534}
535
491static GMenuModel *536static GMenuModel *
492create_switch_section (IndicatorSessionService * self, int profile)537create_switch_section (IndicatorSessionService * self, int profile)
493{538{
@@ -576,12 +621,23 @@
576 for (i=0; i<users->len; ++i)621 for (i=0; i<users->len; ++i)
577 {622 {
578 const IndicatorSessionUser * u = g_ptr_array_index (users, i);623 const IndicatorSessionUser * u = g_ptr_array_index (users, i);
624 const char * label;
579 GVariant * serialized_icon;625 GVariant * serialized_icon;
580626
581 if (profile == PROFILE_LOCKSCREEN && u->is_current_user)627 if (profile == PROFILE_LOCKSCREEN && u->is_current_user)
582 continue;628 continue;
583629
584 item = g_menu_item_new (get_user_label (u), NULL);630 /* Sometimes we get a user without a username? bus hiccup.
631 I can't reproduce it, but let's not confuse users with
632 a meaningless menuitem. (see bug #1263228) */
633 label = get_user_label (u);
634 if (!label || !*label)
635 {
636 report_unusable_user (self, u);
637 continue;
638 }
639
640 item = g_menu_item_new (label, NULL);
585 g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name);641 g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name);
586 g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item");642 g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item");
587643
@@ -1095,6 +1151,9 @@
1095 g_direct_equal,1151 g_direct_equal,
1096 NULL,1152 NULL,
1097 (GDestroyNotify)indicator_session_user_free);1153 (GDestroyNotify)indicator_session_user_free);
1154
1155 p->reported_users = g_hash_table_new (g_direct_hash, g_direct_equal);
1156
1098 maybe_add_users (self);1157 maybe_add_users (self);
10991158
1100 init_gactions (self);1159 init_gactions (self);
@@ -1235,6 +1294,7 @@
1235 }1294 }
12361295
1237 g_clear_pointer (&p->users, g_hash_table_destroy);1296 g_clear_pointer (&p->users, g_hash_table_destroy);
1297 g_clear_pointer (&p->reported_users, g_hash_table_destroy);
1238 g_clear_object (&p->backend_users);1298 g_clear_object (&p->backend_users);
1239 g_clear_object (&p->backend_guest);1299 g_clear_object (&p->backend_guest);
1240 g_clear_object (&p->backend_actions);1300 g_clear_object (&p->backend_actions);

Subscribers

People subscribed via source and target branches