Add default-monitor-time-sec
[platform/upstream/pulseaudio.git] / src / pulsecore / proplist-util.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2008 Lennart Poettering
5
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <string.h>
25 #include <locale.h>
26
27 #ifdef ENABLE_NLS
28 #include <libintl.h>
29 #endif
30
31 #ifdef __APPLE__
32 #include <crt_externs.h>
33 #define environ (*_NSGetEnviron())
34 #elif !HAVE_DECL_ENVIRON
35 extern char **environ;
36 #endif
37
38 #include <pulse/gccmacro.h>
39 #include <pulse/proplist.h>
40 #include <pulse/utf8.h>
41 #include <pulse/xmalloc.h>
42 #include <pulse/util.h>
43
44 #include <pulsecore/core-util.h>
45
46 #if defined(HAVE_GLIB) && defined(PA_GCC_WEAKREF)
47 #include <glib.h>
48 static const gchar* _g_get_application_name(void) PA_GCC_WEAKREF(g_get_application_name);
49 #endif
50
51 #if defined(HAVE_GTK) && defined(PA_GCC_WEAKREF)
52 #pragma GCC diagnostic ignored "-Wstrict-prototypes"
53 #include <gtk/gtk.h>
54 #include <gdk/gdkx.h>
55 static const gchar* _gtk_window_get_default_icon_name(void) PA_GCC_WEAKREF(gtk_window_get_default_icon_name);
56 static Display *_gdk_display PA_GCC_WEAKREF(gdk_display);
57 #endif
58
59 #include "proplist-util.h"
60
61 static void add_glib_properties(pa_proplist *p) {
62
63 #if defined(HAVE_GLIB) && defined(PA_GCC_WEAKREF)
64
65     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_NAME))
66         if (_g_get_application_name) {
67             const gchar *t;
68
69             /* We ignore the tiny race condition here. */
70
71             if ((t = _g_get_application_name()))
72                 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, t);
73         }
74
75 #endif
76 }
77
78 static void add_gtk_properties(pa_proplist *p) {
79
80 #if defined(HAVE_GTK) && defined(PA_GCC_WEAKREF)
81
82     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_ICON_NAME))
83         if (_gtk_window_get_default_icon_name) {
84             const gchar *t;
85
86             /* We ignore the tiny race condition here. */
87
88             if ((t = _gtk_window_get_default_icon_name()))
89                 pa_proplist_sets(p, PA_PROP_APPLICATION_ICON_NAME, t);
90         }
91
92     if (!pa_proplist_contains(p, PA_PROP_WINDOW_X11_DISPLAY))
93         if (&_gdk_display && _gdk_display) {
94             const char *t;
95
96             /* We ignore the tiny race condition here. */
97
98             if ((t = DisplayString(_gdk_display)))
99                 pa_proplist_sets(p, PA_PROP_WINDOW_X11_DISPLAY, t);
100         }
101
102 #endif
103 }
104
105 void pa_init_proplist(pa_proplist *p) {
106     char **e;
107     const char *pp;
108
109     pa_assert(p);
110
111     if (environ) {
112
113         /* Some applications seem to reset environ to NULL for various
114          * reasons, hence we need to check for this explicitly. See
115          * rhbz #473080 */
116
117         for (e = environ; *e; e++) {
118
119             if (pa_startswith(*e, "PULSE_PROP_")) {
120                 size_t kl, skip;
121                 char *k;
122                 bool override;
123
124                 if (pa_startswith(*e, "PULSE_PROP_OVERRIDE_")) {
125                     skip = 20;
126                     override = true;
127                 } else {
128                     skip = 11;
129                     override = false;
130                 }
131
132                 kl = strcspn(*e+skip, "=");
133
134                 if ((*e)[skip+kl] != '=')
135                     continue;
136
137                 k = pa_xstrndup(*e+skip, kl);
138
139                 if (!pa_streq(k, "OVERRIDE"))
140                     if (override || !pa_proplist_contains(p, k))
141                         pa_proplist_sets(p, k, *e+skip+kl+1);
142                 pa_xfree(k);
143             }
144         }
145     }
146
147     if ((pp = getenv("PULSE_PROP"))) {
148         pa_proplist *t;
149
150         if ((t = pa_proplist_from_string(pp))) {
151             pa_proplist_update(p, PA_UPDATE_MERGE, t);
152             pa_proplist_free(t);
153         }
154     }
155
156     if ((pp = getenv("PULSE_PROP_OVERRIDE"))) {
157         pa_proplist *t;
158
159         if ((t = pa_proplist_from_string(pp))) {
160             pa_proplist_update(p, PA_UPDATE_REPLACE, t);
161             pa_proplist_free(t);
162         }
163     }
164
165     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_ID)) {
166         char t[32];
167         pa_snprintf(t, sizeof(t), "%lu", (unsigned long) getpid());
168         pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_ID, t);
169     }
170
171     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_USER)) {
172         char *u;
173
174         if ((u = pa_get_user_name_malloc())) {
175             pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_USER, u);
176             pa_xfree(u);
177         }
178     }
179
180     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_HOST)) {
181         char *h;
182
183         if ((h = pa_get_host_name_malloc())) {
184             pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_HOST, h);
185             pa_xfree(h);
186         }
187     }
188
189     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_BINARY)) {
190         char *t;
191
192         if ((t = pa_get_binary_name_malloc())) {
193             char *c = pa_utf8_filter(t);
194             pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_BINARY, c);
195             pa_xfree(t);
196             pa_xfree(c);
197         }
198     }
199
200     add_glib_properties(p);
201     add_gtk_properties(p);
202
203     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_NAME)) {
204         const char *t;
205
206         if ((t = pa_proplist_gets(p, PA_PROP_APPLICATION_PROCESS_BINARY)))
207             pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, t);
208     }
209
210 #ifdef ENABLE_NLS
211     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_LANGUAGE)) {
212         const char *l;
213
214         if ((l = setlocale(LC_MESSAGES, NULL)))
215             pa_proplist_sets(p, PA_PROP_APPLICATION_LANGUAGE, l);
216     }
217 #endif
218
219     if (!pa_proplist_contains(p, PA_PROP_WINDOW_X11_DISPLAY)) {
220         const char *t;
221
222         if ((t = getenv("DISPLAY"))) {
223             char *c = pa_utf8_filter(t);
224             pa_proplist_sets(p, PA_PROP_WINDOW_X11_DISPLAY, c);
225             pa_xfree(c);
226         }
227     }
228
229     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_MACHINE_ID)) {
230         char *m;
231
232         if ((m = pa_machine_id())) {
233             pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_MACHINE_ID, m);
234             pa_xfree(m);
235         }
236     }
237
238     if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_SESSION_ID)) {
239         char *s;
240
241         if ((s = pa_session_id())) {
242             pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_SESSION_ID, s);
243             pa_xfree(s);
244         }
245     }
246 }
247
248 char *pa_proplist_get_stream_group(pa_proplist *p, const char *prefix, const char *cache) {
249     const char *r;
250     char *t;
251
252     if (!p)
253         return NULL;
254
255     if (cache && (r = pa_proplist_gets(p, cache)))
256         return pa_xstrdup(r);
257
258     if (!prefix)
259         prefix = "stream";
260
261     if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
262         t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
263     else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
264         t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
265     else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
266         t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
267     else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
268         t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
269     else
270 #ifdef __TIZEN__
271         t = pa_sprintf_malloc("%s-fallback:%s", prefix, pa_strnull(r));
272 #else
273         t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
274 #endif
275
276     if (cache)
277         pa_proplist_sets(p, cache, t);
278
279     return t;
280 }
281
282 #ifdef __TIZEN__
283 #define REMOTE_ACCESS_PERMISSION_DENIED    "denied"
284 #define REMOTE_ACCESS_PERMISSION_ALLOWED   "allowed"
285
286 static const char *access_str[] = { REMOTE_ACCESS_PERMISSION_DENIED, REMOTE_ACCESS_PERMISSION_ALLOWED };
287
288 void pa_proplist_remote_init(pa_proplist *p, const char *remote_name) {
289     if (!p)
290         return;
291
292     pa_proplist_sets(p, PA_PROP_MEDIA_REMOTE_NAME, pa_strnull(remote_name));
293     pa_proplist_sets(p, PA_PROP_MEDIA_REMOTE_ACCESS, REMOTE_ACCESS_PERMISSION_DENIED);
294 }
295
296 bool pa_proplist_has_remote_name(pa_proplist *p) {
297     bool is_remote = false;
298
299     if (!p)
300         return false;
301
302     is_remote = pa_proplist_contains(p, PA_PROP_MEDIA_REMOTE_NAME);
303
304     pa_log_info("Is remote : %s", pa_yes_no(is_remote));
305
306     return is_remote;
307 }
308
309 int pa_proplist_set_remote_access_permission(pa_proplist *p, bool allowed) {
310     if (!p)
311         return -1;
312
313     return pa_proplist_sets(p, PA_PROP_MEDIA_REMOTE_ACCESS, access_str[allowed]);
314 }
315
316 bool pa_proplist_remote_is_allowed(pa_proplist *p) {
317     if (!p)
318         return false;
319
320     return pa_safe_streq(pa_proplist_gets(p, PA_PROP_MEDIA_REMOTE_ACCESS), REMOTE_ACCESS_PERMISSION_ALLOWED);
321 }
322 #endif /* __TIZEN__ */