1# Copyright (c) 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4""" 5This profiler will take a screenshot at the specified interval. 6""" 7 8import os, subprocess 9import threading, time 10import logging 11from autotest_lib.client.bin import profiler 12 13 14class screenshot(profiler.profiler): 15 """ Profiler for running screenshot """ 16 17 version = 1 18 19 def initialize(self, interval=300): 20 """Initializes the screenshot profiler. 21 22 Args: 23 interval (int): How often to take a screenshot in seconds 24 """ 25 self.interval = interval 26 27 def start(self, test): 28 self.thread = ScreenshotThread(interval=self.interval, test=test) 29 30 self.thread.start() 31 32 def stop(self, test): 33 self.thread.stop() 34 35 36class ScreenshotThread(threading.Thread): 37 """ Thread that runs screenshot at the specified interval """ 38 39 def __init__(self, interval, test): 40 threading.Thread.__init__(self) 41 self.stopped = threading.Event() 42 self.interval = interval 43 self.test = test 44 45 def run(self): 46 logging.info("screenshot thread starting") 47 48 sleep_time = 0 49 50 while not self.stopped.wait(sleep_time): 51 start_time = time.time() 52 53 path = os.path.join(self.test.profdir, 54 "screenshot-%d.png" % (int(start_time))) 55 56 # Don't use graphics_utils because we can't control the suffix 57 cmd = ['screenshot', path] 58 59 logging.debug("Taking screenshot") 60 61 process = subprocess.Popen( 62 cmd, stderr=subprocess.PIPE, close_fds=True) 63 64 _, stderr = process.communicate() 65 66 if process.returncode: 67 # If the screen is turned off, screenshot will fail 68 logging.info('screenshot failed. code: %d, error: %s ', 69 process.returncode, stderr) 70 71 end_time = time.time() 72 73 sleep_time = self.interval - (end_time - start_time) 74 75 if sleep_time < 0: 76 sleep_time = 0 77 78 def stop(self): 79 """ Stops the thread """ 80 logging.info("Stopping screenshot thread") 81 82 self.stopped.set() 83 84 # Only block for five seconds to not hold up the test shutdown. 85 # It's very unlikely that the screenshot command will take more 86 # than a second. 87 self.join(5) 88 89 logging.info("screenshot thread stopped") 90