1
From 9982f70b68aea1dc162cf08f121674914a30f24f Mon Sep 17 00:00:00 2001
2
From: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
3
Date: Mon, 22 Jul 2013 17:36:19 -0300
4
Subject: [PATCH] Implement get/set property via property service
6
The property service is running inside the android init daemon and
7
creates a socket in /dev/socket/property_service which we can use
8
for setting properties (getting is done via an extra android patch
9
to add 'get' and 'list' support in the property service).
11
Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
13
hybris/Makefile.am | 4 +-
14
hybris/common/Makefile.am | 2 +-
15
hybris/common/hooks.c | 3 +-
16
hybris/common/properties.c | 179 ----------------
17
hybris/common/properties.h | 26 ---
18
hybris/configure.ac | 2 +
19
hybris/include/Makefile.am | 4 +
20
hybris/include/hybris/properties/properties.h | 58 ++++++
21
hybris/properties/Makefile.am | 10 +
22
hybris/properties/properties.c | 287 ++++++++++++++++++++++++++
23
hybris/utils/Makefile.am | 15 ++
24
hybris/utils/getprop.c | 75 +++++++
25
hybris/utils/setprop.c | 35 ++++
26
13 files changed, 491 insertions(+), 209 deletions(-)
27
delete mode 100644 hybris/common/properties.c
28
delete mode 100644 hybris/common/properties.h
29
create mode 100644 hybris/include/hybris/properties/properties.h
30
create mode 100644 hybris/properties/Makefile.am
31
create mode 100644 hybris/properties/properties.c
32
create mode 100644 hybris/utils/Makefile.am
33
create mode 100644 hybris/utils/getprop.c
34
create mode 100644 hybris/utils/setprop.c
36
diff --git a/hybris/Makefile.am b/hybris/Makefile.am
37
index 8cd7eb1..ee0f593 100644
38
--- a/hybris/Makefile.am
39
+++ b/hybris/Makefile.am
41
-SUBDIRS = include common hardware
42
+SUBDIRS = include properties common hardware
48
SUBDIRS += egl glesv1 glesv2 ui sf input camera media
49
SUBDIRS += libnfc_nxp libnfc_ndef_nxp
51
+SUBDIRS += utils tests
53
MAINTAINERCLEANFILES = \
54
aclocal.m4 compile config.guess config.sub \
55
diff --git a/hybris/common/Makefile.am b/hybris/common/Makefile.am
56
index ddece59..0b78b96 100644
57
--- a/hybris/common/Makefile.am
58
+++ b/hybris/common/Makefile.am
59
@@ -17,7 +17,6 @@ endif
60
libhybris_common_la_SOURCES = \
66
libhybris_common_la_CFLAGS = \
67
@@ -33,4 +32,5 @@ libhybris_common_la_LDFLAGS = \
71
+ $(top_builddir)/properties/libandroid-properties.la \
72
-version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)"
73
diff --git a/hybris/common/hooks.c b/hybris/common/hooks.c
74
index 08f599d..715cf25 100644
75
--- a/hybris/common/hooks.c
76
+++ b/hybris/common/hooks.c
79
#include <hybris/internal/floating_point_abi.h>
81
-#include "properties.h"
82
#include "hooks_shm.h"
89
+#include <hybris/properties/properties.h>
91
static locale_t hybris_locale;
92
static int locale_inited = 0;
94
diff --git a/hybris/common/properties.c b/hybris/common/properties.c
95
deleted file mode 100644
96
index 8ed27fd..0000000
97
--- a/hybris/common/properties.c
101
- * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
103
- * Licensed under the Apache License, Version 2.0 (the "License");
104
- * you may not use this file except in compliance with the License.
105
- * You may obtain a copy of the License at
107
- * http://www.apache.org/licenses/LICENSE-2.0
109
- * Unless required by applicable law or agreed to in writing, software
110
- * distributed under the License is distributed on an "AS IS" BASIS,
111
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112
- * See the License for the specific language governing permissions and
113
- * limitations under the License.
122
-#include <sys/types.h>
123
-#include <sys/stat.h>
124
-#include "logging.h"
126
-#define PROP_NAME_MAX 32
128
-static char *find_key(const char *key)
130
- FILE *f = fopen("/system/build.prop", "r");
132
- char *mkey, *value;
137
- while (fgets(buf, 1024, f) != NULL) {
138
- if (strchr(buf, '\r'))
139
- *(strchr(buf, '\r')) = '\0';
140
- if (strchr(buf, '\n'))
141
- *(strchr(buf, '\n')) = '\0';
143
- mkey = strtok(buf, "=");
148
- value = strtok(NULL, "=");
152
- if (strcmp(key, mkey) == 0) {
154
- return strdup(value);
162
-static char *find_key_kernel_cmdline(const char *key)
164
- char cmdline[1024];
168
- fd = open("/proc/cmdline", O_RDONLY);
170
- int n = read(fd, cmdline, 1023);
173
- /* get rid of trailing newline, it happens */
174
- if (n > 0 && cmdline[n-1] == '\n') n--;
184
- while (ptr && *ptr) {
185
- char *x = strchr(ptr, ' ');
186
- if (x != 0) *x++ = 0;
191
- char *value = strchr(name, '=');
192
- int name_len = strlen(name);
194
- if (value == 0) continue;
196
- if (name_len == 0) continue;
198
- if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
199
- const char *boot_prop_name = name + 12;
200
- char prop[PROP_NAME_MAX];
201
- snprintf(prop, sizeof(prop), "ro.%s", boot_prop_name);
202
- if (strcmp(prop, key) == 0)
203
- return strdup(value);
210
-int property_get(const char *key, char *value, const char *default_value)
214
- //printf("property_get: %s\n", key);
217
- ret = find_key(key);
220
- if (strcmp(key, "ro.kernel.qemu") == 0)
224
- else if (strcmp(key, "ro.hardware") == 0)
226
- ret = "tenderloin";
228
- else if (strcmp(key, "ro.product.board") == 0)
230
- ret = "tenderloin";
232
- else if (strcmp(key, "ro.board.platform") == 0)
236
- else if (strcmp(key, "ro.arch") == 0)
240
- else if (strcmp(key, "debug.composition.type") == 0)
244
- else if (strcmp(key, "debug.sf.hw") == 0)
248
- else if (strcmp(key, "debug.gr.numframebuffers") == 0)
254
- /* Property might be available via /proc/cmdline */
255
- ret = find_key_kernel_cmdline(key);
259
- TRACE("found %s for %s\n", key, ret);
260
- strcpy(value, ret);
262
- return strlen(value);
263
- } else if (default_value != NULL) {
264
- strcpy(value, default_value);
265
- return strlen(value);
271
-int property_set(const char *key, const char *value)
273
- printf("property_set: %s %s\n", key, value);
274
- TRACE("property_set: %s %s\n", key, value);
278
-// vim:ts=4:sw=4:noexpandtab
279
diff --git a/hybris/common/properties.h b/hybris/common/properties.h
280
deleted file mode 100644
281
index ea4e28f..0000000
282
--- a/hybris/common/properties.h
286
- * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
288
- * Licensed under the Apache License, Version 2.0 (the "License");
289
- * you may not use this file except in compliance with the License.
290
- * You may obtain a copy of the License at
292
- * http://www.apache.org/licenses/LICENSE-2.0
294
- * Unless required by applicable law or agreed to in writing, software
295
- * distributed under the License is distributed on an "AS IS" BASIS,
296
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
297
- * See the License for the specific language governing permissions and
298
- * limitations under the License.
302
-#ifndef PROPERTIES_H_
303
-#define PROPERTIES_H_
305
-int property_set(const char *key, const char *value);
306
-int property_get(const char *key, char *value, const char *default_value);
310
-// vim:ts=4:sw=4:noexpandtab
311
diff --git a/hybris/configure.ac b/hybris/configure.ac
312
index a9fdfa4..94e209b 100644
313
--- a/hybris/configure.ac
314
+++ b/hybris/configure.ac
315
@@ -133,6 +133,7 @@ AM_CONDITIONAL([HAS_ANDROID_2_3_0], [test $android_headers_major -ge 2 -a $andro
319
+ properties/Makefile
321
common/gingerbread/Makefile
323
@@ -165,6 +166,7 @@ AC_CONFIG_FILES([
331
diff --git a/hybris/include/Makefile.am b/hybris/include/Makefile.am
332
index bd33587..349c276 100644
333
--- a/hybris/include/Makefile.am
334
+++ b/hybris/include/Makefile.am
335
@@ -70,3 +70,7 @@ mediainclude_HEADERS = \
336
hybris/media/surface_texture_client_hybris.h \
337
hybris/media/recorder_compatibility_layer.h
339
+propertiesincludedir = $(includedir)/hybris/properties
340
+propertiesinclude_HEADERS = \
341
+ hybris/properties/properties.h
343
diff --git a/hybris/include/hybris/properties/properties.h b/hybris/include/hybris/properties/properties.h
345
index 0000000..12d56b6
347
+++ b/hybris/include/hybris/properties/properties.h
350
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
351
+ * 2013 Simon Busch <morphis@gravedo.de>
352
+ * 2008 The Android Open Source Project
353
+ * 2013 Canonical Ltd
355
+ * Licensed under the Apache License, Version 2.0 (the "License");
356
+ * you may not use this file except in compliance with the License.
357
+ * You may obtain a copy of the License at
359
+ * http://www.apache.org/licenses/LICENSE-2.0
361
+ * Unless required by applicable law or agreed to in writing, software
362
+ * distributed under the License is distributed on an "AS IS" BASIS,
363
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
364
+ * See the License for the specific language governing permissions and
365
+ * limitations under the License.
369
+#ifndef PROPERTIES_H_
370
+#define PROPERTIES_H_
376
+/* Based on Android */
377
+#define PROP_SERVICE_NAME "property_service"
379
+#define PROP_NAME_MAX 32
380
+#define PROP_VALUE_MAX 92
382
+/* Only SETPROP is defined by Android, for GETPROP and LISTPROP to work
383
+ * an extended Android init service needs to be in place */
384
+#define PROP_MSG_SETPROP 1
385
+#define PROP_MSG_GETPROP 2
386
+#define PROP_MSG_LISTPROP 3
392
+ typedef struct prop_msg_s {
394
+ char name[PROP_NAME_MAX];
395
+ char value[PROP_VALUE_MAX];
398
+ int property_set(const char *key, const char *value);
399
+ int property_get(const char *key, char *value, const char *default_value);
400
+ int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);
406
+#endif // PROPERTIES_H_
407
diff --git a/hybris/properties/Makefile.am b/hybris/properties/Makefile.am
409
index 0000000..00f5d8d
411
+++ b/hybris/properties/Makefile.am
414
+ libandroid-properties.la
416
+libandroid_properties_la_SOURCES = properties.c
417
+libandroid_properties_la_CFLAGS = -I$(top_srcdir)/include
419
+libandroid_properties_la_CFLAGS += -ggdb -O0
421
+libandroid_properties_la_LDFLAGS = \
422
+ -version-info "1":"0":"0"
423
diff --git a/hybris/properties/properties.c b/hybris/properties/properties.c
425
index 0000000..cc350e2
427
+++ b/hybris/properties/properties.c
430
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
431
+ * 2008 The Android Open Source Project
432
+ * 2013 Simon Busch <morphis@gravedo.de>
433
+ * 2013 Canonical Ltd
435
+ * Licensed under the Apache License, Version 2.0 (the "License");
436
+ * you may not use this file except in compliance with the License.
437
+ * You may obtain a copy of the License at
439
+ * http://www.apache.org/licenses/LICENSE-2.0
441
+ * Unless required by applicable law or agreed to in writing, software
442
+ * distributed under the License is distributed on an "AS IS" BASIS,
443
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
444
+ * See the License for the specific language governing permissions and
445
+ * limitations under the License.
454
+#include <sys/types.h>
455
+#include <sys/stat.h>
459
+#include <sys/socket.h>
461
+#include <sys/select.h>
462
+#include <sys/types.h>
463
+#include <netinet/in.h>
466
+#include <hybris/properties/properties.h>
468
+static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
470
+/* Find a key value from a static /system/build.prop file */
471
+static char *find_key(const char *key)
473
+ FILE *f = fopen("/system/build.prop", "r");
475
+ char *mkey, *value;
480
+ while (fgets(buf, 1024, f) != NULL) {
481
+ if (strchr(buf, '\r'))
482
+ *(strchr(buf, '\r')) = '\0';
483
+ if (strchr(buf, '\n'))
484
+ *(strchr(buf, '\n')) = '\0';
486
+ mkey = strtok(buf, "=");
491
+ value = strtok(NULL, "=");
495
+ if (strcmp(key, mkey) == 0) {
497
+ return strdup(value);
505
+/* Find a key value from the kernel command line, which is parsed
506
+ * by Android at init (on an Android working system) */
507
+static char *find_key_kernel_cmdline(const char *key)
509
+ char cmdline[1024];
513
+ fd = open("/proc/cmdline", O_RDONLY);
515
+ int n = read(fd, cmdline, 1023);
518
+ /* get rid of trailing newline, it happens */
519
+ if (n > 0 && cmdline[n-1] == '\n') n--;
529
+ while (ptr && *ptr) {
530
+ char *x = strchr(ptr, ' ');
531
+ if (x != 0) *x++ = 0;
536
+ char *value = strchr(name, '=');
537
+ int name_len = strlen(name);
539
+ if (value == 0) continue;
541
+ if (name_len == 0) continue;
543
+ if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
544
+ const char *boot_prop_name = name + 12;
545
+ char prop[PROP_NAME_MAX];
546
+ snprintf(prop, sizeof(prop), "ro.%s", boot_prop_name);
547
+ if (strcmp(prop, key) == 0)
548
+ return strdup(value);
555
+/* Get/Set a property from the Android Init property socket */
556
+static int send_prop_msg(prop_msg_t *msg,
557
+ void (*propfn)(const char *, const char *, void *),
560
+ struct pollfd pollfds[1];
562
+ struct sockaddr_un addr;
563
+ struct sockaddr addr_g;
571
+ s = socket(AF_LOCAL, SOCK_STREAM, 0);
576
+ memset(&addr, 0, sizeof(addr));
577
+ namelen = strlen(property_service_socket);
578
+ strncpy(addr.addr.sun_path, property_service_socket,
579
+ sizeof(addr.addr.sun_path));
580
+ addr.addr.sun_family = AF_LOCAL;
581
+ alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
583
+ if (TEMP_FAILURE_RETRY(connect(s, &addr.addr_g, alen) < 0)) {
588
+ r = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg_t), 0));
590
+ if (r == sizeof(prop_msg_t)) {
592
+ pollfds[0].events = 0;
593
+ // We successfully wrote to the property server, so use recv
594
+ // in case we need to get a property. Once the other side is
595
+ // finished, the socket is closed.
596
+ while ((r = recv(s, msg, sizeof(prop_msg_t), 0)) > 0) {
597
+ if (r != sizeof(prop_msg_t)) {
603
+ propfn(msg->name, msg->value, cookie);
614
+int property_list(void (*propfn)(const char *key, const char *value, void *cookie),
620
+ memset(&msg, 0, sizeof(msg));
621
+ msg.cmd = PROP_MSG_LISTPROP;
623
+ err = send_prop_msg(&msg, propfn, cookie);
631
+static int property_get_socket(const char *key, char *value, const char *default_value)
637
+ memset(&msg, 0, sizeof(msg));
638
+ msg.cmd = PROP_MSG_GETPROP;
641
+ strncpy(msg.name, key, sizeof(msg.name));
642
+ err = send_prop_msg(&msg, NULL, NULL);
647
+ /* In case it's null, just use the default */
648
+ if ((strlen(msg.value) == 0) && (default_value)) {
649
+ if (strlen(default_value) >= PROP_VALUE_MAX) return -1;
650
+ len = strlen(default_value);
651
+ memcpy(msg.value, default_value, len + 1);
654
+ strncpy(value, msg.value, sizeof(msg.value));
659
+int property_get(const char *key, char *value, const char *default_value)
663
+ if ((key) && (strlen(key) >= PROP_NAME_MAX)) return -1;
665
+ if (property_get_socket(key, value, default_value) == 0) {
667
+ return strlen(value);
672
+ /* In case the socket is not available, parse the file by hand */
673
+ if ((ret = find_key(key)) == NULL) {
674
+ /* Property might be available via /proc/cmdline */
675
+ ret = find_key_kernel_cmdline(key);
679
+ strcpy(value, ret);
681
+ return strlen(value);
682
+ } else if (default_value != NULL) {
683
+ strcpy(value, default_value);
684
+ return strlen(value);
692
+int property_set(const char *key, const char *value)
697
+ if (key == 0) return -1;
698
+ if (value == 0) value = "";
699
+ if (strlen(key) >= PROP_NAME_MAX) return -1;
700
+ if (strlen(value) >= PROP_VALUE_MAX) return -1;
702
+ memset(&msg, 0, sizeof(msg));
703
+ msg.cmd = PROP_MSG_SETPROP;
704
+ strncpy(msg.name, key, sizeof(msg.name));
705
+ strncpy(msg.value, value, sizeof(msg.value));
707
+ err = send_prop_msg(&msg, NULL, NULL);
715
+// vim:ts=4:sw=4:noexpandtab
716
diff --git a/hybris/utils/Makefile.am b/hybris/utils/Makefile.am
718
index 0000000..47dcc62
720
+++ b/hybris/utils/Makefile.am
726
+getprop_SOURCES = getprop.c
728
+ -I$(top_srcdir)/include
730
+ $(top_builddir)/properties/libandroid-properties.la
732
+setprop_SOURCES = setprop.c
734
+ -I$(top_srcdir)/include
736
+ $(top_builddir)/properties/libandroid-properties.la
737
diff --git a/hybris/utils/getprop.c b/hybris/utils/getprop.c
739
index 0000000..c0110d1
741
+++ b/hybris/utils/getprop.c
744
+ * Copyright (c) 2008 The Android Open Source Project
745
+ * 2013 Canonical Ltd
747
+ * Licensed under the Apache License, Version 2.0 (the "License");
748
+ * you may not use this file except in compliance with the License.
749
+ * You may obtain a copy of the License at
751
+ * http://www.apache.org/licenses/LICENSE-2.0
753
+ * Unless required by applicable law or agreed to in writing, software
754
+ * distributed under the License is distributed on an "AS IS" BASIS,
755
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
756
+ * See the License for the specific language governing permissions and
757
+ * limitations under the License.
765
+#include <hybris/properties/properties.h>
772
+static void record_prop(const char* key, const char* name, void* opaque)
774
+ list_t *list = (list_t *) opaque;
776
+ char temp[PROP_VALUE_MAX + PROP_NAME_MAX + 16];
777
+ snprintf(temp, sizeof(temp), "[%s]: [%s]", key, name);
778
+ list->items = realloc(list->items, (list->count + 1) * sizeof(char **));
779
+ list->items[list->count++] = strdup(temp);
782
+static void list_properties(void)
787
+ memset(&list, 0, sizeof(list_t));
789
+ /* Record properties in the string list */
790
+ if (property_list(record_prop, &list) < 0)
793
+ for (n = 0; n < list.count; n++) {
794
+ printf("%s\n", (char *) list.items[n]);
798
+int main(int argc, char *argv[])
805
+ char value[PROP_VALUE_MAX];
806
+ char *default_value;
808
+ default_value = argv[2];
810
+ default_value = "";
813
+ property_get(argv[1], value, default_value);
814
+ printf("%s\n", value);
818
diff --git a/hybris/utils/setprop.c b/hybris/utils/setprop.c
820
index 0000000..fc08178
822
+++ b/hybris/utils/setprop.c
825
+ * Copyright (c) 2008 The Android Open Source Project
826
+ * 2013 Canonical Ltd
828
+ * Licensed under the Apache License, Version 2.0 (the "License");
829
+ * you may not use this file except in compliance with the License.
830
+ * You may obtain a copy of the License at
832
+ * http://www.apache.org/licenses/LICENSE-2.0
834
+ * Unless required by applicable law or agreed to in writing, software
835
+ * distributed under the License is distributed on an "AS IS" BASIS,
836
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
837
+ * See the License for the specific language governing permissions and
838
+ * limitations under the License.
843
+#include <hybris/properties/properties.h>
845
+int main(int argc, char *argv[])
848
+ fprintf(stderr, "usage: setprop <key> <value>\n");
852
+ if (property_set(argv[1], argv[2])){
853
+ fprintf(stderr, "could not set property\n");