• 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_main_screen': cfm_facade_native.CFMFacadeNative(
57                              resource, 'hotrod'),
58            'cfm_mimo_screen': cfm_facade_native.CFMFacadeNative(
59                              resource, 'control'),
60            'kiosk': kiosk_facade_native.KioskFacadeNative(resource)
61        }
62
63
64    def __exit__(self, exception, value, traceback):
65        """Clean up the resources."""
66        self._facades['audio'].cleanup()
67
68
69    def _dispatch(self, method, params):
70        """Dispatches the method to the proper facade.
71
72        We turn off allow_dotted_names option. The method handles the dot
73        and dispatches the method to the proper native facade, like
74        DisplayFacadeNative.
75
76        """
77        try:
78            try:
79                if '.' not in method:
80                    func = getattr(self, method)
81                else:
82                    facade_name, method_name = method.split('.', 1)
83                    if facade_name in self._facades:
84                        func = getattr(self._facades[facade_name], method_name)
85                    else:
86                        raise Exception('unknown facade: %s' % facade_name)
87            except AttributeError:
88                raise Exception('method %s not supported' % method)
89
90            logging.info('Dispatching method %s with args %s',
91                         str(func), str(params))
92            return func(*params)
93        except:
94            # TODO(ihf): Try to return meaningful stacktraces from the client.
95            return traceback.format_exc()
96
97
98def config_logging():
99    """Configs logging to be verbose and use console handler."""
100    config = logging_config.LoggingConfig()
101    config.configure_logging(use_console=True, verbose=True)
102
103
104if __name__ == '__main__':
105    parser = argparse.ArgumentParser()
106    parser.add_argument('-d', '--debug', action='store_true', required=False,
107                        help=('create a debug console with a ServerProxy "s" '
108                              'connecting to the XML RPC sever at localhost'))
109    args = parser.parse_args()
110
111    if args.debug:
112        s = xmlrpclib.ServerProxy('http://localhost:%d' %
113                                  constants.MULTIMEDIA_XMLRPC_SERVER_PORT,
114                                  allow_none=True)
115        code.interact(local=locals())
116    else:
117        config_logging()
118        logging.debug('multimedia_xmlrpc_server main...')
119
120
121        # Restart Cras to clean up any audio activities.
122        upstart.restart_job('cras')
123
124        with facade_resource.FacadeResource() as res:
125            server = xmlrpc_server.XmlRpcServer(
126                    'localhost', constants.MULTIMEDIA_XMLRPC_SERVER_PORT)
127            server.register_delegate(MultimediaXmlRpcDelegate(res))
128            server.run()
129