summaryrefslogtreecommitdiffstats
path: root/init/keychords.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-02-03 17:12:07 -0800
committerElliott Hughes <enh@google.com>2015-02-04 08:59:10 -0800
commitf3cf438714aa1284d8a58e2f3b108ba93f6d3abb (patch)
tree3a1b726c6805315c280d745e8b742ec9542d58e9 /init/keychords.cpp
parent5204b1580e0d0f38272c7da166eee9b88c14dc50 (diff)
downloadsystem_core-f3cf438714aa1284d8a58e2f3b108ba93f6d3abb.zip
system_core-f3cf438714aa1284d8a58e2f3b108ba93f6d3abb.tar.gz
system_core-f3cf438714aa1284d8a58e2f3b108ba93f6d3abb.tar.bz2
Build init as C++.
This is just the minimal change to keep it building. Change-Id: I245c5b8413a1db114576c81462eb5737f5ffcef2
Diffstat (limited to 'init/keychords.cpp')
-rw-r--r--init/keychords.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/init/keychords.cpp b/init/keychords.cpp
new file mode 100644
index 0000000..d6464bd
--- /dev/null
+++ b/init/keychords.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <linux/keychord.h>
+#include <unistd.h>
+
+#include "init.h"
+#include "log.h"
+#include "property_service.h"
+
+static struct input_keychord *keychords = 0;
+static int keychords_count = 0;
+static int keychords_length = 0;
+static int keychord_fd = -1;
+
+void add_service_keycodes(struct service *svc)
+{
+ struct input_keychord *keychord;
+ int i, size;
+
+ if (svc->keycodes) {
+ /* add a new keychord to the list */
+ size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]);
+ keychords = (input_keychord*) realloc(keychords, keychords_length + size);
+ if (!keychords) {
+ ERROR("could not allocate keychords\n");
+ keychords_length = 0;
+ keychords_count = 0;
+ return;
+ }
+
+ keychord = (struct input_keychord *)((char *)keychords + keychords_length);
+ keychord->version = KEYCHORD_VERSION;
+ keychord->id = keychords_count + 1;
+ keychord->count = svc->nkeycodes;
+ svc->keychord_id = keychord->id;
+
+ for (i = 0; i < svc->nkeycodes; i++) {
+ keychord->keycodes[i] = svc->keycodes[i];
+ }
+ keychords_count++;
+ keychords_length += size;
+ }
+}
+
+void keychord_init()
+{
+ int fd, ret;
+
+ service_for_each(add_service_keycodes);
+
+ /* nothing to do if no services require keychords */
+ if (!keychords)
+ return;
+
+ fd = open("/dev/keychord", O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ ERROR("could not open /dev/keychord\n");
+ return;
+ }
+
+ ret = write(fd, keychords, keychords_length);
+ if (ret != keychords_length) {
+ ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno);
+ close(fd);
+ fd = -1;
+ }
+
+ free(keychords);
+ keychords = 0;
+
+ keychord_fd = fd;
+}
+
+void handle_keychord()
+{
+ struct service *svc;
+ char adb_enabled[PROP_VALUE_MAX];
+ int ret;
+ __u16 id;
+
+ // Only handle keychords if adb is enabled.
+ property_get("init.svc.adbd", adb_enabled);
+ ret = read(keychord_fd, &id, sizeof(id));
+ if (ret != sizeof(id)) {
+ ERROR("could not read keychord id\n");
+ return;
+ }
+
+ if (!strcmp(adb_enabled, "running")) {
+ svc = service_find_by_keychord(id);
+ if (svc) {
+ INFO("starting service %s from keychord\n", svc->name);
+ service_start(svc, NULL);
+ } else {
+ ERROR("service for keychord %d not found\n", id);
+ }
+ }
+}
+
+int get_keychord_fd()
+{
+ return keychord_fd;
+}