• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""XML RPC server for multimedia testing."""
7
8import argparse
9import code
10import logging
11import xmlrpclib
12import traceback
13import common   # pylint: disable=unused-import
14from autotest_lib.client.bin import utils
15from autotest_lib.client.common_lib import logging_config
16from autotest_lib.client.cros import constants
17from autotest_lib.client.cros import upstart
18from autotest_lib.client.cros import xmlrpc_server
19from autotest_lib.client.cros.multimedia import audio_facade_native
20from autotest_lib.client.cros.multimedia import browser_facade_native
21from autotest_lib.client.cros.multimedia import cfm_facade_native
22from autotest_lib.client.cros.multimedia import display_facade_native
23from autotest_lib.client.cros.multimedia import facade_resource
24from autotest_lib.client.cros.multimedia import graphics_facade_native
25from autotest_lib.client.cros.multimedia import input_facade_native
26from autotest_lib.client.cros.multimedia import kiosk_facade_native
27from autotest_lib.client.cros.multimedia import system_facade_native
28from autotest_lib.client.cros.multimedia import usb_facade_native
29from autotest_lib.client.cros.multimedia import video_facade_native
30
31
32class MultimediaXmlRpcDelegate(xmlrpc_server.XmlRpcDelegate):
33    """XML RPC delegate for multimedia testing."""
34
35    def __init__(self, resource):
36        """Initializes the facade objects."""
37
38        # TODO: (crbug.com/618111) Add test driven switch for
39        # supporting arc_mode enabled or disabled. At this time
40        # if ARC build is tested, arc_mode is always enabled.
41        arc_res = None
42        if utils.get_board_property('CHROMEOS_ARC_VERSION'):
43            logging.info('Using ARC resource on ARC enabled board.')
44            from autotest_lib.client.cros.multimedia import arc_resource
45            arc_res = arc_resource.ArcResource()
46
47        self._facades = {
48            'audio': audio_facade_native.AudioFacadeNative(
49                    resource, arc_resource=arc_res),
50            'video': video_facade_native.VideoFacadeNative(
51                    resource, arc_resource=arc_res),
52            'display': display_facade_native.DisplayFacadeNative(resource),
53            'system': system_facade_native.SystemFacadeNative(),
54            'usb': usb_facade_native.USBFacadeNative(),
55            'browser': browser_facade_native.BrowserFacadeNative(resource),
56            'input': input_facade_native.InputFacadeNative(),
57            'cfm_main_screen': cfm_facade_native.CFMFacadeNative(
58                              resource, 'hotrod'),
59            'cfm_mimo_screen': cfm_facade_native.CFMFacadeNative(
60                              resource, 'control'),
61            'kiosk': kiosk_facade_native.KioskFacadeNative(resource),
62            'graphics': graphics_facade_native.GraphicsFacadeNative()
63        }
64
65
66    def __exit__(self, exception, value, traceback):
67        """Clean up the resources."""
68        self._facades['audio'].cleanup()
69
70
71    def _dispatch(self, method, params):
72        """Dispatches the method to the proper facade.
73
74        We turn off allow_dotted_names option. The method handles the dot
75        and dispatches the method to the proper native facade, like
76        DisplayFacadeNative.
77
78        """
79        try:
80            try:
81                if '.' not in method:
82                    func = getattr(self, method)
83                else:
84                    facade_name, method_name = method.split('.', 1)
85                    if facade_name in self._facades:
86                        func = getattr(self._facades[facade_name], method_name)
87                    else:
88                        raise Exception('unknown facade: %s' % facade_name)
89            except AttributeError:
90                raise Exception('method %s not supported' % method)
91
92            logging.info('Dispatching method %s with args %s',
93                         str(func), str(params))
94            return func(*params)
95        except:
96            # TODO(ihf): Try to return meaningful stacktraces from the client.
97            return traceback.format_exc()
98
99
100def config_logging():
101    """Configs logging to be verbose and use console handler."""
102    config = logging_config.LoggingConfig()
103    config.configure_logging(use_console=True, verbose=True)
104
105
106if __name__ == '__main__':
107    parser = argparse.ArgumentParser()
108    parser.add_argument('-d', '--debug', action='store_true', required=False,
109                        help=('create a debug console with a ServerProxy "s" '
110                              'connecting to the XML RPC sever at localhost'))
111    args = parser.parse_args()
112
113    if args.debug:
114        s = xmlrpclib.ServerProxy('http://localhost:%d' %
115                                  constants.MULTIMEDIA_XMLRPC_SERVER_PORT,
116                                  allow_none=True)
117        code.interact(local=locals())
118    else:
119        config_logging()
120        logging.debug('multimedia_xmlrpc_server main...')
121
122
123        # Restart Cras to clean up any audio activities.
124        upstart.restart_job('cras')
125
126        with facade_resource.FacadeResource() as res:
127            server = xmlrpc_server.XmlRpcServer(
128                    'localhost', constants.MULTIMEDIA_XMLRPC_SERVER_PORT)
129            server.register_delegate(MultimediaXmlRpcDelegate(res))
130            server.run()
131