1# Copyright 2016 Google Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Shared library for frontends to jsonrpc servers.""" 15 16import code 17import os 18import pprint 19import sys 20 21from mobly.controllers import android_device 22 23 24class Error(Exception): 25 pass 26 27 28class JsonRpcShellBase: 29 30 def _start_services(self, console_env): 31 """Starts the services needed by this client and adds them to console_env. 32 33 Must be implemented by subclasses. 34 """ 35 raise NotImplementedError() 36 37 def _get_banner(self, serial): 38 """Returns the user-friendly banner message to print before the console. 39 40 Must be implemented by subclasses. 41 """ 42 raise NotImplementedError() 43 44 def load_device(self, serial=None): 45 """Creates an AndroidDevice for the given serial number. 46 47 If no serial is given, it will read from the ANDROID_SERIAL 48 environmental variable. If the environmental variable is not set, then 49 it will read from 'adb devices' if there is only one. 50 """ 51 serials = android_device.list_adb_devices() 52 if not serials: 53 raise Error('No adb device found!') 54 # No serial provided, try to pick up the device automatically. 55 if not serial: 56 env_serial = os.environ.get('ANDROID_SERIAL', None) 57 if env_serial is not None: 58 serial = env_serial 59 elif len(serials) == 1: 60 serial = serials[0] 61 else: 62 raise Error('Expected one phone, but %d found. Use the -s flag or ' 63 'specify ANDROID_SERIAL.' % len(serials)) 64 if serial not in serials: 65 raise Error('Device "%s" is not found by adb.' % serial) 66 ads = android_device.get_instances([serial]) 67 assert len(ads) == 1 68 self._ad = ads[0] 69 70 def start_console(self): 71 # Set up initial console environment 72 console_env = { 73 'ad': self._ad, 74 'pprint': pprint.pprint, 75 } 76 77 # Start the services 78 self._start_services(console_env) 79 80 # Start the console 81 console_banner = self._get_banner(self._ad.serial) 82 code.interact(banner=console_banner, local=console_env) 83 84 # Tear everything down 85 self._ad.services.stop_all() 86 87 def main(self, serial=None): 88 try: 89 self.load_device(serial) 90 except Error as e: 91 print('ERROR: %s' % e, file=sys.stderr) 92 sys.exit(1) 93 self.start_console() 94