Refactor finders classes.
Change-Id: Icaf80e1ff13bca059f6ee42a56f36a4b3f65a3fb
This commit is contained in:
committed by
Michael Meeks
parent
19015bd364
commit
d170ecde6c
@@ -10,9 +10,7 @@ package org.libreoffice.impressremote.communication;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import org.libreoffice.impressremote.Globals;
|
|
||||||
import org.libreoffice.impressremote.communication.Server.Protocol;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@@ -22,93 +20,126 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class BluetoothFinder {
|
import org.libreoffice.impressremote.communication.Server.Protocol;
|
||||||
|
|
||||||
|
public class BluetoothFinder extends BroadcastReceiver {
|
||||||
// TODO: add removal of cached items
|
// TODO: add removal of cached items
|
||||||
private Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
BluetoothAdapter mAdapter;
|
private final Map<String, Server> mServers;
|
||||||
|
|
||||||
public BluetoothFinder(Context aContext) {
|
public BluetoothFinder(Context aContext) {
|
||||||
mContext = aContext;
|
mContext = aContext;
|
||||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
||||||
|
mServers = new HashMap<String, Server>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startFinding() {
|
public void startSearch() {
|
||||||
Log.i(Globals.TAG, "BluetoothFinder.startFinding(): mAdapter=" + mAdapter);
|
if (!isBluetoothAvailable()) {
|
||||||
if (mAdapter == null) {
|
return;
|
||||||
return; // No bluetooth adapter found (emulator, special devices)
|
|
||||||
}
|
}
|
||||||
IntentFilter aFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
|
|
||||||
aFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
|
BluetoothAdapter.getDefaultAdapter().startDiscovery();
|
||||||
aFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
|
|
||||||
mContext.registerReceiver(mReceiver, aFilter);
|
registerSearchResultsReceiver();
|
||||||
mAdapter.startDiscovery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopFinding() {
|
private boolean isBluetoothAvailable() {
|
||||||
Log.i(Globals.TAG, "BluetoothFinder.stopFinding(): mAdapter=" + mAdapter);
|
return BluetoothAdapter.getDefaultAdapter() != null;
|
||||||
if (mAdapter == null) {
|
}
|
||||||
return; // No bluetooth adapter found (emulator, special devices)
|
|
||||||
}
|
private void registerSearchResultsReceiver() {
|
||||||
mAdapter.cancelDiscovery();
|
IntentFilter aIntentFilter = new IntentFilter(
|
||||||
try {
|
BluetoothDevice.ACTION_FOUND);
|
||||||
mContext.unregisterReceiver(mReceiver);
|
aIntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
|
||||||
} catch (IllegalArgumentException e) {
|
aIntentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||||
// The receiver wasn't registered
|
|
||||||
Log.i(Globals.TAG, "BluetoothFinder.stopFinding: " + e);
|
mContext.registerReceiver(this, aIntentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopSearch() {
|
||||||
|
if (!isBluetoothAvailable()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
|
||||||
|
|
||||||
|
unregisterSearchResultsReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<String, Server> mServerList = new HashMap<String, Server>();
|
private void unregisterSearchResultsReceiver() {
|
||||||
|
mContext.unregisterReceiver(this);
|
||||||
public Collection<Server> getServerList() {
|
|
||||||
return mServerList.values();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
public Collection<Server> getServers() {
|
||||||
|
return mServers.values();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent aIntent) {
|
public void onReceive(Context aContext, Intent aIntent) {
|
||||||
Log.i(Globals.TAG, "BluetoothFinder: BroadcastReceiver.onReceive: aIntent=" + aIntent);
|
if (aIntent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
|
||||||
if (aIntent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
|
BluetoothDevice aBluetoothDevice = (BluetoothDevice) aIntent
|
||||||
BluetoothDevice aDevice = (BluetoothDevice) aIntent.getExtras()
|
.getExtras().get(BluetoothDevice.EXTRA_DEVICE);
|
||||||
.get(BluetoothDevice.EXTRA_DEVICE);
|
|
||||||
Log.i(Globals.TAG, "BluetoothFinder.onReceive: found " + aDevice.getName() + " at " + aDevice.getAddress());
|
if (aBluetoothDevice == null) {
|
||||||
if (aDevice.getName() == null)
|
return;
|
||||||
return;
|
|
||||||
Server aServer = new Server(Protocol.BLUETOOTH,
|
|
||||||
aDevice.getAddress(), aDevice.getName(),
|
|
||||||
System.currentTimeMillis());
|
|
||||||
mServerList.put(aServer.getAddress(), aServer);
|
|
||||||
Intent aNIntent = new Intent(
|
|
||||||
CommunicationService.MSG_SERVERLIST_CHANGED);
|
|
||||||
LocalBroadcastManager.getInstance(mContext).sendBroadcast(
|
|
||||||
aNIntent);
|
|
||||||
} else if (aIntent.getAction().equals(
|
|
||||||
BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
|
|
||||||
|| aIntent.getAction()
|
|
||||||
.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
|
|
||||||
// Start discovery again after a small delay.
|
|
||||||
// but check whether device is on incase the user manually
|
|
||||||
// disabled bluetooth
|
|
||||||
if (mAdapter.isEnabled()) {
|
|
||||||
Handler aHandler = new Handler();
|
|
||||||
aHandler.postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Looping, huh?
|
|
||||||
Log.i(Globals.TAG, "BluetothFinder: looping");
|
|
||||||
}
|
|
||||||
}, 1000 * 15);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createServer(aBluetoothDevice);
|
||||||
|
|
||||||
|
callUpdatingServersList();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
if (aIntent.getAction()
|
||||||
|
.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
|
||||||
|
startDiscoveryDelayed();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aIntent.getAction()
|
||||||
|
.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
|
||||||
|
startDiscoveryDelayed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createServer(BluetoothDevice aBluetoothDevice) {
|
||||||
|
String aServerAddress = aBluetoothDevice.getAddress();
|
||||||
|
String aServerName = aBluetoothDevice.getName();
|
||||||
|
|
||||||
|
Server aServer = new Server(Protocol.BLUETOOTH, aServerAddress,
|
||||||
|
aServerName, System.currentTimeMillis());
|
||||||
|
mServers.put(aServerAddress, aServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callUpdatingServersList() {
|
||||||
|
Intent aServersListChangedIntent = new Intent(
|
||||||
|
CommunicationService.MSG_SERVERLIST_CHANGED);
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(mContext)
|
||||||
|
.sendBroadcast(aServersListChangedIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startDiscoveryDelayed() {
|
||||||
|
// Start discovery again after a small delay.
|
||||||
|
// but check whether device is on in case the user manually
|
||||||
|
// disabled bluetooth
|
||||||
|
|
||||||
|
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler aHandler = new Handler();
|
||||||
|
aHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Looping, huh?
|
||||||
|
}
|
||||||
|
}, 1000 * 15);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@@ -24,6 +24,7 @@ import android.content.Intent;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@@ -31,7 +32,7 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
|
|
||||||
public class CommunicationService extends Service implements Runnable {
|
public class CommunicationService extends Service implements Runnable {
|
||||||
|
|
||||||
public enum State {
|
public static enum State {
|
||||||
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
|
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ public class CommunicationService extends Service implements Runnable {
|
|||||||
if (aName != null)
|
if (aName != null)
|
||||||
return aName;
|
return aName;
|
||||||
}
|
}
|
||||||
return android.os.Build.MODEL;
|
return Build.MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,20 +140,20 @@ public class CommunicationService extends Service implements Runnable {
|
|||||||
SharedPreferences aPref = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences aPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
boolean bEnableWifi = aPref.getBoolean("option_enablewifi", false);
|
boolean bEnableWifi = aPref.getBoolean("option_enablewifi", false);
|
||||||
if (bEnableWifi)
|
if (bEnableWifi)
|
||||||
mNetworkFinder.startFinding();
|
mNetworkFinder.startSearch();
|
||||||
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (aAdapter != null) {
|
if (aAdapter != null) {
|
||||||
mBluetoothPreviouslyEnabled = aAdapter.isEnabled();
|
mBluetoothPreviouslyEnabled = aAdapter.isEnabled();
|
||||||
if (!mBluetoothPreviouslyEnabled)
|
if (!mBluetoothPreviouslyEnabled)
|
||||||
aAdapter.enable();
|
aAdapter.enable();
|
||||||
mBluetoothFinder.startFinding();
|
mBluetoothFinder.startSearch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopSearching() {
|
public void stopSearching() {
|
||||||
Log.i(Globals.TAG, "CommunicationService.stopSearching()");
|
Log.i(Globals.TAG, "CommunicationService.stopSearching()");
|
||||||
mNetworkFinder.stopFinding();
|
mNetworkFinder.stopSearch();
|
||||||
mBluetoothFinder.stopFinding();
|
mBluetoothFinder.stopSearch();
|
||||||
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (aAdapter != null) {
|
if (aAdapter != null) {
|
||||||
if (!mBluetoothPreviouslyEnabled) {
|
if (!mBluetoothPreviouslyEnabled) {
|
||||||
@@ -165,8 +166,8 @@ public class CommunicationService extends Service implements Runnable {
|
|||||||
Log.i(Globals.TAG, "CommunicationService.connectTo(" + aServer + ")");
|
Log.i(Globals.TAG, "CommunicationService.connectTo(" + aServer + ")");
|
||||||
synchronized (mConnectionVariableMutex) {
|
synchronized (mConnectionVariableMutex) {
|
||||||
if (mState == State.SEARCHING) {
|
if (mState == State.SEARCHING) {
|
||||||
mNetworkFinder.stopFinding();
|
mNetworkFinder.stopSearch();
|
||||||
mBluetoothFinder.stopFinding();
|
mBluetoothFinder.stopSearch();
|
||||||
mState = State.DISCONNECTED;
|
mState = State.DISCONNECTED;
|
||||||
}
|
}
|
||||||
mServerDesired = aServer;
|
mServerDesired = aServer;
|
||||||
@@ -267,8 +268,8 @@ public class CommunicationService extends Service implements Runnable {
|
|||||||
|
|
||||||
public List<Server> getServers() {
|
public List<Server> getServers() {
|
||||||
ArrayList<Server> aServers = new ArrayList<Server>();
|
ArrayList<Server> aServers = new ArrayList<Server>();
|
||||||
aServers.addAll(mNetworkFinder.getServerList());
|
aServers.addAll(mNetworkFinder.getServers());
|
||||||
aServers.addAll(mBluetoothFinder.getServerList());
|
aServers.addAll(mBluetoothFinder.getServers());
|
||||||
aServers.addAll(mManualServers.values());
|
aServers.addAll(mManualServers.values());
|
||||||
return aServers;
|
return aServers;
|
||||||
}
|
}
|
||||||
@@ -324,7 +325,6 @@ public class CommunicationService extends Service implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeServer(Server aServer) {
|
public void removeServer(Server aServer) {
|
||||||
|
|
||||||
mManualServers.remove(aServer.getAddress());
|
mManualServers.remove(aServer.getAddress());
|
||||||
|
|
||||||
SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
|
SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
|
||||||
|
@@ -80,7 +80,7 @@ public class NetworkClient extends Client {
|
|||||||
String aPhoneName = CommunicationService.getDeviceName();
|
String aPhoneName = CommunicationService.getDeviceName();
|
||||||
|
|
||||||
sendCommand(Protocol.Commands
|
sendCommand(Protocol.Commands
|
||||||
.prepareCommand(Protocol.Commands.PAIR, aPhoneName, mPin));
|
.prepareCommand(Protocol.Commands.PAIR_WITH_SERVER, aPhoneName, mPin));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -22,9 +22,18 @@ final class Protocol {
|
|||||||
private Ports() {
|
private Ports() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final int SERVER_SEARCH = 1598;
|
||||||
public static final int CLIENT_CONNECTION = 1599;
|
public static final int CLIENT_CONNECTION = 1599;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class Addresses {
|
||||||
|
private Addresses() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String SERVER_SEARCH = "239.0.0.1";
|
||||||
|
public static final String SERVER_LOCAL_FOR_EMULATOR = "10.0.2.2";
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Messages {
|
public static final class Messages {
|
||||||
private Messages() {
|
private Messages() {
|
||||||
}
|
}
|
||||||
@@ -43,7 +52,8 @@ final class Protocol {
|
|||||||
private Commands() {
|
private Commands() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String PAIR = "LO_SERVER_CLIENT_PAIR";
|
public static final String PAIR_WITH_SERVER = "LO_SERVER_CLIENT_PAIR";
|
||||||
|
public static final String SEARCH_SERVERS = "LOREMOTE_SEARCH";
|
||||||
|
|
||||||
public static final String TRANSITION_NEXT = "transition_next";
|
public static final String TRANSITION_NEXT = "transition_next";
|
||||||
public static final String TRANSITION_PREVIOUS = "transition_previous";
|
public static final String TRANSITION_PREVIOUS = "transition_previous";
|
||||||
|
@@ -9,43 +9,161 @@
|
|||||||
package org.libreoffice.impressremote.communication;
|
package org.libreoffice.impressremote.communication;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import org.libreoffice.impressremote.Globals;
|
|
||||||
import org.libreoffice.impressremote.communication.Server.Protocol;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class ServerFinder {
|
public class ServerFinder implements Runnable {
|
||||||
|
private final Context mContext;
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private static final int PORT = 1598;
|
|
||||||
private static final String GROUPADDRESS = "239.0.0.1";
|
|
||||||
|
|
||||||
private static final String CHARSET = "UTF-8";
|
|
||||||
|
|
||||||
private static final long SEARCH_INTERVAL = 1000 * 15;
|
|
||||||
|
|
||||||
private DatagramSocket mSocket = null;
|
private DatagramSocket mSocket = null;
|
||||||
|
private Thread mListenerThread;
|
||||||
|
private boolean mFinishRequested;
|
||||||
|
|
||||||
private Thread mListenerThread = null;
|
private final Map<String, Server> mServers;
|
||||||
|
|
||||||
private boolean mFinishRequested = false;
|
|
||||||
|
|
||||||
private HashMap<String, Server> mServerList = new HashMap<String, Server>();
|
|
||||||
|
|
||||||
public ServerFinder(Context aContext) {
|
public ServerFinder(Context aContext) {
|
||||||
mContext = aContext;
|
mContext = aContext;
|
||||||
|
|
||||||
|
mSocket = null;
|
||||||
|
mListenerThread = null;
|
||||||
|
mFinishRequested = false;
|
||||||
|
|
||||||
|
mServers = new HashMap<String, Server>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startSearch() {
|
||||||
|
if (mSocket != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mFinishRequested = false;
|
||||||
|
|
||||||
|
if (mListenerThread == null) {
|
||||||
|
mListenerThread = new Thread(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
mListenerThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
addLocalServerForEmulator();
|
||||||
|
|
||||||
|
long aStartSearchTime = 0;
|
||||||
|
|
||||||
|
setUpSearchSocket();
|
||||||
|
|
||||||
|
while (!mFinishRequested) {
|
||||||
|
if (System
|
||||||
|
.currentTimeMillis() - aStartSearchTime > 1000 * 15) {
|
||||||
|
sendSearchCommand();
|
||||||
|
|
||||||
|
aStartSearchTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
removeStaleServers();
|
||||||
|
}
|
||||||
|
|
||||||
|
listenForServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether we are on an emulator and add it's host to the list of
|
||||||
|
* servers if so (although we do not know whether libo is running on
|
||||||
|
* the host).
|
||||||
|
*/
|
||||||
|
private void addLocalServerForEmulator() {
|
||||||
|
if (!isLocalServerForEmulatorReachable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Server aServer = new Server(Server.Protocol.NETWORK,
|
||||||
|
Protocol.Addresses.SERVER_LOCAL_FOR_EMULATOR, "Android Emulator",
|
||||||
|
0);
|
||||||
|
|
||||||
|
mServers.put(aServer.getAddress(), aServer);
|
||||||
|
|
||||||
|
callUpdatingServersList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLocalServerForEmulatorReachable() {
|
||||||
|
try {
|
||||||
|
InetAddress aLocalServerAddress = InetAddress
|
||||||
|
.getByName(Protocol.Addresses.SERVER_LOCAL_FOR_EMULATOR);
|
||||||
|
|
||||||
|
return aLocalServerAddress.isReachable(100);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callUpdatingServersList() {
|
||||||
|
Intent aIntent = new Intent(
|
||||||
|
CommunicationService.MSG_SERVERLIST_CHANGED);
|
||||||
|
LocalBroadcastManager.getInstance(mContext).sendBroadcast(aIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpSearchSocket() {
|
||||||
|
try {
|
||||||
|
mSocket = new DatagramSocket();
|
||||||
|
mSocket.setSoTimeout(1000 * 10);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
throw new RuntimeException("Unable to open search socket.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendSearchCommand() {
|
||||||
|
try {
|
||||||
|
mSocket.send(buildSearchPacket());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Unable to send search packet.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatagramPacket buildSearchPacket() {
|
||||||
|
try {
|
||||||
|
String aSearchCommand = Protocol.Commands
|
||||||
|
.prepareCommand(Protocol.Commands.SEARCH_SERVERS);
|
||||||
|
|
||||||
|
DatagramPacket aSearchPacket = new DatagramPacket(
|
||||||
|
aSearchCommand.getBytes(), aSearchCommand.length());
|
||||||
|
aSearchPacket.setAddress(
|
||||||
|
InetAddress.getByName(Protocol.Addresses.SERVER_SEARCH));
|
||||||
|
aSearchPacket.setPort(Protocol.Ports.SERVER_SEARCH);
|
||||||
|
|
||||||
|
return aSearchPacket;
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new RuntimeException("Unable to find address to search.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeStaleServers() {
|
||||||
|
for (Server aServer : mServers.values()) {
|
||||||
|
if (aServer.mNoTimeout) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.currentTimeMillis()
|
||||||
|
- aServer
|
||||||
|
.getTimeDiscovered() > 60 * 1000) {
|
||||||
|
mServers
|
||||||
|
.remove(aServer.getAddress());
|
||||||
|
callUpdatingServersList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listenForServer() {
|
private void listenForServer() {
|
||||||
@@ -59,7 +177,8 @@ public class ServerFinder {
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < aBuffer.length; i++) {
|
for (i = 0; i < aBuffer.length; i++) {
|
||||||
if (aPacket.getData()[i] == '\n') {
|
if (aPacket.getData()[i] == '\n') {
|
||||||
aCommand = new String(aPacket.getData(), 0, i, CHARSET);
|
aCommand = new String(aPacket.getData(), 0, i,
|
||||||
|
Protocol.CHARSET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +188,7 @@ public class ServerFinder {
|
|||||||
for (int j = i + 1; j < aBuffer.length; j++) {
|
for (int j = i + 1; j < aBuffer.length; j++) {
|
||||||
if (aPacket.getData()[j] == '\n') {
|
if (aPacket.getData()[j] == '\n') {
|
||||||
aName = new String(aPacket.getData(), i + 1, j - (i + 1),
|
aName = new String(aPacket.getData(), i + 1, j - (i + 1),
|
||||||
CHARSET);
|
Protocol.CHARSET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,13 +196,12 @@ public class ServerFinder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Server aServer = new Server(Server.Protocol.NETWORK, aPacket
|
Server aServer = new Server(Server.Protocol.NETWORK, aPacket
|
||||||
.getAddress().getHostAddress(), aName,
|
.getAddress().getHostAddress(), aName,
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
mServerList.put(aServer.getAddress(), aServer);
|
mServers.put(aServer.getAddress(), aServer);
|
||||||
Log.i(Globals.TAG, "ServerFinder.listenForServer: contains " + aName);
|
|
||||||
|
|
||||||
notifyActivity();
|
callUpdatingServersList();
|
||||||
} catch (java.net.SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
// Ignore -- we want to timeout to enable checking whether we
|
// Ignore -- we want to timeout to enable checking whether we
|
||||||
// should stop listening periodically
|
// should stop listening periodically
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -91,100 +209,17 @@ public class ServerFinder {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startFinding() {
|
public void stopSearch() {
|
||||||
if (mSocket != null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mFinishRequested = false;
|
|
||||||
|
|
||||||
if (mListenerThread == null) {
|
if (mListenerThread == null) {
|
||||||
mListenerThread = new Thread() {
|
return;
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
checkAndAddEmulator();
|
|
||||||
long aTime = 0;
|
|
||||||
try {
|
|
||||||
mSocket = new DatagramSocket();
|
|
||||||
mSocket.setSoTimeout(1000 * 10);
|
|
||||||
while (!mFinishRequested) {
|
|
||||||
if (System.currentTimeMillis() - aTime > SEARCH_INTERVAL) {
|
|
||||||
String aString = "LOREMOTE_SEARCH\n";
|
|
||||||
DatagramPacket aPacket = new DatagramPacket(
|
|
||||||
aString.getBytes(CHARSET),
|
|
||||||
aString.length(),
|
|
||||||
InetAddress.getByName(GROUPADDRESS),
|
|
||||||
PORT);
|
|
||||||
mSocket.send(aPacket);
|
|
||||||
aTime = System.currentTimeMillis();
|
|
||||||
// Remove stale servers
|
|
||||||
for (Server aServer : mServerList.values()) {
|
|
||||||
if (!aServer.mNoTimeout
|
|
||||||
&& System.currentTimeMillis()
|
|
||||||
- aServer.getTimeDiscovered() > 60 * 1000) {
|
|
||||||
mServerList.remove(aServer.getAddress());
|
|
||||||
notifyActivity();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listenForServer();
|
|
||||||
}
|
|
||||||
} catch (SocketException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mListenerThread.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFinishRequested = true;
|
||||||
|
mListenerThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopFinding() {
|
public Collection<Server> getServers() {
|
||||||
if (mListenerThread != null) {
|
return mServers.values();
|
||||||
mFinishRequested = true;
|
|
||||||
mListenerThread = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether we are on an emulator and add it's host to the list of
|
|
||||||
* servers if so (although we do not know whether libo is running on
|
|
||||||
* the host).
|
|
||||||
*/
|
|
||||||
private void checkAndAddEmulator() {
|
|
||||||
try {
|
|
||||||
if (InetAddress.getByName("10.0.2.2").isReachable(100)) {
|
|
||||||
Log.i(Globals.TAG, "ServerFinder.checkAndAddEmulator: NulledNot, whatever that is supposed to mean");
|
|
||||||
Server aServer = new Server(Protocol.NETWORK, "10.0.2.2",
|
|
||||||
"Android Emulator Host", 0);
|
|
||||||
aServer.mNoTimeout = true;
|
|
||||||
mServerList.put(aServer.getAddress(), aServer);
|
|
||||||
notifyActivity();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Probably means we can't connect -- i.e. no emulator host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify the activity that the server list has changed.
|
|
||||||
*/
|
|
||||||
private void notifyActivity() {
|
|
||||||
Intent aIntent = new Intent(CommunicationService.MSG_SERVERLIST_CHANGED);
|
|
||||||
LocalBroadcastManager.getInstance(mContext).sendBroadcast(aIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Server> getServerList() {
|
|
||||||
return mServerList.values();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user