1# 2# Copyright (C) 2024 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# 16 17import argparse 18import os 19import signal 20import subprocess 21import sys 22import time 23 24def path_exists(path: str): 25 if path is None: 26 return False 27 return os.path.exists(os.path.expanduser(path)) 28 29def dir_exists(path: str): 30 if path is None: 31 return False 32 return os.path.isdir(os.path.expanduser(path)) 33 34def convert_simpleperf_to_gecko(scripts_path, host_raw_trace_filename, 35 host_gecko_trace_filename, symbols): 36 expanded_symbols = os.path.expanduser(symbols) 37 expanded_scripts_path = os.path.expanduser(scripts_path) 38 print("Building binary cache, please wait. If no samples were recorded," 39 " the trace will be empty.") 40 subprocess.run(("%s/binary_cache_builder.py -i %s -lib %s" 41 % (expanded_scripts_path, host_raw_trace_filename, 42 expanded_symbols)), 43 shell=True) 44 subprocess.run(("%s/gecko_profile_generator.py -i %s > %s" 45 % (expanded_scripts_path, host_raw_trace_filename, 46 host_gecko_trace_filename)), 47 shell=True) 48 if not path_exists(host_gecko_trace_filename): 49 raise Exception("Gecko file was not created.") 50 51def wait_for_process_or_ctrl_c(process): 52 def signal_handler(sig, frame): 53 print("Exiting...") 54 process.kill() 55 sys.exit() 56 57 signal.signal(signal.SIGINT, signal_handler) 58 signal.signal(signal.SIGTERM, signal_handler) 59 60 process.wait() 61 print("Process was killed.") 62 63def wait_for_output(pattern, process, timeout): 64 start_time = time.time() 65 while time.time() - start_time < timeout: 66 line = process.stdout.readline() 67 if pattern in line.decode(): 68 process.stderr = None 69 return False 70 return True # Timed out 71 72def set_default_subparser(self, name): 73 """ 74 A hack to add a default subparser to an argparse.ArgumentParser 75 class. This will add the default subparser after all the global 76 options in sys.argv. 77 78 NOTE: Only works properly if all the global options have the 79 'nargs' argument set to an integer. 80 """ 81 subparser_found = False 82 insertion_idx = 1 83 84 # Get all global options 85 global_opts = {} 86 for action in self._actions: 87 for opt in action.option_strings: 88 global_opts[opt] = action.nargs 89 90 for idx, arg in enumerate(sys.argv[1:]): 91 if arg in ['-h', '--help']: 92 break 93 if arg in global_opts: 94 insertion_idx = idx + global_opts[arg] + 2 95 else: 96 for action in self._subparsers._actions: 97 if not isinstance(action, argparse._SubParsersAction): 98 continue 99 for sp_name in action._name_parser_map.keys(): 100 if sp_name in sys.argv[1:]: 101 subparser_found = True 102 if not subparser_found: 103 # insert default subparser 104 sys.argv.insert(insertion_idx, name) 105