Merge "Enable Systrace to be used during boot."
diff --git a/agents/atrace_agent.py b/agents/atrace_agent.py
index 5ac96d9..c8288c8 100644
--- a/agents/atrace_agent.py
+++ b/agents/atrace_agent.py
@@ -30,6 +30,10 @@
TRACE_START_REGEXP = r'TRACE\:'
# Plain-text trace data should always start with this string.
TRACE_TEXT_HEADER = '# tracer'
+# The property name for switching on and off tracing during boot.
+BOOTTRACE_PROP = 'persist.debug.atrace.boottrace'
+# The file path for specifying categories to be traced during boot.
+BOOTTRACE_CATEGORIES = '/data/misc/boottrace/categories'
# This list is based on the tags in frameworks/native/include/utils/Trace.h for
# legacy platform.
@@ -53,7 +57,17 @@
device_sdk_version = util.get_device_sdk_version()
if device_sdk_version >= 18:
- return AtraceAgent(options, categories)
+ if options.boot:
+ # atrace --async_stop, which is used by BootAgent, does not work properly
+ # on the device SDK version 22 or before.
+ if device_sdk_version <= 22:
+ print >> sys.stderr, ('--boot option does not work on the device SDK '
+ 'version 22 or before.\nYour device SDK version '
+ 'is %d.' % device_sdk_version)
+ sys.exit(1)
+ return BootAgent(options, categories)
+ else:
+ return AtraceAgent(options, categories)
elif device_sdk_version >= 16:
return AtraceLegacyAgent(options, categories)
@@ -350,6 +364,50 @@
return extra_args
+class BootAgent(AtraceAgent):
+ """AtraceAgent that specializes in tracing the boot sequence."""
+
+ def __init__(self, options, categories):
+ super(BootAgent, self).__init__(options, categories)
+
+ def start(self):
+ try:
+ setup_args = self._construct_setup_command()
+ try:
+ subprocess.check_call(setup_args)
+ print 'Hit Ctrl+C once the device has booted up.'
+ while True:
+ time.sleep(1)
+ except KeyboardInterrupt:
+ pass
+ tracer_args = self._construct_trace_command()
+ self._adb = subprocess.Popen(tracer_args, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as error:
+ print >> sys.stderr, (
+ 'The command "%s" failed with the following error:' %
+ ' '.join(tracer_args))
+ print >> sys.stderr, ' ', error
+ sys.exit(1)
+
+ def _construct_setup_command(self):
+ echo_args = ['echo'] + self._categories + ['>', BOOTTRACE_CATEGORIES]
+ setprop_args = ['setprop', BOOTTRACE_PROP, '1']
+ reboot_args = ['reboot']
+ return util.construct_adb_shell_command(
+ echo_args + ['&&'] + setprop_args + ['&&'] + reboot_args,
+ self._options.device_serial)
+
+ def _construct_trace_command(self):
+ self._expect_trace = True
+ atrace_args = ['atrace', '--async_stop']
+ setprop_args = ['setprop', BOOTTRACE_PROP, '0']
+ rm_args = ['rm', BOOTTRACE_CATEGORIES]
+ return util.construct_adb_shell_command(
+ atrace_args + ['&&'] + setprop_args + ['&&'] + rm_args,
+ self._options.device_serial)
+
+
class FileReaderThread(threading.Thread):
"""Reads data from a file/pipe on a worker thread.
diff --git a/run_unittest.py b/run_unittest.py
index 66496ba..5c43322 100755
--- a/run_unittest.py
+++ b/run_unittest.py
@@ -28,6 +28,13 @@
LEGACY_TRACE_CMD = (ADB_SHELL + LEGACY_ATRACE_ARGS +
[';', 'ps', '-t'])
+SYSTRACE_BOOT_CMD = (['./systrace.py', '--boot', '-e', DEVICE_SERIAL] +
+ CATEGORIES)
+TRACE_BOOT_CMD = (ADB_SHELL +
+ ['atrace', '--async_stop', '&&', 'setprop',
+ 'persist.debug.atrace.boottrace', '0', '&&',
+ 'rm', '/data/misc/boottrace/categories'])
+
TEST_DIR = 'test_data/'
ATRACE_DATA = TEST_DIR + 'atrace_data'
ATRACE_DATA_RAW = TEST_DIR + 'atrace_data_raw'
@@ -131,5 +138,15 @@
self.assertEqual(' '.join(LEGACY_TRACE_CMD), ' '.join(tracer_args))
self.assertEqual(True, agent.expect_trace())
+
+class BootAgentUnitTest(unittest.TestCase):
+ def test_boot(self):
+ options, categories = systrace.parse_options(SYSTRACE_BOOT_CMD)
+ agent = atrace_agent.BootAgent(options, categories)
+ tracer_args = agent._construct_trace_command()
+ self.assertEqual(' '.join(TRACE_BOOT_CMD), ' '.join(tracer_args))
+ self.assertEqual(True, agent.expect_trace())
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/systrace.py b/systrace.py
index 38443fe..fdf895a 100755
--- a/systrace.py
+++ b/systrace.py
@@ -69,6 +69,10 @@
parser.add_option('--link-assets', dest='link_assets', default=False,
action='store_true',
help='(deprecated)')
+ parser.add_option('--boot', dest='boot', default=False, action='store_true',
+ help='reboot the device with tracing during boot enabled. '
+ 'The report is created by hitting Ctrl+C after the device '
+ 'has booted up.')
parser.add_option('--from-file', dest='from_file', action='store',
help='read the trace from a file (compressed) rather than '
'running a live trace')