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 8 import argparse 9 import code 10 import logging 11 import xmlrpclib 12 import traceback 13 import common # pylint: disable=unused-import 14 from autotest_lib.client.bin import utils 15 from autotest_lib.client.common_lib import logging_config 16 from autotest_lib.client.cros import constants 17 from autotest_lib.client.cros import upstart 18 from autotest_lib.client.cros import xmlrpc_server 19 from autotest_lib.client.cros.multimedia import audio_facade_native 20 from autotest_lib.client.cros.multimedia import browser_facade_native 21 from autotest_lib.client.cros.multimedia import cfm_facade_native 22 from autotest_lib.client.cros.multimedia import display_facade_native 23 from autotest_lib.client.cros.multimedia import facade_resource 24 from autotest_lib.client.cros.multimedia import input_facade_native 25 from autotest_lib.client.cros.multimedia import kiosk_facade_native 26 from autotest_lib.client.cros.multimedia import system_facade_native 27 from autotest_lib.client.cros.multimedia import usb_facade_native 28 from autotest_lib.client.cros.multimedia import video_facade_native 29 30 31 class 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 95 def 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 101 if __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