xref: /aosp_15_r20/external/autotest/client/cros/multimedia/video_facade.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Copyright 2016 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 Li"""Facade to access the video-related functionality."""
6*9c5db199SXin Li
7*9c5db199SXin Liimport functools
8*9c5db199SXin Liimport glob
9*9c5db199SXin Liimport os
10*9c5db199SXin Li
11*9c5db199SXin Lifrom autotest_lib.client.bin import utils
12*9c5db199SXin Lifrom autotest_lib.client.cros.multimedia import display_facade
13*9c5db199SXin Lifrom autotest_lib.client.cros.video import builtin_html5_player
14*9c5db199SXin Li
15*9c5db199SXin Li
16*9c5db199SXin Liclass VideoFacadeLocalError(Exception):
17*9c5db199SXin Li    """Error in VideoFacadeLocal."""
18*9c5db199SXin Li    pass
19*9c5db199SXin Li
20*9c5db199SXin Li
21*9c5db199SXin Lidef check_arc_resource(func):
22*9c5db199SXin Li    """Decorator function for ARC related functions in VideoFacadeLocal."""
23*9c5db199SXin Li    @functools.wraps(func)
24*9c5db199SXin Li    def wrapper(instance, *args, **kwargs):
25*9c5db199SXin Li        """Wrapper for the methods to check _arc_resource.
26*9c5db199SXin Li
27*9c5db199SXin Li        @param instance: Object instance.
28*9c5db199SXin Li
29*9c5db199SXin Li        @raises: VideoFacadeLocalError if there is no ARC resource.
30*9c5db199SXin Li
31*9c5db199SXin Li        """
32*9c5db199SXin Li        if not instance._arc_resource:
33*9c5db199SXin Li            raise VideoFacadeLocalError('There is no ARC resource.')
34*9c5db199SXin Li        return func(instance, *args, **kwargs)
35*9c5db199SXin Li    return wrapper
36*9c5db199SXin Li
37*9c5db199SXin Li
38*9c5db199SXin Liclass VideoFacadeLocal(object):
39*9c5db199SXin Li    """Facede to access the video-related functionality.
40*9c5db199SXin Li
41*9c5db199SXin Li    The methods inside this class only accept Python native types.
42*9c5db199SXin Li
43*9c5db199SXin Li    """
44*9c5db199SXin Li
45*9c5db199SXin Li    def __init__(self, resource, arc_resource=None):
46*9c5db199SXin Li        """Initializes an video facade.
47*9c5db199SXin Li
48*9c5db199SXin Li        @param resource: A FacadeResource object.
49*9c5db199SXin Li        @param arc_resource: An ArcResource object.
50*9c5db199SXin Li
51*9c5db199SXin Li        """
52*9c5db199SXin Li        self._resource = resource
53*9c5db199SXin Li        self._player = None
54*9c5db199SXin Li        self._arc_resource = arc_resource
55*9c5db199SXin Li        self._display_facade = display_facade.DisplayFacadeLocal(
56*9c5db199SXin Li                resource)
57*9c5db199SXin Li        self.bindir = os.path.dirname(os.path.realpath(__file__))
58*9c5db199SXin Li
59*9c5db199SXin Li
60*9c5db199SXin Li    def cleanup(self):
61*9c5db199SXin Li        """Clean up the temporary files."""
62*9c5db199SXin Li        for path in glob.glob('/tmp/playback_*'):
63*9c5db199SXin Li            os.unlink(path)
64*9c5db199SXin Li
65*9c5db199SXin Li        if self._arc_resource:
66*9c5db199SXin Li            self._arc_resource.cleanup()
67*9c5db199SXin Li
68*9c5db199SXin Li
69*9c5db199SXin Li    def prepare_playback(self, file_path, fullscreen=True):
70*9c5db199SXin Li        """Copies the html file to /tmp and loads the webpage.
71*9c5db199SXin Li
72*9c5db199SXin Li        @param file_path: The path to the file.
73*9c5db199SXin Li        @param fullscreen: Plays the video in fullscreen.
74*9c5db199SXin Li
75*9c5db199SXin Li        """
76*9c5db199SXin Li        # Copies the html file to /tmp to make it accessible.
77*9c5db199SXin Li        utils.get_file(
78*9c5db199SXin Li                os.path.join(self.bindir, 'video.html'),
79*9c5db199SXin Li                '/tmp/playback_video.html')
80*9c5db199SXin Li
81*9c5db199SXin Li        html_path = 'file:///tmp/playback_video.html'
82*9c5db199SXin Li
83*9c5db199SXin Li        tab = self._resource._browser.tabs.New()
84*9c5db199SXin Li        tab.Navigate(html_path)
85*9c5db199SXin Li        self._player = builtin_html5_player.BuiltinHtml5Player(
86*9c5db199SXin Li                tab=tab,
87*9c5db199SXin Li                full_url=html_path,
88*9c5db199SXin Li                video_id='video',
89*9c5db199SXin Li                video_src_path=file_path)
90*9c5db199SXin Li        self._player.load_video()
91*9c5db199SXin Li
92*9c5db199SXin Li        if fullscreen:
93*9c5db199SXin Li            self._display_facade.set_fullscreen(True)
94*9c5db199SXin Li
95*9c5db199SXin Li
96*9c5db199SXin Li    def start_playback(self, blocking=False):
97*9c5db199SXin Li        """Starts video playback on the webpage.
98*9c5db199SXin Li
99*9c5db199SXin Li        Before calling this method, user should call prepare_playback to
100*9c5db199SXin Li        put the files to /tmp and load the webpage.
101*9c5db199SXin Li
102*9c5db199SXin Li        @param blocking: Blocks this call until playback finishes.
103*9c5db199SXin Li
104*9c5db199SXin Li        """
105*9c5db199SXin Li        self._player.play()
106*9c5db199SXin Li        if blocking:
107*9c5db199SXin Li            self._player.wait_video_ended()
108*9c5db199SXin Li
109*9c5db199SXin Li
110*9c5db199SXin Li    def pause_playback(self):
111*9c5db199SXin Li        """Pauses playback on the webpage."""
112*9c5db199SXin Li        self._player.pause()
113*9c5db199SXin Li
114*9c5db199SXin Li
115*9c5db199SXin Li    def dropped_frame_count(self):
116*9c5db199SXin Li        """
117*9c5db199SXin Li        Gets the number of dropped frames.
118*9c5db199SXin Li
119*9c5db199SXin Li        @returns: An integer indicates the number of dropped frame.
120*9c5db199SXin Li
121*9c5db199SXin Li        """
122*9c5db199SXin Li        return self._player.dropped_frame_count()
123*9c5db199SXin Li
124*9c5db199SXin Li
125*9c5db199SXin Li    @check_arc_resource
126*9c5db199SXin Li    def prepare_arc_playback(self, file_path, fullscreen=True):
127*9c5db199SXin Li        """Copies the video file to be played into container and starts the app.
128*9c5db199SXin Li
129*9c5db199SXin Li        User should call this method to put the file into container before
130*9c5db199SXin Li        calling start_arc_playback.
131*9c5db199SXin Li
132*9c5db199SXin Li        @param file_path: Path to the file to be played on Cros host.
133*9c5db199SXin Li        @param fullscreen: Plays the video in fullscreen.
134*9c5db199SXin Li
135*9c5db199SXin Li        """
136*9c5db199SXin Li        self._arc_resource.play_video.prepare_playback(file_path, fullscreen)
137*9c5db199SXin Li
138*9c5db199SXin Li
139*9c5db199SXin Li    @check_arc_resource
140*9c5db199SXin Li    def start_arc_playback(self, blocking_secs=None):
141*9c5db199SXin Li        """Starts playback through Play Video app.
142*9c5db199SXin Li
143*9c5db199SXin Li        Before calling this method, user should call set_arc_playback_file to
144*9c5db199SXin Li        put the file into container and start the app.
145*9c5db199SXin Li
146*9c5db199SXin Li        @param blocking_secs: A positive number indicates the timeout to wait
147*9c5db199SXin Li                              for the playback is finished. Set None to make
148*9c5db199SXin Li                              it non-blocking.
149*9c5db199SXin Li
150*9c5db199SXin Li
151*9c5db199SXin Li        """
152*9c5db199SXin Li        self._arc_resource.play_video.start_playback(blocking_secs)
153*9c5db199SXin Li
154*9c5db199SXin Li
155*9c5db199SXin Li    @check_arc_resource
156*9c5db199SXin Li    def pause_arc_playback(self):
157*9c5db199SXin Li        """Pauses playback through Play Video app."""
158*9c5db199SXin Li        self._arc_resource.play_video.pause_playback()
159*9c5db199SXin Li
160*9c5db199SXin Li
161*9c5db199SXin Li    @check_arc_resource
162*9c5db199SXin Li    def stop_arc_playback(self):
163*9c5db199SXin Li        """Stops playback through Play Video app."""
164*9c5db199SXin Li        self._arc_resource.play_video.stop_playback()
165