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 20import socket 21import threading 22 23HOST = os.environ.get('AP_HOST', None) 24PORT = os.environ.get('AP_PORT', 9999) 25 26 27class SL4NException(Exception): 28 pass 29 30 31class SL4NAPIError(SL4NException): 32 """Raised when remote API reports an error.""" 33 34 35class SL4NProtocolError(SL4NException): 36 """Raised when there is an error exchanging data with the device server.""" 37 NO_RESPONSE_FROM_HANDSHAKE = "No response from handshake." 38 NO_RESPONSE_FROM_SERVER = "No response from server." 39 MISMATCHED_API_ID = "Mismatched API id." 40 41 42def IDCounter(): 43 i = 0 44 while True: 45 yield i 46 i += 1 47 48 49class NativeAndroid(RpcConnection): 50 COUNTER = IDCounter() 51 52 def _rpc(self, method, *args): 53 with self._lock: 54 apiid = next(self._counter) 55 data = {'id': apiid, 'method': method, 'params': args} 56 request = json.dumps(data) 57 self.client.write(request.encode("utf8") + b'\n') 58 self.client.flush() 59 response = self.client.readline() 60 if not response: 61 raise SL4NProtocolError(SL4NProtocolError.NO_RESPONSE_FROM_SERVER) 62 #TODO: (tturney) fix the C side from sending \x00 char over the socket. 63 result = json.loads( 64 str(response, encoding="utf8").rstrip().replace("\x00", "")) 65 if result['error']: 66 raise SL4NAPIError(result['error']) 67 if result['id'] != apiid: 68 raise SL4NProtocolError(SL4NProtocolError.MISMATCHED_API_ID) 69 return result['result'] 70