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