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