1#!/usr/bin/env python3 2# 3# Copyright (C) 2009 Google Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16 17from acts.controllers.sl4a_lib.rpc_connection import RpcConnection 18import json 19import os 20 21HOST = os.environ.get('AP_HOST', None) 22PORT = os.environ.get('AP_PORT', 9999) 23 24 25class SL4NException(Exception): 26 pass 27 28 29class SL4NAPIError(SL4NException): 30 """Raised when remote API reports an error.""" 31 32 33class SL4NProtocolError(SL4NException): 34 """Raised when there is an error exchanging data with the device server.""" 35 NO_RESPONSE_FROM_HANDSHAKE = "No response from handshake." 36 NO_RESPONSE_FROM_SERVER = "No response from server." 37 MISMATCHED_API_ID = "Mismatched API id." 38 39 40def IDCounter(): 41 i = 0 42 while True: 43 yield i 44 i += 1 45 46 47class NativeAndroid(RpcConnection): 48 COUNTER = IDCounter() 49 50 def _rpc(self, method, *args): 51 with self._lock: 52 apiid = next(self._counter) 53 data = {'id': apiid, 'method': method, 'params': args} 54 request = json.dumps(data) 55 self.client.write(request.encode("utf8") + b'\n') 56 self.client.flush() 57 response = self.client.readline() 58 if not response: 59 raise SL4NProtocolError(SL4NProtocolError.NO_RESPONSE_FROM_SERVER) 60 #TODO: (tturney) fix the C side from sending \x00 char over the socket. 61 result = json.loads( 62 str(response, encoding="utf8").rstrip().replace("\x00", "")) 63 if result['error']: 64 raise SL4NAPIError(result['error']) 65 if result['id'] != apiid: 66 raise SL4NProtocolError(SL4NProtocolError.MISMATCHED_API_ID) 67 return result['result'] 68