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': 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