Merge "init: Create classes for Action and Command"
diff --git a/adb/Android.mk b/adb/Android.mk
index 355bb7f..73b1a98 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -11,6 +11,9 @@
adb_host_clang := true
endif
+adb_host_sanitize :=
+adb_target_sanitize :=
+
adb_version := $(shell git -C $(LOCAL_PATH) rev-parse --short=12 HEAD 2>/dev/null)-android
ADB_COMMON_CFLAGS := \
@@ -80,6 +83,7 @@
qemu_tracing.cpp \
usb_linux_client.cpp \
+LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_SHARED_LIBRARIES := libbase
# Even though we're building a static library (and thus there's no link step for
@@ -97,6 +101,7 @@
$(LIBADB_$(HOST_OS)_SRC_FILES) \
adb_auth_host.cpp \
+LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_SHARED_LIBRARIES := libbase
# Even though we're building a static library (and thus there's no link step for
@@ -114,6 +119,7 @@
LOCAL_MODULE := adbd_test
LOCAL_CFLAGS := -DADB_HOST=0 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS)
+LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STATIC_LIBRARIES := libadbd
LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
include $(BUILD_NATIVE_TEST)
@@ -124,6 +130,7 @@
LOCAL_MODULE := adb_test
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.cpp
+LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_SHARED_LIBRARIES := liblog libbase
LOCAL_STATIC_LIBRARIES := \
libadb \
@@ -150,6 +157,7 @@
LOCAL_MODULE := adb_device_tracker_test
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := test_track_devices.cpp
+LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_SHARED_LIBRARIES := liblog libbase
LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils
LOCAL_LDLIBS += -lrt -ldl -lpthread
@@ -193,6 +201,7 @@
LOCAL_MODULE := adb
LOCAL_MODULE_TAGS := debug
+LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_STATIC_LIBRARIES := \
libadb \
libbase \
@@ -257,6 +266,7 @@
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
LOCAL_C_INCLUDES += system/extras/ext4_utils
+LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STATIC_LIBRARIES := \
libadbd \
libbase \
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 97ce125..aa9ef55 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -770,12 +770,12 @@
if (android::base::StartsWith(service, "killforward:")) {
kill_forward = true;
service += 12;
+ } else {
+ service += 8; // skip past "forward:"
if (android::base::StartsWith(service, "norebind:")) {
no_rebind = true;
service += 9;
}
- } else {
- service += 8;
}
std::vector<std::string> pieces = android::base::Split(service, ";");
@@ -824,7 +824,7 @@
message = android::base::StringPrintf("cannot bind to socket: %s", strerror(errno));
break;
case INSTALL_STATUS_CANNOT_REBIND:
- message = android::base::StringPrintf("cannot rebind existing socket: %s", strerror(errno));
+ message = android::base::StringPrintf("cannot rebind existing socket");
break;
case INSTALL_STATUS_LISTENER_NOT_FOUND:
message = android::base::StringPrintf("listener '%s' not found", service);
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index cd3c7bc..6fa6c2e 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -72,16 +72,17 @@
return result;
}
-int mkdirs(const char *path)
-{
+int mkdirs(const std::string& path) {
+ // TODO: rewrite this function and merge it with the *other* mkdirs in adb.
+ std::unique_ptr<char> path_rw(strdup(path.c_str()));
int ret;
- char *x = (char *)path + 1;
+ char* x = path_rw.get() + 1;
for(;;) {
- x = adb_dirstart(x);
+ x = const_cast<char*>(adb_dirstart(x));
if(x == 0) return 0;
*x = 0;
- ret = adb_mkdir(path, 0775);
+ ret = adb_mkdir(path_rw.get(), 0775);
*x = OS_PATH_SEPARATOR;
if((ret < 0) && (errno != EEXIST)) {
return ret;
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index d1a3f5f..673aaac 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -22,7 +22,7 @@
bool getcwd(std::string* cwd);
bool directory_exists(const std::string& path);
-int mkdirs(const char *path);
+int mkdirs(const std::string& path);
std::string escape_arg(const std::string& s);
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index f190336..d54faec 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -487,8 +487,8 @@
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
if (show_progress) {
- char *x = strrchr(service, ':');
- if(x) service = x + 1;
+ const char* x = strrchr(service, ':');
+ if (x) service = x + 1;
}
while (sz > 0) {
@@ -1496,7 +1496,7 @@
int last_apk = -1;
for (i = argc - 1; i >= 0; i--) {
const char* file = argv[i];
- char* dot = strrchr(file, '.');
+ const char* dot = strrchr(file, '.');
if (dot && !strcasecmp(dot, ".apk")) {
if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
fprintf(stderr, "Invalid APK file: %s\n", file);
@@ -1542,7 +1542,7 @@
int first_apk = -1;
for (i = argc - 1; i >= 0; i--) {
const char* file = argv[i];
- char* dot = strrchr(file, '.');
+ const char* dot = strrchr(file, '.');
if (dot && !strcasecmp(dot, ".apk")) {
if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
fprintf(stderr, "Invalid APK file: %s\n", file);
diff --git a/adb/device.py b/adb/device.py
index 601989b..b6eaad6 100644
--- a/adb/device.py
+++ b/adb/device.py
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import logging
import os
import re
import subprocess
@@ -60,6 +61,7 @@
raise NoUniqueDeviceError()
return AndroidDevice(devices[0], product)
+
def _get_device_by_serial(serial, product=None):
for device in get_devices():
if device == serial:
@@ -145,10 +147,12 @@
return result, out
def _simple_call(self, cmd):
+ logging.info(' '.join(self.adb_cmd + cmd))
return subprocess.check_output(
self.adb_cmd + cmd, stderr=subprocess.STDOUT)
def shell(self, cmd):
+ logging.info(' '.join(self.adb_cmd + ['shell'] + cmd))
cmd = self._make_shell_cmd(cmd)
out = subprocess.check_output(cmd)
rc, out = self._parse_shell_output(out)
@@ -160,6 +164,7 @@
def shell_nocheck(self, cmd):
cmd = self._make_shell_cmd(cmd)
+ logging.info(' '.join(cmd))
p = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = p.communicate()
@@ -189,6 +194,9 @@
def usb(self):
return self._simple_call(['usb'])
+ def reboot(self):
+ return self._simple_call(['reboot'])
+
def root(self):
return self._simple_call(['root'])
@@ -220,7 +228,7 @@
return self._simple_call(['wait-for-device'])
def get_prop(self, prop_name):
- output = self.shell(['getprop', prop_name])
+ output = self.shell(['getprop', prop_name]).splitlines()
if len(output) != 1:
raise RuntimeError('Too many lines in getprop output:\n' +
'\n'.join(output))
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index 5cd4988..a8abade 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -234,7 +234,7 @@
#else /* USE_SELECT */
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
#include <winsock2.h>
#else
#include <sys/select.h>
@@ -617,7 +617,7 @@
fde->func = func;
fde->arg = arg;
-#ifndef HAVE_WINSOCK
+#if !defined(_WIN32)
fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
fdevent_register(fde);
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index e8e9a0f..2067836 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -53,7 +53,7 @@
if(name[0] != '/') return -1;
for(;;) {
- x = adb_dirstart(x);
+ x = const_cast<char*>(adb_dirstart(x));
if(x == 0) return 0;
*x = 0;
if (should_use_fs_config(name)) {
diff --git a/adb/services.cpp b/adb/services.cpp
index 82efb1c..708ef42 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -443,7 +443,7 @@
return -1;
#endif
}
-#ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */
+#if !defined(_WIN32) /* winsock doesn't implement unix domain sockets */
} else if(!strncmp(name, "local:", 6)) {
ret = socket_local_client(name + 6,
ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 6160923..729bbcb 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -247,10 +247,10 @@
return p;
}
-static __inline__ char* adb_dirstop( const char* path )
+static __inline__ const char* adb_dirstop( const char* path )
{
- char* p = strrchr(path, '/');
- char* p2 = strrchr(path, '\\');
+ const char* p = strrchr(path, '/');
+ const char* p2 = strrchr(path, '\\');
if ( !p )
p = p2;
@@ -521,12 +521,12 @@
{
}
-static __inline__ char* adb_dirstart(const char* path)
+static __inline__ const char* adb_dirstart(const char* path)
{
return strchr(path, '/');
}
-static __inline__ char* adb_dirstop(const char* path)
+static __inline__ const char* adb_dirstop(const char* path)
{
return strrchr(path, '/');
}
diff --git a/adb/test_device.py b/adb/test_device.py
index 6c20b6e..81c4a94 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -32,13 +32,38 @@
import adb
+def requires_root(func):
+ def wrapper(self, *args):
+ if self.device.get_prop('ro.debuggable') != '1':
+ raise unittest.SkipTest('requires rootable build')
+
+ was_root = self.device.shell(['id', '-un']).strip() == 'root'
+ if not was_root:
+ self.device.root()
+ self.device.wait()
+
+ try:
+ func(self, *args)
+ finally:
+ if not was_root:
+ self.device.unroot()
+ self.device.wait()
+
+ return wrapper
+
+
class GetDeviceTest(unittest.TestCase):
def setUp(self):
self.android_serial = os.getenv('ANDROID_SERIAL')
- del os.environ['ANDROID_SERIAL']
+ if 'ANDROID_SERIAL' in os.environ:
+ del os.environ['ANDROID_SERIAL']
def tearDown(self):
- os.environ['ANDROID_SERIAL'] = self.android_serial
+ if self.android_serial is not None:
+ os.environ['ANDROID_SERIAL'] = self.android_serial
+ else:
+ if 'ANDROID_SERIAL' in os.environ:
+ del os.environ['ANDROID_SERIAL']
@mock.patch('adb.device.get_devices')
def test_explicit(self, mock_get_devices):
@@ -188,6 +213,9 @@
def test_root_unroot(self):
"""Make sure that adb root and adb unroot work, using id(1)."""
+ if self.device.get_prop('ro.debuggable') != '1':
+ raise unittest.SkipTest('requires rootable build')
+
original_user = self.device.shell(['id', '-un']).strip()
try:
if original_user == 'root':
@@ -216,6 +244,20 @@
subprocess.CalledProcessError, self.device.tcpip, 'foo')
+class SystemPropertiesTest(DeviceTest):
+ def test_get_prop(self):
+ self.assertEqual(self.device.get_prop('init.svc.adbd'), 'running')
+
+ @requires_root
+ def test_set_prop(self):
+ prop_name = 'foo.bar'
+ self.device.shell(['setprop', prop_name, '""'])
+
+ self.device.set_prop(prop_name, 'qux')
+ self.assertEqual(
+ self.device.shell(['getprop', prop_name]).strip(), 'qux')
+
+
def compute_md5(string):
hsh = hashlib.md5()
hsh.update(string)
@@ -274,7 +316,7 @@
size = random.randrange(min_size, max_size, 1024)
base_name = 'device_tmpfile' + str(file_num)
- full_path = os.path.join(in_dir, base_name)
+ full_path = posixpath.join(in_dir, base_name)
device.shell(['dd', 'if=/dev/urandom', 'of={}'.format(full_path),
'bs={}'.format(size), 'count=1'])
@@ -393,7 +435,6 @@
self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
shutil.rmtree(base_dir + self.DEVICE_TEMP_DIR)
-
def test_unicode_paths(self):
"""Ensure that we can support non-ASCII paths, even on Windows."""
name = u'로보카 폴리'.encode('utf-8')
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index e570ef5..dd22712 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -264,14 +264,12 @@
// Determine the device path
if (!fstat(fd, &st) && S_ISCHR(st.st_mode)) {
- char *slash;
- ssize_t link_len;
snprintf(pathbuf, sizeof(pathbuf), "/sys/dev/char/%d:%d",
major(st.st_rdev), minor(st.st_rdev));
- link_len = readlink(pathbuf, link, sizeof(link) - 1);
+ ssize_t link_len = readlink(pathbuf, link, sizeof(link) - 1);
if (link_len > 0) {
link[link_len] = '\0';
- slash = strrchr(link, '/');
+ const char* slash = strrchr(link, '/');
if (slash) {
snprintf(pathbuf, sizeof(pathbuf),
"usb:%s", slash + 1);
diff --git a/crash_reporter/MODULE_LICENSE_BSD b/crash_reporter/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/crash_reporter/MODULE_LICENSE_BSD
diff --git a/crash_reporter/NOTICE b/crash_reporter/NOTICE
new file mode 100644
index 0000000..b9e779f
--- /dev/null
+++ b/crash_reporter/NOTICE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index af86fe9..b5064b4 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -157,12 +157,6 @@
} else if (!strcmp(arg, "SIGFPE")) {
raise(SIGFPE);
return EXIT_SUCCESS;
- } else if (!strcmp(arg, "SIGPIPE")) {
- int pipe_fds[2];
- pipe(pipe_fds);
- close(pipe_fds[0]);
- write(pipe_fds[1], "oops", 4);
- return EXIT_SUCCESS;
} else if (!strcmp(arg, "SIGTRAP")) {
raise(SIGTRAP);
return EXIT_SUCCESS;
@@ -189,7 +183,6 @@
fprintf(stderr, " LOG_ALWAYS_FATAL call LOG_ALWAYS_FATAL\n");
fprintf(stderr, " LOG_ALWAYS_FATAL_IF call LOG_ALWAYS_FATAL\n");
fprintf(stderr, " SIGFPE cause a SIGFPE\n");
- fprintf(stderr, " SIGPIPE cause a SIGPIPE\n");
fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n");
fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n");
fprintf(stderr, " SIGSEGV-unmapped mmap/munmap a region of memory and then attempt to access it\n");
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 787b7aa..599995c 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -408,7 +408,6 @@
case SIGBUS:
case SIGFPE:
case SIGILL:
- case SIGPIPE:
case SIGSEGV:
#ifdef SIGSTKFLT
case SIGSTKFLT:
diff --git a/debuggerd/test/tombstone_test.cpp b/debuggerd/test/tombstone_test.cpp
index a771a39..d945d27 100644
--- a/debuggerd/test/tombstone_test.cpp
+++ b/debuggerd/test/tombstone_test.cpp
@@ -76,7 +76,7 @@
resetLogs();
elf_set_fake_build_id("");
siginfo_t si;
- si.si_signo = SIGPIPE;
+ si.si_signo = SIGABRT;
ptrace_set_fake_getsiginfo(si);
}
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 114c7e4..e283923 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -81,7 +81,6 @@
case SIGBUS: return "SIGBUS";
case SIGFPE: return "SIGFPE";
case SIGILL: return "SIGILL";
- case SIGPIPE: return "SIGPIPE";
case SIGSEGV: return "SIGSEGV";
#if defined(SIGSTKFLT)
case SIGSTKFLT: return "SIGSTKFLT";
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 9078c8f..7b87907 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -26,29 +26,22 @@
* SUCH DAMAGE.
*/
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread.h>
-#include <ctype.h>
+#include <unistd.h>
#include <linux/usbdevice_fs.h>
-#include <linux/usbdevice_fs.h>
#include <linux/version.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
#include <linux/usb/ch9.h>
-#else
-#include <linux/usb_ch9.h>
-#endif
-#include <asm/byteorder.h>
#include "fastboot.h"
#include "usb.h"
@@ -69,9 +62,19 @@
#define DBG1(x...)
#endif
-/* The max bulk size for linux is 16384 which is defined
- * in drivers/usb/core/devio.c.
- */
+// Kernels before 3.3 have a 16KiB transfer limit. That limit was replaced
+// with a 16MiB global limit in 3.3, but each URB submitted required a
+// contiguous kernel allocation, so you would get ENOMEM if you tried to
+// send something larger than the biggest available contiguous kernel
+// memory region. 256KiB contiguous allocations are generally not reliable
+// on a device kernel that has been running for a while fragmenting its
+// memory, but that shouldn't be a problem for fastboot on the host.
+// In 3.6, the contiguous buffer limit was removed by allocating multiple
+// 16KiB chunks and having the USB driver stitch them back together while
+// transmitting using a scatter-gather list, so 256KiB bulk transfers should
+// be reliable.
+// 256KiB seems to work, but 1MiB bulk transfers lock up my z620 with a 3.13
+// kernel.
#define MAX_USBFS_BULK_SIZE (16 * 1024)
struct usb_handle
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index 07d1351..2d3c743 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -23,7 +23,7 @@
#include <string.h>
#include <stdbool.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
#include <winsock2.h>
typedef int socklen_t;
#else
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 0c071ca..9046fbe 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -26,7 +26,7 @@
#include <sys/types.h>
#include <stdint.h>
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
#include <linux/capability.h>
#else
#include "android_filesystem_capability.h"
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
index aad1e82..4c2dd49 100644
--- a/include/utils/AndroidThreads.h
+++ b/include/utils/AndroidThreads.h
@@ -73,7 +73,7 @@
// ------------------------------------------------------------------
// Extra functions working with raw pids.
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// Change the priority AND scheduling group of a particular thread. The priority
// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
// if the priority set failed, else another value if just the group set failed;
diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h
index baa3a83..44ea13d 100644
--- a/include/utils/ByteOrder.h
+++ b/include/utils/ByteOrder.h
@@ -21,7 +21,7 @@
#include <stdint.h>
#include <sys/types.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
#include <winsock2.h>
#else
#include <netinet/in.h>
diff --git a/include/utils/Compat.h b/include/utils/Compat.h
index 7d96310..c5f9d6a 100644
--- a/include/utils/Compat.h
+++ b/include/utils/Compat.h
@@ -75,4 +75,10 @@
_rc; })
#endif
+#if defined(_WIN32)
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
+#endif
+
#endif /* __LIB_UTILS_COMPAT_H */
diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h
index f70fc92..afd7bfd 100644
--- a/include/utils/FileMap.h
+++ b/include/utils/FileMap.h
@@ -26,7 +26,7 @@
#if defined(__MINGW32__)
// Ensure that we always pull in winsock2.h before windows.h
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
#include <winsock2.h>
#endif
#include <windows.h>
diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
index 757519b..f027c79 100644
--- a/include/utils/Mutex.h
+++ b/include/utils/Mutex.h
@@ -59,7 +59,7 @@
// lock if possible; returns 0 on success, error otherwise
status_t tryLock();
-#if HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// lock the mutex, but don't wait longer than timeoutMilliseconds.
// Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
//
@@ -128,7 +128,7 @@
inline status_t Mutex::tryLock() {
return -pthread_mutex_trylock(&mMutex);
}
-#if HAVE_ANDROID_OS
+#if defined(__ANDROID__)
inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
const struct timespec ts = {
/* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
diff --git a/include/utils/Thread.h b/include/utils/Thread.h
index 28839fd..1532b7e 100644
--- a/include/utils/Thread.h
+++ b/include/utils/Thread.h
@@ -70,7 +70,7 @@
// Indicates whether this thread is running or not.
bool isRunning() const;
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// Return the thread's kernel ID, same as the thread itself calling gettid(),
// or -1 if the thread is not running.
pid_t getTid() const;
@@ -101,7 +101,7 @@
volatile bool mExitPending;
volatile bool mRunning;
sp<Thread> mHoldSelf;
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// legacy for debugging, not used by getTid() as it is set by the child thread
// and so is not initialized until the child reaches that point
pid_t mTid;
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index 6ee343d..6ba68f6 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_TRACE_H
#define ANDROID_TRACE_H
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
#include <fcntl.h>
#include <stdint.h>
@@ -59,11 +59,11 @@
}; // namespace android
-#else // HAVE_ANDROID_OS
+#else // !__ANDROID__
#define ATRACE_NAME(...)
#define ATRACE_CALL()
-#endif // HAVE_ANDROID_OS
+#endif // __ANDROID__
#endif // ANDROID_TRACE_H
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index 5ef2ab0..3591a6b 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -22,6 +22,7 @@
#include <stdint.h>
#include <string.h>
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <utils/Compat.h>
diff --git a/init/Android.mk b/init/Android.mk
index a6eb5d6..045e213 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -20,6 +20,27 @@
# --
+# If building on Linux, then build unit test for the host.
+ifeq ($(HOST_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_CPPFLAGS := $(init_cflags)
+LOCAL_SRC_FILES:= \
+ parser/tokenizer.cpp \
+
+LOCAL_MODULE := libinit_parser
+LOCAL_CLANG := true
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := init_parser_tests
+LOCAL_SRC_FILES := \
+ parser/tokenizer_test.cpp \
+
+LOCAL_STATIC_LIBRARIES := libinit_parser
+LOCAL_CLANG := true
+include $(BUILD_HOST_NATIVE_TEST)
+endif
+
include $(CLEAR_VARS)
LOCAL_CPPFLAGS := $(init_cflags)
LOCAL_SRC_FILES:= \
diff --git a/init/parser/tokenizer.cpp b/init/parser/tokenizer.cpp
new file mode 100644
index 0000000..340e0d9
--- /dev/null
+++ b/init/parser/tokenizer.cpp
@@ -0,0 +1,129 @@
+// 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 "tokenizer.h"
+
+namespace init {
+
+Tokenizer::Tokenizer(const std::string& data)
+ : data_(data), eof_(false), pos_(0), tok_start_(0) {
+ current_.type = TOK_START;
+
+ if (data.size() > 0) {
+ cur_char_ = data[0];
+ } else {
+ eof_ = true;
+ cur_char_ = '\0';
+ }
+}
+
+Tokenizer::~Tokenizer() {}
+
+const Tokenizer::Token& Tokenizer::current() {
+ return current_;
+}
+
+bool Tokenizer::Next() {
+ while (!eof_) {
+ AdvWhiteSpace();
+
+ // Check for comments.
+ if (cur_char_ == '#') {
+ AdvChar();
+ // Skip rest of line
+ while (!eof_ && cur_char_ != '\n') {
+ AdvChar();
+ }
+ }
+
+ if (eof_) {
+ break;
+ }
+
+ if (cur_char_ == '\0') {
+ AdvChar();
+ } else if (cur_char_ == '\n') {
+ current_.type = TOK_NEWLINE;
+ current_.text.clear();
+ AdvChar();
+ return true;
+ } else if (cur_char_ == '\\') {
+ AdvChar(); // skip backslash
+ // This is line continuation so
+ // do not generated TOK_NEWLINE at
+ // the next \n.
+ AdvUntil('\n');
+ AdvChar(); // skip \n
+ } else if (cur_char_ == '\"') {
+ AdvChar();
+ StartText();
+ // Grab everything until the next quote.
+ AdvUntil('\"');
+ EndText();
+ AdvChar(); // skip quote.
+ return true;
+ } else {
+ StartText();
+ AdvText();
+ EndText();
+ return true;
+ }
+ }
+ current_.type = TOK_END;
+ current_.text.clear();
+ return false;
+}
+
+void Tokenizer::AdvChar() {
+ pos_++;
+ if (pos_ < data_.size()) {
+ cur_char_ = data_[pos_];
+ } else {
+ eof_ = true;
+ cur_char_ = '\0';
+ }
+}
+
+void Tokenizer::AdvWhiteSpace() {
+ while (cur_char_ == '\t' || cur_char_ == '\r' || cur_char_ == ' ') {
+ AdvChar();
+ }
+}
+
+void Tokenizer::AdvUntil(char x) {
+ while (!eof_ && cur_char_ != x) {
+ AdvChar();
+ }
+}
+
+void Tokenizer::AdvText() {
+ while (cur_char_ != '\t' && cur_char_ != '\r' && cur_char_ != '\0' &&
+ cur_char_ != ' ' && cur_char_ != '\n' && cur_char_ != '#') {
+ AdvChar();
+ }
+}
+
+void Tokenizer::StartText() {
+ current_.text.clear();
+ tok_start_ = pos_;
+ current_.type = TOK_TEXT;
+}
+
+void Tokenizer::EndText() {
+ if (pos_ != tok_start_) {
+ current_.text.append(data_, tok_start_, pos_ - tok_start_);
+ }
+}
+
+} // namespace init
\ No newline at end of file
diff --git a/init/parser/tokenizer.h b/init/parser/tokenizer.h
new file mode 100644
index 0000000..40a22b1
--- /dev/null
+++ b/init/parser/tokenizer.h
@@ -0,0 +1,69 @@
+// 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 <string>
+
+namespace init {
+
+// Used to tokenize a std::string.
+// Call Next() to advance through each token until it returns false,
+// indicating there are no more tokens left in the string.
+// The current token can be accessed with current(), which returns
+// a Token.
+// Supported tokens are:
+// TOK_START - Next() has yet to be called
+// TOK_END - At the end of string
+// TOK_NEWLINE - The end of a line denoted by \n.
+// TOK_TEXT - A word.
+// Comments are denoted with '#' and the tokenizer will ignore
+// the rest of the line.
+// Double quotes can be used to insert whitespace into words.
+// A backslash at the end of a line denotes continuation and
+// a TOK_NEWLINE will not be generated for that line.
+class Tokenizer {
+ public:
+ Tokenizer(const std::string& data);
+ ~Tokenizer();
+
+ enum TokenType { TOK_START, TOK_END, TOK_NEWLINE, TOK_TEXT };
+ struct Token {
+ TokenType type;
+ std::string text;
+ };
+
+ // Returns the curret token.
+ const Token& current();
+
+ // Move to the next token, returns false at the end of input.
+ bool Next();
+
+ private:
+ void GetData();
+ void AdvChar();
+ void AdvText();
+ void AdvUntil(char x);
+ void AdvWhiteSpace();
+ void StartText();
+ void EndText();
+
+ const std::string& data_;
+ Token current_;
+
+ bool eof_;
+ size_t pos_;
+ char cur_char_;
+ size_t tok_start_;
+};
+
+} // namespace init
diff --git a/init/parser/tokenizer_test.cpp b/init/parser/tokenizer_test.cpp
new file mode 100644
index 0000000..c4a48df
--- /dev/null
+++ b/init/parser/tokenizer_test.cpp
@@ -0,0 +1,230 @@
+// 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 "tokenizer.h"
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+#include <string>
+
+namespace init {
+
+#define SETUP_TEST(test_data) \
+ std::string data(test_data); \
+ Tokenizer tokenizer(data); \
+ ASSERT_EQ(Tokenizer::TOK_START, tokenizer.current().type)
+
+#define ASSERT_TEXT_TOKEN(test_text) \
+ ASSERT_TRUE(tokenizer.Next()); \
+ ASSERT_EQ(test_text, tokenizer.current().text); \
+ ASSERT_EQ(Tokenizer::TOK_TEXT, tokenizer.current().type)
+
+#define ASSERT_NEWLINE_TOKEN() \
+ ASSERT_TRUE(tokenizer.Next()); \
+ ASSERT_EQ(Tokenizer::TOK_NEWLINE, tokenizer.current().type)
+
+TEST(Tokenizer, Empty) {
+ SETUP_TEST("");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, Simple) {
+ SETUP_TEST("test");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, LeadingWhiteSpace) {
+ SETUP_TEST(" \t \r test");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, TrailingWhiteSpace) {
+ SETUP_TEST("test \t \r ");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, WhiteSpace) {
+ SETUP_TEST(" \t \r test \t \r ");
+ ASSERT_TEXT_TOKEN("test");
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, TwoTokens) {
+ SETUP_TEST(" foo bar ");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("bar");
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, MultiToken) {
+ SETUP_TEST("one two three four five");
+ ASSERT_TEXT_TOKEN("one");
+ ASSERT_TEXT_TOKEN("two");
+ ASSERT_TEXT_TOKEN("three");
+ ASSERT_TEXT_TOKEN("four");
+ ASSERT_TEXT_TOKEN("five");
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, NewLine) {
+ SETUP_TEST("\n");
+ ASSERT_NEWLINE_TOKEN();
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, TextNewLine) {
+ SETUP_TEST("test\n");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_NEWLINE_TOKEN();
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, MultiTextNewLine) {
+ SETUP_TEST("one\ntwo\nthree\n");
+ ASSERT_TEXT_TOKEN("one");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_TEXT_TOKEN("two");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_TEXT_TOKEN("three");
+ ASSERT_NEWLINE_TOKEN();
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, MultiTextNewLineNoLineEnding) {
+ SETUP_TEST("one\ntwo\nthree");
+ ASSERT_TEXT_TOKEN("one");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_TEXT_TOKEN("two");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_TEXT_TOKEN("three");
+
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, Comment) {
+ SETUP_TEST("#test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentWhiteSpace) {
+ SETUP_TEST(" \t \r #test \t \r ");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentNewLine) {
+ SETUP_TEST(" #test \n");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentTwoNewLine) {
+ SETUP_TEST(" #test \n#test");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentWithText) {
+ SETUP_TEST("foo bar #test");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentWithTextNoSpace) {
+ SETUP_TEST("foo bar#test");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentWithTextLineFeed) {
+ SETUP_TEST("foo bar #test\n");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, CommentWithMultiTextLineFeed) {
+ SETUP_TEST("#blah\nfoo bar #test\n#blah");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_NEWLINE_TOKEN();
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, SimpleEscaped) {
+ SETUP_TEST("fo\\no bar");
+ ASSERT_TEXT_TOKEN("fo\\no");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, EscapedLineContNoLineFeed) {
+ SETUP_TEST("fo\\no bar \\ hello");
+ ASSERT_TEXT_TOKEN("fo\\no");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, EscapedLineContLineFeed) {
+ SETUP_TEST("fo\\no bar \\ hello\n");
+ ASSERT_TEXT_TOKEN("fo\\no");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, EscapedLineCont) {
+ SETUP_TEST("fo\\no bar \\\ntest");
+ ASSERT_TEXT_TOKEN("fo\\no");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, EscapedLineContWithBadChars) {
+ SETUP_TEST("fo\\no bar \\bad bad bad\ntest");
+ ASSERT_TEXT_TOKEN("fo\\no");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_TEXT_TOKEN("test");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, SimpleQuotes) {
+ SETUP_TEST("foo \"single token\" bar");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("single token");
+ ASSERT_TEXT_TOKEN("bar");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+TEST(Tokenizer, BadQuotes) {
+ SETUP_TEST("foo \"single token");
+ ASSERT_TEXT_TOKEN("foo");
+ ASSERT_TEXT_TOKEN("single token");
+ ASSERT_FALSE(tokenizer.Next());
+}
+
+} // namespace init
diff --git a/init/perfboot.py b/init/perfboot.py
new file mode 100755
index 0000000..2cd4699
--- /dev/null
+++ b/init/perfboot.py
@@ -0,0 +1,411 @@
+#!/usr/bin/env python
+# 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.
+"""Record the event logs during boot and output them to a file.
+
+This script repeats the record of each event log during Android boot specified
+times. By default, interval between measurements is adjusted in such a way that
+CPUs are cooled down sufficiently to avoid boot time slowdown caused by CPU
+thermal throttling. The result is output in a tab-separated value format.
+
+Examples:
+
+Repeat measurements 10 times. Interval between iterations is adjusted based on
+CPU temperature of the device.
+
+$ ./perfboot.py --iterations=10
+
+Repeat measurements 20 times. 60 seconds interval is taken between each
+iteration.
+
+$ ./perfboot.py --iterations=20 --interval=60
+
+Repeat measurements 20 times, show verbose output, output the result to
+data.tsv, and read event tags from eventtags.txt.
+
+$ ./perfboot.py --iterations=30 -v --output=data.tsv --tags=eventtags.txt
+"""
+
+import argparse
+import atexit
+import cStringIO
+import inspect
+import logging
+import math
+import os
+import re
+import subprocess
+import sys
+import threading
+import time
+
+sys.path.append(os.path.dirname(os.path.dirname(__file__)))
+import adb
+
+# The default event tags to record.
+_DEFAULT_EVENT_TAGS = [
+ 'boot_progress_start',
+ 'boot_progress_preload_start',
+ 'boot_progress_preload_end',
+ 'boot_progress_system_run',
+ 'boot_progress_pms_start',
+ 'boot_progress_pms_system_scan_start',
+ 'boot_progress_pms_data_scan_start',
+ 'boot_progress_pms_scan_end',
+ 'boot_progress_pms_ready',
+ 'boot_progress_ams_ready',
+ 'boot_progress_enable_screen',
+]
+
+
+class IntervalAdjuster(object):
+ """A helper class to take suffficient interval between iterations."""
+
+ # CPU temperature values per product used to decide interval
+ _CPU_COOL_DOWN_THRESHOLDS = {
+ 'flo': 40,
+ 'flounder': 40000,
+ 'razor': 40,
+ 'volantis': 40000,
+ }
+ # The interval between CPU temperature checks
+ _CPU_COOL_DOWN_WAIT_INTERVAL = 10
+ # The wait time used when the value of _CPU_COOL_DOWN_THRESHOLDS for
+ # the product is not defined.
+ _CPU_COOL_DOWN_WAIT_TIME_DEFAULT = 120
+
+ def __init__(self, interval, device):
+ self._interval = interval
+ self._device = device
+ self._temp_paths = device.shell(
+ ['ls', '/sys/class/thermal/thermal_zone*/temp']).splitlines()
+ self._product = device.get_prop('ro.build.product')
+ self._waited = False
+
+ def wait(self):
+ """Waits certain amount of time for CPUs cool-down."""
+ if self._interval is None:
+ self._wait_cpu_cool_down(self._product, self._temp_paths)
+ else:
+ if self._waited:
+ print 'Waiting for %d seconds' % self._interval
+ time.sleep(self._interval)
+ self._waited = True
+
+ def _get_cpu_temp(self, threshold):
+ max_temp = 0
+ for temp_path in self._temp_paths:
+ temp = int(self._device.shell(['cat', temp_path]).rstrip())
+ max_temp = max(max_temp, temp)
+ if temp >= threshold:
+ return temp
+ return max_temp
+
+ def _wait_cpu_cool_down(self, product, temp_paths):
+ threshold = IntervalAdjuster._CPU_COOL_DOWN_THRESHOLDS.get(
+ self._product)
+ if threshold is None:
+ print 'No CPU temperature threshold is set for ' + self._product
+ print ('Just wait %d seconds' %
+ IntervalAdjuster._CPU_COOL_DOWN_WAIT_TIME_DEFAULT)
+ time.sleep(IntervalAdjuster._CPU_COOL_DOWN_WAIT_TIME_DEFAULT)
+ return
+ while True:
+ temp = self._get_cpu_temp(threshold)
+ if temp < threshold:
+ logging.info('Current CPU temperature %s' % temp)
+ return
+ print 'Waiting until CPU temperature (%d) falls below %d' % (
+ temp, threshold)
+ time.sleep(IntervalAdjuster._CPU_COOL_DOWN_WAIT_INTERVAL)
+
+
+class WatchdogTimer(object):
+ """A timer that makes is_timedout() return true in |timeout| seconds."""
+ def __init__(self, timeout):
+ self._timedout = False
+
+ def notify_timeout():
+ self._timedout = True
+ self._timer = threading.Timer(timeout, notify_timeout)
+ self._timer.start()
+
+ def is_timedout(self):
+ return self._timedout
+
+ def cancel(self):
+ self._timer.cancel()
+
+
+def readlines_unbuffered(proc):
+ """Read lines from |proc|'s standard out without buffering."""
+ while True:
+ buf = []
+ c = proc.stdout.read(1)
+ if c == '' and proc.poll() is not None:
+ break
+ while c != '\n':
+ if c == '' and proc.poll() is not None:
+ break
+ buf.append(c)
+ c = proc.stdout.read(1)
+ yield ''.join(buf)
+
+
+def disable_dropbox(device):
+ """Removes the files created by Dropbox and avoids creating the files."""
+ device.root()
+ device.wait()
+ device.shell(['rm', '-rf', '/system/data/dropbox'])
+ original_dropbox_max_files = device.shell(
+ ['settings', 'get', 'global', 'dropbox_max_files']).rstrip()
+ device.shell(['settings', 'put', 'global', 'dropbox_max_files', '0'])
+ return original_dropbox_max_files
+
+
+def restore_dropbox(device, original_dropbox_max_files):
+ """Restores the dropbox_max_files setting."""
+ device.root()
+ device.wait()
+ if original_dropbox_max_files == 'null':
+ device.shell(['settings', 'delete', 'global', 'dropbox_max_files'])
+ else:
+ device.shell(['settings', 'put', 'global', 'dropbox_max_files',
+ original_dropbox_max_files])
+
+
+def init_perf(device, output, record_list, tags):
+ device.wait()
+ build_type = device.get_prop('ro.build.type')
+ original_dropbox_max_files = None
+ if build_type != 'user':
+ # Workaround for Dropbox issue (http://b/20890386).
+ original_dropbox_max_files = disable_dropbox(device)
+
+ def cleanup():
+ try:
+ if record_list:
+ print_summary(record_list, tags[-1])
+ output_results(output, record_list, tags)
+ if original_dropbox_max_files is not None:
+ restore_dropbox(device, original_dropbox_max_files)
+ except subprocess.CalledProcessError, RuntimeError:
+ pass
+ atexit.register(cleanup)
+
+
+def read_event_tags(tags_file):
+ """Reads event tags from |tags_file|."""
+ if not tags_file:
+ return _DEFAULT_EVENT_TAGS
+ tags = []
+ with open(tags_file) as f:
+ for line in f:
+ if '#' in line:
+ line = line[:line.find('#')]
+ line = line.strip()
+ if line:
+ tags.append(line)
+ return tags
+
+
+def make_event_tags_re(tags):
+ """Makes a regular expression object that matches event logs of |tags|."""
+ return re.compile(r'(?P<pid>[0-9]+) +[0-9]+ I (?P<tag>%s): (?P<time>\d+)' %
+ '|'.join(tags))
+
+
+def get_values(record, tag):
+ """Gets values that matches |tag| from |record|."""
+ keys = [key for key in record.keys() if key[0] == tag]
+ return [record[k] for k in sorted(keys)]
+
+
+def get_last_value(record, tag):
+ """Gets the last value that matches |tag| from |record|."""
+ values = get_values(record, tag)
+ if not values:
+ return 0
+ return values[-1]
+
+
+def output_results(filename, record_list, tags):
+ """Outputs |record_list| into |filename| in a TSV format."""
+ # First, count the number of the values of each tag.
+ # This is for dealing with events that occur multiple times.
+ # For instance, boot_progress_preload_start and boot_progress_preload_end
+ # are recorded twice on 64-bit system. One is for 64-bit zygote process
+ # and the other is for 32-bit zygote process.
+ values_counter = {}
+ for record in record_list:
+ for tag in tags:
+ # Some record might lack values for some tags due to unanticipated
+ # problems (e.g. timeout), so take the maximum count among all the
+ # record.
+ values_counter[tag] = max(values_counter.get(tag, 1),
+ len(get_values(record, tag)))
+
+ # Then creates labels for the data. If there are multiple values for one
+ # tag, labels for these values are numbered except the first one as
+ # follows:
+ #
+ # event_tag event_tag2 event_tag3
+ #
+ # The corresponding values are sorted in an ascending order of PID.
+ labels = []
+ for tag in tags:
+ for i in range(1, values_counter[tag] + 1):
+ labels.append('%s%s' % (tag, '' if i == 1 else str(i)))
+
+ # Finally write the data into the file.
+ with open(filename, 'w') as f:
+ f.write('\t'.join(labels) + '\n')
+ for record in record_list:
+ line = cStringIO.StringIO()
+ invalid_line = False
+ for i, tag in enumerate(tags):
+ if i != 0:
+ line.write('\t')
+ values = get_values(record, tag)
+ if len(values) < values_counter[tag]:
+ invalid_line = True
+ # Fill invalid record with 0
+ values += [0] * (values_counter[tag] - len(values))
+ line.write('\t'.join(str(t) for t in values))
+ if invalid_line:
+ logging.error('Invalid record found: ' + line.getvalue())
+ line.write('\n')
+ f.write(line.getvalue())
+ print 'Wrote: ' + filename
+
+
+def median(data):
+ """Calculates the median value from |data|."""
+ data = sorted(data)
+ n = len(data)
+ if n % 2 == 1:
+ return data[n / 2]
+ else:
+ n2 = n / 2
+ return (data[n2 - 1] + data[n2]) / 2.0
+
+
+def mean(data):
+ """Calculates the mean value from |data|."""
+ return float(sum(data)) / len(data)
+
+
+def stddev(data):
+ """Calculates the standard deviation value from |value|."""
+ m = mean(data)
+ return math.sqrt(sum((x - m) ** 2 for x in data) / len(data))
+
+
+def print_summary(record_list, end_tag):
+ """Prints the summary of |record_list|."""
+ # Filter out invalid data.
+ end_times = [get_last_value(record, end_tag) for record in record_list
+ if get_last_value(record, end_tag) != 0]
+ print 'mean: ', mean(end_times)
+ print 'median:', median(end_times)
+ print 'standard deviation:', stddev(end_times)
+
+
+def do_iteration(device, interval_adjuster, event_tags_re, end_tag):
+ """Measures the boot time once."""
+ device.wait()
+ interval_adjuster.wait()
+ device.reboot()
+ print 'Rebooted the device'
+ record = {}
+ booted = False
+ while not booted:
+ device.wait()
+ # Stop the iteration if it does not finish within 120 seconds.
+ timeout = 120
+ t = WatchdogTimer(timeout)
+ p = subprocess.Popen(
+ ['adb', 'logcat', '-b', 'events', '-v', 'threadtime'],
+ stdout=subprocess.PIPE)
+ for line in readlines_unbuffered(p):
+ if t.is_timedout():
+ print '*** Timed out ***'
+ return record
+ m = event_tags_re.search(line)
+ if not m:
+ continue
+ tag = m.group('tag')
+ event_time = int(m.group('time'))
+ pid = m.group('pid')
+ record[(tag, pid)] = event_time
+ print 'Event log recorded: %s (%s) - %d ms' % (
+ tag, pid, event_time)
+ if tag == end_tag:
+ booted = True
+ t.cancel()
+ break
+ return record
+
+
+def parse_args():
+ """Parses the command line arguments."""
+ parser = argparse.ArgumentParser(
+ description=inspect.getdoc(sys.modules[__name__]),
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument('--iterations', type=int, default=5,
+ help='Number of times to repeat boot measurements.')
+ parser.add_argument('--interval', type=int,
+ help=('Duration between iterations. If this is not '
+ 'set explicitly, durations are determined '
+ 'adaptively based on CPUs temperature.'))
+ parser.add_argument('-o', '--output', help='File name of output data.')
+ parser.add_argument('-v', '--verbose', action='store_true',
+ help='Show verbose output.')
+ parser.add_argument('-s', '--serial', default=os.getenv('ANDROID_SERIAL'),
+ help='Adb device serial number.')
+ parser.add_argument('-t', '--tags', help='Specify the filename from which '
+ 'event tags are read. Every line contains one event '
+ 'tag and the last event tag is used to detect that '
+ 'the device has finished booting.')
+ return parser.parse_args()
+
+
+def main():
+ args = parse_args()
+ if args.verbose:
+ logging.getLogger().setLevel(logging.INFO)
+
+ device = adb.get_device(args.serial)
+
+ if not args.output:
+ device.wait()
+ args.output = 'perf-%s-%s.tsv' % (
+ device.get_prop('ro.build.flavor'),
+ device.get_prop('ro.build.version.incremental'))
+
+ record_list = []
+ event_tags = read_event_tags(args.tags)
+ init_perf(device, args.output, record_list, event_tags)
+ interval_adjuster = IntervalAdjuster(args.interval, device)
+ event_tags_re = make_event_tags_re(event_tags)
+ end_tag = event_tags[-1]
+ for i in range(args.iterations):
+ print 'Run #%d ' % i
+ record = do_iteration(
+ device, interval_adjuster, event_tags_re, end_tag)
+ record_list.append(record)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/init/readme.txt b/init/readme.txt
index 5a758d7..d70c6f3 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -377,6 +377,29 @@
bootanimation ends at: 33790 31230 (-2560)
+Systrace
+--------
+Systrace [1] can be used for obtaining performance analysis reports during boot
+time on userdebug or eng builds.
+Here is an example of trace events of "wm" and "am" categories:
+
+ $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py wm am --boot
+
+This command will cause the device to reboot. After the device is rebooted and
+the boot sequence has finished, the trace report is obtained from the device
+and written as trace.html on the host by hitting Ctrl+C.
+
+LIMITATION
+Recording trace events is started after persistent properties are loaded, so
+the trace events that are emitted before that are not recorded. Several
+services such as vold, surfaceflinger, and servicemanager are affected by this
+limitation since they are started before persistent properties are loaded.
+Zygote initialization and the processes that are forked from the zygote are not
+affected.
+
+[1] http://developer.android.com/tools/help/systrace.html
+
+
Debugging init
--------------
By default, programs executed by init will drop stdout and stderr into
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 1316339..5f6f8f9 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -118,6 +118,7 @@
{ 00550, AID_DHCP, AID_SHELL, 0, "system/etc/dhcpcd/dhcpcd-run-hooks" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" },
+ { 00440, AID_ROOT, AID_ROOT, 0, "system/etc/recovery.img" },
{ 00444, AID_ROOT, AID_ROOT, 0, conf_dir + 1 },
{ 00444, AID_ROOT, AID_ROOT, 0, conf_file + 1 },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
diff --git a/libcutils/iosched_policy.c b/libcutils/iosched_policy.c
index 8946d3c..71bc94b 100644
--- a/libcutils/iosched_policy.c
+++ b/libcutils/iosched_policy.c
@@ -23,7 +23,7 @@
#include <cutils/iosched_policy.h>
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
#include <linux/ioprio.h>
#include <sys/syscall.h>
#define __android_unused
@@ -32,7 +32,7 @@
#endif
int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) {
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio | (clazz << IOPRIO_CLASS_SHIFT))) {
return -1;
}
@@ -41,7 +41,7 @@
}
int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) {
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
int rc;
if ((rc = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, pid)) < 0) {
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
index cc931eb..5d28b6f 100644
--- a/libcutils/process_name.c
+++ b/libcutils/process_name.c
@@ -25,19 +25,19 @@
#include <unistd.h>
#include <cutils/process_name.h>
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
#include <cutils/properties.h>
#endif
#define PROCESS_NAME_DEVICE "/sys/qemu_trace/process_name"
static const char* process_name = "unknown";
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
static int running_in_emulator = -1;
#endif
void set_process_name(const char* new_name) {
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
char propBuf[PROPERTY_VALUE_MAX];
#endif
@@ -59,7 +59,7 @@
}
#endif
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// If we know we are not running in the emulator, then return.
if (running_in_emulator == 0) {
return;
diff --git a/libcutils/record_stream.c b/libcutils/record_stream.c
index 6994904..2bc4226 100644
--- a/libcutils/record_stream.c
+++ b/libcutils/record_stream.c
@@ -22,7 +22,7 @@
#include <cutils/record_stream.h>
#include <string.h>
#include <stdint.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
#include <winsock2.h> /* for ntohl */
#else
#include <netinet/in.h>
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index dfc8777..103ff66 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -37,7 +37,7 @@
return p == SP_DEFAULT ? SP_SYSTEM_DEFAULT : p;
}
-#if defined(HAVE_ANDROID_OS)
+#if defined(__ANDROID__)
#include <pthread.h>
#include <sched.h>
@@ -142,7 +142,7 @@
*/
static int getSchedulerGroup(int tid, char* buf, size_t bufLen)
{
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
char pathBuf[32];
char lineBuf[256];
FILE *fp;
diff --git a/libcutils/socket_inaddr_any_server.c b/libcutils/socket_inaddr_any_server.c
index 6c849de..7f0ccb8 100644
--- a/libcutils/socket_inaddr_any_server.c
+++ b/libcutils/socket_inaddr_any_server.c
@@ -20,7 +20,7 @@
#include <string.h>
#include <unistd.h>
-#ifndef HAVE_WINSOCK
+#if !defined(_WIN32)
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
diff --git a/libcutils/socket_local_client.c b/libcutils/socket_local_client.c
index 7b42daa..2526146 100644
--- a/libcutils/socket_local_client.c
+++ b/libcutils/socket_local_client.c
@@ -22,7 +22,7 @@
#include <cutils/sockets.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
int socket_local_client(const char *name, int namespaceId, int type)
{
@@ -30,7 +30,7 @@
return -1;
}
-#else /* !HAVE_WINSOCK */
+#else /* !_WIN32 */
#include <sys/socket.h>
#include <sys/un.h>
@@ -165,4 +165,4 @@
return s;
}
-#endif /* !HAVE_WINSOCK */
+#endif /* !_WIN32 */
diff --git a/libcutils/socket_local_server.c b/libcutils/socket_local_server.c
index 60eb86b..c9acdad 100644
--- a/libcutils/socket_local_server.c
+++ b/libcutils/socket_local_server.c
@@ -23,7 +23,7 @@
#include <errno.h>
#include <stddef.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
int socket_local_server(const char *name, int namespaceId, int type)
{
@@ -31,7 +31,7 @@
return -1;
}
-#else /* !HAVE_WINSOCK */
+#else /* !_WIN32 */
#include <sys/socket.h>
#include <sys/un.h>
@@ -123,4 +123,4 @@
return s;
}
-#endif /* !HAVE_WINSOCK */
+#endif /* !_WIN32 */
diff --git a/libcutils/socket_loopback_client.c b/libcutils/socket_loopback_client.c
index 9aed7b7..e14cffb 100644
--- a/libcutils/socket_loopback_client.c
+++ b/libcutils/socket_loopback_client.c
@@ -20,7 +20,7 @@
#include <string.h>
#include <unistd.h>
-#ifndef HAVE_WINSOCK
+#if !defined(_WIN32)
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
diff --git a/libcutils/socket_loopback_server.c b/libcutils/socket_loopback_server.c
index 71afce7..b600e34 100644
--- a/libcutils/socket_loopback_server.c
+++ b/libcutils/socket_loopback_server.c
@@ -22,7 +22,7 @@
#define LISTEN_BACKLOG 4
-#ifndef HAVE_WINSOCK
+#if !defined(_WIN32)
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
diff --git a/libcutils/sockets.c b/libcutils/sockets.c
index 15ede2b..d438782 100644
--- a/libcutils/sockets.c
+++ b/libcutils/sockets.c
@@ -17,7 +17,7 @@
#include <cutils/sockets.h>
#include <log/log.h>
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
/* For the socket trust (credentials) check */
#include <private/android_filesystem_config.h>
#define __android_unused
@@ -27,7 +27,7 @@
bool socket_peer_is_trusted(int fd __android_unused)
{
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
struct ucred cr;
socklen_t len = sizeof(cr);
int n = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 9c4af30..cfc8a7a 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -37,7 +37,7 @@
/* branchless on many architectures. */
#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
-#if (defined(USE_MINGW) || defined(HAVE_WINSOCK))
+#if defined(_WIN32)
#define WEAK static
#else
#define WEAK __attribute__((weak))
@@ -48,7 +48,7 @@
/* Private copy of ../libcutils/socket_local_client.c prevent library loops */
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
int WEAK socket_local_client(const char *name, int namespaceId, int type)
{
@@ -56,7 +56,7 @@
return -ENOSYS;
}
-#else /* !HAVE_WINSOCK */
+#else /* !_WIN32 */
#include <sys/socket.h>
#include <sys/un.h>
@@ -193,7 +193,7 @@
return s;
}
-#endif /* !HAVE_WINSOCK */
+#endif /* !_WIN32 */
/* End of ../libcutils/socket_local_client.c */
#define logger_for_each(logger, logger_list) \
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index a9671a9..32a65ea 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -295,13 +295,13 @@
// so we save the extra file existence check.
char cpuinfo_path[1024];
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/lib"
#ifdef __LP64__
"64"
#endif // __LP64__
"/%s/cpuinfo", instruction_set);
-#else // !HAVE_ANDROID_OS
+#else // !__ANDROID__
// To be able to test on the host, we hardwire a relative path.
snprintf(cpuinfo_path, sizeof(cpuinfo_path), "./cpuinfo");
#endif
diff --git a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp b/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
index cec26ce..d3bbebe 100644
--- a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
+++ b/libnativebridge/tests/PreInitializeNativeBridge_test.cpp
@@ -32,8 +32,8 @@
TEST_F(NativeBridgeTest, PreInitializeNativeBridge) {
ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr));
-#ifndef __APPLE__ // Mac OS does not support bind-mount.
-#ifndef HAVE_ANDROID_OS // Cannot write into the hard-wired location.
+#if !defined(__APPLE__) // Mac OS does not support bind-mount.
+#if !defined(__ANDROID__) // Cannot write into the hard-wired location.
// Try to create our mount namespace.
if (unshare(CLONE_NEWNS) != -1) {
// Create a dummy file.
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 7d2a5fb..956ed30 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -50,7 +50,7 @@
#define ALOGW printf
#endif
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
/* SIOCKILLADDR is an Android extension. */
#define SIOCKILLADDR 0x8939
#endif
@@ -596,7 +596,7 @@
int ifc_reset_connections(const char *ifname, const int reset_mask)
{
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
int result, success;
in_addr_t myaddr = 0;
struct ifreq ifr;
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 3323b82..28be60f 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -16,6 +16,7 @@
#include <utils/String8.h>
+#include <utils/Compat.h>
#include <utils/Log.h>
#include <utils/Unicode.h>
#include <utils/SharedBuffer.h>
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp
index 64204a8..1fca2b2 100644
--- a/libutils/SystemClock.cpp
+++ b/libutils/SystemClock.cpp
@@ -19,7 +19,7 @@
* System clock functions.
*/
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
#include <linux/ioctl.h>
#include <linux/rtc.h>
#include <utils/Atomic.h>
@@ -107,7 +107,7 @@
*/
int64_t elapsedRealtimeNano()
{
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
struct timespec ts;
int result;
int64_t timestamp;
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index c3666e4..6dda6b5 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -45,7 +45,7 @@
#include <cutils/sched_policy.h>
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
# define __android_unused
#else
# define __android_unused __attribute__((__unused__))
@@ -132,7 +132,7 @@
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */
+#if defined(__ANDROID__) /* valgrind is rejecting RT-priority create reqs */
if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
// Now that the pthread_t has a method to find the associated
// android_thread_id_t (pid) from pthread_t, it would be possible to avoid
@@ -176,7 +176,7 @@
return 1;
}
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
static pthread_t android_thread_id_t_to_pthread(android_thread_id_t thread)
{
return (pthread_t) thread;
@@ -302,12 +302,10 @@
gCreateThreadFn = func;
}
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
int androidSetThreadPriority(pid_t tid, int pri)
{
int rc = 0;
-
-#if !defined(_WIN32)
int lasterr = 0;
if (pri >= ANDROID_PRIORITY_BACKGROUND) {
@@ -325,17 +323,12 @@
} else {
errno = lasterr;
}
-#endif
return rc;
}
int androidGetThreadPriority(pid_t tid) {
-#if !defined(_WIN32)
return getpriority(PRIO_PROCESS, tid);
-#else
- return ANDROID_PRIORITY_NORMAL;
-#endif
}
#endif
@@ -658,7 +651,7 @@
mLock("Thread::mLock"),
mStatus(NO_ERROR),
mExitPending(false), mRunning(false)
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
, mTid(-1)
#endif
{
@@ -728,7 +721,7 @@
wp<Thread> weak(strong);
self->mHoldSelf.clear();
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif
@@ -839,7 +832,7 @@
return mRunning;
}
-#ifdef HAVE_ANDROID_OS
+#if defined(__ANDROID__)
pid_t Thread::getTid() const
{
// mTid is not defined until the child initializes it, and the caller may need it earlier
diff --git a/libutils/Timers.cpp b/libutils/Timers.cpp
index fb70e15..201bc41 100644
--- a/libutils/Timers.cpp
+++ b/libutils/Timers.cpp
@@ -23,7 +23,7 @@
#include <sys/time.h>
#include <time.h>
-#if defined(HAVE_ANDROID_OS)
+#if defined(__ANDROID__)
nsecs_t systemTime(int clock)
{
static const clockid_t clocks[] = {
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
index fb876c9..6f4b721 100644
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -18,7 +18,7 @@
#include <stddef.h>
-#ifdef HAVE_WINSOCK
+#if defined(_WIN32)
# undef nhtol
# undef htonl
# undef nhtos
diff --git a/metrics/MODULE_LICENSE_BSD b/metrics/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/metrics/MODULE_LICENSE_BSD
diff --git a/metrics/NOTICE b/metrics/NOTICE
new file mode 100644
index 0000000..b9e779f
--- /dev/null
+++ b/metrics/NOTICE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/rootdir/init.rc b/rootdir/init.rc
index f5febde..12999bd 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -259,6 +259,7 @@
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root
mkdir /data/misc/media 0700 media media
+ mkdir /data/misc/boottrace 0771 system shell
# For security reasons, /data/local/tmp should always be empty.
# Do not place files or directories in /data/local/tmp
diff --git a/rootdir/init.trace.rc b/rootdir/init.trace.rc
index 50944e6..ed4629e 100644
--- a/rootdir/init.trace.rc
+++ b/rootdir/init.trace.rc
@@ -33,3 +33,11 @@
# Allow only the shell group to read and truncate the kernel trace.
chown root shell /sys/kernel/debug/tracing/trace
chmod 0660 /sys/kernel/debug/tracing/trace
+
+on property:persist.debug.atrace.boottrace=1
+ start boottrace
+
+# Run atrace with the categories written in a file
+service boottrace /system/bin/atrace --async_start -f /data/misc/boottrace/categories
+ disabled
+ oneshot
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 893c0dc..5b657bb 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -264,7 +264,7 @@
* buffer at the same time. This allows us to share the underlying storage. */
union {
__u8 request_buffer[MAX_REQUEST_SIZE];
- __u8 read_buffer[MAX_READ + PAGESIZE];
+ __u8 read_buffer[MAX_READ + PAGE_SIZE];
};
};
@@ -1282,7 +1282,7 @@
__u32 size = req->size;
__u64 offset = req->offset;
int res;
- __u8 *read_buffer = (__u8 *) ((uintptr_t)(handler->read_buffer + PAGESIZE) & ~((uintptr_t)PAGESIZE-1));
+ __u8 *read_buffer = (__u8 *) ((uintptr_t)(handler->read_buffer + PAGE_SIZE) & ~((uintptr_t)PAGE_SIZE-1));
/* Don't access any other fields of hdr or req beyond this point, the read buffer
* overlaps the request buffer and will clobber data in the request. This
@@ -1308,7 +1308,7 @@
struct fuse_write_out out;
struct handle *h = id_to_ptr(req->fh);
int res;
- __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGESIZE)));
+ __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGE_SIZE)));
if (req->flags & O_DIRECT) {
memcpy(aligned_buffer, buffer, req->size);
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 273b263..aa92af7 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -2,7 +2,7 @@
common_cflags := \
- -Werror -Wno-unused-parameter \
+ -Werror -Wno-unused-parameter -Wno-unused-const-variable \
-I$(LOCAL_PATH)/upstream-netbsd/include/ \
-include bsd-compatibility.h \