package com.openrobot.touchrobot;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.openrobot.common.AmarinoService;
import com.openrobot.common.CameraPreviewFeed;
import com.openrobot.common.CameraPreviewFeedInterface;
import com.openrobot.common.ClientSocketByteService;
import com.openrobot.common.ClientSocketService;
import com.openrobot.common.ClientSocketServiceInterface;
import com.openrobot.common.ControlCommunicationConstants;
import com.openrobot.common.DialogHelper;
import com.openrobot.common.EditTextDialogInterface;
import com.openrobot.common.NetworkHelper;
import com.openrobot.common.PreferenceHelper;
import com.openrobot.common.ServerSocketService;
import com.openrobot.common.ServerSocketServiceInterface;
import com.openrobot.common.ThumbBall;
import com.openrobot.common.ThumbBallListener;
public class BeRobotActivity extends Activity implements ThumbBallListener, ServerSocketServiceInterface,
ClientSocketServiceInterface, EditTextDialogInterface,
CameraPreviewFeedInterface {
private final String DEVICE_ADDRESS = "00:19:5D:EE:25:1C";
private static final char ARDUINO_CONTROL_INPUT_FUNCTION_FLAG = 'c';
private static final char ARDUINO_SHOULD_KILL_FUNCTION_FLAG = 'd';
private final boolean BLUETOOTH_ENABLED = true;
private static final String ARDUINO_MAC_ADDRESS_KEY = "ARDUINO_MAC_ADDRESS";
private static final String VIDEO_CLIENT_PORT_KEY = "VIDEO_CLIENT_PORT";
private static final String VIDEO_CLIENT_IP_KEY = "VIDEO_CLIENT_IP";
private static final String CONTROL_SERVER_PORT_KEY = "CONTROL_SERVER_PORT";
private static final int ARDUINO_MAC_DIALOG_TAG = 1;
private static final int VIDEO_CLIENT_PORT_DIALOG_TAG = 2;
private static final int VIDEO_CLIENT_IP_DIALOG_TAG = 3;
private static final int CONTROL_SERVER_PORT_DIALOG_TAG = 4;
private static final String DEFAULT_ARDUINO_MAC_ADDRESS = "00:19:5D:EE:25:1C";
public static final String DEFAULT_SERVER_IP_ADDRESS = "192.168.0.164";
private static final int DEFAULT_SERVER_PORT_ADDRESS = 8080;
public static final int DEFAULT_CONTROL_SERVER_PORT_ADDRESS = 8090;
public static final int DEFAULT_VIDEO_SERVER_PORT_ADDRESS = 8095;
public final static int DELAY = 150;
public final static int CIRCLE_RADIUS = 40;
private ThumbBall thumbBall;
private TextView xPosTextView;
private TextView yPosTextView;
private FrameLayout main;
private SurfaceView cameraSurfaceView;
private boolean shouldKill = false;
private boolean shouldEnable = false;
private boolean killEnabled = false;
private ServerSocketService mainServerService;
private ServerSocketService controlServerService;
private ClientSocketByteService videoClientService;
private CameraPreviewFeed cameraPreviewFeed;
private long lastChange;
private AmarinoService amarinoService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.be_robot_main);
if (BLUETOOTH_ENABLED) {
Log.d("DEVICE ADDRESS", DEVICE_ADDRESS);
amarinoService = new AmarinoService(this, DEVICE_ADDRESS);
}
lastChange = System.currentTimeMillis();
main = (FrameLayout) findViewById(R.id.main_view);
main.setBackgroundColor(Color.TRANSPARENT); // Was formerly Color.CYAN
xPosTextView = (TextView)findViewById(R.id.x_position_textview);
yPosTextView = (TextView)findViewById(R.id.y_position_textview);
thumbBall = new ThumbBall(this,
(main.getRight() - main.getLeft()) / 2,
(main.getBottom() - main.getTop()) / 2 ,
CIRCLE_RADIUS);
thumbBall.setDelegate(this);
main.addView(thumbBall);
this.cameraSurfaceView = (SurfaceView)findViewById(R.id.preview);
cameraPreviewFeed = new CameraPreviewFeed(this.cameraSurfaceView, this);
}
private void makeMainServerServiceConnection() {
this.destroyMainServerServiceConnection();
mainServerService = new ServerSocketService(this);
mainServerService.makeConnection(DEFAULT_SERVER_PORT_ADDRESS);
}
private void destroyMainServerServiceConnection() {
if (mainServerService != null) {
mainServerService.disconnect();
mainServerService = null;
}
}
private void makeControlServerServiceConnection() {
this.destroyMainServerServiceConnection();
controlServerService = new ServerSocketService(this);
controlServerService.makeConnection(DEFAULT_CONTROL_SERVER_PORT_ADDRESS);
}
private void destroyControlServerServiceConnection() {
if (controlServerService != null) {
controlServerService.disconnect();
controlServerService = null;
}
}
private void makeVideoClientServiceConnection() {
this.destroyVideoClientServiceConnection();
videoClientService = new ClientSocketByteService(this);
videoClientService.makeConnection(this.getVideoClientIP(), this.getVideoClientPort(), false);
}
private void destroyVideoClientServiceConnection() {
if (videoClientService != null) {
videoClientService.disconnect();
videoClientService = null;
}
}
@Override
public void onStart() {
super.onStart();
thumbBall.setX(ThumbBall.FRAME_WIDTH / 2);
thumbBall.setY(ThumbBall.FRAME_HEIGHT / 2);
thumbBall.invalidate();
}
@Override
protected void onStop() {
super.onStop();
// Housekeeping
if (amarinoService != null) {
amarinoService.disconnect();
}
}
@Override
protected void onDestroy() {
// prevents circular reference memory leak ???
if (thumbBall != null) {
thumbBall.setDelegate(null);
}
this.destroyMainServerServiceConnection();
this.destroyControlServerServiceConnection();
this.destroyVideoClientServiceConnection();
if (cameraPreviewFeed != null) {
cameraPreviewFeed.destroy();
cameraPreviewFeed = null;
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.be_robot_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.toggle_control_server_state:
if (controlServerService != null) {
destroyControlServerServiceConnection();
} else {
makeControlServerServiceConnection();
}
return true;
case R.id.toggle_video_client_state:
if (videoClientService != null) {
destroyVideoClientServiceConnection();
} else {
makeVideoClientServiceConnection();
}
return true;
case R.id.set_arduino_mac:
letUserSetArduinoMacAddress();
return true;
case R.id.set_control_server_port:
letUserSetControlServerPort();
return true;
case R.id.set_video_client_port:
this.letUserSetVideoClientPort();
return true;
case R.id.set_video_client_ip:
this.letUserSetVideoClientIP();
return true;
case R.id.control_server_settings:
case R.id.video_client_settings:
case R.id.curr_be_device_ip:
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
MenuItem controlServerItem = menu.findItem(R.id.toggle_control_server_state);
controlServerItem.setTitle(controlServerService != null ? R.string.stop_control_server : R.string.start_control_server);
MenuItem videoClientItem = menu.findItem(R.id.toggle_video_client_state);
videoClientItem.setTitle(videoClientService != null ? R.string.stop_video_client : R.string.start_video_client);
MenuItem currBeDeviceIP = menu.findItem(R.id.curr_be_device_ip);
currBeDeviceIP.setTitle("Device IP: " + NetworkHelper.getLocalIpAddress());
currBeDeviceIP.setEnabled(false);
MenuItem arduinoMACItem = menu.findItem(R.id.set_arduino_mac);
arduinoMACItem.setTitle("Arduino: " + getArduinoMACAddress());
MenuItem setControlServerPort = menu.findItem(R.id.set_control_server_port);
setControlServerPort.setTitle("Control Server Port: " + Integer.toString(this.getControlServerPort()));
MenuItem setVideoClientIP = menu.findItem(R.id.set_video_client_ip);
setVideoClientIP.setTitle("Video Client IP: " + this.getVideoClientIP());
MenuItem setVideoClientPort = menu.findItem(R.id.set_video_client_port);
setVideoClientPort.setTitle("Video Client Port: " + Integer.toString(this.getVideoClientPort()));
return true;
}
// EditTextDialogInterface
public void dialogFinishedWithStatus(boolean positiveStatus, String endingString, int tag) {
if (positiveStatus) {
if (tag == ARDUINO_MAC_DIALOG_TAG) {
this.setArduinoMACAddress(endingString);
} else if (tag == VIDEO_CLIENT_PORT_DIALOG_TAG) {
this.setVideoClientPort(Integer.parseInt(endingString));
} else if (tag == VIDEO_CLIENT_IP_DIALOG_TAG) {
this.setVideoClientIP(endingString);
} else if (tag == CONTROL_SERVER_PORT_DIALOG_TAG) {
this.setControlServerPort(Integer.parseInt(endingString));
}
}
}
// ThumbBallInterface
@Override
public void thumbBallPositionChanged(ThumbBall tb) {
Log.d("OUTPUT", "X: " + tb.getX() + " Y: " + tb.getY());
xPosTextView.setText(Integer.toString(tb.translatedX()));
yPosTextView.setText(Integer.toString(-tb.translatedY()));
<<<<<<< HEAD
/*
if (videoClientService != null && videoClientService.isConnected()) {
Float xFloat = new Float(thumbBall.getX());
Float yFloat = new Float(thumbBall.getY());
String stringToSend = xFloat.toString() + ControlCommunicationConstants.DELIMITER + yFloat.toString();
if (!videoClientService.sendStringToServer(stringToSend)) {
Log.d("TouchControl", "VideoClientService wasn't able to send String");
}
}
*/
=======
>>>>>>> 547a8b05736be17fe026a741d43f1b348a63b535
this.messageArduinoIfAppropriate((int)thumbBall.getX(), (int)thumbBall.getY());
}
// *****************************
// CameraPreviewFeedInterface
// *****************************
public void newImageFromCameraPreviewFeed(CameraPreviewFeed theFeed, byte[] theImage) {
if (videoClientService != null) {
videoClientService.sendByteArrayToServer(theImage);
}
}
// *****************************
// ServerSocketServiceInterface
// *****************************
@Override
public void serverServiceStatusChange(ServerSocketService theService, String message, int status) {
Log.d("OUTPUT", message);
}
@Override
public String serverServiceReceivedMessage(ServerSocketService service, String message) {
String[] splitArray = message.split(ControlCommunicationConstants.DELIMITER);
if (service == mainServerService) {
Log.d("OUTPUT", "Message: " + message);
String response = null;
if (splitArray.length >= 1) {
if (splitArray[0].equalsIgnoreCase(ControlCommunicationConstants.REQUEST_TYPE_CONTROL_CONNECTION)) {
if (controlServerService != null) { // already bound
response = ControlCommunicationConstants.REQUEST_STATUS_FAILURE;
} else {
response = ControlCommunicationConstants.REQUEST_STATUS_SUCCESS + ControlCommunicationConstants.DELIMITER + ControlCommunicationConstants.RESPONSE_TYPE_CONTROL_CONNECTION + ControlCommunicationConstants.DELIMITER + BeRobotActivity.DEFAULT_CONTROL_SERVER_PORT_ADDRESS;
return response;
}
}
}
return response;
} else if (service == controlServerService) {
//Log.d("OUTPUT", "Message: " + message);
if (splitArray.length >= 2) {
float x = Float.parseFloat(((String)splitArray[0]));
float y = Float.parseFloat(((String)splitArray[1]));
Log.d("OUTPUT", splitArray[0] + ", " + x + " " + splitArray[1] + ", " + y);
thumbBall.setX(x);
thumbBall.setY(y);
thumbBall.invalidate();
this.messageArduinoIfAppropriate((int)thumbBall.getX(), (int)thumbBall.getScaledY(0.3f));
}
return null;
}
return null;
}
// *****************************
// ClientSocketServiceInterface
// *****************************
public void clientServiceStatusChange(ClientSocketService theService, String message, int status) {
Log.d("OUTPUT", message);
}
public String messageToSend() {
return null;
}
public void clientServiceReceivedResponse(ClientSocketService theClientService, String response) {
}
private void messageArduinoIfAppropriate(int x, int y) {
if (shouldKill || shouldEnable) {
// Send unconditional kill or resume message
if (BLUETOOTH_ENABLED) {
if (amarinoService != null) {
amarinoService.sendIntToArduino(shouldKill ? 1 : 0, ARDUINO_SHOULD_KILL_FUNCTION_FLAG);
}
lastChange = System.currentTimeMillis();
}
shouldKill = false;
shouldEnable = false;
thumbBall.zeroThumbBallPosition();
return;
}
if (System.currentTimeMillis() - lastChange > DELAY ) {
lastChange = System.currentTimeMillis();
int[] values = new int[2];
values[0] = x;
values[1] = y;
Log.d("OUTPUT", "X: " + x + ", " + "Y:" + y);
if (BLUETOOTH_ENABLED) {
if (amarinoService != null) {
amarinoService.sendIntArrayToArduino(values, ARDUINO_CONTROL_INPUT_FUNCTION_FLAG);
}
}
}
}
// ***************************
// VideoClientService Settings
// ***************************
private int getVideoClientPort() {
return PreferenceHelper.getPreferenceIntForKey(this, VIDEO_CLIENT_PORT_KEY, BeRobotActivity.DEFAULT_VIDEO_SERVER_PORT_ADDRESS);
}
private void setVideoClientPort(int newPort) {
PreferenceHelper.setPreferenceIntForKey(this, VIDEO_CLIENT_PORT_KEY, newPort);
}
private void letUserSetVideoClientPort() {
DialogHelper.textEntryAlertDialog(this, "Video Client Port",
Integer.toString(this.getVideoClientPort()), this, VIDEO_CLIENT_PORT_DIALOG_TAG).show();
}
private String getVideoClientIP() {
return PreferenceHelper.getPreferenceStringForKey(this, VIDEO_CLIENT_IP_KEY, BeRobotActivity.DEFAULT_SERVER_IP_ADDRESS);
}
private void setVideoClientIP(String newIP) {
PreferenceHelper.setPreferenceStringForKey(this, VIDEO_CLIENT_IP_KEY, newIP);
}
private void letUserSetVideoClientIP() {
DialogHelper.textEntryAlertDialog(this, "Video Client IP",
this.getVideoClientIP(), this, VIDEO_CLIENT_IP_DIALOG_TAG).show();
}
// *****************************
// ControlServerService Settings
// *****************************
private int getControlServerPort() {
return PreferenceHelper.getPreferenceIntForKey(this, CONTROL_SERVER_PORT_KEY, BeRobotActivity.DEFAULT_CONTROL_SERVER_PORT_ADDRESS);
}
private void setControlServerPort(int newPort) {
PreferenceHelper.setPreferenceIntForKey(this, CONTROL_SERVER_PORT_KEY, newPort);
}
private void letUserSetControlServerPort() {
DialogHelper.textEntryAlertDialog(this, "Control Server Port",
Integer.toString(this.getControlServerPort()), this, CONTROL_SERVER_PORT_DIALOG_TAG).show();
}
// *****************************
// Arduino MAC Address settings
// *****************************
private String getArduinoMACAddress() {
return PreferenceHelper.getPreferenceStringForKey(this, ARDUINO_MAC_ADDRESS_KEY, DEFAULT_ARDUINO_MAC_ADDRESS);
}
private void setArduinoMACAddress(String newAddress) {
PreferenceHelper.setPreferenceStringForKey(this, ARDUINO_MAC_ADDRESS_KEY, newAddress);
}
private void letUserSetArduinoMacAddress() {
DialogHelper.textEntryAlertDialog(this, "Set Arduino MAC",
this.getArduinoMACAddress(), this, ARDUINO_MAC_DIALOG_TAG).show();
}
}