mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
148 lines
4.5 KiB
Python
Executable File
148 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2013 The Flutter Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
BUILDROOT_DIR = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', '..'))
|
|
|
|
PERFETTO_SESSION_KEY = 'session1'
|
|
PERFETTO_TRACE_FILE = '/data/misc/perfetto-traces/trace'
|
|
PERFETTO_CONFIG = """
|
|
write_into_file: true
|
|
file_write_period_ms: 1000000000
|
|
flush_period_ms: 1000
|
|
|
|
buffers: {
|
|
size_kb: 129024
|
|
}
|
|
data_sources: {
|
|
config {
|
|
name: "linux.ftrace"
|
|
ftrace_config {
|
|
ftrace_events: "ftrace/print"
|
|
atrace_apps: "%s"
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
|
|
def install_apk(apk_path, package_name, adb_path='adb'):
|
|
print('Installing APK')
|
|
subprocess.check_output([adb_path, 'shell', 'am', 'force-stop', package_name])
|
|
# Allowed to fail if APK was never installed.
|
|
subprocess.call([adb_path, 'uninstall', package_name], stdout=subprocess.DEVNULL)
|
|
subprocess.check_output([adb_path, 'install', apk_path])
|
|
|
|
|
|
def start_perfetto(package_name, adb_path='adb'):
|
|
print('Starting trace')
|
|
cmd = [
|
|
adb_path, 'shell', 'echo', "'" + PERFETTO_CONFIG % package_name + "'", '|', 'perfetto', '-c',
|
|
'-', '--txt', '-o', PERFETTO_TRACE_FILE, '--detach', PERFETTO_SESSION_KEY
|
|
]
|
|
|
|
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
|
|
|
|
|
|
def launch_package(package_name, activity_name, adb_path='adb'):
|
|
print('Scanning logcat')
|
|
subprocess.check_output([adb_path, 'logcat', '-c'], stderr=subprocess.STDOUT)
|
|
logcat = subprocess.Popen([adb_path, 'logcat'],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True)
|
|
|
|
print('Launching %s (%s)' % (package_name, activity_name))
|
|
subprocess.check_output([
|
|
adb_path, 'shell', 'am ', 'start', '-n',
|
|
'%s/%s' % (package_name, activity_name)
|
|
],
|
|
stderr=subprocess.STDOUT)
|
|
for line in logcat.stdout:
|
|
print('>>>>>>>> ' + line.strip())
|
|
if ('Observatory listening' in line) or ('Dart VM service is listening' in line):
|
|
logcat.kill()
|
|
break
|
|
|
|
|
|
def collect_and_validate_trace(adb_path='adb'):
|
|
print('Fetching trace')
|
|
subprocess.check_output([
|
|
adb_path, 'shell', 'perfetto', '--attach', PERFETTO_SESSION_KEY, '--stop'
|
|
],
|
|
stderr=subprocess.STDOUT)
|
|
subprocess.check_output([adb_path, 'pull', PERFETTO_TRACE_FILE, 'trace.pb'],
|
|
stderr=subprocess.STDOUT)
|
|
|
|
print('Validating trace')
|
|
traceconv = os.path.join(
|
|
BUILDROOT_DIR, 'flutter', 'third_party', 'android_tools', 'trace_to_text', 'trace_to_text'
|
|
)
|
|
traceconv_output = subprocess.check_output([traceconv, 'systrace', 'trace.pb'],
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True)
|
|
|
|
print('Trace output:')
|
|
print(traceconv_output)
|
|
|
|
if 'ShellSetupUISubsystem' in traceconv_output:
|
|
return 0
|
|
|
|
print('Trace did not contain ShellSetupUISubsystem, failing.')
|
|
return 1
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument(
|
|
'--apk-path', dest='apk_path', action='store', help='Provide the path to the APK to install'
|
|
)
|
|
parser.add_argument(
|
|
'--package-name',
|
|
dest='package_name',
|
|
action='store',
|
|
help='The package name of the APK, e.g. dev.flutter.scenarios'
|
|
)
|
|
parser.add_argument(
|
|
'--activity-name',
|
|
dest='activity_name',
|
|
action='store',
|
|
help='The activity to launch as it appears in AndroidManifest.xml, '
|
|
'e.g. .PlatformViewsActivity'
|
|
)
|
|
parser.add_argument(
|
|
'--adb-path',
|
|
dest='adb_path',
|
|
action='store',
|
|
default='adb',
|
|
help='Provide the path of adb used for android tests. '
|
|
'By default it looks on $PATH.'
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
android_api_level = subprocess.check_output([
|
|
args.adb_path, 'shell', 'getprop', 'ro.build.version.sdk'
|
|
],
|
|
text=True).strip()
|
|
if int(android_api_level) < 29:
|
|
print('Android API %s detected. This script requires API 29 or above.' % android_api_level)
|
|
return 0
|
|
|
|
install_apk(args.apk_path, args.package_name, args.adb_path)
|
|
start_perfetto(args.package_name, args.adb_path)
|
|
launch_package(args.package_name, args.activity_name, args.adb_path)
|
|
return collect_and_validate_trace(args.adb_path)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|