1#!/usr/bin/env python3 2# 3# Copyright (C) 2023 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import argparse 19import os 20import subprocess 21import sys 22 23def subprocess_run(command, shell=True): 24 try: 25 print(f'subprocess run {command}') 26 result = subprocess.run(command, shell=shell, stdout=subprocess.PIPE, check=True) 27 except Exception as e: 28 raise Exception(f'Execution error for {command}: {e}') 29 30 return result.stdout.decode('utf-8') 31 32def adb_run(ip, cmd): 33 if cmd == ['connect']: 34 adb_cmd = ['adb', 'connect', ip] 35 else: 36 adb_cmd = ['adb', '-s', ip] + cmd 37 return subprocess_run(adb_cmd, False) 38 39def prepare_qnx(tracing_dir, qnx_dev_dir, qnx_ip, filepath): 40 source_file = os.path.join(tracing_dir, 'tooling', 'qnx_perfetto.py') 41 target_file = os.path.join(qnx_dev_dir, 'qnx_perfetto.py') 42 try: 43 os.symlink(source_file, target_file) 44 except FileExistsError: 45 print(f"Symbolic link creation failed: {target_file} already exists.") 46 except Exception as e: 47 sys.exit(f"An error occurred: {type(e).__name__}: {e}") 48 49 # setup qnx environment source qnxsdp-env.sh 50 qnx_env_file = os.path.join(qnx_dev_dir, "qnxsdp-env.sh") 51 clock_util = 'QnxClocktime' 52 command = f'source {qnx_env_file} && qcc -Vgcc_ntoaarch64le {filepath} -o {clock_util}' 53 subprocess_run(command) 54 55 command = f'scp -F /dev/null {clock_util} root@{qnx_ip}:/bin/' 56 subprocess_run(command) 57 58def prepare_android(serial_num, aaos_time_util): 59 adb_run(serial_num, ['connect']) 60 adb_run(serial_num, ['root']) 61 adb_run(serial_num, ['remount']) 62 63 command = ['push', aaos_time_util, '/vendor/bin/android.automotive.time_util'] 64 adb_run(serial_num, command) 65 66def parse_arguments(): 67 parser = argparse.ArgumentParser( 68 prog = 'prepare_tracing.py', 69 description='Setup environment and tools for cross-VM Android tracing') 70 parser.add_argument('--host_ip', required=True, 71 help = 'host IP address') 72 parser.add_argument('--qnx_dev_dir', required=True, 73 help = 'QNX SDK Directory') 74 parser.add_argument('--tracing_tool_dir', required=True, 75 help = 'Tracing Tool Directory Path') 76 # One can build Anroid time utility function with source code and locates at: 77 # ./target/product/trout_arm64/vendor/bin/android.automotive.time_util 78 parser.add_argument('--aaos_time_util', help = 'Android Clock Executable File') 79 parser.add_argument('--guest_serial', required='--aaos_time_util' in sys.argv, 80 help = 'Guest VM serial number. Required argument if --aaos_time_util is set') 81 return parser.parse_args() 82 83def main(): 84 args = parse_arguments() 85 86 clock_file_path = os.path.join(args.tracing_tool_dir, "time_utility", "ClocktimeMain.cpp") 87 prepare_qnx(args.tracing_tool_dir, args.qnx_dev_dir, args.host_ip, clock_file_path) 88 89 if args.aaos_time_util: 90 prepare_android(args.guest_serial, args.aaos_time_util) 91 92if __name__ == '__main__': 93 main() 94