Fields Summary |
---|
private static final String | DEFAULT_ENCODING |
private static final int | WAIT_TIME |
private static final int | STD_TIMEOUT |
private static final String | HOST |
private static final String | COMMAND_PING |
private static final String | COMMAND_AVD_NAME |
private static final String | COMMAND_KILL |
private static final String | COMMAND_GSM_STATUS |
private static final String | COMMAND_GSM_CALL |
private static final String | COMMAND_GSM_CANCEL_CALL |
private static final String | COMMAND_GSM_DATA |
private static final String | COMMAND_GSM_VOICE |
private static final String | COMMAND_SMS_SEND |
private static final String | COMMAND_NETWORK_STATUS |
private static final String | COMMAND_NETWORK_SPEED |
private static final String | COMMAND_NETWORK_LATENCY |
private static final String | COMMAND_GPS |
private static final Pattern | RE_KO |
public static final int[] | MIN_LATENCIESArray of delay values: no delay, gprs, edge/egprs, umts/3d |
public final int[] | DOWNLOAD_SPEEDSArray of download speeds: full speed, gsm, hscsd, gprs, edge/egprs, umts/3g, hsdpa. |
public static final String[] | NETWORK_SPEEDSArrays of valid network speeds |
public static final String[] | NETWORK_LATENCIESArrays of valid network latencies |
public static final String | RESULT_OK |
private static final Pattern | sEmulatorRegexp |
private static final Pattern | sVoiceStatusRegexp |
private static final Pattern | sDataStatusRegexp |
private static final Pattern | sDownloadSpeedRegexp |
private static final Pattern | sMinLatencyRegexp |
private static final HashMap | sEmulators |
private int | mPort |
private SocketChannel | mSocketChannel |
private byte[] | mBuffer |
Methods Summary |
---|
private static synchronized void | RemoveConsole(int port)Removes the console object associated with a port from the map.
sEmulators.remove(port);
|
public synchronized java.lang.String | call(java.lang.String number)Initiate an incoming call on the emulator.
String command = String.format(COMMAND_GSM_CALL, number);
return processCommand(command);
|
public synchronized java.lang.String | cancelCall(java.lang.String number)Cancels a current call.
String command = String.format(COMMAND_GSM_CANCEL_CALL, number);
return processCommand(command);
|
private boolean | endsWithOK(int currentPosition)Returns true if the 4 characters *before* the current position are "OK\r\n"
if (mBuffer[currentPosition-1] == '\n" &&
mBuffer[currentPosition-2] == '\r" &&
mBuffer[currentPosition-3] == 'K" &&
mBuffer[currentPosition-4] == 'O") {
return true;
}
return false;
|
public synchronized java.lang.String | getAvdName()
if (sendCommand(COMMAND_AVD_NAME)) {
String[] result = readLines();
if (result != null && result.length == 2) { // this should be the name on first line,
// and ok on 2nd line
return result[0];
} else {
// try to see if there's a message after KO
Matcher m = RE_KO.matcher(result[result.length-1]);
if (m.matches()) {
return m.group(1);
}
}
}
return null;
|
public static synchronized com.android.ddmlib.EmulatorConsole | getConsole(Device d)Returns an {@link EmulatorConsole} object for the given {@link Device}. This can
be an already existing console, or a new one if it hadn't been created yet.
// we need to make sure that the device is an emulator
Matcher m = sEmulatorRegexp.matcher(d.serialNumber);
if (m.matches()) {
// get the port number. This is the console port.
int port;
try {
port = Integer.parseInt(m.group(1));
if (port <= 0) {
return null;
}
} catch (NumberFormatException e) {
// looks like we failed to get the port number. This is a bit strange since
// it's coming from a regexp that only accept digit, but we handle the case
// and return null.
return null;
}
EmulatorConsole console = sEmulators.get(port);
if (console != null) {
// if the console exist, we ping the emulator to check the connection.
if (console.ping() == false) {
RemoveConsole(console.mPort);
console = null;
}
}
if (console == null) {
// no console object exists for this port so we create one, and start
// the connection.
console = new EmulatorConsole(port);
if (console.start()) {
sEmulators.put(port, console);
} else {
console = null;
}
}
return console;
}
return null;
|
public synchronized com.android.ddmlib.EmulatorConsole$GsmStatus | getGsmStatus()Returns the current gsm status of the emulator
if (sendCommand(COMMAND_GSM_STATUS)) {
/*
* result is in the format:
* gsm status
* gsm voice state: home
* gsm data state: home
*/
String[] result = readLines();
if (isValid(result)) {
GsmStatus status = new GsmStatus();
// let's not rely on the order of the output, and simply loop through
// the line testing the regexp.
for (String line : result) {
Matcher m = sVoiceStatusRegexp.matcher(line);
if (m.matches()) {
// get the string value
String value = m.group(1);
// get the index from the list
status.voice = GsmMode.getEnum(value.toLowerCase());
// move on to next line.
continue;
}
m = sDataStatusRegexp.matcher(line);
if (m.matches()) {
// get the string value
String value = m.group(1);
// get the index from the list
status.data = GsmMode.getEnum(value.toLowerCase());
// move on to next line.
continue;
}
}
return status;
}
}
return null;
|
private int | getLatencyIndex(java.lang.String value)
try {
// get the int value
int latency = Integer.parseInt(value);
// check for the speed from the index
for (int i = 0 ; i < MIN_LATENCIES.length; i++) {
if (MIN_LATENCIES[i] == latency) {
return i;
}
}
} catch (NumberFormatException e) {
// Do nothing, we'll just return -1.
}
return -1;
|
public synchronized com.android.ddmlib.EmulatorConsole$NetworkStatus | getNetworkStatus()Get the network status of the emulator.
if (sendCommand(COMMAND_NETWORK_STATUS)) {
/* Result is in the format
Current network status:
download speed: 14400 bits/s (1.8 KB/s)
upload speed: 14400 bits/s (1.8 KB/s)
minimum latency: 0 ms
maximum latency: 0 ms
*/
String[] result = readLines();
if (isValid(result)) {
// we only compare agains the min latency and the download speed
// let's not rely on the order of the output, and simply loop through
// the line testing the regexp.
NetworkStatus status = new NetworkStatus();
for (String line : result) {
Matcher m = sDownloadSpeedRegexp.matcher(line);
if (m.matches()) {
// get the string value
String value = m.group(1);
// get the index from the list
status.speed = getSpeedIndex(value);
// move on to next line.
continue;
}
m = sMinLatencyRegexp.matcher(line);
if (m.matches()) {
// get the string value
String value = m.group(1);
// get the index from the list
status.latency = getLatencyIndex(value);
// move on to next line.
continue;
}
}
return status;
}
}
return null;
|
private int | getSpeedIndex(java.lang.String value)
try {
// get the int value
int speed = Integer.parseInt(value);
// check for the speed from the index
for (int i = 0 ; i < DOWNLOAD_SPEEDS.length; i++) {
if (DOWNLOAD_SPEEDS[i] == speed) {
return i;
}
}
} catch (NumberFormatException e) {
// Do nothing, we'll just return -1.
}
return -1;
|
private boolean | isValid(java.lang.String[] result)Returns true if the last line of the result does not start with KO
if (result != null && result.length > 0) {
return !(RE_KO.matcher(result[result.length-1]).matches());
}
return false;
|
public synchronized void | kill()Sends a KILL command to the emulator.
if (sendCommand(COMMAND_KILL)) {
RemoveConsole(mPort);
}
|
private boolean | lastLineIsKO(int currentPosition)Returns true if the last line starts with KO and is also terminated by \r\n
// first check that the last 2 characters are CRLF
if (mBuffer[currentPosition-1] != '\n" ||
mBuffer[currentPosition-2] != '\r") {
return false;
}
// now loop backward looking for the previous CRLF, or the beginning of the buffer
int i = 0;
for (i = currentPosition-3 ; i >= 0; i--) {
if (mBuffer[i] == '\n") {
// found \n!
if (i > 0 && mBuffer[i-1] == '\r") {
// found \r!
break;
}
}
}
// here it is either -1 if we reached the start of the buffer without finding
// a CRLF, or the position of \n. So in both case we look at the characters at i+1 and i+2
if (mBuffer[i+1] == 'K" && mBuffer[i+2] == 'O") {
// found error!
return true;
}
return false;
|
private synchronized boolean | ping()Ping the emulator to check if the connection is still alive.
// it looks like we can send stuff, even when the emulator quit, but we can't read
// from the socket. So we check the return of readLines()
if (sendCommand(COMMAND_PING)) {
return readLines() != null;
}
return false;
|
private java.lang.String | processCommand(java.lang.String command)Sends a command to the emulator and parses its answer.
if (sendCommand(command)) {
String[] result = readLines();
if (result != null && result.length > 0) {
Matcher m = RE_KO.matcher(result[result.length-1]);
if (m.matches()) {
return m.group(1);
}
return RESULT_OK;
}
return "Unable to communicate with the emulator";
}
return "Unable to send command to the emulator";
|
private java.lang.String[] | readLines()Reads line from the console socket. This call is blocking until we read the lines:
try {
ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
int numWaits = 0;
boolean stop = false;
while (buf.position() != buf.limit() && stop == false) {
int count;
count = mSocketChannel.read(buf);
if (count < 0) {
return null;
} else if (count == 0) {
if (numWaits * WAIT_TIME > STD_TIMEOUT) {
return null;
}
// non-blocking spin
try {
Thread.sleep(WAIT_TIME);
} catch (InterruptedException ie) {
}
numWaits++;
} else {
numWaits = 0;
}
// check the last few char aren't OK. For a valid message to test
// we need at least 4 bytes (OK/KO + \r\n)
if (buf.position() >= 4) {
int pos = buf.position();
if (endsWithOK(pos) || lastLineIsKO(pos)) {
stop = true;
}
}
}
String msg = new String(mBuffer, 0, buf.position(), DEFAULT_ENCODING);
return msg.split("\r\n"); //$NON-NLS-1$
} catch (IOException e) {
return null;
}
|
private boolean | sendCommand(java.lang.String command)Sends a command to the emulator console.
boolean result = false;
try {
byte[] bCommand;
try {
bCommand = command.getBytes(DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
// wrong encoding...
return result;
}
// write the command
AdbHelper.write(mSocketChannel, bCommand, bCommand.length, AdbHelper.STD_TIMEOUT);
result = true;
} catch (IOException e) {
return false;
} finally {
if (result == false) {
// FIXME connection failed somehow, we need to disconnect the console.
RemoveConsole(mPort);
}
}
return result;
|
public synchronized java.lang.String | sendLocation(double longitude, double latitude, double elevation)
Calendar c = Calendar.getInstance();
double absLong = Math.abs(longitude);
int longDegree = (int)Math.floor(absLong);
char longDirection = 'E";
if (longitude < 0) {
longDirection = 'W";
}
double longMinute = (absLong - Math.floor(absLong)) * 60;
double absLat = Math.abs(latitude);
int latDegree = (int)Math.floor(absLat);
char latDirection = 'N";
if (latitude < 0) {
latDirection = 'S";
}
double latMinute = (absLat - Math.floor(absLat)) * 60;
String command = String.format(COMMAND_GPS,
c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND),
latDegree, latMinute, latDirection,
longDegree, longMinute, longDirection);
return processCommand(command);
|
public synchronized java.lang.String | sendSms(java.lang.String number, java.lang.String message)Sends an SMS to the emulator
String command = String.format(COMMAND_SMS_SEND, number, message);
return processCommand(command);
|
public synchronized java.lang.String | setGsmDataMode(com.android.ddmlib.EmulatorConsole$GsmMode mode)Sets the GSM data mode.
if (mode == GsmMode.UNKNOWN) {
throw new InvalidParameterException();
}
String command = String.format(COMMAND_GSM_DATA, mode.getTag());
return processCommand(command);
|
public synchronized java.lang.String | setGsmVoiceMode(com.android.ddmlib.EmulatorConsole$GsmMode mode)Sets the GSM voice mode.
if (mode == GsmMode.UNKNOWN) {
throw new InvalidParameterException();
}
String command = String.format(COMMAND_GSM_VOICE, mode.getTag());
return processCommand(command);
|
public synchronized java.lang.String | setNetworkLatency(int selectionIndex)Sets the network latency.
String command = String.format(COMMAND_NETWORK_LATENCY, NETWORK_LATENCIES[selectionIndex]);
return processCommand(command);
|
public synchronized java.lang.String | setNetworkSpeed(int selectionIndex)Sets the network speed.
String command = String.format(COMMAND_NETWORK_SPEED, NETWORK_SPEEDS[selectionIndex]);
return processCommand(command);
|
private boolean | start()Starts the connection of the console.
InetSocketAddress socketAddr;
try {
InetAddress hostAddr = InetAddress.getByName(HOST);
socketAddr = new InetSocketAddress(hostAddr, mPort);
} catch (UnknownHostException e) {
return false;
}
try {
mSocketChannel = SocketChannel.open(socketAddr);
} catch (IOException e1) {
return false;
}
// read some stuff from it
readLines();
return true;
|