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(); } }