summaryrefslogtreecommitdiff
path: root/systrace/catapult/devil/devil/utils/battor_device_mapping.py
diff options
context:
space:
mode:
Diffstat (limited to 'systrace/catapult/devil/devil/utils/battor_device_mapping.py')
-rwxr-xr-xsystrace/catapult/devil/devil/utils/battor_device_mapping.py309
1 files changed, 0 insertions, 309 deletions
diff --git a/systrace/catapult/devil/devil/utils/battor_device_mapping.py b/systrace/catapult/devil/devil/utils/battor_device_mapping.py
deleted file mode 100755
index 8cabb83..0000000
--- a/systrace/catapult/devil/devil/utils/battor_device_mapping.py
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/python
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-'''
-This script provides tools to map BattOrs to phones.
-
-Phones are identified by the following string:
-
-"Phone serial number" - Serial number of the phone. This can be
-obtained via 'adb devices' or 'usb-devices', and is not expected
-to change for a given phone.
-
-BattOrs are identified by the following two strings:
-
-"BattOr serial number" - Serial number of the BattOr. This can be
-obtained via 'usb-devices', and is not expected to change for
-a given BattOr.
-
-"BattOr path" - The path of the form '/dev/ttyUSB*' that is used
-to communicate with the BattOr (the battor_agent binary takes
-this BattOr path as a parameter). The BattOr path is frequently
-reassigned by the OS, most often when the device is disconnected
-and then reconnected. Thus, the BattOr path cannot be expected
-to be stable.
-
-In a typical application, the user will require the BattOr path
-for the BattOr that is plugged into a given phone. For instance,
-the user will be running tracing on a particular phone, and will
-need to know which BattOr path to use to communicate with the BattOr
-to get the corresponding power trace.
-
-Getting this mapping requires two steps: (1) determining the
-mapping between phone serial numbers and BattOr serial numbers, and
-(2) getting the BattOr path corresponding to a given BattOr serial
-number.
-
-For step (1), we generate a JSON file giving this mapping. This
-JSON file consists of a list of items of the following form:
-[{'phone': <phone serial 1>, 'battor': <battor serial 1>},
-{'phone': <phone serial 2>, 'battor': <battor serial 2>}, ...]
-
-The default way to generate this JSON file is using the function
-GenerateSerialMapFile, which generates a mapping based on assuming
-that the system has two identical USB hubs connected to it, and
-the phone plugged into physical port number 1 on one hub corresponds
-to the BattOr plugged into physical port number 1 on the other hub,
-and similarly with physical port numbers 2, 3, etc. This generates
-the map file based on the structure at the time GenerateSerialMapFile called.
-Note that after the map file is generated, port numbers are no longer used;
-the user could move around the devices in the ports without affecting
-which phone goes with which BattOr. (Thus, if the user wanted to update the
-mapping to match the new port connections, the user would have to
-re-generate this file.)
-
-The script update_mapping.py will do this updating from the command line.
-
-If the user wanted to specify a custom mapping, the user could instead
-create the JSON file manually. (In this case, hubs would not be necessary
-and the physical ports connected would be irrelevant.)
-
-Step (2) is conducted through the function GetBattOrPathFromPhoneSerial,
-which takes a serial number mapping generated via step (1) and a phone
-serial number, then gets the corresponding BattOr serial number from the
-map and determines its BattOr path (e.g. /dev/ttyUSB0). Since BattOr paths
-can change if devices are connected and disconnected (even if connected
-or disconnected via the same port) this function should be called to
-determine the BattOr path every time before connecting to the BattOr.
-
-Note that if there is only one BattOr connected to the system, then
-GetBattOrPathFromPhoneSerial will always return that BattOr and will ignore
-the mapping file. Thus, if the user never has more than one BattOr connected
-to the system, the user will not need to generate mapping files.
-'''
-
-
-import json
-import collections
-
-from battor import battor_error
-from devil.utils import find_usb_devices
-from devil.utils import usb_hubs
-
-
-def GetBattOrList(device_tree_map):
- return [x for x in find_usb_devices.GetTTYList()
- if IsBattOr(x, device_tree_map)]
-
-
-def IsBattOr(tty_string, device_tree_map):
- (bus, device) = find_usb_devices.GetBusDeviceFromTTY(tty_string)
- node = device_tree_map[bus].FindDeviceNumber(device)
- return '0403:6001' in node.desc
-
-
-def GetBattOrSerialNumbers(device_tree_map):
- for x in find_usb_devices.GetTTYList():
- if IsBattOr(x, device_tree_map):
- (bus, device) = find_usb_devices.GetBusDeviceFromTTY(x)
- devnode = device_tree_map[bus].FindDeviceNumber(device)
- yield devnode.serial
-
-
-def ReadSerialMapFile(filename):
- """Reads JSON file giving phone-to-battor serial number map.
-
- Parses a JSON file consisting of a list of items of the following form:
- [{'phone': <phone serial 1>, 'battor': <battor serial 1>},
- {'phone': <phone serial 2>, 'battor': <battor serial 2>}, ...]
-
- indicating which phone serial numbers should be matched with
- which BattOr serial numbers. Returns dictionary of the form:
-
- {<phone serial 1>: <BattOr serial 1>,
- <phone serial 2>: <BattOr serial 2>}
-
- Args:
- filename: Name of file to read.
- """
- result = {}
- with open(filename, 'r') as infile:
- in_dict = json.load(infile)
- for x in in_dict:
- result[x['phone']] = x['battor']
- return result
-
-def WriteSerialMapFile(filename, serial_map):
- """Writes a map of phone serial numbers to BattOr serial numbers to file.
-
- Writes a JSON file consisting of a list of items of the following form:
- [{'phone': <phone serial 1>, 'battor': <battor serial 1>},
- {'phone': <phone serial 2>, 'battor': <battor serial 2>}, ...]
-
- indicating which phone serial numbers should be matched with
- which BattOr serial numbers. Mapping is based on the physical port numbers
- of the hubs that the BattOrs and phones are connected to.
-
- Args:
- filename: Name of file to write.
- serial_map: Serial map {phone: battor}
- """
- result = []
- for (phone, battor) in serial_map.iteritems():
- result.append({'phone': phone, 'battor': battor})
- with open(filename, 'w') as outfile:
- json.dump(result, outfile)
-
-def GenerateSerialMap(hub_types=None):
- """Generates a map of phone serial numbers to BattOr serial numbers.
-
- Generates a dict of:
- {<phone serial 1>: <battor serial 1>,
- <phone serial 2>: <battor serial 2>}
- indicating which phone serial numbers should be matched with
- which BattOr serial numbers. Mapping is based on the physical port numbers
- of the hubs that the BattOrs and phones are connected to.
-
- Args:
- hub_types: List of hub types to check for. If not specified, checks
- for all defined hub types. (see usb_hubs.py for details)
- """
- if hub_types:
- hub_types = [usb_hubs.GetHubType(x) for x in hub_types]
- else:
- hub_types = usb_hubs.ALL_HUBS
-
- devtree = find_usb_devices.GetBusNumberToDeviceTreeMap()
-
- # List of serial numbers in the system that represent BattOrs.
- battor_serials = list(GetBattOrSerialNumbers(devtree))
-
- # If there's only one BattOr in the system, then a serial number ma
- # is not necessary.
- if len(battor_serials) == 1:
- return {}
-
- # List of dictionaries, one for each hub, that maps the physical
- # port number to the serial number of that hub. For instance, in a 2
- # hub system, this could return [{1:'ab', 2:'cd'}, {1:'jkl', 2:'xyz'}]
- # where 'ab' and 'cd' are the phone serial numbers and 'jkl' and 'xyz'
- # are the BattOr serial numbers.
- port_to_serial = find_usb_devices.GetAllPhysicalPortToSerialMaps(
- hub_types, device_tree_map=devtree)
-
- class serials(object):
- def __init__(self):
- self.phone = None
- self.battor = None
-
- # Map of {physical port number: [phone serial #, BattOr serial #]. This
- # map is populated by executing the code below. For instance, in the above
- # example, after the code below is executed, port_to_devices would equal
- # {1: ['ab', 'jkl'], 2: ['cd', 'xyz']}
- port_to_devices = collections.defaultdict(serials)
- for hub in port_to_serial:
- for (port, serial) in hub.iteritems():
- if serial in battor_serials:
- if port_to_devices[port].battor is not None:
- raise battor_error.BattOrError('Multiple BattOrs on same port number')
- else:
- port_to_devices[port].battor = serial
- else:
- if port_to_devices[port].phone is not None:
- raise battor_error.BattOrError('Multiple phones on same port number')
- else:
- port_to_devices[port].phone = serial
-
- # Turn the port_to_devices map into a map of the form
- # {phone serial number: BattOr serial number}.
- result = {}
- for pair in port_to_devices.values():
- if pair.phone is None:
- continue
- if pair.battor is None:
- raise battor_error.BattOrError(
- 'Phone detected with no corresponding BattOr')
- result[pair.phone] = pair.battor
- return result
-
-def GenerateSerialMapFile(filename, hub_types=None):
- """Generates a serial map file and writes it."""
- WriteSerialMapFile(filename, GenerateSerialMap(hub_types))
-
-def _PhoneToPathMap(serial, serial_map, devtree):
- """Maps phone serial number to TTY path, assuming serial map is provided."""
- try:
- battor_serial = serial_map[serial]
- except KeyError:
- raise battor_error.BattOrError('Serial number not found in serial map.')
- for tree in devtree.values():
- for node in tree.AllNodes():
- if isinstance(node, find_usb_devices.USBDeviceNode):
- if node.serial == battor_serial:
- bus_device_to_tty = find_usb_devices.GetBusDeviceToTTYMap()
- bus_device = (node.bus_num, node.device_num)
- try:
- return bus_device_to_tty[bus_device]
- except KeyError:
- raise battor_error.BattOrError(
- 'Device with given serial number not a BattOr '
- '(does not have TTY path)')
-
-
-def GetBattOrPathFromPhoneSerial(serial, serial_map=None,
- serial_map_file=None):
- """Gets the TTY path (e.g. '/dev/ttyUSB0') to communicate with the BattOr.
-
- (1) If serial_map is given, it is treated as a dictionary mapping
- phone serial numbers to BattOr serial numbers. This function will get the
- TTY path for the given BattOr serial number.
-
- (2) If serial_map_file is given, it is treated as the name of a
- phone-to-BattOr mapping file (generated with GenerateSerialMapFile)
- and this will be loaded and used as the dict to map port numbers to
- BattOr serial numbers.
-
- You can only give one of serial_map and serial_map_file.
-
- Args:
- serial: Serial number of phone connected on the same physical port that
- the BattOr is connected to.
- serial_map: Map of phone serial numbers to BattOr serial numbers, given
- as a dictionary.
- serial_map_file: Map of phone serial numbers to BattOr serial numbers,
- given as a file.
- hub_types: List of hub types to check for. Used only if serial_map_file
- is None.
-
- Returns:
- Device string used to communicate with device.
-
- Raises:
- ValueError: If serial number is not given.
- BattOrError: If BattOr not found or unexpected USB topology.
- """
- # If there's only one BattOr connected to the system, just use that one.
- # This allows for use on, e.g., a developer's workstation with no hubs.
- devtree = find_usb_devices.GetBusNumberToDeviceTreeMap()
- all_battors = GetBattOrList(devtree)
- if len(all_battors) == 1:
- return '/dev/' + all_battors[0]
-
- if not serial:
- raise battor_error.BattOrError(
- 'Two or more BattOrs connected, no serial provided')
-
- if serial_map and serial_map_file:
- raise ValueError('Cannot specify both serial_map and serial_map_file')
-
- if serial_map_file:
- serial_map = ReadSerialMapFile(serial_map_file)
-
- tty_string = _PhoneToPathMap(serial, serial_map, devtree)
-
- if not tty_string:
- raise battor_error.BattOrError(
- 'No device with given serial number detected.')
-
- if IsBattOr(tty_string, devtree):
- return '/dev/' + tty_string
- else:
- raise battor_error.BattOrError(
- 'Device with given serial number is not a BattOr.')
-
-if __name__ == '__main__':
- # Main function for testing purposes
- print GenerateSerialMap()