add support for legacy (pre-4.3) platform
It seems systrace-legacy.py had not maintained for a while and has some
bugs and missing features.
So implement atrace_legacy_agent to use legacy platforms.
Change-Id: I9a60c4d9899cff5d088d00c8be643493fc163272
Signed-off-by: Young-Ho Cha <ganadist@gmail.com>
diff --git a/agents/atrace_agent.py b/agents/atrace_agent.py
index f01ce51..5ac96d9 100644
--- a/agents/atrace_agent.py
+++ b/agents/atrace_agent.py
@@ -31,9 +31,31 @@
# Plain-text trace data should always start with this string.
TRACE_TEXT_HEADER = '# tracer'
+# This list is based on the tags in frameworks/native/include/utils/Trace.h for
+# legacy platform.
+LEGACY_TRACE_TAG_BITS = (
+ ('gfx', 1<<1),
+ ('input', 1<<2),
+ ('view', 1<<3),
+ ('webview', 1<<4),
+ ('wm', 1<<5),
+ ('am', 1<<6),
+ ('sm', 1<<7),
+ ('audio', 1<<8),
+ ('video', 1<<9),
+ ('camera', 1<<10),
+)
+
def try_create_agent(options, categories):
- return AtraceAgent(options, categories)
+ if options.from_file is not None:
+ return AtraceAgent(options, categories)
+
+ device_sdk_version = util.get_device_sdk_version()
+ if device_sdk_version >= 18:
+ return AtraceAgent(options, categories)
+ elif device_sdk_version >= 16:
+ return AtraceLegacyAgent(options, categories)
class AtraceAgent(systrace_agent.SystraceAgent):
@@ -69,6 +91,23 @@
def get_class_name(self):
return 'trace-data'
+ def _construct_list_categories_command(self):
+ return util.construct_adb_shell_command(
+ LIST_CATEGORIES_ARGS, self._options.device_serial)
+
+ def _construct_extra_trace_command(self):
+ extra_args = []
+ if self._options.app_name is not None:
+ extra_args.extend(['-a', self._options.app_name])
+
+ if self._options.kfuncs is not None:
+ extra_args.extend(['-k', self._options.kfuncs])
+
+ if not self._categories:
+ self._categories = get_default_categories(self._options.device_serial)
+ extra_args.extend(self._categories)
+ return extra_args
+
def _construct_trace_command(self):
"""Builds a command-line used to invoke a trace process.
@@ -78,14 +117,13 @@
stream trace data.
"""
if self._options.list_categories:
- tracer_args = util.construct_adb_shell_command(
- LIST_CATEGORIES_ARGS, self._options.device_serial)
+ tracer_args = self._construct_list_categories_command()
self._expect_trace = False
elif self._options.from_file is not None:
tracer_args = ['cat', self._options.from_file]
self._expect_trace = True
else:
- atrace_args = ATRACE_BASE_ARGS
+ atrace_args = ATRACE_BASE_ARGS[:]
self._expect_trace = True
if self._options.compress_trace_data:
atrace_args.extend(['-z'])
@@ -97,16 +135,8 @@
if ((self._options.trace_buf_size is not None)
and (self._options.trace_buf_size > 0)):
atrace_args.extend(['-b', str(self._options.trace_buf_size)])
-
- if self._options.app_name is not None:
- atrace_args.extend(['-a', self._options.app_name])
-
- if self._options.kfuncs is not None:
- atrace_args.extend(['-k', self._options.kfuncs])
-
- if not self._categories:
- self._categories = get_default_categories(self._options.device_serial)
- atrace_args.extend(self._categories)
+ extra_args = self._construct_extra_trace_command()
+ atrace_args.extend(extra_args)
if self._options.fix_threads:
atrace_args.extend([';', 'ps', '-t'])
@@ -262,6 +292,64 @@
return trace_data
+class AtraceLegacyAgent(AtraceAgent):
+ def _construct_list_categories_command(self):
+ LEGACY_CATEGORIES = """ sched - CPU Scheduling
+ freq - CPU Frequency
+ idle - CPU Idle
+ load - CPU Load
+ disk - Disk I/O (requires root)
+ bus - Bus utilization (requires root)
+ workqueue - Kernel workqueues (requires root)"""
+ return ["echo", LEGACY_CATEGORIES]
+
+ def start(self):
+ super(AtraceLegacyAgent, self).start()
+ if self.expect_trace():
+ SHELL_ARGS = ['getprop', 'debug.atrace.tags.enableflags']
+ output, return_code = util.run_adb_shell(SHELL_ARGS, self._options.device_serial)
+ flags = 0
+ if return_code == 0:
+ try:
+ if output.startswith('0x'):
+ flags = int(output, 16)
+ elif output.startswith('0'):
+ flags = int(output, 8)
+ else:
+ flags = int(output)
+ except ValueError, e:
+ pass
+
+ if flags:
+ tags = []
+ for desc, bit in LEGACY_TRACE_TAG_BITS:
+ if bit & flags:
+ tags.append(desc)
+ categories = tags + self._categories
+ print 'Collecting data with following categories:', ' '.join(categories)
+
+ def _construct_extra_trace_command(self):
+ extra_args = []
+ if not self._categories:
+ self._categories = ['sched', ]
+ if 'sched' in self._categories:
+ extra_args.append('-s')
+ if 'freq' in self._categories:
+ extra_args.append('-f')
+ if 'idle' in self._categories:
+ extra_args.append('-i')
+ if 'load' in self._categories:
+ extra_args.append('-l')
+ if 'disk' in self._categories:
+ extra_args.append('-d')
+ if 'bus' in self._categories:
+ extra_args.append('-u')
+ if 'workqueue' in self._categories:
+ extra_args.append('-w')
+
+ return extra_args
+
+
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 db1b95e..98f5628 100755
--- a/run_unittest.py
+++ b/run_unittest.py
@@ -50,7 +50,7 @@
class AtraceAgentUnitTest(unittest.TestCase):
def test_construct_trace_command(self):
options, categories = systrace.parse_options(SYSTRACE_CMD)
- agent = atrace_agent.try_create_agent(options, categories)
+ agent = atrace_agent.AtraceAgent(options, categories)
tracer_args = agent._construct_trace_command()
self.assertEqual(' '.join(TRACE_CMD), ' '.join(tracer_args))
self.assertEqual(True, agent.expect_trace())
@@ -98,13 +98,13 @@
atrace_data = f2.read()
options, categories = systrace.parse_options([])
- agent = atrace_agent.try_create_agent(options, categories)
+ agent = atrace_agent.AtraceAgent(options, categories)
trace_data = agent._preprocess_trace_data(atrace_data_with_thread_list)
self.assertEqual(atrace_data, trace_data)
def test_list_categories(self):
options, categories = systrace.parse_options(SYSTRACE_LIST_CATEGORIES_CMD)
- agent = atrace_agent.try_create_agent(options, categories)
+ agent = atrace_agent.AtraceAgent(options, categories)
tracer_args = agent._construct_trace_command()
self.assertEqual(' '.join(TRACE_LIST_CATEGORIES_CMD), ' '.join(tracer_args))
self.assertEqual(False, agent.expect_trace())
diff --git a/systrace.py b/systrace.py
index e25ef77..38443fe 100755
--- a/systrace.py
+++ b/systrace.py
@@ -167,16 +167,9 @@
def main():
- device_sdk_version = util.get_device_sdk_version()
- if device_sdk_version < 18:
- legacy_script = os.path.join(os.path.dirname(sys.argv[0]),
- 'systrace-legacy.py')
- # execv() does not return.
- os.execv(legacy_script, sys.argv)
-
options, categories = parse_options(sys.argv)
-
agents = create_agents(options, categories)
+
if not agents:
dirs = DEFAULT_AGENT_DIR
if options.agent_dirs: