1import argparse 2from importlib import resources 3import os 4import subprocess 5import sys 6import tempfile 7import time 8import config_pb2 9import google.protobuf.text_format as text_format 10 11kwargs = { 12 "text": True, 13 "shell": True, 14 "capture_output": True, 15 "check": True, 16} 17 18 19def adb_root(): 20 subprocess.run("adb root", **kwargs) 21 22 23def create_and_push_config_proto(name="test_slog"): 24 with resources.open_text("test", f"{name}.textproto") as textproto: 25 message = text_format.Parse( 26 textproto.read(), config_pb2.UprobestatsConfig() 27 ) 28 textproto.close() 29 30 with tempfile.NamedTemporaryFile() as temp: 31 temp.write(message.SerializeToString()) 32 temp.flush() 33 print(f"creating {name}") 34 config_cmd = ( 35 f"adb push {temp.name} /data/misc/uprobestats-configs/config" 36 ) 37 subprocess.run(config_cmd, **kwargs) 38 39 40def clear_logcat(): 41 print("clearing logcat") 42 subprocess.run("adb logcat -c", **kwargs) 43 44 45def start_uprobestats(run_as_shell=False): 46 if (run_as_shell): 47 print("starting uprobestats as Shell") 48 subprocess.run( 49 f"adb shell /apex/com.android.uprobestats/bin/uprobestats", **kwargs) 50 else: 51 print("starting uprobestats") 52 subprocess.run( 53 f"adb shell setprop ctl.start uprobestats", **kwargs) 54 55def get_ring_buffer_values(): 56 time.sleep(10) 57 lines = subprocess.run( 58 'adb logcat -d | grep "ringbuf result callback. value:"', **kwargs 59 ).stdout.splitlines() 60 for line in lines: 61 print(line) 62 63 64def get_ring_buffer_size(): 65 # print('generating log messages and fetching ring buffer size') 66 # subprocess.run('adb shell killall com.google.android.apps.photos', shell=True) 67 # time.sleep(2) 68 # subprocess.run( 69 # 'adb shell monkey -p com.google.android.apps.photos -c' 70 # ' android.intent.category.LAUNCHER 1', 71 # **kwargs, 72 # ) 73 ring_buffer_size = ( 74 subprocess.run( 75 'adb logcat -d | grep "uprobestats: ring buffer size"', **kwargs 76 ) 77 .stdout.splitlines()[0] 78 .split(":")[4] 79 .split(" ")[1] 80 .strip() 81 ) 82 83 print(f"ring buffer size: {ring_buffer_size}") 84 return int(ring_buffer_size, 0) 85 86 87if __name__ == "__main__": 88 parser = argparse.ArgumentParser( 89 "Drops a uprobestats config over adb and checks start it. Optionally acts" 90 " as a test by checking logcat output" 91 ) 92 parser.add_argument( 93 "-n", 94 "--name", 95 type=str, 96 default="test_slog", 97 help="Name of the config file e.g. test_slog", 98 ) 99 parser.add_argument( 100 "-t", 101 "--test", 102 default=False, 103 action="store_true", 104 help=( 105 "Run a test, meaning start uprobestats and then look for particular" 106 " logcat output to exit successfully" 107 ), 108 ) 109 parser.add_argument( 110 "-s", 111 action="store_true", # Store True if the flag is present 112 help="Run uprobestats as Shell", 113) 114 args = parser.parse_args() 115 116 adb_root() 117 create_and_push_config_proto(args.name) 118 119 if not args.test: 120 start_uprobestats(args.s) 121 sys.exit(0) 122 123 clear_logcat() 124 start_uprobestats(args.s) 125 time.sleep(60) 126 ring_buf = get_ring_buffer_size() 127 get_ring_buffer_values() 128 if ring_buf > 0: 129 sys.exit(0) 130 else: 131 raise SystemExit("Did not find a ring buffer greater than zero") 132