Merge "audio: Fix false positives in audio_is_remote_submix_device()"
diff --git a/adb/Android.mk b/adb/Android.mk
index dd1343b..4ffb589 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -6,11 +6,18 @@
LOCAL_PATH:= $(call my-dir)
ifeq ($(HOST_OS),windows)
- adb_host_clang := false # libc++ for mingw not ready yet.
+ adb_host_clang := false # libc++ for mingw not ready yet.
else
- adb_host_clang := true
+ adb_host_clang := true
endif
+adb_version := $(shell git -C $(LOCAL_PATH) rev-parse --short=12 HEAD 2>/dev/null)-android
+
+ADB_COMMON_CFLAGS := \
+ -Wall -Werror \
+ -Wno-unused-parameter \
+ -DADB_REVISION='"$(adb_version)"' \
+
# libadb
# =========================================================
@@ -37,8 +44,7 @@
transport_test.cpp \
LIBADB_CFLAGS := \
- -Wall -Werror \
- -Wno-unused-parameter \
+ $(ADB_COMMON_CFLAGS) \
-Wno-missing-field-initializers \
-fvisibility=hidden \
@@ -90,6 +96,9 @@
ifeq ($(HOST_OS),windows)
LOCAL_C_INCLUDES += development/host/windows/usb/api/
+ # Windows.h defines an awful ERROR macro that collides with base/logging.h.
+ # Suppress it with NOGDI.
+ LOCAL_CFLAGS += -DNOGDI
endif
include $(BUILD_HOST_STATIC_LIBRARY)
@@ -103,6 +112,7 @@
LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
include $(BUILD_NATIVE_TEST)
+ifneq ($(HOST_OS),windows)
include $(CLEAR_VARS)
LOCAL_CLANG := $(adb_host_clang)
LOCAL_MODULE := adb_test
@@ -115,14 +125,15 @@
libcutils \
ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lrt -ldl -lpthread
+ LOCAL_LDLIBS += -lrt -ldl -lpthread
endif
ifeq ($(HOST_OS),darwin)
- LOCAL_LDLIBS += -framework CoreFoundation -framework IOKit
+ LOCAL_LDLIBS += -framework CoreFoundation -framework IOKit
endif
include $(BUILD_HOST_NATIVE_TEST)
+endif
# adb device tracker (used by ddms) test tool
# =========================================================
@@ -144,24 +155,27 @@
include $(CLEAR_VARS)
ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lrt -ldl -lpthread
- LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
+ LOCAL_LDLIBS += -lrt -ldl -lpthread
+ LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
endif
ifeq ($(HOST_OS),darwin)
- LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
- LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
+ LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
+ LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
endif
ifeq ($(HOST_OS),windows)
- LOCAL_LDLIBS += -lws2_32 -lgdi32
- EXTRA_STATIC_LIBS := AdbWinApi
+ # Windows.h defines an awful ERROR macro that collides with base/logging.h.
+ # Suppress it with NOGDI.
+ LOCAL_CFLAGS += -DNOGDI
+ LOCAL_LDLIBS += -lws2_32 -lgdi32
+ EXTRA_STATIC_LIBS := AdbWinApi
endif
LOCAL_CLANG := $(adb_host_clang)
LOCAL_SRC_FILES := \
- adb_main.cpp \
+ client/main.cpp \
console.cpp \
commandline.cpp \
adb_client.cpp \
@@ -169,8 +183,7 @@
file_sync_client.cpp \
LOCAL_CFLAGS += \
- -Wall -Werror \
- -Wno-unused-parameter \
+ $(ADB_COMMON_CFLAGS) \
-D_GNU_SOURCE \
-DADB_HOST=1 \
@@ -214,7 +227,7 @@
LOCAL_CLANG := true
LOCAL_SRC_FILES := \
- adb_main.cpp \
+ daemon/main.cpp \
services.cpp \
file_sync_service.cpp \
framebuffer_service.cpp \
@@ -222,10 +235,9 @@
set_verity_enable_state_service.cpp \
LOCAL_CFLAGS := \
+ $(ADB_COMMON_CFLAGS) \
-DADB_HOST=0 \
-D_GNU_SOURCE \
- -Wall -Werror \
- -Wno-unused-parameter \
-Wno-deprecated-declarations \
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
diff --git a/adb/adb.cpp b/adb/adb.cpp
index c78076d..c4e3434 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -696,7 +696,7 @@
// Try to handle a network forwarding request.
// This returns 1 on success, 0 on failure, and -1 to indicate this is not
// a forwarding-related request.
-int handle_forward_request(const char* service, TransportType type, char* serial, int reply_fd)
+int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd)
{
if (!strcmp(service, "list-forward")) {
// Create the list of forward redirections.
@@ -796,13 +796,12 @@
return 0;
}
-int handle_host_request(char *service, TransportType type, char* serial, int reply_fd, asocket *s)
-{
- if(!strcmp(service, "kill")) {
- fprintf(stderr,"adb server killed by remote request\n");
+int handle_host_request(const char* service, TransportType type,
+ const char* serial, int reply_fd, asocket* s) {
+ if (strcmp(service, "kill") == 0) {
+ fprintf(stderr, "adb server killed by remote request\n");
fflush(stdout);
SendOkay(reply_fd);
- usb_cleanup();
exit(0);
}
@@ -856,7 +855,7 @@
if (!strncmp(service, "disconnect:", 11)) {
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
- char* serial = service + 11;
+ const char* serial = service + 11;
if (serial[0] == 0) {
// disconnect from all TCP devices
unregister_all_tcp_transports();
diff --git a/adb/adb.h b/adb/adb.h
index 5d20165..7942a86 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -284,7 +284,7 @@
int create_jdwp_connection_fd(int jdwp_pid);
#endif
-int handle_forward_request(const char* service, TransportType type, char* serial, int reply_fd);
+int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd);
#if !ADB_HOST
void framebuffer_service(int fd, void *cookie);
@@ -324,7 +324,6 @@
/* usb host/client interface */
void usb_init();
-void usb_cleanup();
int usb_write(usb_handle *h, const void *data, int len);
int usb_read(usb_handle *h, void *data, int len);
int usb_close(usb_handle *h);
@@ -366,7 +365,7 @@
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
#endif
-int handle_host_request(char *service, TransportType type, char* serial, int reply_fd, asocket *s);
+int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s);
void handle_online(atransport *t);
void handle_offline(atransport *t);
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 510dcc2..e4658f5 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -16,6 +16,11 @@
#define TRACE_TAG TRACE_AUTH
+#ifdef _WIN32
+// This blocks some definitions we need on Windows.
+#undef NOGDI
+#endif
+
#include "sysdeps.h"
#include "adb_auth.h"
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 18e14de..532af45 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -80,36 +80,6 @@
__adb_server_name = hostname;
}
-int adb_get_emulator_console_port() {
- if (__adb_serial) {
- // The user specified a serial number; is it an emulator?
- int port;
- return (sscanf(__adb_serial, "emulator-%d", &port) == 1) ? port : -1;
- }
-
- // No specific device was given, so get the list of connected
- // devices and search for emulators. If there's one, we'll
- // take it. If there are more than one, that's an error.
- std::string devices;
- std::string error;
- if (!adb_query("host:devices", &devices, &error)) {
- printf("no emulator connected: %s\n", error.c_str());
- return -1;
- }
-
- int port;
- size_t emulator_count = 0;
- for (auto& device : android::base::Split(devices, "\n")) {
- if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
- if (++emulator_count > 1) {
- return -2;
- }
- }
- }
- if (emulator_count == 0) return -1;
- return port;
-}
-
static int switch_socket_transport(int fd, std::string* error) {
std::string service;
if (__adb_serial) {
diff --git a/adb/adb_client.h b/adb/adb_client.h
index de5c2db..9895c49 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
#ifndef _ADB_CLIENT_H_
#define _ADB_CLIENT_H_
@@ -5,16 +21,13 @@
#include <string>
-/* connect to adb, connect to the named service, and return
-** a valid fd for interacting with that service upon success
-** or a negative number on failure
-*/
+// Connect to adb, connect to the named service, and return a valid fd for
+// interacting with that service upon success or a negative number on failure.
int adb_connect(const std::string& service, std::string* error);
int _adb_connect(const std::string& service, std::string* error);
-/* connect to adb, connect to the named service, return 0 if
-** the connection succeeded AND the service returned OKAY
-*/
+// Connect to adb, connect to the named service, return 0 if the connection
+// succeeded AND the service returned OKAY.
int adb_command(const std::string& service, std::string* error);
// Connects to the named adb service and fills 'result' with the response.
@@ -24,29 +37,19 @@
// Set the preferred transport to connect to.
void adb_set_transport(TransportType type, const char* serial);
-/* Set TCP specifics of the transport to use
-*/
+// Set TCP specifics of the transport to use.
void adb_set_tcp_specifics(int server_port);
-/* Set TCP Hostname of the transport to use
-*/
+// Set TCP Hostname of the transport to use.
void adb_set_tcp_name(const char* hostname);
-/* Return the console port of the currently connected emulator (if any)
- * of -1 if there is no emulator, and -2 if there is more than one.
- * assumes adb_set_transport() was alled previously...
- */
-int adb_get_emulator_console_port(void);
+// Send commands to the current emulator instance. Will fail if there is not
+// exactly one emulator connected (or if you use -s <serial> with a <serial>
+// that does not designate an emulator).
+int adb_send_emulator_command(int argc, const char** argv, const char* serial);
-/* send commands to the current emulator instance. will fail if there
- * is zero, or more than one emulator connected (or if you use -s <serial>
- * with a <serial> that does not designate an emulator)
- */
-int adb_send_emulator_command(int argc, const char** argv);
-
-// Reads a standard adb status response (OKAY|FAIL) and
-// returns true in the event of OKAY, false in the event of FAIL
-// or protocol error.
+// Reads a standard adb status response (OKAY|FAIL) and returns true in the
+// event of OKAY, false in the event of FAIL or protocol error.
bool adb_status(int fd, std::string* error);
#endif
diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
deleted file mode 100644
index bd22d74..0000000
--- a/adb/adb_main.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define TRACE_TAG TRACE_ADB
-
-#include "sysdeps.h"
-
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "adb_listeners.h"
-#include "transport.h"
-
-#include <base/stringprintf.h>
-
-#if !ADB_HOST
-#include <getopt.h>
-#include <sys/prctl.h>
-
-#include "cutils/properties.h"
-#include "private/android_filesystem_config.h"
-#include "selinux/selinux.h"
-
-#include "qemu_tracing.h"
-#endif
-
-static void adb_cleanup(void)
-{
- usb_cleanup();
-}
-
-#if defined(_WIN32)
-static BOOL WINAPI ctrlc_handler(DWORD type)
-{
- exit(STATUS_CONTROL_C_EXIT);
- return TRUE;
-}
-#endif
-
-#if ADB_HOST
-#ifdef WORKAROUND_BUG6558362
-#include <sched.h>
-#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362"
-void adb_set_affinity(void)
-{
- cpu_set_t cpu_set;
- const char* cpunum_str = getenv(AFFINITY_ENVVAR);
- char* strtol_res;
- int cpu_num;
-
- if (!cpunum_str || !*cpunum_str)
- return;
- cpu_num = strtol(cpunum_str, &strtol_res, 0);
- if (*strtol_res != '\0')
- fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR);
-
- sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
- D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
- CPU_ZERO(&cpu_set);
- CPU_SET(cpu_num, &cpu_set);
- sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
- sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
- D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
-}
-#endif
-#else /* ADB_HOST */
-static const char *root_seclabel = NULL;
-
-static void drop_capabilities_bounding_set_if_needed() {
-#ifdef ALLOW_ADBD_ROOT
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.debuggable", value, "");
- if (strcmp(value, "1") == 0) {
- return;
- }
-#endif
- int i;
- for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
- if (i == CAP_SETUID || i == CAP_SETGID) {
- // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
- continue;
- }
- int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
-
- // Some kernels don't have file capabilities compiled in, and
- // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically
- // die when we see such misconfigured kernels.
- if ((err < 0) && (errno != EINVAL)) {
- exit(1);
- }
- }
-}
-
-static bool should_drop_privileges() {
-#if defined(ALLOW_ADBD_ROOT)
- char value[PROPERTY_VALUE_MAX];
-
- // The emulator is never secure, so don't drop privileges there.
- // TODO: this seems like a bug --- shouldn't the emulator behave like a device?
- property_get("ro.kernel.qemu", value, "");
- if (strcmp(value, "1") == 0) {
- return false;
- }
-
- // The properties that affect `adb root` and `adb unroot` are ro.secure and
- // ro.debuggable. In this context the names don't make the expected behavior
- // particularly obvious.
- //
- // ro.debuggable:
- // Allowed to become root, but not necessarily the default. Set to 1 on
- // eng and userdebug builds.
- //
- // ro.secure:
- // Drop privileges by default. Set to 1 on userdebug and user builds.
- property_get("ro.secure", value, "1");
- bool ro_secure = (strcmp(value, "1") == 0);
-
- property_get("ro.debuggable", value, "");
- bool ro_debuggable = (strcmp(value, "1") == 0);
-
- // Drop privileges if ro.secure is set...
- bool drop = ro_secure;
-
- property_get("service.adb.root", value, "");
- bool adb_root = (strcmp(value, "1") == 0);
- bool adb_unroot = (strcmp(value, "0") == 0);
-
- // ...except "adb root" lets you keep privileges in a debuggable build.
- if (ro_debuggable && adb_root) {
- drop = false;
- }
-
- // ...and "adb unroot" lets you explicitly drop privileges.
- if (adb_unroot) {
- drop = true;
- }
-
- return drop;
-#else
- return true; // "adb root" not allowed, always drop privileges.
-#endif /* ALLOW_ADBD_ROOT */
-}
-#endif /* ADB_HOST */
-
-void start_logging(void)
-{
-#if defined(_WIN32)
- char temp[ MAX_PATH ];
- FILE* fnul;
- FILE* flog;
-
- GetTempPath( sizeof(temp) - 8, temp );
- strcat( temp, "adb.log" );
-
- /* Win32 specific redirections */
- fnul = fopen( "NUL", "rt" );
- if (fnul != NULL)
- stdin[0] = fnul[0];
-
- flog = fopen( temp, "at" );
- if (flog == NULL)
- flog = fnul;
-
- setvbuf( flog, NULL, _IONBF, 0 );
-
- stdout[0] = flog[0];
- stderr[0] = flog[0];
- fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
-#else
- int fd;
-
- fd = unix_open("/dev/null", O_RDONLY);
- dup2(fd, 0);
- adb_close(fd);
-
- fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
- if(fd < 0) {
- fd = unix_open("/dev/null", O_WRONLY);
- }
- dup2(fd, 1);
- dup2(fd, 2);
- adb_close(fd);
- fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
-#endif
-}
-
-int adb_main(int is_daemon, int server_port)
-{
-#if !ADB_HOST
- int port;
- char value[PROPERTY_VALUE_MAX];
-
- umask(000);
-#endif
-
- atexit(adb_cleanup);
-#if defined(_WIN32)
- SetConsoleCtrlHandler( ctrlc_handler, TRUE );
-#else
- // No SIGCHLD. Let the service subproc handle its children.
- signal(SIGPIPE, SIG_IGN);
-#endif
-
- init_transport_registration();
-
-#if ADB_HOST
- HOST = 1;
-
-#ifdef WORKAROUND_BUG6558362
- if(is_daemon) adb_set_affinity();
-#endif
- usb_init();
- local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
- adb_auth_init();
-
- std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
- if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
- exit(1);
- }
-#else
- // We need to call this even if auth isn't enabled because the file
- // descriptor will always be open.
- adbd_cloexec_auth_socket();
-
- property_get("ro.adb.secure", value, "0");
- auth_enabled = !strcmp(value, "1");
- if (auth_enabled)
- adbd_auth_init();
-
- // Our external storage path may be different than apps, since
- // we aren't able to bind mount after dropping root.
- const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
- if (NULL != adb_external_storage) {
- setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
- } else {
- D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE"
- " unchanged.\n");
- }
-
- /* add extra groups:
- ** AID_ADB to access the USB driver
- ** AID_LOG to read system logs (adb logcat)
- ** AID_INPUT to diagnose input issues (getevent)
- ** AID_INET to diagnose network issues (ping)
- ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
- ** AID_SDCARD_R to allow reading from the SD card
- ** AID_SDCARD_RW to allow writing to the SD card
- ** AID_NET_BW_STATS to read out qtaguid statistics
- */
- gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_NET_BT,
- AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
- AID_NET_BW_STATS };
- if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
- exit(1);
- }
-
- /* don't listen on a port (default 5037) if running in secure mode */
- /* don't run as root if we are running in secure mode */
- if (should_drop_privileges()) {
- drop_capabilities_bounding_set_if_needed();
-
- /* then switch user and group to "shell" */
- if (setgid(AID_SHELL) != 0) {
- exit(1);
- }
- if (setuid(AID_SHELL) != 0) {
- exit(1);
- }
-
- D("Local port disabled\n");
- } else {
- if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) {
- // b/12587913: fix setcon to allow const pointers
- if (setcon((char *)root_seclabel) < 0) {
- exit(1);
- }
- }
- std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
- if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
- exit(1);
- }
- }
-
- int usb = 0;
- if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
- // listen on USB
- usb_init();
- usb = 1;
- }
-
- // If one of these properties is set, also listen on that port
- // If one of the properties isn't set and we couldn't listen on usb,
- // listen on the default port.
- property_get("service.adb.tcp.port", value, "");
- if (!value[0]) {
- property_get("persist.adb.tcp.port", value, "");
- }
- if (sscanf(value, "%d", &port) == 1 && port > 0) {
- printf("using port=%d\n", port);
- // listen on TCP port specified by service.adb.tcp.port property
- local_init(port);
- } else if (!usb) {
- // listen on default port
- local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
- }
-
- D("adb_main(): pre init_jdwp()\n");
- init_jdwp();
- D("adb_main(): post init_jdwp()\n");
-#endif
-
- if (is_daemon)
- {
- // inform our parent that we are up and running.
-#if defined(_WIN32)
- DWORD count;
- WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
-#else
- fprintf(stderr, "OK\n");
-#endif
- start_logging();
- }
- D("Event loop starting\n");
-
- fdevent_loop();
-
- usb_cleanup();
-
- return 0;
-}
-
-#if !ADB_HOST
-void close_stdin() {
- int fd = unix_open("/dev/null", O_RDONLY);
- if (fd == -1) {
- perror("failed to open /dev/null, stdin will remain open");
- return;
- }
- dup2(fd, 0);
- adb_close(fd);
-}
-#endif
-
-int main(int argc, char **argv) {
-#if ADB_HOST
- adb_sysdeps_init();
-#else
- close_stdin();
-#endif
- adb_trace_init();
-
-#if ADB_HOST
- D("Handling commandline()\n");
- return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
-#else
- /* If adbd runs inside the emulator this will enable adb tracing via
- * adb-debug qemud service in the emulator. */
- adb_qemu_trace_init();
- while (true) {
- int c;
- int option_index = 0;
- static struct option opts[] = {
- {"root_seclabel", required_argument, 0, 's' },
- {"device_banner", required_argument, 0, 'b' }
- };
- c = getopt_long(argc, argv, "", opts, &option_index);
- if (c == -1)
- break;
- switch (c) {
- case 's':
- root_seclabel = optarg;
- break;
- case 'b':
- adb_device_banner = optarg;
- break;
- default:
- break;
- }
- }
-
- D("Handling main()\n");
- return adb_main(0, DEFAULT_ADB_PORT);
-#endif
-}
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
new file mode 100644
index 0000000..468909a
--- /dev/null
+++ b/adb/client/main.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define TRACE_TAG TRACE_ADB
+
+#include "sysdeps.h"
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// We only build the affinity WAR code for Linux.
+#if defined(__linux__)
+#include <sched.h>
+#endif
+
+#include "base/file.h"
+#include "base/logging.h"
+#include "base/stringprintf.h"
+
+#include "adb.h"
+#include "adb_auth.h"
+#include "adb_listeners.h"
+#include "transport.h"
+
+#if defined(WORKAROUND_BUG6558362) && defined(__linux__)
+static const bool kWorkaroundBug6558362 = true;
+#else
+static const bool kWorkaroundBug6558362 = false;
+#endif
+
+static void adb_workaround_affinity(void) {
+#if defined(__linux__)
+ const char affinity_env[] = "ADB_CPU_AFFINITY_BUG6558362";
+ const char* cpunum_str = getenv(affinity_env);
+ if (cpunum_str == nullptr || *cpunum_str == '\0') {
+ return;
+ }
+
+ char* strtol_res;
+ int cpu_num = strtol(cpunum_str, &strtol_res, 0);
+ if (*strtol_res != '\0') {
+ fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str,
+ affinity_env);
+ }
+
+ cpu_set_t cpu_set;
+ sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+ D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu_num, &cpu_set);
+ sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+
+ sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+ D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+#else
+ // No workaround was ever implemented for the other platforms.
+#endif
+}
+
+#if defined(_WIN32)
+static const char kNullFileName[] = "NUL";
+
+static BOOL WINAPI ctrlc_handler(DWORD type) {
+ exit(STATUS_CONTROL_C_EXIT);
+ return TRUE;
+}
+
+static std::string GetLogFilePath() {
+ const char log_name[] = "adb.log";
+ char temp_path[MAX_PATH - sizeof(log_name) + 1];
+
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
+ DWORD nchars = GetTempPath(sizeof(temp_path), temp_path);
+ CHECK_LE(nchars, sizeof(temp_path));
+ if (nchars == 0) {
+ // TODO(danalbert): Log the error message from FormatError().
+ // Windows unfortunately has two errnos, errno and GetLastError(), so
+ // I'm not sure what to do about PLOG here. Probably better to just
+ // ignore it and add a simplified version of FormatError() for use in
+ // log messages.
+ LOG(ERROR) << "Error creating log file";
+ }
+
+ return std::string(temp_path) + log_name;
+}
+#else
+static const char kNullFileName[] = "/dev/null";
+
+static std::string GetLogFilePath() {
+ return std::string("/tmp/adb.log");
+}
+#endif
+
+static void close_stdin() {
+ int fd = unix_open(kNullFileName, O_RDONLY);
+ CHECK_NE(fd, -1);
+ dup2(fd, STDIN_FILENO);
+ adb_close(fd);
+}
+
+static void setup_daemon_logging(void) {
+ int fd = unix_open(GetLogFilePath().c_str(), O_WRONLY | O_CREAT | O_APPEND,
+ 0640);
+ if (fd == -1) {
+ fd = unix_open(kNullFileName, O_WRONLY);
+ }
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ adb_close(fd);
+ fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
+}
+
+int adb_main(int is_daemon, int server_port) {
+ HOST = 1;
+
+#if defined(_WIN32)
+ SetConsoleCtrlHandler(ctrlc_handler, TRUE);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ init_transport_registration();
+
+ if (kWorkaroundBug6558362 && is_daemon) {
+ adb_workaround_affinity();
+ }
+
+ usb_init();
+ local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
+ adb_auth_init();
+
+ std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
+ if (install_listener(local_name, "*smartsocket*", nullptr, 0)) {
+ LOG(FATAL) << "Could not install *smartsocket* listener";
+ }
+
+ if (is_daemon) {
+ // Inform our parent that we are up and running.
+ // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
+ // "OKAY".
+ // TODO(danalbert): Why do we use stdout for Windows?
+#if defined(_WIN32)
+ int reply_fd = STDOUT_FILENO;
+#else
+ int reply_fd = STDERR_FILENO;
+#endif
+ android::base::WriteStringToFd("OK\n", reply_fd);
+ close_stdin();
+ setup_daemon_logging();
+ }
+
+ D("Event loop starting\n");
+ fdevent_loop();
+
+ return 0;
+}
+
+int main(int argc, char** argv) {
+ adb_sysdeps_init();
+
+ android::base::InitLogging(argv);
+ adb_trace_init();
+ D("Handling commandline()\n");
+ return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
+}
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index ed09028..6caec6c 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -66,8 +66,8 @@
}
static void version(FILE* out) {
- fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
- ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
+ fprintf(out, "Android Debug Bridge version %d.%d.%d\nRevision %s\n",
+ ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_REVISION);
}
static void help() {
@@ -263,23 +263,16 @@
}
#endif
-static void read_and_dump(int fd)
-{
- char buf[4096];
- int len;
-
- while(fd >= 0) {
+static void read_and_dump(int fd) {
+ while (fd >= 0) {
D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
- len = adb_read(fd, buf, 4096);
+ char buf[BUFSIZ];
+ int len = adb_read(fd, buf, sizeof(buf));
D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
- if(len == 0) {
+ if (len <= 0) {
break;
}
- if(len < 0) {
- if(errno == EINTR) continue;
- break;
- }
fwrite(buf, 1, len, stdout);
fflush(stdout);
}
@@ -928,13 +921,13 @@
static int adb_connect_command(const std::string& command) {
std::string error;
int fd = adb_connect(command, &error);
- if (fd != -1) {
- read_and_dump(fd);
- adb_close(fd);
- return 0;
+ if (fd < 0) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return 1;
}
- fprintf(stderr, "Error: %s\n", error.c_str());
- return 1;
+ read_and_dump(fd);
+ adb_close(fd);
+ return 0;
}
static int adb_query_command(const std::string& command) {
@@ -1136,7 +1129,7 @@
return adb_query_command(query);
}
else if (!strcmp(argv[0], "emu")) {
- return adb_send_emulator_command(argc, argv);
+ return adb_send_emulator_command(argc, argv, serial);
}
else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
char h = (argv[0][0] == 'h');
@@ -1242,13 +1235,13 @@
!strcmp(argv[0], "unroot") ||
!strcmp(argv[0], "disable-verity") ||
!strcmp(argv[0], "enable-verity")) {
- char command[100];
+ std::string command;
if (!strcmp(argv[0], "reboot-bootloader")) {
- snprintf(command, sizeof(command), "reboot:bootloader");
+ command = "reboot:bootloader";
} else if (argc > 1) {
- snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
+ command = android::base::StringPrintf("%s:%s", argv[0], argv[1]);
} else {
- snprintf(command, sizeof(command), "%s:", argv[0]);
+ command = android::base::StringPrintf("%s:", argv[0]);
}
return adb_connect_command(command);
}
diff --git a/adb/console.cpp b/adb/console.cpp
index 452ee41..0707960 100644
--- a/adb/console.cpp
+++ b/adb/console.cpp
@@ -1,44 +1,115 @@
+/*
+ * Copyright (C) 2015 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 "sysdeps.h"
-#include "adb.h"
-#include "adb_client.h"
+
#include <stdio.h>
-static int connect_to_console(void)
-{
- int fd, port;
+#include "base/file.h"
+#include "base/logging.h"
+#include "base/strings.h"
- port = adb_get_emulator_console_port();
- if (port < 0) {
- if (port == -2)
- fprintf(stderr, "error: more than one emulator detected. use -s option\n");
- else
- fprintf(stderr, "error: no emulator detected\n");
+#include "adb.h"
+#include "adb_client.h"
+
+// Return the console port of the currently connected emulator (if any) or -1 if
+// there is no emulator, and -2 if there is more than one.
+static int adb_get_emulator_console_port(const char* serial) {
+ if (serial) {
+ // The user specified a serial number; is it an emulator?
+ int port;
+ return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1;
+ }
+
+ // No specific device was given, so get the list of connected devices and
+ // search for emulators. If there's one, we'll take it. If there are more
+ // than one, that's an error.
+ std::string devices;
+ std::string error;
+ if (!adb_query("host:devices", &devices, &error)) {
+ fprintf(stderr, "error: no emulator connected: %s\n", error.c_str());
return -1;
}
- fd = socket_loopback_client( port, SOCK_STREAM );
- if (fd < 0) {
+
+ int port;
+ size_t emulator_count = 0;
+ for (const auto& device : android::base::Split(devices, "\n")) {
+ if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
+ if (++emulator_count > 1) {
+ fprintf(
+ stderr, "error: more than one emulator detected; use -s\n");
+ return -1;
+ }
+ }
+ }
+
+ if (emulator_count == 0) {
+ fprintf(stderr, "error: no emulator detected\n");
+ return -1;
+ }
+
+ return port;
+}
+
+static int connect_to_console(const char* serial) {
+ int port = adb_get_emulator_console_port(serial);
+ if (port == -1) {
+ return -1;
+ }
+
+ int fd = socket_loopback_client(port, SOCK_STREAM);
+ if (fd == -1) {
fprintf(stderr, "error: could not connect to TCP port %d\n", port);
return -1;
}
- return fd;
+ return fd;
}
-
-int adb_send_emulator_command(int argc, const char** argv)
-{
- int fd, nn;
-
- fd = connect_to_console();
- if (fd < 0)
+int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
+ int fd = connect_to_console(serial);
+ if (fd == -1) {
return 1;
-
-#define QUIT "quit\n"
-
- for (nn = 1; nn < argc; nn++) {
- adb_write( fd, argv[nn], strlen(argv[nn]) );
- adb_write( fd, (nn == argc-1) ? "\n" : " ", 1 );
}
- adb_write( fd, QUIT, sizeof(QUIT)-1 );
+
+ for (int i = 1; i < argc; i++) {
+ adb_write(fd, argv[i], strlen(argv[i]));
+ adb_write(fd, i == argc - 1 ? "\n" : " ", 1);
+ }
+
+ const char disconnect_command[] = "quit\n";
+ if (adb_write(fd, disconnect_command, sizeof(disconnect_command) - 1) == -1) {
+ LOG(FATAL) << "Could not finalize emulator command";
+ }
+
+ // Drain output that the emulator console has sent us to prevent a problem
+ // on Windows where if adb closes the socket without reading all the data,
+ // the emulator's next call to recv() will have an ECONNABORTED error,
+ // preventing the emulator from reading the command that adb has sent.
+ // https://code.google.com/p/android/issues/detail?id=21021
+ int result;
+ do {
+ char buf[BUFSIZ];
+ result = adb_read(fd, buf, sizeof(buf));
+ // Keep reading until zero bytes (EOF) or an error. If 'adb emu kill'
+ // is executed, the emulator calls exit() which causes adb to get
+ // ECONNRESET. Any other emu command is followed by the quit command
+ // that we sent above, and that causes the emulator to close the socket
+ // which should cause zero bytes (EOF) to be returned.
+ } while (result > 0);
+
adb_close(fd);
return 0;
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
new file mode 100644
index 0000000..99ff539
--- /dev/null
+++ b/adb/daemon/main.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define TRACE_TAG TRACE_ADB
+
+#include "sysdeps.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <sys/prctl.h>
+
+#include "base/logging.h"
+#include "base/stringprintf.h"
+#include "cutils/properties.h"
+#include "private/android_filesystem_config.h"
+#include "selinux/selinux.h"
+
+#include "adb.h"
+#include "adb_auth.h"
+#include "adb_listeners.h"
+#include "transport.h"
+#include "qemu_tracing.h"
+
+static const char* root_seclabel = nullptr;
+
+static void drop_capabilities_bounding_set_if_needed() {
+#ifdef ALLOW_ADBD_ROOT
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.debuggable", value, "");
+ if (strcmp(value, "1") == 0) {
+ return;
+ }
+#endif
+ for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
+ if (i == CAP_SETUID || i == CAP_SETGID) {
+ // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
+ continue;
+ }
+
+ int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
+
+ // Some kernels don't have file capabilities compiled in, and
+ // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically
+ // die when we see such misconfigured kernels.
+ if ((err < 0) && (errno != EINVAL)) {
+ PLOG(FATAL) << "Could not drop capabilities";
+ }
+ }
+}
+
+static bool should_drop_privileges() {
+#if defined(ALLOW_ADBD_ROOT)
+ char value[PROPERTY_VALUE_MAX];
+
+ // The emulator is never secure, so don't drop privileges there.
+ // TODO: this seems like a bug --- shouldn't the emulator behave like a device?
+ property_get("ro.kernel.qemu", value, "");
+ if (strcmp(value, "1") == 0) {
+ return false;
+ }
+
+ // The properties that affect `adb root` and `adb unroot` are ro.secure and
+ // ro.debuggable. In this context the names don't make the expected behavior
+ // particularly obvious.
+ //
+ // ro.debuggable:
+ // Allowed to become root, but not necessarily the default. Set to 1 on
+ // eng and userdebug builds.
+ //
+ // ro.secure:
+ // Drop privileges by default. Set to 1 on userdebug and user builds.
+ property_get("ro.secure", value, "1");
+ bool ro_secure = (strcmp(value, "1") == 0);
+
+ property_get("ro.debuggable", value, "");
+ bool ro_debuggable = (strcmp(value, "1") == 0);
+
+ // Drop privileges if ro.secure is set...
+ bool drop = ro_secure;
+
+ property_get("service.adb.root", value, "");
+ bool adb_root = (strcmp(value, "1") == 0);
+ bool adb_unroot = (strcmp(value, "0") == 0);
+
+ // ...except "adb root" lets you keep privileges in a debuggable build.
+ if (ro_debuggable && adb_root) {
+ drop = false;
+ }
+
+ // ...and "adb unroot" lets you explicitly drop privileges.
+ if (adb_unroot) {
+ drop = true;
+ }
+
+ return drop;
+#else
+ return true; // "adb root" not allowed, always drop privileges.
+#endif // ALLOW_ADBD_ROOT
+}
+
+int adbd_main(int server_port) {
+ umask(0);
+
+ signal(SIGPIPE, SIG_IGN);
+
+ init_transport_registration();
+
+ // We need to call this even if auth isn't enabled because the file
+ // descriptor will always be open.
+ adbd_cloexec_auth_socket();
+
+ auth_enabled = property_get_bool("ro.adb.secure", 0) != 0;
+ if (auth_enabled) {
+ adbd_auth_init();
+ }
+
+ // Our external storage path may be different than apps, since
+ // we aren't able to bind mount after dropping root.
+ const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
+ if (adb_external_storage != nullptr) {
+ setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
+ } else {
+ D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE"
+ " unchanged.\n");
+ }
+
+ // Add extra groups:
+ // AID_ADB to access the USB driver
+ // AID_LOG to read system logs (adb logcat)
+ // AID_INPUT to diagnose input issues (getevent)
+ // AID_INET to diagnose network issues (ping)
+ // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+ // AID_SDCARD_R to allow reading from the SD card
+ // AID_SDCARD_RW to allow writing to the SD card
+ // AID_NET_BW_STATS to read out qtaguid statistics
+ gid_t groups[] = {AID_ADB, AID_LOG, AID_INPUT,
+ AID_INET, AID_NET_BT, AID_NET_BT_ADMIN,
+ AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS};
+ if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
+ PLOG(FATAL) << "Could not set supplental groups";
+ }
+
+ /* don't listen on a port (default 5037) if running in secure mode */
+ /* don't run as root if we are running in secure mode */
+ if (should_drop_privileges()) {
+ drop_capabilities_bounding_set_if_needed();
+
+ /* then switch user and group to "shell" */
+ if (setgid(AID_SHELL) != 0) {
+ PLOG(FATAL) << "Could not setgid";
+ }
+ if (setuid(AID_SHELL) != 0) {
+ PLOG(FATAL) << "Could not setuid";
+ }
+
+ D("Local port disabled\n");
+ } else {
+ if ((root_seclabel != nullptr) && (is_selinux_enabled() > 0)) {
+ if (setcon(root_seclabel) < 0) {
+ LOG(FATAL) << "Could not set selinux context";
+ }
+ }
+ std::string local_name =
+ android::base::StringPrintf("tcp:%d", server_port);
+ if (install_listener(local_name, "*smartsocket*", nullptr, 0)) {
+ LOG(FATAL) << "Could not install *smartsocket* listener";
+ }
+ }
+
+ bool is_usb = false;
+ if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
+ // Listen on USB.
+ usb_init();
+ is_usb = true;
+ }
+
+ // If one of these properties is set, also listen on that port.
+ // If one of the properties isn't set and we couldn't listen on usb, listen
+ // on the default port.
+ char prop_port[PROPERTY_VALUE_MAX];
+ property_get("service.adb.tcp.port", prop_port, "");
+ if (prop_port[0] == '\0') {
+ property_get("persist.adb.tcp.port", prop_port, "");
+ }
+
+ int port;
+ if (sscanf(prop_port, "%d", &port) == 1 && port > 0) {
+ printf("using port=%d\n", port);
+ // Listen on TCP port specified by service.adb.tcp.port property.
+ local_init(port);
+ } else if (!is_usb) {
+ // Listen on default port.
+ local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
+ }
+
+ D("adbd_main(): pre init_jdwp()\n");
+ init_jdwp();
+ D("adbd_main(): post init_jdwp()\n");
+
+ D("Event loop starting\n");
+ fdevent_loop();
+
+ return 0;
+}
+
+static void close_stdin() {
+ int fd = unix_open("/dev/null", O_RDONLY);
+ if (fd == -1) {
+ perror("failed to open /dev/null, stdin will remain open");
+ return;
+ }
+ dup2(fd, STDIN_FILENO);
+ adb_close(fd);
+}
+
+int main(int argc, char** argv) {
+ android::base::InitLogging(argv);
+
+ while (true) {
+ static struct option opts[] = {
+ {"root_seclabel", required_argument, nullptr, 's'},
+ {"device_banner", required_argument, nullptr, 'b'},
+ {"version", no_argument, nullptr, 'v'},
+ };
+
+ int option_index = 0;
+ int c = getopt_long(argc, argv, "", opts, &option_index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 's':
+ root_seclabel = optarg;
+ break;
+ case 'b':
+ adb_device_banner = optarg;
+ break;
+ case 'v':
+ printf("Android Debug Bridge Daemon version %d.%d.%d %s\n",
+ ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
+ ADB_REVISION);
+ return 0;
+ default:
+ // getopt already prints "adbd: invalid option -- %c" for us.
+ return 1;
+ }
+ }
+
+ close_stdin();
+
+ adb_trace_init();
+
+ /* If adbd runs inside the emulator this will enable adb tracing via
+ * adb-debug qemud service in the emulator. */
+ adb_qemu_trace_init();
+
+ D("Handling main()\n");
+ return adbd_main(DEFAULT_ADB_PORT);
+}
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index aded301..2efc890 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -79,8 +79,7 @@
fflush(stderr);
}
-void sync_quit(int fd)
-{
+static void sync_quit(int fd) {
syncmsg msg;
msg.req.id = ID_QUIT;
@@ -91,8 +90,7 @@
typedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie);
-int sync_ls(int fd, const char *path, sync_ls_cb func, void *cookie)
-{
+static int sync_ls(int fd, const char* path, sync_ls_cb func, void* cookie) {
syncmsg msg;
char buf[257];
int len;
@@ -138,9 +136,7 @@
static syncsendbuf send_buffer;
-int sync_readtime(int fd, const char *path, unsigned int *timestamp,
- unsigned int *mode)
-{
+static int sync_readtime(int fd, const char* path, unsigned int* timestamp, unsigned int* mode) {
syncmsg msg;
int len = strlen(path);
@@ -199,8 +195,7 @@
return 0;
}
-int sync_readmode(int fd, const char *path, unsigned *mode)
-{
+static int sync_readmode(int fd, const char* path, unsigned* mode) {
syncmsg msg;
int len = strlen(path);
@@ -419,8 +414,7 @@
return 0;
}
-int sync_recv(int fd, const char *rpath, const char *lpath, int show_progress)
-{
+static int sync_recv(int fd, const char* rpath, const char* lpath, int show_progress) {
syncmsg msg;
int len;
int lfd = -1;
@@ -566,17 +560,14 @@
int flag;
};
-copyinfo *mkcopyinfo(const char *spath, const char *dpath,
- const char *name, int isdir)
-{
+static copyinfo* mkcopyinfo(const char* spath, const char* dpath, const char* name, int isdir) {
int slen = strlen(spath);
int dlen = strlen(dpath);
int nlen = strlen(name);
int ssize = slen + nlen + 2;
int dsize = dlen + nlen + 2;
- copyinfo *ci = reinterpret_cast<copyinfo*>(
- malloc(sizeof(copyinfo) + ssize + dsize));
+ copyinfo *ci = reinterpret_cast<copyinfo*>(malloc(sizeof(copyinfo) + ssize + dsize));
if(ci == 0) {
fprintf(stderr,"out of memory\n");
abort();
@@ -807,9 +798,8 @@
const char *lpath;
};
-void
-sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time,
- const char *name, void *cookie)
+static void sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time,
+ const char* name, void* cookie)
{
sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie;
copyinfo *ci;
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 87702b0..7a3b89a 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -34,87 +34,67 @@
#include "adb_utils.h"
#include "cutils/properties.h"
-static int system_ro = 1;
-static int vendor_ro = 1;
-static int oem_ro = 1;
-
-/* Returns the device used to mount a directory in /proc/mounts */
-static std::string find_mount(const char *dir) {
- FILE* fp;
- struct mntent* mentry;
- char* device = NULL;
-
- if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
- return NULL;
+// Returns the device used to mount a directory in /proc/mounts.
+static std::string find_mount(const char* dir) {
+ std::unique_ptr<FILE, int(*)(FILE*)> fp(setmntent("/proc/mounts", "r"), endmntent);
+ if (!fp) {
+ return "";
}
- while ((mentry = getmntent(fp)) != NULL) {
- if (strcmp(dir, mentry->mnt_dir) == 0) {
- device = mentry->mnt_fsname;
- break;
+
+ mntent* e;
+ while ((e = getmntent(fp.get())) != nullptr) {
+ if (strcmp(dir, e->mnt_dir) == 0) {
+ return e->mnt_fsname;
}
}
- endmntent(fp);
- return device;
+ return "";
}
-int make_block_device_writable(const std::string& dev) {
+bool make_block_device_writable(const std::string& dev) {
int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
if (fd == -1) {
- return -1;
+ return false;
}
- int result = -1;
int OFF = 0;
- if (!ioctl(fd, BLKROSET, &OFF)) {
- result = 0;
- }
+ bool result = (ioctl(fd, BLKROSET, &OFF) != -1);
adb_close(fd);
-
return result;
}
-// Init mounts /system as read only, remount to enable writes.
-static int remount(const char* dir, int* dir_ro) {
- std::string dev(find_mount(dir));
- if (dev.empty() || make_block_device_writable(dev)) {
- return -1;
+static bool remount_partition(int fd, const char* dir) {
+ if (!directory_exists(dir)) {
+ return true;
}
-
- int rc = mount(dev.c_str(), dir, "none", MS_REMOUNT, NULL);
- *dir_ro = rc;
- return rc;
-}
-
-static bool remount_partition(int fd, const char* partition, int* ro) {
- if (!directory_exists(partition)) {
+ std::string dev = find_mount(dir);
+ if (dev.empty()) {
+ return true;
+ }
+ if (!make_block_device_writable(dev)) {
+ WriteFdFmt(fd, "remount of %s failed; couldn't make block device %s writable: %s\n",
+ dir, dev.c_str(), strerror(errno));
+ return false;
+ }
+ if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
+ WriteFdFmt(fd, "remount of %s failed: %s\n", dir, strerror(errno));
+ return false;
+ }
return true;
- }
- if (remount(partition, ro)) {
- WriteFdFmt(fd, "remount of %s failed: %s\n", partition, strerror(errno));
- return false;
- }
- return true;
}
void remount_service(int fd, void* cookie) {
- char prop_buf[PROPERTY_VALUE_MAX];
-
if (getuid() != 0) {
WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");
adb_close(fd);
return;
}
- bool system_verified = false, vendor_verified = false;
+ char prop_buf[PROPERTY_VALUE_MAX];
property_get("partition.system.verified", prop_buf, "");
- if (strlen(prop_buf) > 0) {
- system_verified = true;
- }
+ bool system_verified = (strlen(prop_buf) > 0);
property_get("partition.vendor.verified", prop_buf, "");
- if (strlen(prop_buf) > 0) {
- vendor_verified = true;
- }
+ bool vendor_verified = (strlen(prop_buf) > 0);
if (system_verified || vendor_verified) {
// Allow remount but warn of likely bad effects
@@ -132,9 +112,9 @@
}
bool success = true;
- success &= remount_partition(fd, "/system", &system_ro);
- success &= remount_partition(fd, "/vendor", &vendor_ro);
- success &= remount_partition(fd, "/oem", &oem_ro);
+ success &= remount_partition(fd, "/system");
+ success &= remount_partition(fd, "/vendor");
+ success &= remount_partition(fd, "/oem");
WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
diff --git a/adb/remount_service.h b/adb/remount_service.h
index e1763cf..7bda1be 100644
--- a/adb/remount_service.h
+++ b/adb/remount_service.h
@@ -19,7 +19,7 @@
#include <string>
-int make_block_device_writable(const std::string&);
+bool make_block_device_writable(const std::string&);
void remount_service(int, void*);
#endif
diff --git a/adb/services.cpp b/adb/services.cpp
index e53a28c..b869479 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -618,16 +618,15 @@
}
}
-static void connect_service(int fd, void* cookie)
-{
- char *host = reinterpret_cast<char*>(cookie);
-
+static void connect_service(int fd, void* data) {
+ char* host = reinterpret_cast<char*>(data);
std::string response;
if (!strncmp(host, "emu:", 4)) {
connect_emulator(host + 4, &response);
} else {
connect_device(host, &response);
}
+ free(host);
// Send response for emulator and device
SendProtocolString(fd, response);
@@ -664,6 +663,9 @@
sinfo->transport_type = kTransportAny;
sinfo->state = CS_DEVICE;
} else {
+ if (sinfo->serial) {
+ free(sinfo->serial);
+ }
free(sinfo);
return NULL;
}
@@ -671,8 +673,8 @@
int fd = create_service_thread(wait_for_state, sinfo);
return create_local_socket(fd);
} else if (!strncmp(name, "connect:", 8)) {
- const char *host = name + 8;
- int fd = create_service_thread(connect_service, (void *)host);
+ char* host = strdup(name + 8);
+ int fd = create_service_thread(connect_service, host);
return create_local_socket(fd);
}
return NULL;
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index cc42bc0..bae38cf 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -86,7 +86,7 @@
int device = -1;
int retval = -1;
- if (make_block_device_writable(block_device)) {
+ if (!make_block_device_writable(block_device)) {
WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
block_device, strerror(errno));
goto errout;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 95d0e20..0aa1570 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -84,8 +84,8 @@
typedef void (*win_thread_func_t)(void* arg);
static __inline__ bool adb_thread_create(adb_thread_func_t func, void* arg) {
- unsigned tid = _beginthread( (win_thread_func_t)func, 0, arg );
- return (tid != (unsigned)-1L);
+ uintptr_t tid = _beginthread((win_thread_func_t)func, 0, arg);
+ return (tid != static_cast<uintptr_t>(-1L));
}
static __inline__ unsigned long adb_thread_id()
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index a21272f..b7962b9 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -16,6 +16,9 @@
#define TRACE_TAG TRACE_SYSDEPS
+// For whatever reason this blocks the definition of ToAscii...
+#undef NOGDI
+
#include "sysdeps.h"
#include <winsock2.h> /* winsock.h *must* be included before windows.h. */
diff --git a/adb/transport.cpp b/adb/transport.cpp
index bb5be6b..29cf580 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -853,7 +853,8 @@
#if ADB_HOST
-static void append_transport_info(std::string* result, const char* key, const char* value, bool sanitize) {
+static void append_transport_info(std::string* result, const char* key,
+ const char* value, bool sanitize) {
if (value == nullptr || *value == '\0') {
return;
}
@@ -869,7 +870,7 @@
static void append_transport(atransport* t, std::string* result, bool long_listing) {
const char* serial = t->serial;
if (!serial || !serial[0]) {
- serial = "????????????";
+ serial = "(no serial number)";
}
if (!long_listing) {
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index b61bf71..1e5d5c8 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -310,10 +310,6 @@
closedir(busdir);
}
-void usb_cleanup()
-{
-}
-
static int usb_bulk_write(usb_handle *h, const void *data, int len)
{
struct usbdevfs_urb *urb = &h->urb_out;
@@ -569,16 +565,15 @@
static void register_device(const char* dev_name, const char* dev_path,
unsigned char ep_in, unsigned char ep_out,
- int interface, int serial_index, unsigned zero_mask)
-{
- /* Since Linux will not reassign the device ID (and dev_name)
- ** as long as the device is open, we can add to the list here
- ** once we open it and remove from the list when we're finally
- ** closed and everything will work out fine.
- **
- ** If we have a usb_handle on the list 'o handles with a matching
- ** name, we have no further work to do.
- */
+ int interface, int serial_index,
+ unsigned zero_mask) {
+ // Since Linux will not reassign the device ID (and dev_name) as long as the
+ // device is open, we can add to the list here once we open it and remove
+ // from the list when we're finally closed and everything will work out
+ // fine.
+ //
+ // If we have a usb_handle on the list 'o handles with a matching name, we
+ // have no further work to do.
adb_mutex_lock(&usb_lock);
for (usb_handle* usb = handle_list.next; usb != &handle_list; usb = usb->next) {
if (!strcmp(usb->fname, dev_name)) {
@@ -599,7 +594,8 @@
adb_cond_init(&usb->notify, 0);
adb_mutex_init(&usb->lock, 0);
- /* initialize mark to 1 so we don't get garbage collected after the device scan */
+ // Initialize mark to 1 so we don't get garbage collected after the device
+ // scan.
usb->mark = 1;
usb->reaper_thread = 0;
@@ -615,11 +611,13 @@
usb->writeable = 0;
}
- D("[ usb opened %s%s, fd=%d]\n", usb->fname, (usb->writeable ? "" : " (read-only)"), usb->desc);
+ D("[ usb opened %s%s, fd=%d]\n", usb->fname,
+ (usb->writeable ? "" : " (read-only)"), usb->desc);
if (usb->writeable) {
if (ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface) != 0) {
- D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]\n", usb->desc, strerror(errno));
+ D("[ usb ioctl(%d, USBDEVFS_CLAIMINTERFACE) failed: %s]\n",
+ usb->desc, strerror(errno));
adb_close(usb->desc);
free(usb);
return;
@@ -627,18 +625,19 @@
}
// Read the device's serial number.
- std::string serial_path =
- android::base::StringPrintf("/sys/bus/usb/devices/%s/serial", dev_path + 4);
+ std::string serial_path = android::base::StringPrintf(
+ "/sys/bus/usb/devices/%s/serial", dev_path + 4);
std::string serial;
if (!android::base::ReadFileToString(serial_path, &serial)) {
D("[ usb read %s failed: %s ]\n", serial_path.c_str(), strerror(errno));
- adb_close(usb->desc);
- free(usb);
- return;
+ // We don't actually want to treat an unknown serial as an error because
+ // devices aren't able to communicate a serial number in early bringup.
+ // http://b/20883914
+ serial = "";
}
serial = android::base::Trim(serial);
- /* add to the end of the active handles */
+ // Add to the end of the active handles.
adb_mutex_lock(&usb_lock);
usb->next = &handle_list;
usb->prev = handle_list.prev;
@@ -649,20 +648,18 @@
register_usb_transport(usb, serial.c_str(), dev_path, usb->writeable);
}
-static void* device_poll_thread(void* unused)
-{
+static void* device_poll_thread(void* unused) {
D("Created device thread\n");
- for(;;) {
- /* XXX use inotify */
+ while (true) {
+ // TODO: Use inotify.
find_usb_device("/dev/bus/usb", register_device);
kick_disconnected_devices();
sleep(1);
}
- return NULL;
+ return nullptr;
}
-static void sigalrm_handler(int signo)
-{
+static void sigalrm_handler(int signo) {
// don't need to do anything here
}
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index f337ccd..63bb1c7 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -82,7 +82,7 @@
struct func_desc fs_descs, hs_descs;
} __attribute__((packed));
-struct func_desc fs_descriptors = {
+static struct func_desc fs_descriptors = {
.intf = {
.bLength = sizeof(fs_descriptors.intf),
.bDescriptorType = USB_DT_INTERFACE,
@@ -109,7 +109,7 @@
},
};
-struct func_desc hs_descriptors = {
+static struct func_desc hs_descriptors = {
.intf = {
.bLength = sizeof(hs_descriptors.intf),
.bDescriptorType = USB_DT_INTERFACE,
@@ -495,10 +495,6 @@
usb_adb_init();
}
-void usb_cleanup()
-{
-}
-
int usb_write(usb_handle *h, const void *data, int len)
{
return h->write(h, data, len);
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 0d0b3ad..af65130 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -401,11 +401,18 @@
return NULL;
}
+static void usb_cleanup() {
+ DBG("usb_cleanup\n");
+ close_usb_devices();
+ if (currentRunLoop)
+ CFRunLoopStop(currentRunLoop);
+}
-static int initialized = 0;
void usb_init() {
- if (!initialized)
- {
+ static bool initialized = false;
+ if (!initialized) {
+ atexit(usb_cleanup);
+
adb_mutex_init(&start_lock, NULL);
adb_cond_init(&start_cond, NULL);
@@ -421,18 +428,10 @@
adb_mutex_destroy(&start_lock);
adb_cond_destroy(&start_cond);
- initialized = 1;
+ initialized = true;
}
}
-void usb_cleanup()
-{
- DBG("usb_cleanup\n");
- close_usb_devices();
- if (currentRunLoop)
- CFRunLoopStop(currentRunLoop);
-}
-
int usb_write(usb_handle *handle, const void *buf, int len)
{
IOReturn result;
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index 1d6ec8c..25deb1b 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -93,9 +93,6 @@
/// Initializes this module
void usb_init();
-/// Cleans up this module
-void usb_cleanup();
-
/// Opens usb interface (device) by interface (device) name.
usb_handle* do_usb_open(const wchar_t* interface_name);
@@ -186,9 +183,6 @@
}
}
-void usb_cleanup() {
-}
-
usb_handle* do_usb_open(const wchar_t* interface_name) {
// Allocate our handle
usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
diff --git a/base/include/base/logging.h b/base/include/base/logging.h
index 84ec538..4a15f43 100644
--- a/base/include/base/logging.h
+++ b/base/include/base/logging.h
@@ -23,8 +23,10 @@
#endif
#ifdef _WIN32
+#ifndef NOGDI
#define NOGDI // Suppress the evil ERROR macro.
#endif
+#endif
#include <functional>
#include <memory>
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 56c03f7..b7e6b17 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -371,7 +371,8 @@
} else {
line += '-';
}
- line += android::base::StringPrintf(" %8" PRIxPTR, it->end - it->start);
+ line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR,
+ it->offset, it->end - it->start);
if (it->name.length() > 0) {
line += " " + it->name;
std::string build_id;
diff --git a/fastboot/engineering_key.p12 b/fastboot/engineering_key.p12
deleted file mode 100644
index d8183b0..0000000
--- a/fastboot/engineering_key.p12
+++ /dev/null
Binary files differ
diff --git a/fastboot/p12topem.sh b/fastboot/p12topem.sh
deleted file mode 100755
index f081eb5..0000000
--- a/fastboot/p12topem.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-if [ $# -ne 2 ]
-then
- echo "Usage: $0 alias passphrase"
- exit -1
-fi
-
-openssl pkcs12 -passin pass:"$2" -passout pass:"$2" -in $1.p12 -out $1.pem
diff --git a/fastboot/signfile.sh b/fastboot/signfile.sh
deleted file mode 100755
index 3188d2d..0000000
--- a/fastboot/signfile.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-if [ $# -ne 3 ]
-then
- echo "Usage: $0 alias filename passpharse"
- exit -1
-fi
-
-openssl dgst -passin pass:"$3" -binary -sha1 -sign $1.pem $2 > $2.sign
-
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 6ef46ba..63b23b9 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -934,10 +934,6 @@
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
char *mount_point = basename(fstab->mount_point);
- // set the dm_ioctl flags
- io->flags |= 1;
- io->target_count = 1;
-
// get verity filesystem size
if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
return retval;
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index 731c248..784bc03 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -37,6 +37,7 @@
uintptr_t start;
uintptr_t end;
+ uintptr_t offset;
uintptr_t load_base;
int flags;
std::string name;
diff --git a/include/log/log.h b/include/log/log.h
index f9299b0..0b17574 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -598,6 +598,7 @@
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
LOG_ID_CRASH = 4,
+ LOG_ID_KERNEL = 5,
#endif
LOG_ID_MAX
diff --git a/init/Android.mk b/init/Android.mk
index 0dc257d..b14f9b5 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -50,7 +50,10 @@
watchdogd.cpp \
LOCAL_MODULE:= init
-LOCAL_C_INCLUDES += system/extras/ext4_utils
+LOCAL_C_INCLUDES += \
+ system/extras/ext4_utils \
+ system/core/mkbootimg
+
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 88d6165..9e5f9ff 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -57,16 +57,13 @@
static int insmod(const char *filename, char *options)
{
- std::string module;
char filename_val[PROP_VALUE_MAX];
- int ret;
-
- ret = expand_props(filename_val, filename, sizeof(filename_val));
- if (ret) {
+ if (expand_props(filename_val, filename, sizeof(filename_val)) == -1) {
ERROR("insmod: cannot expand '%s'\n", filename);
return -EINVAL;
}
+ std::string module;
if (!read_file(filename_val, &module)) {
return -1;
}
diff --git a/init/init.cpp b/init/init.cpp
index 68c8b7f..4f46560 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -43,6 +43,7 @@
#include <base/file.h>
#include <base/stringprintf.h>
+#include <base/strings.h>
#include <cutils/android_reboot.h>
#include <cutils/fs.h>
#include <cutils/iosched_policy.h>
@@ -205,16 +206,15 @@
return;
}
- struct stat s;
- if (stat(svc->args[0], &s) != 0) {
- ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
+ struct stat sb;
+ if (stat(svc->args[0], &sb) == -1) {
+ ERROR("cannot find '%s' (%s), disabling '%s'\n", svc->args[0], strerror(errno), svc->name);
svc->flags |= SVC_DISABLED;
return;
}
if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
- ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
- svc->args[0]);
+ ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]);
svc->flags |= SVC_DISABLED;
return;
}
@@ -746,36 +746,20 @@
return 0;
}
-static void import_kernel_nv(char *name, bool for_emulator)
-{
- char *value = strchr(name, '=');
- int name_len = strlen(name);
-
- if (value == 0) return;
- *value++ = 0;
- if (name_len == 0) return;
+static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
+ if (key.empty()) return;
if (for_emulator) {
- /* in the emulator, export any kernel option with the
- * ro.kernel. prefix */
- char buff[PROP_NAME_MAX];
- int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
-
- if (len < (int)sizeof(buff))
- property_set( buff, value );
+ // In the emulator, export any kernel option with the "ro.kernel." prefix.
+ property_set(android::base::StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
return;
}
- if (!strcmp(name,"qemu")) {
- strlcpy(qemu, value, sizeof(qemu));
- } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
- const char *boot_prop_name = name + 12;
- char prop[PROP_NAME_MAX];
- int cnt;
-
- cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
- if (cnt < PROP_NAME_MAX)
- property_set(prop, value);
+ if (key == "qemu") {
+ strlcpy(qemu, value.c_str(), sizeof(qemu));
+ } else if (android::base::StartsWith(key, "androidboot.")) {
+ property_set(android::base::StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(),
+ value.c_str());
}
}
@@ -799,8 +783,7 @@
}
}
-static void process_kernel_dt(void)
-{
+static void process_kernel_dt() {
static const char android_dir[] = "/proc/device-tree/firmware/android";
std::string file_name = android::base::StringPrintf("%s/compatible", android_dir);
@@ -813,13 +796,13 @@
}
std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dir), closedir);
- if (!dir)
- return;
+ if (!dir) return;
struct dirent *dp;
while ((dp = readdir(dir.get())) != NULL) {
- if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible"))
+ if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible")) {
continue;
+ }
file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name);
@@ -831,18 +814,15 @@
}
}
-static void process_kernel_cmdline(void)
-{
- /* don't expose the raw commandline to nonpriv processes */
+static void process_kernel_cmdline() {
+ // Don't expose the raw commandline to unprivileged processes.
chmod("/proc/cmdline", 0440);
- /* first pass does the common stuff, and finds if we are in qemu.
- * second pass is only necessary for qemu to export all kernel params
- * as props.
- */
+ // The first pass does the common stuff, and finds if we are in qemu.
+ // The second pass is only necessary for qemu to export all kernel params
+ // as properties.
import_kernel_cmdline(false, import_kernel_nv);
- if (qemu[0])
- import_kernel_cmdline(true, import_kernel_nv);
+ if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
}
static int queue_property_triggers_action(int nargs, char **args)
@@ -865,17 +845,11 @@
static selinux_enforcing_status selinux_status_from_cmdline() {
selinux_enforcing_status status = SELINUX_ENFORCING;
- std::function<void(char*,bool)> fn = [&](char* name, bool in_qemu) {
- char *value = strchr(name, '=');
- if (value == nullptr) { return; }
- *value++ = '\0';
- if (strcmp(name, "androidboot.selinux") == 0) {
- if (strcmp(value, "permissive") == 0) {
- status = SELINUX_PERMISSIVE;
- }
+ import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
+ if (key == "androidboot.selinux" && value == "permissive") {
+ status = SELINUX_PERMISSIVE;
}
- };
- import_kernel_cmdline(false, fn);
+ });
return status;
}
@@ -989,7 +963,7 @@
klog_init();
klog_set_level(KLOG_NOTICE_LEVEL);
- NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");
+ NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
if (!is_first_stage) {
// Indicate that booting is in progress to background fw loaders, etc.
@@ -1002,7 +976,7 @@
process_kernel_dt();
process_kernel_cmdline();
- // Propogate the kernel variables to internal variables
+ // Propagate the kernel variables to internal variables
// used by init as well as the current required properties.
export_kernel_boot_props();
}
@@ -1028,7 +1002,7 @@
// These directories were necessarily created before initial policy load
// and therefore need their security context restored to the proper value.
// This must happen before /dev is populated by ueventd.
- INFO("Running restorecon...\n");
+ NOTICE("Running restorecon...\n");
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index b76b04e..df049ed 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -382,13 +382,13 @@
static void parse_config(const char *fn, const std::string& data)
{
- struct parse_state state;
struct listnode import_list;
struct listnode *node;
char *args[INIT_PARSER_MAXARGS];
- int nargs;
- nargs = 0;
+ int nargs = 0;
+
+ parse_state state;
state.filename = fn;
state.line = 0;
state.ptr = strdup(data.c_str()); // TODO: fix this code!
@@ -426,29 +426,28 @@
parser_done:
list_for_each(node, &import_list) {
- struct import *import = node_to_item(node, struct import, list);
- int ret;
-
- ret = init_parse_config_file(import->filename);
- if (ret)
- ERROR("could not import file '%s' from '%s'\n",
- import->filename, fn);
+ struct import* import = node_to_item(node, struct import, list);
+ if (!init_parse_config_file(import->filename)) {
+ ERROR("could not import file '%s' from '%s': %s\n",
+ import->filename, fn, strerror(errno));
+ }
}
}
-int init_parse_config_file(const char* path) {
+bool init_parse_config_file(const char* path) {
INFO("Parsing %s...\n", path);
Timer t;
std::string data;
if (!read_file(path, &data)) {
- return -1;
+ return false;
}
+ data.push_back('\n'); // TODO: fix parse_config.
parse_config(path, data);
dump_parser_state();
NOTICE("(Parsing %s took %.2fs.)\n", path, t.duration());
- return 0;
+ return true;
}
static int valid_name(const char *name)
diff --git a/init/init_parser.h b/init/init_parser.h
index 6348607..90f880f 100644
--- a/init/init_parser.h
+++ b/init/init_parser.h
@@ -31,7 +31,7 @@
void queue_all_property_triggers();
void queue_builtin_action(int (*func)(int nargs, char **args), const char *name);
-int init_parse_config_file(const char *fn);
+bool init_parse_config_file(const char* path);
int expand_props(char *dst, const char *src, int len);
service* make_exec_oneshot_service(int argc, char** argv);
diff --git a/init/log.cpp b/init/log.cpp
index d32f2da..eb5ec42 100644
--- a/init/log.cpp
+++ b/init/log.cpp
@@ -14,30 +14,35 @@
* limitations under the License.
*/
+#include "log.h"
+
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <selinux/selinux.h>
-#include "log.h"
+#include <base/stringprintf.h>
static void init_klog_vwrite(int level, const char* fmt, va_list ap) {
static const char* tag = basename(getprogname());
- char prefix[64];
- snprintf(prefix, sizeof(prefix), "<%d>%s: ", level, tag);
+ // The kernel's printk buffer is only 1024 bytes.
+ // TODO: should we automatically break up long lines into multiple lines?
+ // Or we could log but with something like "..." at the end?
+ char buf[1024];
+ size_t prefix_size = snprintf(buf, sizeof(buf), "<%d>%s: ", level, tag);
+ size_t msg_size = vsnprintf(buf + prefix_size, sizeof(buf) - prefix_size, fmt, ap);
+ if (msg_size >= sizeof(buf) - prefix_size) {
+ msg_size = snprintf(buf + prefix_size, sizeof(buf) - prefix_size,
+ "(%zu-byte message too long for printk)\n", msg_size);
+ }
- char msg[512];
- vsnprintf(msg, sizeof(msg), fmt, ap);
+ iovec iov[1];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = prefix_size + msg_size;
- iovec iov[2];
- iov[0].iov_base = prefix;
- iov[0].iov_len = strlen(prefix);
- iov[1].iov_base = msg;
- iov[1].iov_len = strlen(msg);
-
- klog_writev(level, iov, 2);
+ klog_writev(level, iov, 1);
}
void init_klog_write(int level, const char* fmt, ...) {
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 930ef82..0ee0351 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -46,12 +46,18 @@
#include <selinux/selinux.h>
#include <selinux/label.h>
+#include <fs_mgr.h>
+#include <base/file.h>
+#include "bootimg.h"
+
#include "property_service.h"
#include "init.h"
#include "util.h"
#include "log.h"
#define PERSISTENT_PROPERTY_DIR "/data/property"
+#define FSTAB_PREFIX "/fstab."
+#define RECOVERY_MOUNT_POINT "/recovery"
static int persistent_properties_loaded = 0;
static bool property_area_initialized = false;
@@ -414,6 +420,7 @@
Timer t;
std::string data;
if (read_file(filename, &data)) {
+ data.push_back('\n');
load_properties(&data[0], filter);
}
NOTICE("(Loading properties from %s took %.2fs.)\n", filename, t.duration());
@@ -506,16 +513,57 @@
load_persistent_properties();
}
+void load_recovery_id_prop() {
+ char fstab_filename[PROP_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+ char propbuf[PROP_VALUE_MAX];
+ int ret = property_get("ro.hardware", propbuf);
+ if (!ret) {
+ ERROR("ro.hardware not set - unable to load recovery id\n");
+ return;
+ }
+ snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX "%s", propbuf);
+
+ std::unique_ptr<fstab, void(*)(fstab*)> tab(fs_mgr_read_fstab(fstab_filename),
+ fs_mgr_free_fstab);
+ if (!tab) {
+ ERROR("unable to read fstab %s: %s\n", fstab_filename, strerror(errno));
+ return;
+ }
+
+ fstab_rec* rec = fs_mgr_get_entry_for_mount_point(tab.get(), RECOVERY_MOUNT_POINT);
+ if (rec == NULL) {
+ ERROR("/recovery not specified in fstab\n");
+ return;
+ }
+
+ int fd = open(rec->blk_device, O_RDONLY);
+ if (fd == -1) {
+ ERROR("error opening block device %s: %s\n", rec->blk_device, strerror(errno));
+ return;
+ }
+
+ boot_img_hdr hdr;
+ if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) {
+ std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id));
+ property_set("ro.recovery_id", hex.c_str());
+ } else {
+ ERROR("error reading /recovery: %s\n", strerror(errno));
+ }
+
+ close(fd);
+}
+
void load_all_props() {
load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
- load_properties_from_file(PROP_PATH_BOOTIMAGE_BUILD, NULL);
load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
load_override_properties();
/* Read persistent properties after all default values have been loaded. */
load_persistent_properties();
+
+ load_recovery_id_prop();
}
void start_property_service() {
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 7a4841f..497c606 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -193,10 +193,10 @@
static void parse_config(const char *fn, const std::string& data)
{
- struct parse_state state;
char *args[UEVENTD_PARSER_MAXARGS];
- int nargs;
- nargs = 0;
+
+ int nargs = 0;
+ parse_state state;
state.filename = fn;
state.line = 1;
state.ptr = strdup(data.c_str()); // TODO: fix this code!
@@ -231,6 +231,7 @@
return -1;
}
+ data.push_back('\n'); // TODO: fix parse_config.
parse_config(fn, data);
dump_parser_state();
return 0;
diff --git a/init/util.cpp b/init/util.cpp
index 9343145..9c62f68 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -33,9 +33,11 @@
#include <sys/un.h>
#include <base/file.h>
+#include <base/strings.h>
/* for ANDROID_SOCKET_* */
#include <cutils/sockets.h>
+#include <base/stringprintf.h>
#include <private/android_filesystem_config.h>
@@ -170,9 +172,6 @@
bool okay = android::base::ReadFdToString(fd, content);
TEMP_FAILURE_RETRY(close(fd));
- if (okay) {
- content->append("\n", 1);
- }
return okay;
}
@@ -403,32 +402,16 @@
}
}
-void import_kernel_cmdline(bool in_qemu, std::function<void(char*,bool)> import_kernel_nv)
-{
- char cmdline[2048];
- char *ptr;
- int fd;
+void import_kernel_cmdline(bool in_qemu,
+ std::function<void(const std::string&, const std::string&, bool)> fn) {
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
- fd = open("/proc/cmdline", O_RDONLY | O_CLOEXEC);
- if (fd >= 0) {
- int n = read(fd, cmdline, sizeof(cmdline) - 1);
- if (n < 0) n = 0;
-
- /* get rid of trailing newline, it happens */
- if (n > 0 && cmdline[n-1] == '\n') n--;
-
- cmdline[n] = 0;
- close(fd);
- } else {
- cmdline[0] = 0;
- }
-
- ptr = cmdline;
- while (ptr && *ptr) {
- char *x = strchr(ptr, ' ');
- if (x != 0) *x++ = 0;
- import_kernel_nv(ptr, in_qemu);
- ptr = x;
+ for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
+ std::vector<std::string> pieces = android::base::Split(entry, "=");
+ if (pieces.size() == 2) {
+ fn(pieces[0], pieces[1], in_qemu);
+ }
}
}
@@ -464,3 +447,13 @@
{
return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE);
}
+
+/*
+ * Writes hex_len hex characters (1/2 byte) to hex from bytes.
+ */
+std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
+ std::string hex("0x");
+ for (size_t i = 0; i < bytes_len; i++)
+ android::base::StringAppendF(&hex, "%02x", bytes[i]);
+ return hex;
+}
diff --git a/init/util.h b/init/util.h
index 6864acf..3aba599 100644
--- a/init/util.h
+++ b/init/util.h
@@ -58,8 +58,10 @@
void remove_link(const char *oldpath, const char *newpath);
int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);
-void import_kernel_cmdline(bool in_qemu, std::function<void(char*,bool)>);
+void import_kernel_cmdline(bool in_qemu,
+ std::function<void(const std::string&, const std::string&, bool)>);
int make_dir(const char *path, mode_t mode);
int restorecon(const char *pathname);
int restorecon_recursive(const char *pathname);
+std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
#endif
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index 6134438..e10cce1 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -83,13 +83,12 @@
if (!PtraceRead(Tid(), addr & ~(sizeof(word_t) - 1), &data_word)) {
return 0;
}
- align_bytes = sizeof(word_t) - align_bytes;
- memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + sizeof(word_t) - align_bytes,
- align_bytes);
- addr += align_bytes;
- buffer += align_bytes;
- bytes -= align_bytes;
- bytes_read += align_bytes;
+ size_t copy_bytes = MIN(sizeof(word_t) - align_bytes, bytes);
+ memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + align_bytes, copy_bytes);
+ addr += copy_bytes;
+ buffer += copy_bytes;
+ bytes -= copy_bytes;
+ bytes_read += copy_bytes;
}
size_t num_words = bytes / sizeof(word_t);
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 4a4e2f3..879fea5 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -51,6 +51,7 @@
map.start = unw_map.start;
map.end = unw_map.end;
+ map.offset = unw_map.offset;
map.load_base = unw_map.load_base;
map.flags = unw_map.flags;
map.name = unw_map.path;
@@ -92,6 +93,7 @@
map.start = unw_map.start;
map.end = unw_map.end;
+ map.offset = unw_map.offset;
map.load_base = unw_map.load_base;
map.flags = unw_map.flags;
map.name = unw_map.path;
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 28d146a..a086547 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -883,6 +883,17 @@
ASSERT_EQ(waitpid(pid, nullptr, 0), pid);
}
+void InitMemory(uint8_t* memory, size_t bytes) {
+ for (size_t i = 0; i < bytes; i++) {
+ memory[i] = i;
+ if (memory[i] == '\0') {
+ // Don't use '\0' in our data so we can verify that an overread doesn't
+ // occur by using a '\0' as the character after the read data.
+ memory[i] = 23;
+ }
+ }
+}
+
void* ThreadReadTest(void* data) {
thread_t* thread_data = reinterpret_cast<thread_t*>(data);
@@ -901,9 +912,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
thread_data->data = memory;
@@ -931,9 +940,8 @@
// Create a page of data to use to do quick compares.
uint8_t* expected = new uint8_t[pagesize];
- for (size_t i = 0; i < pagesize; i++) {
- expected[i] = i;
- }
+ InitMemory(expected, pagesize);
+
uint8_t* data = new uint8_t[2*pagesize];
// Verify that we can only read one page worth of data.
size_t bytes_read = backtrace->Read(read_addr, data, 2 * pagesize);
@@ -947,6 +955,20 @@
ASSERT_TRUE(memcmp(data, &expected[i], 2 * sizeof(word_t)) == 0)
<< "Offset at " << i << " failed";
}
+
+ // Verify small unaligned reads.
+ for (size_t i = 1; i < sizeof(word_t); i++) {
+ for (size_t j = 1; j < sizeof(word_t); j++) {
+ // Set one byte past what we expect to read, to guarantee we don't overread.
+ data[j] = '\0';
+ bytes_read = backtrace->Read(read_addr + i, data, j);
+ ASSERT_EQ(j, bytes_read);
+ ASSERT_TRUE(memcmp(data, &expected[i], j) == 0)
+ << "Offset at " << i << " length " << j << " miscompared";
+ ASSERT_EQ('\0', data[j])
+ << "Offset at " << i << " length " << j << " wrote too much data";
+ }
+ }
delete data;
delete expected;
}
@@ -990,9 +1012,7 @@
}
// Set up a simple pattern in memory.
- for (size_t i = 0; i < pagesize; i++) {
- memory[i] = i;
- }
+ InitMemory(memory, pagesize);
g_addr = reinterpret_cast<uintptr_t>(memory);
g_ready = 1;
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 9dc15d1..d5a9050 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -106,9 +106,6 @@
trace-dev.c \
uevent.c \
-# arch-arm/memset32.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-
LOCAL_SRC_FILES_arm += arch-arm/memset32.S
LOCAL_SRC_FILES_arm64 += arch-arm64/android_memset.S
diff --git a/libcutils/arch-arm/memset32.S b/libcutils/arch-arm/memset32.S
index 6efab9f..1e89636 100644
--- a/libcutils/arch-arm/memset32.S
+++ b/libcutils/arch-arm/memset32.S
@@ -18,6 +18,8 @@
*
*/
+ .syntax unified
+
.text
.align
@@ -45,7 +47,7 @@
/* align to 32 bits */
tst r0, #2
- strneh r1, [r0], #2
+ strhne r1, [r0], #2
subne r2, r2, #2
.fnend
@@ -68,27 +70,27 @@
/* conditionally writes 0 to 7 words (length in r3) */
movs r3, r3, lsl #28
- stmcsia r0!, {r1, lr}
- stmcsia r0!, {r1, lr}
- stmmiia r0!, {r1, lr}
+ stmiacs r0!, {r1, lr}
+ stmiacs r0!, {r1, lr}
+ stmiami r0!, {r1, lr}
movs r3, r3, lsl #2
strcs r1, [r0], #4
.Laligned32:
mov r3, r1
1: subs r2, r2, #32
- stmhsia r0!, {r1,r3,r12,lr}
- stmhsia r0!, {r1,r3,r12,lr}
+ stmiahs r0!, {r1,r3,r12,lr}
+ stmiahs r0!, {r1,r3,r12,lr}
bhs 1b
add r2, r2, #32
/* conditionally stores 0 to 30 bytes */
movs r2, r2, lsl #28
- stmcsia r0!, {r1,r3,r12,lr}
- stmmiia r0!, {r1,lr}
+ stmiacs r0!, {r1,r3,r12,lr}
+ stmiami r0!, {r1,lr}
movs r2, r2, lsl #2
strcs r1, [r0], #4
- strmih lr, [r0], #2
+ strhmi lr, [r0], #2
ldr lr, [sp], #4
.cfi_def_cfa_offset 0
diff --git a/liblog/Android.mk b/liblog/Android.mk
index 70aff83..d7766f5 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -85,7 +85,7 @@
LOCAL_CFLAGS := -Werror $(liblog_cflags)
# TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
include $(BUILD_SHARED_LIBRARY)
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 5364e4f..9c4af30 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -208,6 +208,7 @@
[LOG_ID_EVENTS] = "events",
[LOG_ID_SYSTEM] = "system",
[LOG_ID_CRASH] = "crash",
+ [LOG_ID_KERNEL] = "kernel",
};
const char *android_log_id_to_name(log_id_t log_id)
diff --git a/liblog/log_read_kern.c b/liblog/log_read_kern.c
index bdc7b18..69b405c 100644
--- a/liblog/log_read_kern.c
+++ b/liblog/log_read_kern.c
@@ -62,7 +62,8 @@
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
[LOG_ID_SYSTEM] = "system",
- [LOG_ID_CRASH] = "crash"
+ [LOG_ID_CRASH] = "crash",
+ [LOG_ID_KERNEL] = "kernel",
};
const char *android_log_id_to_name(log_id_t log_id)
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index c62a246..bdee28f 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -310,7 +310,8 @@
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
[LOG_ID_SYSTEM] = "system",
- [LOG_ID_CRASH] = "crash"
+ [LOG_ID_CRASH] = "crash",
+ [LOG_ID_KERNEL] = "kernel",
};
const char *android_log_id_to_name(log_id_t log_id)
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 6a05700..164faa9 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -50,6 +50,13 @@
delete [] mMsg;
}
+uint32_t LogBufferElement::getTag() const {
+ if ((mLogId != LOG_ID_EVENTS) || !mMsg || (mMsgLen < sizeof(uint32_t))) {
+ return 0;
+ }
+ return le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag);
+}
+
// caller must own and free character string
static char *tidToName(pid_t tid) {
char *retval = NULL;
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index b6c6196..75ec59e 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -36,6 +36,9 @@
// Furnished in LogStatistics.cpp. Caller must own and free returned value
char *pidToName(pid_t pid);
+// Furnished in main.cpp. Thread safe.
+const char *tagToName(uint32_t tag);
+
}
static inline bool worstUidEnabledForLogid(log_id_t id) {
@@ -85,6 +88,8 @@
static uint64_t getCurrentSequence(void) { return sequence.load(memory_order_relaxed); }
log_time getRealTime(void) const { return mRealTime; }
+ uint32_t getTag(void) const;
+
static const uint64_t FLUSH_ERROR;
uint64_t flushTo(SocketClient *writer, LogBuffer *parent);
};
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 10f7255..4511e0b 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -80,6 +80,11 @@
}
pidTable.add(e->getPid(), e);
+
+ uint32_t tag = e->getTag();
+ if (tag) {
+ tagTable.add(tag, e);
+ }
}
void LogStatistics::subtract(LogBufferElement *e) {
@@ -95,6 +100,11 @@
}
pidTable.subtract(e->getPid(), e);
+
+ uint32_t tag = e->getTag();
+ if (tag) {
+ tagTable.subtract(tag, e);
+ }
}
// Atomically set an entry to drop
@@ -131,7 +141,11 @@
}
// Parse /data/system/packages.list
- char *name = android::uidToName(uid);
+ uid_t userId = uid % AID_USER;
+ char *name = android::uidToName(userId);
+ if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
+ name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
+ }
if (name) {
return name;
}
@@ -149,7 +163,8 @@
name = strdup(n);
} else if (strcmp(name, n)) {
free(name);
- return NULL;
+ name = NULL;
+ break;
}
}
}
@@ -368,6 +383,51 @@
}
}
+ if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
+ // Tag table
+ bool headerPrinted = false;
+ std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
+ ssize_t index = -1;
+ while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
+ const TagEntry *entry = sorted[index];
+ uid_t u = entry->getUid();
+ if ((uid != AID_ROOT) && (u != uid)) {
+ continue;
+ }
+
+ android::String8 pruned("");
+
+ if (!headerPrinted) {
+ output.appendFormat("\n\n");
+ android::String8 name("Chattiest events log buffer TAGs:");
+ android::String8 size("Size");
+ format_line(output, name, size, pruned);
+
+ name.setTo(" TAG/UID TAGNAME");
+ size.setTo("BYTES");
+ format_line(output, name, size, pruned);
+
+ headerPrinted = true;
+ }
+
+ android::String8 name("");
+ if (u == (uid_t)-1) {
+ name.appendFormat("%7u", entry->getKey());
+ } else {
+ name.appendFormat("%7u/%u", entry->getKey(), u);
+ }
+ const char *n = entry->getName();
+ if (n) {
+ name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
+ }
+
+ android::String8 size("");
+ size.appendFormat("%zu", entry->getSizes());
+
+ format_line(output, name, size, pruned);
+ }
+ }
+
*buf = strdup(output.string());
}
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index a935c27..d21a75b 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -154,8 +154,6 @@
};
namespace android {
-// caller must own and free character string
-char *pidToName(pid_t pid);
uid_t pidToUid(pid_t pid);
}
@@ -186,6 +184,10 @@
const char*getName() const { return name; }
inline void add(pid_t p) {
+ if (name && !strncmp(name, "zygote", 6)) {
+ free(name);
+ name = NULL;
+ }
if (!name) {
char *n = android::pidToName(p);
if (n) {
@@ -205,7 +207,28 @@
}
EntryBaseDropped::add(e);
}
+};
+struct TagEntry : public EntryBase {
+ const uint32_t tag;
+ uid_t uid;
+
+ TagEntry(LogBufferElement *e):
+ EntryBase(e),
+ tag(e->getTag()),
+ uid(e->getUid()) { }
+
+ const uint32_t&getKey() const { return tag; }
+ const uid_t&getUid() const { return uid; }
+ const char*getName() const { return android::tagToName(tag); }
+
+ inline void add(LogBufferElement *e) {
+ uid_t u = e->getUid();
+ if (uid != u) {
+ uid = -1;
+ }
+ EntryBase::add(e);
+ }
};
// Log Statistics
@@ -224,6 +247,10 @@
typedef LogHashtable<pid_t, PidEntry> pidTable_t;
pidTable_t pidTable;
+ // tag list
+ typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
+ tagTable_t tagTable;
+
public:
LogStatistics();
diff --git a/logd/libaudit.c b/logd/libaudit.c
index cf76305..d00d579 100644
--- a/logd/libaudit.c
+++ b/logd/libaudit.c
@@ -177,7 +177,7 @@
*/
status.pid = pid;
status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT;
- status.rate_limit = 5; // audit entries per second
+ status.rate_limit = 20; // audit entries per second
/* Let the kernel know this pid will be registering for audit events */
rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
diff --git a/logd/main.cpp b/logd/main.cpp
index 237c7c1..7b8e94e 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -35,6 +35,7 @@
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
+#include <log/event_tag_map.h>
#include <private/android_filesystem_config.h>
#include "CommandListener.h"
@@ -238,6 +239,23 @@
sem_post(&reinit);
}
+// tagToName converts an events tag into a name
+const char *android::tagToName(uint32_t tag) {
+ static const EventTagMap *map;
+
+ if (!map) {
+ sem_wait(&sem_name);
+ if (!map) {
+ map = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ }
+ sem_post(&sem_name);
+ if (!map) {
+ return NULL;
+ }
+ }
+ return android_lookupEventTag(map, tag);
+}
+
// Foreground waits for exit of the main persistent threads
// that are started here. The threads are created to manage
// UNIX domain client sockets for writing, reading and
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h
index 9171d85..5ab6195 100644
--- a/mkbootimg/bootimg.h
+++ b/mkbootimg/bootimg.h
@@ -15,6 +15,8 @@
** limitations under the License.
*/
+#include <stdint.h>
+
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
@@ -28,31 +30,31 @@
struct boot_img_hdr
{
- unsigned char magic[BOOT_MAGIC_SIZE];
+ uint8_t magic[BOOT_MAGIC_SIZE];
- unsigned kernel_size; /* size in bytes */
- unsigned kernel_addr; /* physical load addr */
+ uint32_t kernel_size; /* size in bytes */
+ uint32_t kernel_addr; /* physical load addr */
- unsigned ramdisk_size; /* size in bytes */
- unsigned ramdisk_addr; /* physical load addr */
+ uint32_t ramdisk_size; /* size in bytes */
+ uint32_t ramdisk_addr; /* physical load addr */
- unsigned second_size; /* size in bytes */
- unsigned second_addr; /* physical load addr */
+ uint32_t second_size; /* size in bytes */
+ uint32_t second_addr; /* physical load addr */
- unsigned tags_addr; /* physical addr for kernel tags */
- unsigned page_size; /* flash page size we assume */
- unsigned unused[2]; /* future expansion: should be 0 */
+ uint32_t tags_addr; /* physical addr for kernel tags */
+ uint32_t page_size; /* flash page size we assume */
+ uint32_t unused[2]; /* future expansion: should be 0 */
- unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
+ uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
- unsigned char cmdline[BOOT_ARGS_SIZE];
+ uint8_t cmdline[BOOT_ARGS_SIZE];
- unsigned id[8]; /* timestamp / checksum / sha1 / etc */
+ uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
/* Supplemental command line data; kept here to maintain
* binary compatibility with older versions of mkbootimg */
- unsigned char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
-};
+ uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
+} __attribute__((packed));
/*
** +-----------------+
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index fc92b4d..40e5261 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdbool.h>
#include "mincrypt/sha.h"
#include "bootimg.h"
@@ -65,6 +66,7 @@
" [ --board <boardname> ]\n"
" [ --base <address> ]\n"
" [ --pagesize <pagesize> ]\n"
+ " [ --id ]\n"
" -o|--output <filename>\n"
);
return 1;
@@ -74,6 +76,14 @@
static unsigned char padding[16384] = { 0, };
+static void print_id(const uint8_t *id, size_t id_len) {
+ printf("0x");
+ for (unsigned i = 0; i < id_len; i++) {
+ printf("%02x", id[i]);
+ }
+ printf("\n");
+}
+
int write_padding(int fd, unsigned pagesize, unsigned itemsize)
{
unsigned pagemask = pagesize - 1;
@@ -96,24 +106,24 @@
{
boot_img_hdr hdr;
- char *kernel_fn = 0;
- void *kernel_data = 0;
- char *ramdisk_fn = 0;
- void *ramdisk_data = 0;
- char *second_fn = 0;
- void *second_data = 0;
+ char *kernel_fn = NULL;
+ void *kernel_data = NULL;
+ char *ramdisk_fn = NULL;
+ void *ramdisk_data = NULL;
+ char *second_fn = NULL;
+ void *second_data = NULL;
char *cmdline = "";
- char *bootimg = 0;
+ char *bootimg = NULL;
char *board = "";
- unsigned pagesize = 2048;
+ uint32_t pagesize = 2048;
int fd;
SHA_CTX ctx;
const uint8_t* sha;
- unsigned base = 0x10000000;
- unsigned kernel_offset = 0x00008000;
- unsigned ramdisk_offset = 0x01000000;
- unsigned second_offset = 0x00f00000;
- unsigned tags_offset = 0x00000100;
+ uint32_t base = 0x10000000U;
+ uint32_t kernel_offset = 0x00008000U;
+ uint32_t ramdisk_offset = 0x01000000U;
+ uint32_t second_offset = 0x00f00000U;
+ uint32_t tags_offset = 0x00000100U;
size_t cmdlen;
argc--;
@@ -121,42 +131,48 @@
memset(&hdr, 0, sizeof(hdr));
+ bool get_id = false;
while(argc > 0){
char *arg = argv[0];
- char *val = argv[1];
- if(argc < 2) {
- return usage();
- }
- argc -= 2;
- argv += 2;
- if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
- bootimg = val;
- } else if(!strcmp(arg, "--kernel")) {
- kernel_fn = val;
- } else if(!strcmp(arg, "--ramdisk")) {
- ramdisk_fn = val;
- } else if(!strcmp(arg, "--second")) {
- second_fn = val;
- } else if(!strcmp(arg, "--cmdline")) {
- cmdline = val;
- } else if(!strcmp(arg, "--base")) {
- base = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--kernel_offset")) {
- kernel_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--ramdisk_offset")) {
- ramdisk_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--second_offset")) {
- second_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--tags_offset")) {
- tags_offset = strtoul(val, 0, 16);
- } else if(!strcmp(arg, "--board")) {
- board = val;
- } else if(!strcmp(arg,"--pagesize")) {
- pagesize = strtoul(val, 0, 10);
- if ((pagesize != 2048) && (pagesize != 4096)
- && (pagesize != 8192) && (pagesize != 16384)) {
- fprintf(stderr,"error: unsupported page size %d\n", pagesize);
- return -1;
+ if (!strcmp(arg, "--id")) {
+ get_id = true;
+ argc -= 1;
+ argv += 1;
+ } else if(argc >= 2) {
+ char *val = argv[1];
+ argc -= 2;
+ argv += 2;
+ if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
+ bootimg = val;
+ } else if(!strcmp(arg, "--kernel")) {
+ kernel_fn = val;
+ } else if(!strcmp(arg, "--ramdisk")) {
+ ramdisk_fn = val;
+ } else if(!strcmp(arg, "--second")) {
+ second_fn = val;
+ } else if(!strcmp(arg, "--cmdline")) {
+ cmdline = val;
+ } else if(!strcmp(arg, "--base")) {
+ base = strtoul(val, 0, 16);
+ } else if(!strcmp(arg, "--kernel_offset")) {
+ kernel_offset = strtoul(val, 0, 16);
+ } else if(!strcmp(arg, "--ramdisk_offset")) {
+ ramdisk_offset = strtoul(val, 0, 16);
+ } else if(!strcmp(arg, "--second_offset")) {
+ second_offset = strtoul(val, 0, 16);
+ } else if(!strcmp(arg, "--tags_offset")) {
+ tags_offset = strtoul(val, 0, 16);
+ } else if(!strcmp(arg, "--board")) {
+ board = val;
+ } else if(!strcmp(arg,"--pagesize")) {
+ pagesize = strtoul(val, 0, 10);
+ if ((pagesize != 2048) && (pagesize != 4096)
+ && (pagesize != 8192) && (pagesize != 16384)) {
+ fprintf(stderr,"error: unsupported page size %d\n", pagesize);
+ return -1;
+ }
+ } else {
+ return usage();
}
} else {
return usage();
@@ -266,6 +282,10 @@
if(write_padding(fd, pagesize, hdr.second_size)) goto fail;
}
+ if (get_id) {
+ print_id((uint8_t *) hdr.id, sizeof(hdr.id));
+ }
+
return 0;
fail:
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 3ecb1db..7ab76b8 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -26,7 +26,7 @@
#
# create some directories (some are mount points)
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data)
+ sbin dev proc sys system data oem)
include $(BUILD_SYSTEM)/base_rules.mk
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 657ef16..9fe1b4f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -260,6 +260,7 @@
mkdir /data/misc/ethernet 0770 system system
mkdir /data/misc/dhcp 0770 dhcp dhcp
mkdir /data/misc/user 0771 root root
+ mkdir /data/misc/perfprofd 0775 root root
# give system access to wpa_supplicant.conf for backup and restore
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root