blob: 8cd27f69d0e77881293532ae43fdf0611068ddbf [file] [log] [blame]
Hector Dearman355d7ba2017-10-24 15:44:43 +01001#!/usr/bin/env python
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import print_function
17import argparse
18import datetime
19import os
20import subprocess
21import sys
22
23"""Pulls all format files from an Android device.
24
25Usage: ./tools/pull_ftrace_format_files.py [-s serial] [-p directory_prefix]
26"""
27
28ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
29ADB_PATH = os.path.join(ROOT_DIR, 'buildtools/android_sdk/platform-tools/adb')
30
31def adb(*cmd, **kwargs):
32 serial = kwargs.get('serial', None)
33 prefix = [ADB_PATH]
34 if serial:
35 prefix += ['-s', serial]
36 cmd = prefix + list(cmd)
37 output = subprocess.check_output(cmd)
38 return output
39
40
41def get_devices():
42 # adb devices output looks like:
43 # List of devices attached
44 # 557dccd8\tdevice
45 # With a trailing newline.
46 serials = [s.split('\t')[0] for s in adb('devices').split('\n')[1:] if s]
47 return serials
48
49
50def ensure_output_directory_empty(path):
51 if os.path.isfile(path):
52 print('The output directory {} exists as a file.'.format(path))
53 sys.exit(1)
54
55 if os.path.isdir(path) and os.listdir(path):
56 print('The output directory {} exists but is not empty.'.format(path))
57 sys.exit(1)
58
59 if not os.path.isdir(path):
60 os.makedirs(path)
61
62
63def ensure_dir(path):
64 try:
65 os.makedirs(path)
66 except OSError:
67 if not os.path.isdir(path):
68 raise
69
70
71def ensure_single_device(serial):
72 serials = get_devices()
73 if serial is None and len(serials) == 1:
74 return serials[0]
75
76 if serial in serials:
77 return serial
78
79 if not serials:
80 print('No devices connected.')
81 elif serial is None:
82 print('More than one device connected, use -s.')
83 else:
84 print('No device with serial {} found.'.format(serial))
85 sys.exit(1)
86
87
88def pull_format_files(serial, output_directory):
89 # Pulling each file individually is 100x slower so we pipe all together then
90 # split them on the host.
91 cmd = "find /sys/kernel/debug/tracing/events/ " \
92 "-name format -o " \
93 "-name header_event -o " \
94 "-name header_page | " \
95 "while read f; do echo 'path:' $f; cat $f; done"
96
97 output = adb('shell', cmd, serial=serial)
98 sections = output.split('path: /sys/kernel/debug/tracing/events/')
99 for section in sections:
100 if not section:
101 continue
102 path, rest = section.split('\n', 1)
103 path = os.path.join(output_directory, path)
104 ensure_dir(os.path.dirname(path))
105 with open(path, 'wb') as f:
106 f.write(rest)
107
108
109# Produces output of the form: prefix_android_seed_N2F62_3.10.49
110def get_output_directory(prefix=None):
111 build_id = adb('shell', 'getprop', 'ro.build.id').replace('\n', '')
112 product = adb('shell', 'getprop', 'ro.build.product').replace('\n', '')
113 kernel = adb('shell', 'uname', '-r').split('-')[0]
114 parts = ['android', product, build_id, kernel]
115 if prefix:
116 parts = [prefix] + parts
117 return '_'.join(parts)
118
119
120def main():
121 parser = argparse.ArgumentParser(description='Pull format files.')
122 parser.add_argument('-p', dest='prefix', default=None,
123 help='the output directory prefix')
124 parser.add_argument('-s', dest='serial', default=None,
125 help='use device with the given serial')
126 args = parser.parse_args()
127
128 prefix = args.prefix
129 serial = args.serial
130
131 serial = ensure_single_device(serial)
132 output_directory = get_output_directory(prefix)
133
134 ensure_output_directory_empty(output_directory)
135 pull_format_files(serial, output_directory)
136
137 return 0
138
139
140if __name__ == '__main__':
141 sys.exit(main())
142