touch_firmware_test: enable ChromeOS webplot for Python 3.x
Some modules were already adapted for Python 3.x, this converts the
rest of the modules needed for 'webplot' tool functionality on ChromeOS.
Not intended to break Python 2.x operation.
* General 2/3 compatible pythonic language changes (print, range, dict,
except, map & bytestrings)
* Adjust wrapper script to ensure webplot runs under python3, as we do
not keep ws4py around for python2.
Also (unclear if this is related to python 3):
* Fix apparently incidental bug of reading ev data: description
ends after a blank line, not a 2-second timeout.
BUG=chromium:1095095
TEST=webplot validated manually, and test_that --board=hatch ${DUT}
platform_GesturesRegressionTestValidated passed; both on hatch.
Cq-Depend: chromium:2441402
Change-Id: Ie6887bf913c76d9a53a215b98bc56c0b1ce053fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/touch_firmware_test/+/2437494
Reviewed-by: Harry Cutts <hcutts@chromium.org>
Reviewed-by: Sean O'Brien <seobrien@chromium.org>
Tested-by: Kenneth Albanowski <kenalba@google.com>
Commit-Queue: Kenneth Albanowski <kenalba@google.com>
diff --git a/gesture_interpreter.py b/gesture_interpreter.py
index 6fbd3f0..5c4a210 100644
--- a/gesture_interpreter.py
+++ b/gesture_interpreter.py
@@ -226,7 +226,7 @@
fn = lambda: _PerformSquareResolutionTest(variation, robot, device_spec)
if fn is None:
- print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
+ print(color.Fore.RED + 'Robot unable to perform gesture! Skipping...')
return None
return Thread(target=fn)
diff --git a/heatmap/heatmapplot.py b/heatmap/heatmapplot.py
index 17e22da..7569941 100755
--- a/heatmap/heatmapplot.py
+++ b/heatmap/heatmapplot.py
@@ -42,7 +42,7 @@
proc = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = proc.communicate()
- except Exception, e:
+ except Exception as e:
logging.warning('Command (%s) failed (%s).', cmd, e)
else:
return None if proc.returncode else stdout.strip()
diff --git a/heatmap/remote/remote_device.py b/heatmap/remote/remote_device.py
index 78d6f2b..7aabd11 100644
--- a/heatmap/remote/remote_device.py
+++ b/heatmap/remote/remote_device.py
@@ -120,7 +120,7 @@
items = line.split()
if len(items) < 1 or (items[0] != 'x' and items[0] != 'y'):
return None
- data = map(float, items[1:])
+ data = list(map(float, items[1:]))
return HeatMapEvent(items[0], data)
def _RunRemoteCmd(self, cmd):
@@ -128,8 +128,8 @@
RSA_KEY_PATH = os.path.dirname(
os.path.realpath(inspect.getfile(
inspect.currentframe()))) + '/data/testing_rsa'
- if stat.S_IMODE(os.stat(RSA_KEY_PATH).st_mode) != 0600:
- os.chmod(RSA_KEY_PATH, 0600)
+ if stat.S_IMODE(os.stat(RSA_KEY_PATH).st_mode) != 0o600:
+ os.chmod(RSA_KEY_PATH, 0o600)
args = ['ssh', 'root@%s' % self.addr,
'-i', RSA_KEY_PATH,
diff --git a/remote/mt/input/linux_input.py b/remote/mt/input/linux_input.py
index 9209260..1ada752 100644
--- a/remote/mt/input/linux_input.py
+++ b/remote/mt/input/linux_input.py
@@ -791,7 +791,7 @@
ABS_MT_FIRST = ABS_MT_TOUCH_MAJOR
ABS_MT_LAST = ABS_MT_DISTANCE
-ABS_MT_RANGE = range(ABS_MT_FIRST, ABS_MT_LAST+1)
+ABS_MT_RANGE = list(range(ABS_MT_FIRST, ABS_MT_LAST+1))
ABS_MAX = 0x3f
ABS_CNT = (ABS_MAX + 1)
diff --git a/remote/remote_in_system.py b/remote/remote_in_system.py
index 6c0c37c..b3f937f 100644
--- a/remote/remote_in_system.py
+++ b/remote/remote_in_system.py
@@ -181,7 +181,7 @@
if inputs[0] not in readable:
return None
- line = self.event_stream_process.stdout.readline()
+ line = self.event_stream_process.stdout.readline().decode()
# If the event_stream_process had been terminated, just return None.
if self.event_stream_process is None:
@@ -227,7 +227,7 @@
"""
def GetAllDeviceNumberMappings():
# This file contains the mappings so we can determine which event file
- output = self._RunRemoteCmd('cat /proc/bus/input/devices').stdout.read()
+ output = self._RunRemoteCmd('cat /proc/bus/input/devices').stdout.read().decode()
# Build up a dictionary mapping device names -> device numbers
mappings = {}
@@ -259,7 +259,7 @@
if selection:
print('Error: That is not a legal device number')
- selection = raw_input('Enter the device number you wish to test: ')
+ selection = input('Enter the device number you wish to test: ')
try:
selection = int(selection)
except:
@@ -363,7 +363,7 @@
x = y = p = None
touch_major = touch_minor = {}
cmd = 'getevent -p /dev/input/event%d' % self.device_num
- output = self._RunRemoteCmd(cmd).stdout.read()
+ output = self._RunRemoteCmd(cmd).stdout.read().decode()
for line in output.split('\n'):
pattern = '^.*([0-9a-f]{4})\s+:\s+.*min (\d*),\s+max (\d*),.*$'
matches = re.match(pattern, line, re.M)
@@ -482,8 +482,8 @@
x = y = p = tilt_x = tilt_y = None
touch_major = touch_minor = {}
while not all([x, y, p, tilt_x, tilt_y]):
- line = self._GetNextLine(timeout=2)
- if line is None:
+ line = self._GetNextLine()
+ if line is None or 'interrupt to exit' in line:
break
if '(ABS_MT_POSITION_X)' in line or '(ABS_X)' in line:
diff --git a/webplot/centroiding/centroiding_receiver.py b/webplot/centroiding/centroiding_receiver.py
index 14e63db..b5311ab 100644
--- a/webplot/centroiding/centroiding_receiver.py
+++ b/webplot/centroiding/centroiding_receiver.py
@@ -12,6 +12,7 @@
import os
import socket
import time
+from builtins import range
# Pre-load librt.so for MonotonicTime()
librt_name = ctypes.util.find_library('rt')
@@ -127,15 +128,15 @@
if self._NULL_CHAR in chunk_buffer:
chunk_buffer = self._ExtractSnapshots(chunk_buffer, f)
except KeyboardInterrupt:
- print 'Keyboard interrupt accepted!'
- print 'Centroiding receiver is terminated...'
- print 'Webplot server is terminated...'
+ print('Keyboard interrupt accepted!')
+ print('Centroiding receiver is terminated...')
+ print('Webplot server is terminated...')
self.sock.close()
self.webplot.Quit()
break
except IOError as e:
- print 'Oops!! something wrong while saving data to %s: %s' % (
- self.save_path, str(e))
+ print('Oops!! something wrong while saving data to %s: %s' % (
+ self.save_path, str(e)))
self.sock.close()
self.webplot.Quit()
@@ -150,7 +151,7 @@
The residue on chunk buffer after snapshot extraction.
"""
snapshots = chunk_buffer.split(self._NULL_CHAR)
- for i in xrange(len(snapshots)):
+ for i in range(len(snapshots)):
if i == len(snapshots) - 1:
return snapshots[i]
if len(snapshots[i]) == 0:
@@ -189,4 +190,4 @@
{"fps": [self.fps_receiver.GetFPS(), self.fps_plot.GetFPS()]})
self.webplot.AddSnapshot(snapshot_json)
except Exception as e:
- print 'Exception while plotting snapshot = %r:' % snapshot, e
+ print('Exception while plotting snapshot = %r:' % snapshot, e)
diff --git a/webplot/centroiding_main.py b/webplot/centroiding_main.py
index 67b04fc..b01f4a4 100644
--- a/webplot/centroiding_main.py
+++ b/webplot/centroiding_main.py
@@ -55,7 +55,7 @@
Returns:
Return False if errors happen; otherwise return True.
"""
- print '\n' + '-' * SEPARATION_LINEWIDTH
+ print('\n' + '-' * SEPARATION_LINEWIDTH)
# To prevent adb no permissions issue, it needs sudo to start adb server.
os.system('sudo adb kill-server')
@@ -65,7 +65,7 @@
return subprocess.check_output(['adb', 'get-state']).strip() == 'device'
if not _GetDeviceOnline():
- print 'Currently no device attached!\nPlease attach your testing device...'
+ print('Currently no device attached!\nPlease attach your testing device...')
retry_times = 0
while True:
time.sleep(0.2)
@@ -73,12 +73,12 @@
break
retry_times += 1
if retry_times > ADB_GETSTATE_RETRIES:
- print 'Timeout polling for testing device (%.1f seconds)...' % (
- 0.2 * ADB_GETSTATE_RETRIES)
+ print('Timeout polling for testing device (%.1f seconds)...' % (
+ 0.2 * ADB_GETSTATE_RETRIES))
return False
- print '\nDevice is attached.\n'
- print 'Try to build tunnel port %d between device and server...' % port
+ print('\nDevice is attached.\n')
+ print('Try to build tunnel port %d between device and server...' % port)
retry_times = 0
while True:
@@ -93,7 +93,7 @@
if retry_times > ADB_FORWARD_RETRIES:
return False
- print '\nTunnel is established successfully.\n'
+ print('\nTunnel is established successfully.\n')
return True
@@ -125,33 +125,33 @@
def Main():
args = _ParseArguments()
- print '\n' + '-' * SEPARATION_LINEWIDTH + '\n'
- print '**** Centroiding Data Visualizing Tool ****'
- print 'webplot server address:', args.server_addr
- print 'webplot server port:', args.server_port
+ print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
+ print('**** Centroiding Data Visualizing Tool ****')
+ print('webplot server address:', args.server_addr)
+ print('webplot server port:', args.server_port)
- print '\n' + '-' * SEPARATION_LINEWIDTH + '\n'
- print 'dut socket forwarding port:', args.dut_forward_port
- print ' (this port will be tunneled between dut and server)\n'
- print 'dut config file:', args.config
+ print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
+ print('dut socket forwarding port:', args.dut_forward_port)
+ print(' (this port will be tunneled between dut and server)\n')
+ print('dut config file:', args.config)
device = CentroidingDevice(config=args.config)
- print ' - device name:', device.device
- print ' - data_scale:', device.data_scale
- print ' - data_offset:', device.data_offset
- print ' - width:', device.width
- print ' - height:', device.height
+ print(' - device name:', device.device)
+ print(' - data_scale:', device.data_scale)
+ print(' - data_offset:', device.data_offset)
+ print(' - width:', device.width)
+ print(' - height:', device.height)
if not EstablishADBConnectionTunnel(args.dut_forward_port):
- print 'Connection to device failed. Task is aborted...'
+ print('Connection to device failed. Task is aborted...')
return
- print '\n' + '-' * SEPARATION_LINEWIDTH + '\n'
- print 'webplot server has started...'
- print 'port %d is listening on sockets from dut...' % args.dut_forward_port
- print ('check http://%s:%d on browser of your device to view the plot...\n' %
- (args.server_addr, args.server_port))
+ print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
+ print('webplot server has started...')
+ print('port %d is listening on sockets from dut...' % args.dut_forward_port)
+ print(('check http://%s:%d on browser of your device to view the plot...\n' %
+ (args.server_addr, args.server_port)))
if args.log_data:
time_now = datetime.now().strftime('%Y%m%d%H%M%S')
@@ -171,11 +171,11 @@
receiver.StartReceive()
if args.log_data:
- print '\ncentroiding raw data are saved into file %s\n' % save_data
- print 'parsing saved raw data to analytical format...'
+ print('\ncentroiding raw data are saved into file %s\n' % save_data)
+ print('parsing saved raw data to analytical format...')
data_parser = CentroidingDataParser(save_data, device)
data_parser.Parse()
- print 'parse finished...'
+ print('parse finished...')
if __name__ == '__main__':
diff --git a/webplot/chromeos_wrapper.sh b/webplot/chromeos_wrapper.sh
index 975ca37..d907d11 100755
--- a/webplot/chromeos_wrapper.sh
+++ b/webplot/chromeos_wrapper.sh
@@ -53,8 +53,9 @@
fi
# Search the webplot directory.
-# Stop at the first found webplot directory. Priority is given to /usr/lib*.
-DIRS="/usr/lib* /usr/local/lib*"
+# Stop at the first found python3 webplot directory.
+# Priority is given to /usr/lib*.
+DIRS="/usr/lib*/python3* /usr/local/lib*/python3*"
for d in $DIRS; do
PROG_DIR="$(find $d -name $PROG -type d -print -quit)"
if [ -n "$PROG_DIR" ]; then
@@ -83,5 +84,5 @@
echo "Start $PROG server..."
[ "$FLAGS_grab" = "$FLAGS_FALSE" ] && grab_option="--nograb"
- exec python "${PROG_DIR}/${PROG}".py $grab_option --behind_firewall -p80
+ exec python3 "${PROG_DIR}/${PROG}".py $grab_option --behind_firewall -p80
fi
diff --git a/webplot/webplot.py b/webplot/webplot.py
index 12b1ecd..3fc8de2 100755
--- a/webplot/webplot.py
+++ b/webplot/webplot.py
@@ -51,10 +51,10 @@
proc = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, _ = proc.communicate()
- except Exception, e:
+ except Exception as e:
logging.warning('Command (%s) failed (%s).', cmd, e)
else:
- return None if proc.returncode else stdout.strip()
+ return None if proc.returncode else stdout.decode().strip()
def IsDestinationPortEnabled(port):
@@ -117,7 +117,7 @@
def received_message(self, msg):
"""A callback for received message."""
- data = msg.data.split(':', 1)
+ data = msg.data.decode().split(':', 1)
mtype = data[0].lower()
content = data[1] if len(data) == 2 else None
@@ -322,7 +322,7 @@
'dataWidth': str(self.data_width),
'dataHeight': str(self.data_height),
}
- print websocket_dict
+ print(websocket_dict)
root_page = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'centroiding.html')
with open(root_page) as f:
@@ -487,10 +487,10 @@
so that the corresponding finger color could be released for reuse.
"""
# Convert MtSnapshot.
- converted = dict(snapshot.__dict__.items())
+ converted = snapshot._asdict()
# Convert MtFinger.
- converted['fingers'] = [dict(finger.__dict__.items())
+ converted['fingers'] = [finger._asdict()
for finger in converted['fingers']]
converted['raw_events'] = [str(event) for event in converted['raw_events']]
@@ -580,7 +580,7 @@
reason.
"""
if os.path.exists('/etc/cros_chroot_version') and os.getuid() == 0:
- print ('You should run webplot in chroot as a regular user '
+ print('You should run webplot in chroot as a regular user '
'instead of as root.\n')
exit(1)
@@ -655,7 +655,7 @@
# Specify Webplot for centroiding purpose.
is_centroiding = args.dut_type == 'centroiding'
- print '\n' + '-' * 70
+ print('\n' + '-' * 70)
if is_centroiding:
cherrypy.log('**** Centroiding Data Visualizing Tool ****')
cherrypy.log('dut config file: %s' % args.config)
@@ -673,7 +673,7 @@
cherrypy.log('Warning: the grab option is not supported on Android devices'
' yet.')
cherrypy.log('touch events are saved in %s' % SAVED_FILE)
- print '-' * 70 + '\n\n'
+ print('-' * 70 + '\n\n')
if args.server_port == 80:
url = 'http://%s' % args.server_addr
@@ -686,10 +686,10 @@
else:
which_machine = 'on any machine'
- print '*' * 70
- print msg % (url, which_machine)
- print 'Press \'q\' on the browser to quit.'
- print '*' * 70 + '\n\n'
+ print('*' * 70)
+ print(msg % (url, which_machine))
+ print('Press \'q\' on the browser to quit.')
+ print('*' * 70 + '\n\n')
# Instantiate a touch device.
if args.dut_type == 'chromeos':
@@ -703,7 +703,7 @@
from centroiding import CentroidingDataReceiver, CentroidingDevice
device = CentroidingDevice(args.config)
else:
- print 'Unrecognized dut_type: %s. Webplot is aborted...' % args.dut_type
+ print('Unrecognized dut_type: %s. Webplot is aborted...' % args.dut_type)
exit(1)
# Instantiate a webplot server daemon and start it.
@@ -715,12 +715,12 @@
if args.automatically_start_browser:
opened_successfully = webbrowser.open(url)
if opened_successfully:
- print 'Web browser opened successfully!'
+ print('Web browser opened successfully!')
else:
- print '!' * 80
- print 'Sorry, we were unable to automatically open a web browser for you'
- print 'Please navigate to "%s" in a browser manually, instead' % url
- print '!' * 80
+ print('!' * 80)
+ print('Sorry, we were unable to automatically open a web browser for you')
+ print('Please navigate to "%s" in a browser manually, instead' % url)
+ print('!' * 80)
if not is_centroiding:
# Get touch snapshots from the touch device and have clients plot them.