Android Open Source - webots-remote-control Client






From Project

Back to project page webots-remote-control.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project webots-remote-control listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.black_mesa.webots_remote_control.client;
//from   ww w .  j  a va2  s  .c  o m
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import org.black_mesa.webots_remote_control.communication_structures.CommunicationStructure;
import org.black_mesa.webots_remote_control.database.Server;
import org.black_mesa.webots_remote_control.listeners.ClientListener;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;

/**
 * This class controls communications between the application and a server.
 * 
 * @author Ilja Kroonen
 * 
 */
public class Client {
  private static final int SENDING_INTERVAL = 32;
  private static final int SOCKET_TIMEOUT = 1000;

  private final Server mServer;

  private ConnectionState mState = ConnectionState.INIT;

  private final ClientListener mListener;

  private final Socket mSocket = new Socket();

  private boolean mDispose = false;

  private final Thread mReceivingThread;
  private final Thread mSendingThread;

  private final SparseArray<CommunicationStructure> mBoarding = new SparseArray<CommunicationStructure>();
  private SparseArray<CommunicationStructure> mInitialData;
  private final SparseArray<List<CommunicationStructure>> mAdditionalData =
      new SparseArray<List<CommunicationStructure>>();

  /**
   * Instantiates a Client and connects it to the server. This allocates
   * resources that you must not forget to free later by calling dispose().
   * 
   * @param server
   *            Server this client will connect to.
   * @param listener
   *            Listener to be notified of state changes and object
   *            receptions.
   */
  public Client(final Server server, final ClientListener listener) {
    mListener = listener;
    mServer = server;

    mReceivingThread = new Thread(new Runnable() {
      @Override
      public void run() {
        initTask();
      }
    });

    mSendingThread = new Thread(new Runnable() {
      @Override
      public void run() {
        sendingTask();
      }
    });

    mReceivingThread.start();
  }

  /**
   * Boards data into the client. It will be sent as soon as possible.
   * 
   * @param data
   *            Data that must be sent to the server.
   */
  public final void board(final CommunicationStructure data) {
    int id = data.getId();
    synchronized (mBoarding) {
      mBoarding.put(id, data.board(mBoarding.get(id)));
    }
  }

  /**
   * Liberates the resources allocated to this client (terminates threads and
   * closes socket).
   */
  public final void dispose() {
    mDispose = true;
  }

  /**
   * Getter for the client state.
   * 
   * @return Current state of the client.
   */
  public final ConnectionState getState() {
    return mState;
  }

  /**
   * When the connection is established, the server sends initial data to the
   * client. The data is available after OnStateChange has been called with
   * CONNECTED as the new state.
   * 
   * @return Initial data received by the client.
   */
  public final SparseArray<CommunicationStructure> getInitialData() {
    // This array will never be modified by the Client, we don't need to
    // copy it
    Log.d(getClass().getName(), "Request for received data");
    Log.d(getClass().getName(), "Returning " + mInitialData.get(0));
    return mInitialData;
  }

  /**
   * Use this function to retrieve additional objects sent by the server.
   * Availability of objects is notified by an OnReception call.
   * 
   * @return Array containing the data.
   */
  public final SparseArray<List<CommunicationStructure>> getAdditionalData() {
    // We need to make a copy of the data, because the reception of a new
    // object would trigger a modification of the array
    SparseArray<List<CommunicationStructure>> ret;
    synchronized (mAdditionalData) {
      ret = mAdditionalData.clone();
    }
    return ret;
  }

  private void initTask() {
    try {
      InetSocketAddress address = new InetSocketAddress(mServer.getAdress(), mServer.getPort());
      mSocket.connect(address, SOCKET_TIMEOUT);
      mSocket.setSoTimeout(SOCKET_TIMEOUT);
    } catch (IOException e) {
      changeState(ConnectionState.CONNECTION_ERROR);
      return;
    }
    mSendingThread.start();
    receivingTask();
    try {
      mSocket.close();
    } catch (IOException e) {
    }
  }

  private void sendingTask() {
    try {
      ObjectOutputStream out = new ObjectOutputStream(mSocket.getOutputStream());

      while (!mDispose) {
        sendingRoutine(out);
      }
    } catch (IOException e) {
      changeState(ConnectionState.CONNECTION_ERROR);
    }
  }

  private void receivingTask() {
    ObjectInputStream in;
    try {
      in = new ObjectInputStream(mSocket.getInputStream());
    } catch (IOException e) {
      changeState(ConnectionState.CONNECTION_ERROR);
      return;
    }

    Integer n;

    try {
      n = (Integer) in.readObject();

      SparseArray<CommunicationStructure> initialData = new SparseArray<CommunicationStructure>();

      for (int i = 0; i < n; i++) {
        CommunicationStructure r = (CommunicationStructure) in.readObject();
        if (!r.checkIntegrity()) {
          changeState(ConnectionState.COMMUNICATION_ERROR);
          return;
        }
        initialData.put(r.getId(), r);
        Log.d(getClass().getName(), "Received object of id " + r.getId());
      }
      mInitialData = initialData;

      changeState(ConnectionState.CONNECTED);

      while (!mDispose) {
        receivingRoutine(in);
      }
    } catch (ClassNotFoundException e) {
      changeState(ConnectionState.COMMUNICATION_ERROR);
    } catch (IOException e) {
      changeState(ConnectionState.CONNECTION_ERROR);
    } catch (ClassCastException e) {
      changeState(ConnectionState.COMMUNICATION_ERROR);
    }
  }

  private void sendingRoutine(final ObjectOutputStream out) throws IOException {
    SparseArray<CommunicationStructure> data;

    synchronized (mBoarding) {
      data = mBoarding.clone();
      mBoarding.clear();
    }

    for (int i = 0; i < data.size(); i++) {
      out.writeObject(data.valueAt(i));
    }

    synchronized (mSendingThread) {
      try {
        mSendingThread.wait(SENDING_INTERVAL);
      } catch (InterruptedException e) {
      }
    }
  }

  private void receivingRoutine(final ObjectInputStream in) throws ClassNotFoundException, IOException {
    CommunicationStructure o;
    try {
      o = (CommunicationStructure) in.readObject();
      synchronized (mAdditionalData) {
        List<CommunicationStructure> l = mAdditionalData.get(o.getId());
        if (l == null) {
          l = new ArrayList<CommunicationStructure>();
          mAdditionalData.put(o.getId(), l);
        }
        l.add(o);
      }
      notifyReception(o);
    } catch (SocketTimeoutException e) {
    }
  }

  private void changeState(final ConnectionState s) {
    if (s != ConnectionState.CONNECTED) {
      mDispose = true;
    }
    mState = s;
    Runnable notification = new Runnable() {
      @Override
      public void run() {
        mListener.onStateChange(mServer, s);
      }
    };
    new Handler(Looper.getMainLooper()).post(notification);
  }

  private void notifyReception(final CommunicationStructure data) {
    Runnable notification = new Runnable() {
      @Override
      public void run() {
        mListener.onReception(mServer, data);
      }
    };
    new Handler(Looper.getMainLooper()).post(notification);
  }
}




Java Source Code List

org.black_mesa.webots_remote_control.activities.AboutFragment.java
org.black_mesa.webots_remote_control.activities.AddServerActivity.java
org.black_mesa.webots_remote_control.activities.CameraFragment.java
org.black_mesa.webots_remote_control.activities.ConnectionFragment.java
org.black_mesa.webots_remote_control.activities.MainActivity.java
org.black_mesa.webots_remote_control.client.CamerasManager.java
org.black_mesa.webots_remote_control.client.Client.java
org.black_mesa.webots_remote_control.client.ConnectionManager.java
org.black_mesa.webots_remote_control.client.ConnectionState.java
org.black_mesa.webots_remote_control.client.package-info.java
org.black_mesa.webots_remote_control.communication_structures.CameraInstructionQueue.java
org.black_mesa.webots_remote_control.communication_structures.CameraInstruction.java
org.black_mesa.webots_remote_control.communication_structures.CommunicationStructure.java
org.black_mesa.webots_remote_control.communication_structures.package-info.java
org.black_mesa.webots_remote_control.database.DataBaseContract.java
org.black_mesa.webots_remote_control.database.DataBaseHelper.java
org.black_mesa.webots_remote_control.database.DataSource.java
org.black_mesa.webots_remote_control.database.ServerListAdapter.java
org.black_mesa.webots_remote_control.database.Server.java
org.black_mesa.webots_remote_control.listeners.CameraJoysticksViewListener.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV1.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV2.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV3.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV4.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV5.java
org.black_mesa.webots_remote_control.listeners.ClientListener.java
org.black_mesa.webots_remote_control.listeners.ConnectionManagerListener.java
org.black_mesa.webots_remote_control.listeners.OnListEventsListener.java
org.black_mesa.webots_remote_control.listeners.package-info.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV1.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV2.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV3.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV4.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV5.java
org.black_mesa.webots_remote_control.utils.package-info.java
org.black_mesa.webots_remote_control.views.CameraJoysticksView.java
org.black_mesa.webots_remote_control.views.CameraView.java