blob: e77997e92325e4c83bfac68e9883ea321adde246 [file] [log] [blame]
#!/usr/bin/env python2
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""XML RPC server for multimedia testing."""
import argparse
import code
import logging
import os
import six.moves.xmlrpc_client
import traceback
import common # pylint: disable=unused-import
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import logging_config
from autotest_lib.client.cros import constants
from autotest_lib.client.cros import upstart
from autotest_lib.client.cros import xmlrpc_server
from autotest_lib.client.cros.multimedia import assistant_facade_native
from autotest_lib.client.cros.multimedia import audio_facade_native
from autotest_lib.client.cros.multimedia import bluetooth_facade_native
from autotest_lib.client.cros.multimedia import browser_facade_native
from autotest_lib.client.cros.multimedia import cfm_facade_native
from autotest_lib.client.cros.multimedia import display_facade_native
from autotest_lib.client.cros.multimedia import facade_resource
from autotest_lib.client.cros.multimedia import graphics_facade_native
from autotest_lib.client.cros.multimedia import input_facade_native
from autotest_lib.client.cros.multimedia import kiosk_facade_native
from autotest_lib.client.cros.multimedia import system_facade_native
from autotest_lib.client.cros.multimedia import usb_facade_native
from autotest_lib.client.cros.multimedia import video_facade_native
class MultimediaXmlRpcDelegate(xmlrpc_server.XmlRpcDelegate):
"""XML RPC delegate for multimedia testing."""
def __init__(self, resource):
"""Initializes the facade objects."""
# TODO: (crbug.com/618111) Add test driven switch for
# supporting arc_mode enabled or disabled. At this time
# if ARC build is tested, arc_mode is always enabled.
arc_res = None
if utils.get_board_property('CHROMEOS_ARC_VERSION'):
logging.info('Using ARC resource on ARC enabled board.')
from autotest_lib.client.cros.multimedia import arc_resource
arc_res = arc_resource.ArcResource()
self._facades = {
'assistant':
assistant_facade_native.AssistantFacadeNative(resource),
'audio':
audio_facade_native.AudioFacadeNative(resource,
arc_resource=arc_res),
'bluetooth':
bluetooth_facade_native.BluetoothFacadeNative(),
'video':
video_facade_native.VideoFacadeNative(resource,
arc_resource=arc_res),
'display':
display_facade_native.DisplayFacadeNative(resource),
'system':
system_facade_native.SystemFacadeNative(),
'usb':
usb_facade_native.USBFacadeNative(),
'browser':
browser_facade_native.BrowserFacadeNative(resource),
'input':
input_facade_native.InputFacadeNative(),
'cfm_main_screen':
cfm_facade_native.CFMFacadeNative(resource, 'hotrod'),
'cfm_mimo_screen':
cfm_facade_native.CFMFacadeNative(resource, 'control'),
'kiosk':
kiosk_facade_native.KioskFacadeNative(resource),
'graphics':
graphics_facade_native.GraphicsFacadeNative()
}
def __exit__(self, exception, value, traceback):
"""Clean up the resources."""
self._facades['audio'].cleanup()
def _dispatch(self, method, params):
"""Dispatches the method to the proper facade.
We turn off allow_dotted_names option. The method handles the dot
and dispatches the method to the proper native facade, like
DisplayFacadeNative.
"""
try:
try:
if '.' not in method:
func = getattr(self, method)
else:
facade_name, method_name = method.split('.', 1)
if facade_name in self._facades:
func = getattr(self._facades[facade_name], method_name)
else:
raise Exception('unknown facade: %s' % facade_name)
except AttributeError:
raise Exception('method %s not supported' % method)
logging.info('Dispatching method %s with args %s',
str(func), str(params))
return func(*params)
except:
# TODO(ihf): Try to return meaningful stacktraces from the client.
return traceback.format_exc()
def config_logging():
"""Configs logging to be verbose and use console handler."""
config = logging_config.LoggingConfig()
config.configure_logging(use_console=True, verbose=True)
def main():
"""The main function, to run the XMLRPC server."""
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--debug', action='store_true', required=False,
help=('create a debug console with a ServerProxy "s" '
'connecting to the XML RPC sever at localhost'))
args = parser.parse_args()
pid = os.getpid()
if args.debug:
s = six.moves.xmlrpc_client.ServerProxy('http://localhost:%d' %
constants.MULTIMEDIA_XMLRPC_SERVER_PORT,
allow_none=True)
code.interact(local=locals())
else:
config_logging()
logging.debug('multimedia_xmlrpc_server[%s] main...', pid)
xmlrpc_server.terminate_old(__file__)
# bind before full setup, so the error is the last thing in the log
server = xmlrpc_server.XmlRpcServer(
'localhost', constants.MULTIMEDIA_XMLRPC_SERVER_PORT)
# Restart Cras to clean up any audio activities.
upstart.restart_job('cras')
with facade_resource.FacadeResource() as res:
server.register_delegate(MultimediaXmlRpcDelegate(res))
server.run()
logging.debug('multimedia_xmlrpc_server[%s] exiting...', pid)
logging.debug('multimedia_xmlrpc_server[%s] done.\n', pid)
if __name__ == '__main__':
main()