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