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