#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import json
from host_controller.tfc import device_info
class RemoteOperationException(Exception):
"""Raised when remote operation fails."""
pass
class RemoteOperation(object):
"""The operation sent to TradeFed remote manager.
Args:
_obj: A JSON object with at least 2 entries, "type" and "version".
"""
CURRENT_PROTOCOL_VERSION = 8
def __init__(self, type, **kwargs):
"""Initializes a remote operation.
Args:
type: A string, the type of the operation.
**kwargs: The arguments which are specific to the operation type.
"""
self._obj = kwargs
self._obj["type"] = type
if "version" not in self._obj:
self._obj["version"] = self.CURRENT_PROTOCOL_VERSION
def ParseResponse(self, response_str):
"""Parses the response to the operation.
Args:
response_str: A JSON string.
Returns:
A JSON object.
Raises:
RemoteOperationException if the response is an error.
"""
response = json.loads(response_str)
if "error" in response:
raise RemoteOperationException(response["error"])
return response
@property
def type(self):
"""Returns the type of this operation."""
return self._obj["type"]
def __str__(self):
"""Converts the JSON object to string."""
return json.dumps(self._obj)
def ListDevices():
"""Creates an operation of listing devices."""
return RemoteOperation("LIST_DEVICES")
def ParseListDevicesResponse(json_obj):
"""Parses ListDevices response to a list of DeviceInfo.
Sample response:
{"serials": [
{"product": "unknown", "battery": "0", "variant": "unknown",
"stub": True, "state": "Available", "build": "unknown",
"serial": "emulator-5554", "sdk": "unknown"},
]}
Args:
json_obj: A JSON object, the response to ListDevices.
Returns:
A list of DeviceInfo object.
"""
dev_infos = []
for dev_obj in json_obj["serials"]:
if dev_obj["product"] == dev_obj["variant"]:
run_target = dev_obj["product"]
else:
run_target = dev_obj["product"] + ":" + dev_obj["variant"]
dev_info = device_info.DeviceInfo(
battery_level=dev_obj["battery"],
build_id=dev_obj["build"],
device_serial=dev_obj["serial"],
product=dev_obj["product"],
product_variant=dev_obj["variant"],
run_target=run_target,
sdk_version=dev_obj["sdk"],
state=dev_obj["state"],
stub=dev_obj["stub"])
dev_infos.append(dev_info)
return dev_infos
def AllocateDevice(serial):
"""Creates an operation of allocating a device.
Args:
serial: The serial number of the device.
"""
return RemoteOperation("ALLOCATE_DEVICE", serial=serial)
def FreeDevice(serial):
"""Creates an operation of freeing a device.
Args:
serial: The serial number of the device.
"""
return RemoteOperation("FREE_DEVICE", serial=serial)
def Close():
"""Creates an operation of stopping the remote manager."""
return RemoteOperation("CLOSE")
def AddCommand(time, *command_args):
"""Creates an operation of adding a command to the queue.
Args:
time: The time in ms that the command has been executing for. The value
is non-zero in handover situation.
command_args: The command to execute.
"""
return RemoteOperation("ADD_COMMAND", time=time, commandArgs=command_args)
def ExecuteCommand(serial, *command_args):
"""Creates an operation of executing a command on a device.
Args:
serial: The serial number of the device.
command_args: The command to execute.
"""
return RemoteOperation(
"EXEC_COMMAND", serial=serial, commandArgs=command_args)
def GetLastCommandResult(serial):
"""Creates an operation of getting last EXEC_COMMAND result on a device.
Sample response:
{"status": "INVOCATION_ERROR",
"invocation_error": "java.lang.NullPointerException",
"free_device_state": "AVAILABLE"
}
Args:
serial: The serial number of the device.
"""
return RemoteOperation("GET_LAST_COMMAND_RESULT", serial=serial)