1# 2# Copyright (C) 2017 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import json 18 19from host_controller.tfc import device_info 20 21 22class RemoteOperationException(Exception): 23 """Raised when remote operation fails.""" 24 pass 25 26 27class RemoteOperation(object): 28 """The operation sent to TradeFed remote manager. 29 30 Args: 31 _obj: A JSON object with at least 2 entries, "type" and "version". 32 """ 33 CURRENT_PROTOCOL_VERSION = 8 34 35 def __init__(self, type, **kwargs): 36 """Initializes a remote operation. 37 38 Args: 39 type: A string, the type of the operation. 40 **kwargs: The arguments which are specific to the operation type. 41 """ 42 self._obj = kwargs 43 self._obj["type"] = type 44 if "version" not in self._obj: 45 self._obj["version"] = self.CURRENT_PROTOCOL_VERSION 46 47 def ParseResponse(self, response_str): 48 """Parses the response to the operation. 49 50 Args: 51 response_str: A JSON string. 52 53 Returns: 54 A JSON object. 55 56 Raises: 57 RemoteOperationException if the response is an error. 58 """ 59 response = json.loads(response_str) 60 if "error" in response: 61 raise RemoteOperationException(response["error"]) 62 return response 63 64 @property 65 def type(self): 66 """Returns the type of this operation.""" 67 return self._obj["type"] 68 69 def __str__(self): 70 """Converts the JSON object to string.""" 71 return json.dumps(self._obj) 72 73 74def ListDevices(): 75 """Creates an operation of listing devices.""" 76 return RemoteOperation("LIST_DEVICES") 77 78 79def ParseListDevicesResponse(json_obj): 80 """Parses ListDevices response to a list of DeviceInfo. 81 82 Sample response: 83 {"serials": [ 84 {"product": "unknown", "battery": "0", "variant": "unknown", 85 "stub": True, "state": "Available", "build": "unknown", 86 "serial": "emulator-5554", "sdk": "unknown"}, 87 ]} 88 89 Args: 90 json_obj: A JSON object, the response to ListDevices. 91 92 Returns: 93 A list of DeviceInfo object. 94 """ 95 dev_infos = [] 96 for dev_obj in json_obj["serials"]: 97 if dev_obj["product"] == dev_obj["variant"]: 98 run_target = dev_obj["product"] 99 else: 100 run_target = dev_obj["product"] + ":" + dev_obj["variant"] 101 dev_info = device_info.DeviceInfo( 102 battery_level=dev_obj["battery"], 103 build_id=dev_obj["build"], 104 device_serial=dev_obj["serial"], 105 product=dev_obj["product"], 106 product_variant=dev_obj["variant"], 107 run_target=run_target, 108 sdk_version=dev_obj["sdk"], 109 state=dev_obj["state"], 110 stub=dev_obj["stub"]) 111 dev_infos.append(dev_info) 112 return dev_infos 113 114 115def AllocateDevice(serial): 116 """Creates an operation of allocating a device. 117 118 Args: 119 serial: The serial number of the device. 120 """ 121 return RemoteOperation("ALLOCATE_DEVICE", serial=serial) 122 123 124def FreeDevice(serial): 125 """Creates an operation of freeing a device. 126 127 Args: 128 serial: The serial number of the device. 129 """ 130 return RemoteOperation("FREE_DEVICE", serial=serial) 131 132 133def Close(): 134 """Creates an operation of stopping the remote manager.""" 135 return RemoteOperation("CLOSE") 136 137 138def AddCommand(time, *command_args): 139 """Creates an operation of adding a command to the queue. 140 141 Args: 142 time: The time in ms that the command has been executing for. The value 143 is non-zero in handover situation. 144 command_args: The command to execute. 145 """ 146 return RemoteOperation("ADD_COMMAND", time=time, commandArgs=command_args) 147 148 149def ExecuteCommand(serial, *command_args): 150 """Creates an operation of executing a command on a device. 151 152 Args: 153 serial: The serial number of the device. 154 command_args: The command to execute. 155 """ 156 return RemoteOperation( 157 "EXEC_COMMAND", serial=serial, commandArgs=command_args) 158 159 160def GetLastCommandResult(serial): 161 """Creates an operation of getting last EXEC_COMMAND result on a device. 162 163 Sample response: 164 {"status": "INVOCATION_ERROR", 165 "invocation_error": "java.lang.NullPointerException", 166 "free_device_state": "AVAILABLE" 167 } 168 169 Args: 170 serial: The serial number of the device. 171 """ 172 return RemoteOperation("GET_LAST_COMMAND_RESULT", serial=serial) 173