Home | History | Annotate | Download | only in multimedia
      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_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 
     98 def 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 
    104 if __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