From cef8cb45c1166a141cc9c20e56fc54f4cc0010b3 Mon Sep 17 00:00:00 2001 From: JohanBlome Date: Wed, 5 Jun 2024 15:03:58 -0700 Subject: [PATCH] metiq: change to devicectl for iOS >= 17 * older versions should work as before. * added a cli option "--bundleid" to set a bundle id which also will set idb mode imlicitly Signed-off-by: JohanBlome --- scripts/encapp.py | 96 +++++++++++++++++++++++++-------- scripts/encapp_tool/adb_cmds.py | 67 +++++++++++++++++------ 2 files changed, 124 insertions(+), 39 deletions(-) diff --git a/scripts/encapp.py b/scripts/encapp.py index fe798ea2..03635fd6 100755 --- a/scripts/encapp.py +++ b/scripts/encapp.py @@ -172,7 +172,7 @@ def wait_for_exit(serial, debug=0): state = "Running" while state == "Running": time.sleep(1) - # ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd(f"idb list-apps --fetch-process-state --udid {serial} | grep Meta.Encapp") + # ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd(f"idb list-apps --fetch-process-state --udid {serial} | grep {encapp_tool.adb_cmds.IDB_BUNDLE_ID}") # state = stdout.split("|")[4].strip() # Since the above does not work (not state info), let us look for the lock file if not encapp_tool.adb_cmds.file_exists_in_device("running.lock", serial): @@ -200,13 +200,21 @@ def run_encapp_test(protobuf_txt_filepath, serial, device_workdir, debug): if encapp_tool.adb_cmds.USE_IDB: # remove log file first ret, _, stderr = encapp_tool.adb_cmds.run_cmd( - f"idb file rm Documents/encapp.log --udid {serial} Meta.Encapp ", - debug, - ) - ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( - f"idb launch --udid {serial} Meta.Encapp " f"test {protobuf_txt_filepath}", + f"idb file rm Documents/encapp.log --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} ", debug, ) + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} " + f"test {protobuf_txt_filepath}", + debug, + ) + else: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} " + f"test {protobuf_txt_filepath}", + debug, + ) else: # clean the logcat first encapp_tool.adb_cmds.reset_logcat(serial) @@ -230,7 +238,7 @@ def collect_results( # There seems to be somethign fishy here which causes files to show up late # Not a problem if running a single file but multiple is a problem. Sleep... time.sleep(2) - cmd = f"idb file ls {device_workdir}/ --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file ls {device_workdir}/ --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" else: cmd = f"adb -s {serial} shell ls {device_workdir}/" ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd(cmd, debug) @@ -239,7 +247,14 @@ def collect_results( ) if encapp_tool.adb_cmds.USE_IDB: # Set app in standby so screen is not locked - cmd = (f"idb launch --udid {serial} Meta.Encapp standby",) + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + cmd = ( + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} standby", + ) + else: + cmd = ( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} standby", + ) encapp_tool.adb_cmds.run_cmd(cmd, debug) if debug > 0: print(f"outputfiles: {len(output_files)}") @@ -259,7 +274,7 @@ def collect_results( continue # pull the output file if encapp_tool.adb_cmds.USE_IDB: - cmd = f"idb file pull {device_workdir}/{file} {local_workdir} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/{file} {local_workdir} --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" else: cmd = f"adb -s {serial} pull {device_workdir}/{file} " f"{local_workdir}" encapp_tool.adb_cmds.run_cmd(cmd, debug) @@ -274,7 +289,7 @@ def collect_results( result_json.append(os.path.join(local_workdir, tmpname)) # remove/process the test file if encapp_tool.adb_cmds.USE_IDB: - cmd = f"idb file pull {device_workdir}/{protobuf_txt_filepath} {local_workdir} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/{protobuf_txt_filepath} {local_workdir} --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" else: cmd = f"adb -s {serial} shell rm " f"{device_workdir}/{protobuf_txt_filepath}" encapp_tool.adb_cmds.run_cmd(cmd, debug) @@ -285,15 +300,21 @@ def collect_results( # get logcat result_ok = False if encapp_tool.adb_cmds.USE_IDB: - cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" encapp_tool.adb_cmds.run_cmd(cmd, debug) # Release the app encapp_tool.app_utils.force_stop(serial) # Remove test output files - ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( - f"idb launch --udid {serial} Meta.Encapp reset", - debug, - ) + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} reset", + debug, + ) + else: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} reset", + debug, + ) # TODO: checks on ios result_ok = True return result_ok, result_json @@ -1028,7 +1049,7 @@ def run_codec_tests( "Currently filesystem synch on ios seems to be slow, sleep a little while" ) time.sleep(1) - cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" encapp_tool.adb_cmds.run_cmd(cmd, debug) try: os.rename( @@ -1048,7 +1069,14 @@ def run_codec_tests( # (b) one pbtxt for all tests # push all the files to the device workdir if encapp_tool.adb_cmds.USE_IDB: - cmd = f"idb launch --udid {serial} Meta.Encapp standby" + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + cmd = ( + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} standby", + ) + else: + cmd = ( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} standby", + ) encapp_tool.adb_cmds.run_cmd(cmd) protobuf_txt_filepath = "" @@ -1081,7 +1109,7 @@ def run_codec_tests( "Currently filesystem synch on ios seems to be slow, sleep a little while" ) time.sleep(1) - cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/encapp.log {local_workdir} --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" encapp_tool.adb_cmds.run_cmd(cmd, debug) try: os.rename( @@ -1104,11 +1132,19 @@ def list_codecs(serial, model, device_workdir, debug=0): model_clean = model.replace(" ", "_") filename = f"codecs_{model_clean}.txt" if encapp_tool.adb_cmds.USE_IDB: - cmd = {f"idb launch --udid {serial} Meta.Encapp list_codecs"} + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + cmd = { + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} list_codecs" + } + else: + cmd = ( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} list_codecs", + ) + # cmd = {f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} list_codecs"} ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd(cmd, debug) assert ret, 'error getting codec list: "%s"' % stdout # for some bizzare reason if using a destination a directory is created... - cmd = f"idb file pull {device_workdir}/codecs.txt . --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {device_workdir}/codecs.txt . --udid {serial} --bundle-id {encapp_tool.adb_cmds.IDB_BUNDLE_ID}" ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd(cmd, debug) cmd = f"mv codecs.txt {filename}" @@ -1470,6 +1506,12 @@ def __call__(self, parser, options, values, option_string=None): default=False, help="Do not execute the tests. Just prepare the test(s).", ) + parser.add_argument( + "--bundleid", + type=str, + default=None, + help="Implicitly it will turn on IDB option", + ) options = parser.parse_args(argv[1:]) options.desc = "testing" @@ -1488,6 +1530,9 @@ def __call__(self, parser, options, values, option_string=None): def process_options(options): # 0. Set device type and workdir + if options.bundleid: + encapp_tool.adb_cmds.set_bundleid(options.bundleid) + options.idb = True encapp_tool.adb_cmds.set_idb_mode(options.idb) default_values["device_workdir"] = get_device_dir() @@ -1730,9 +1775,14 @@ def main(argv): if options.func == "reset": print("Removes all encapp_* files in target folder") # idb is to slow so let us use the app - ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( - f"idb launch --udid {serial} Meta.Encapp reset" - ) + if encapp_tool.adb_cmds.IOS_MAJOR_VERSION < 17: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"idb launch --udid {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} reset" + ) + else: + ret, stdout, stderr = encapp_tool.adb_cmds.run_cmd( + f"xcrun devicectl device process launch --device {serial} {encapp_tool.adb_cmds.IDB_BUNDLE_ID} reset", + ) return if options.func == "pull_result": diff --git a/scripts/encapp_tool/adb_cmds.py b/scripts/encapp_tool/adb_cmds.py index 4059391d..536531f9 100644 --- a/scripts/encapp_tool/adb_cmds.py +++ b/scripts/encapp_tool/adb_cmds.py @@ -9,6 +9,9 @@ ENCAPP_OUTPUT_FILE_NAME_RE = r"encapp_.*" USE_IDB = False +IDB_BUNDLE_ID = "Meta.Encapp" +IOS_VERSION_NAME = "" +IOS_MAJOR_VERSION = -1 def run_cmd(cmd: str, debug: int = 0) -> typing.Tuple[bool, str, str]: @@ -78,6 +81,14 @@ def get_device_info( if debug > 0: print(f"selecting device: serial: {serial} model: {model}") + if USE_IDB: + global IOS_VERSION, IOS_MAJOR_VERSION + IOS_VERSION = device_info[serial]["version"] + # iOS 17.3.1 + m = re.search(r"([\d]+)\.([\d]+)\.([\d]+)", IOS_VERSION) + if m: + IOS_MAJOR_VERSION = int(m.group(1)) + return model, serial @@ -93,14 +104,14 @@ def remove_files_using_regex( debug (int): Debug level """ if USE_IDB: - cmd = f"idb file ls {location} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file ls {location} --udid {serial} --bundle-id {IDB_BUNDLE_ID}" _, stdout, _ = run_cmd(cmd, debug) output_files = re.findall(regex_str, stdout, re.MULTILINE) counter = 1 for file in output_files: # remove the output print(f"Removing {counter}/{len(output_files)}", end="\r") - cmd = f"idb file rm {location}/{file} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file rm {location}/{file} --udid {serial} --bundle-id {IDB_BUNDLE_ID}" run_cmd(cmd, debug) counter += 1 else: @@ -177,14 +188,23 @@ def get_app_pid(serial: str, package_name: str, debug=0): -1 if process not running; -2 if fail to process. """ pid = -1 - adb_cmd = f"adb -s {serial} shell pidof {package_name}" - ret, stdout, _ = run_cmd(adb_cmd, debug) - if ret is True and stdout: - try: - pid = int(stdout) - except ValueError: - print(f'Unable to cast stdout: "{stdout}" to int') - pid = -2 + if USE_IDB: + # This is only for >= V17 but lower version do not need the pid (at this point) + cmd = f" xcrun devicectl device info processes --device {serial} | grep Encapp.app" + ret, stdout, _ = run_cmd(cmd, debug) + if ret and stdout: + m = re.search(r"^[0-9]*", stdout) + if m: + pid = int(m.group(0)) + else: + adb_cmd = f"adb -s {serial} shell pidof {package_name}" + ret, stdout, _ = run_cmd(adb_cmd, debug) + if ret is True and stdout: + try: + pid = int(stdout) + except ValueError: + print(f'Unable to cast stdout: "{stdout}" to int') + pid = -2 return pid @@ -302,7 +322,17 @@ def force_stop(serial: str, package: str, debug=0): debug (int): Debug level """ if USE_IDB: - run_cmd(f"idb terminate --udid {serial} Meta.Encapp", debug) + # for iso 17 devicectl needs to be used and it cannot terminate an application directly + # lookup pid and send sigterm + if IOS_MAJOR_VERSION < 17: + run_cmd(f"idb terminate --udid {serial} {IDB_BUNDLE_ID}", debug) + else: + pid = get_app_pid(serial, package, debug) + if pid > 0: + run_cmd( + f"xcrun devicectl device process signal --signal sigterm --device {serial} --pid {pid} ", + debug, + ) else: run_cmd(f"adb -s {serial} shell am force-stop {package}", debug) @@ -494,7 +524,7 @@ def get_host_hash(filepath, debug): def file_exists_in_device(filename, serial, debug=False): if USE_IDB: - cmd = f"idb file ls /Documents --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file ls /Documents --udid {serial} --bundle-id {IDB_BUNDLE_ID}" _, stdout, _ = run_cmd(cmd, debug) output_files = re.findall(f"{filename}", stdout, re.MULTILINE) return len(output_files) > 0 @@ -508,7 +538,7 @@ def file_already_in_device(host_filepath, serial, device_filepath, fast_copy, de if USE_IDB and fast_copy: # TODO: fix basename = os.path.basename(device_filepath) - cmd = f"idb file ls Documents --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file ls Documents --udid {serial} --bundle-id {IDB_BUNDLE_ID}" _, stdout, _ = run_cmd(cmd, debug) output_files = re.findall(f"{basename}", stdout, re.MULTILINE) return len(output_files) > 0 @@ -548,7 +578,7 @@ def push_file_to_device(filepath, serial, device_workdir, fast_copy, debug): if file_already_in_device(filepath, serial, device_filepath, fast_copy, debug): return True ret, stdout, _ = run_cmd( - f"idb file push {filepath} {device_workdir}/ --udid {serial} --bundle-id Meta.Encapp", + f"idb file push {filepath} {device_workdir}/ --udid {serial} --bundle-id {IDB_BUNDLE_ID}", debug, ) if not ret: @@ -570,13 +600,13 @@ def pull_files_from_device( ) -> None: if USE_IDB: - cmd = f"idb file ls {location} --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file ls {location} --udid {serial} --bundle-id {IDB_BUNDLE_ID}" _, stdout, _ = run_cmd(cmd, debug) output_files = re.findall(regex_str, stdout, re.MULTILINE) counter = 1 for file in output_files: print(f"Pulling {counter}/{len(output_files)}", end="\r") - cmd = f"idb file pull {location}/{file} . --udid {serial} --bundle-id Meta.Encapp" + cmd = f"idb file pull {location}/{file} . --udid {serial} --bundle-id {IDB_BUNDLE_ID}" run_cmd(cmd, debug) counter += 1 else: @@ -598,3 +628,8 @@ def set_idb_mode(mode): def is_using_idb(): global USE_IDB return USE_IDB + + +def set_bundleid(bundleid): + global IDB_BUNDLE_ID + IDB_BUNDLE_ID = bundleid