1#!/usr/bin/env vpython3 2# 3# Copyright 2013 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Command line tool for forwarding ports from a device to the host. 8 9Allows an Android device to connect to services running on the host machine, 10i.e., "adb forward" in reverse. Requires |host_forwarder| and |device_forwarder| 11to be built. 12""" 13 14import argparse 15import sys 16import time 17 18import devil_chromium 19 20from devil.android import device_denylist 21from devil.android import device_utils 22from devil.android import forwarder 23from devil.utils import run_tests_helper 24 25from pylib import constants 26 27 28def main(argv): 29 parser = argparse.ArgumentParser( 30 usage='Usage: %(prog)s [options] device_port ' 31 'host_port [device_port_2 host_port_2] ...', 32 description=__doc__) 33 parser.add_argument( 34 '-v', '--verbose', 35 dest='verbose_count', 36 default=0, 37 action='count', 38 help='Verbose level (multiple times for more)') 39 parser.add_argument( 40 '--device', 41 help='Serial number of device we should use.') 42 parser.add_argument('--denylist-file', help='Device denylist JSON file.') 43 parser.add_argument( 44 '--debug', 45 action='store_const', 46 const='Debug', 47 dest='build_type', 48 default='Release', 49 help='DEPRECATED: use --output-directory instead.') 50 parser.add_argument( 51 '--output-directory', 52 help='Path to the root build directory.') 53 parser.add_argument( 54 'ports', 55 nargs='+', 56 type=int, 57 help='Port pair to reverse forward.') 58 59 args = parser.parse_args(argv) 60 run_tests_helper.SetLogLevel(args.verbose_count) 61 62 if len(args.ports) < 2 or len(args.ports) % 2: 63 parser.error('Need even number of port pairs') 64 65 port_pairs = list(zip(args.ports[::2], args.ports[1::2])) 66 67 if args.build_type: 68 constants.SetBuildType(args.build_type) 69 if args.output_directory: 70 constants.SetOutputDirectory(args.output_directory) 71 devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) 72 73 denylist = (device_denylist.Denylist(args.denylist_file) 74 if args.denylist_file else None) 75 device = device_utils.DeviceUtils.HealthyDevices(denylist=denylist, 76 device_arg=args.device)[0] 77 try: 78 forwarder.Forwarder.Map(port_pairs, device) 79 while True: 80 time.sleep(60) 81 except KeyboardInterrupt: 82 sys.exit(0) 83 finally: 84 forwarder.Forwarder.UnmapAllDevicePorts(device) 85 86if __name__ == '__main__': 87 sys.exit(main(sys.argv[1:])) 88