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 graphics_facade_native
     25 from autotest_lib.client.cros.multimedia import input_facade_native
     26 from autotest_lib.client.cros.multimedia import kiosk_facade_native
     27 from autotest_lib.client.cros.multimedia import system_facade_native
     28 from autotest_lib.client.cros.multimedia import usb_facade_native
     29 from autotest_lib.client.cros.multimedia import video_facade_native
     30 
     31 
     32 class 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 
    100 def 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 
    106 if __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