summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorArtur Dryomov <artur.dryomov@gmail.com>2013-06-20 18:23:40 +0300
committerMichael Meeks <michael.meeks@suse.com>2013-07-25 18:01:47 +0100
commitd170ecde6ce91f6be43fe465889de4fa4498d25f (patch)
tree0df652beca8b86f37ba2f43db5188ad5553e6d2f /android
parent19015bd364731a30dccea61d1dfddf096b1a6665 (diff)
Refactor finders classes.
Change-Id: Icaf80e1ff13bca059f6ee42a56f36a4b3f65a3fb
Diffstat (limited to 'android')
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java167
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java22
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java2
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java12
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java263
5 files changed, 271 insertions, 195 deletions
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java b/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java
index 972a8a403074..4ed99a13aa8f 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java
@@ -10,9 +10,7 @@ package org.libreoffice.impressremote.communication;
import java.util.Collection;
import java.util.HashMap;
-
-import org.libreoffice.impressremote.Globals;
-import org.libreoffice.impressremote.communication.Server.Protocol;
+import java.util.Map;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -22,93 +20,126 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
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
- private Context mContext;
+ private final Context mContext;
- BluetoothAdapter mAdapter;
+ private final Map<String, Server> mServers;
public BluetoothFinder(Context aContext) {
mContext = aContext;
- mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ mServers = new HashMap<String, Server>();
}
- public void startFinding() {
- Log.i(Globals.TAG, "BluetoothFinder.startFinding(): mAdapter=" + mAdapter);
- if (mAdapter == null) {
- return; // No bluetooth adapter found (emulator, special devices)
+ public void startSearch() {
+ if (!isBluetoothAvailable()) {
+ return;
}
- IntentFilter aFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
- aFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- aFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- mContext.registerReceiver(mReceiver, aFilter);
- mAdapter.startDiscovery();
+
+ BluetoothAdapter.getDefaultAdapter().startDiscovery();
+
+ registerSearchResultsReceiver();
}
- public void stopFinding() {
- Log.i(Globals.TAG, "BluetoothFinder.stopFinding(): mAdapter=" + mAdapter);
- if (mAdapter == null) {
- return; // No bluetooth adapter found (emulator, special devices)
- }
- mAdapter.cancelDiscovery();
- try {
- mContext.unregisterReceiver(mReceiver);
- } catch (IllegalArgumentException e) {
- // The receiver wasn't registered
- Log.i(Globals.TAG, "BluetoothFinder.stopFinding: " + e);
+ private boolean isBluetoothAvailable() {
+ return BluetoothAdapter.getDefaultAdapter() != null;
+ }
+
+ private void registerSearchResultsReceiver() {
+ IntentFilter aIntentFilter = new IntentFilter(
+ BluetoothDevice.ACTION_FOUND);
+ aIntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
+ aIntentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+
+ 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();
+ public Collection<Server> getServers() {
+ return mServers.values();
}
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent aIntent) {
- Log.i(Globals.TAG, "BluetoothFinder: BroadcastReceiver.onReceive: aIntent=" + aIntent);
- if (aIntent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
- BluetoothDevice aDevice = (BluetoothDevice) aIntent.getExtras()
- .get(BluetoothDevice.EXTRA_DEVICE);
- Log.i(Globals.TAG, "BluetoothFinder.onReceive: found " + aDevice.getName() + " at " + aDevice.getAddress());
- if (aDevice.getName() == null)
- 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);
- }
+ @Override
+ public void onReceive(Context aContext, Intent aIntent) {
+ if (aIntent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
+ BluetoothDevice aBluetoothDevice = (BluetoothDevice) aIntent
+ .getExtras().get(BluetoothDevice.EXTRA_DEVICE);
+
+ if (aBluetoothDevice == null) {
+ return;
}
+ 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: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
index f7401fbde351..00a903940d55 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Binder;
+import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.preference.PreferenceManager;
@@ -31,7 +32,7 @@ import android.support.v4.content.LocalBroadcastManager;
public class CommunicationService extends Service implements Runnable {
- public enum State {
+ public static enum State {
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
}
@@ -48,7 +49,7 @@ public class CommunicationService extends Service implements Runnable {
if (aName != null)
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);
boolean bEnableWifi = aPref.getBoolean("option_enablewifi", false);
if (bEnableWifi)
- mNetworkFinder.startFinding();
+ mNetworkFinder.startSearch();
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
if (aAdapter != null) {
mBluetoothPreviouslyEnabled = aAdapter.isEnabled();
if (!mBluetoothPreviouslyEnabled)
aAdapter.enable();
- mBluetoothFinder.startFinding();
+ mBluetoothFinder.startSearch();
}
}
public void stopSearching() {
Log.i(Globals.TAG, "CommunicationService.stopSearching()");
- mNetworkFinder.stopFinding();
- mBluetoothFinder.stopFinding();
+ mNetworkFinder.stopSearch();
+ mBluetoothFinder.stopSearch();
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
if (aAdapter != null) {
if (!mBluetoothPreviouslyEnabled) {
@@ -165,8 +166,8 @@ public class CommunicationService extends Service implements Runnable {
Log.i(Globals.TAG, "CommunicationService.connectTo(" + aServer + ")");
synchronized (mConnectionVariableMutex) {
if (mState == State.SEARCHING) {
- mNetworkFinder.stopFinding();
- mBluetoothFinder.stopFinding();
+ mNetworkFinder.stopSearch();
+ mBluetoothFinder.stopSearch();
mState = State.DISCONNECTED;
}
mServerDesired = aServer;
@@ -267,8 +268,8 @@ public class CommunicationService extends Service implements Runnable {
public List<Server> getServers() {
ArrayList<Server> aServers = new ArrayList<Server>();
- aServers.addAll(mNetworkFinder.getServerList());
- aServers.addAll(mBluetoothFinder.getServerList());
+ aServers.addAll(mNetworkFinder.getServers());
+ aServers.addAll(mBluetoothFinder.getServers());
aServers.addAll(mManualServers.values());
return aServers;
}
@@ -324,7 +325,6 @@ public class CommunicationService extends Service implements Runnable {
}
public void removeServer(Server aServer) {
-
mManualServers.remove(aServer.getAddress());
SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java b/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
index abaaf58f3e9d..438148034d0f 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
@@ -80,7 +80,7 @@ public class NetworkClient extends Client {
String aPhoneName = CommunicationService.getDeviceName();
sendCommand(Protocol.Commands
- .prepareCommand(Protocol.Commands.PAIR, aPhoneName, mPin));
+ .prepareCommand(Protocol.Commands.PAIR_WITH_SERVER, aPhoneName, mPin));
}
@Override
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
index 11cf86ef268b..6081669b89c8 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
@@ -22,9 +22,18 @@ final class Protocol {
private Ports() {
}
+ public static final int SERVER_SEARCH = 1598;
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 {
private Messages() {
}
@@ -43,7 +52,8 @@ final class Protocol {
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_PREVIOUS = "transition_previous";
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java b/android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java
index f1726ad85474..9ac70376e1a6 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java
@@ -9,43 +9,161 @@
package org.libreoffice.impressremote.communication;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
import java.util.Collection;
import java.util.HashMap;
-
-import org.libreoffice.impressremote.Globals;
-import org.libreoffice.impressremote.communication.Server.Protocol;
+import java.util.Map;
import android.content.Context;
import android.content.Intent;
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 DatagramSocket mSocket = null;
+ private Thread mListenerThread;
+ private boolean mFinishRequested;
- private static final int PORT = 1598;
- private static final String GROUPADDRESS = "239.0.0.1";
+ private final Map<String, Server> mServers;
- private static final String CHARSET = "UTF-8";
+ public ServerFinder(Context aContext) {
+ mContext = aContext;
- private static final long SEARCH_INTERVAL = 1000 * 15;
+ mSocket = null;
+ mListenerThread = null;
+ mFinishRequested = false;
- private DatagramSocket mSocket = null;
+ mServers = new HashMap<String, Server>();
+ }
- private Thread mListenerThread = null;
+ public void startSearch() {
+ if (mSocket != null) {
+ return;
+ }
- private boolean mFinishRequested = false;
+ mFinishRequested = false;
- private HashMap<String, Server> mServerList = new HashMap<String, Server>();
+ if (mListenerThread == null) {
+ mListenerThread = new Thread(this);
+ }
- public ServerFinder(Context aContext) {
- mContext = aContext;
+ 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() {
@@ -59,7 +177,8 @@ public class ServerFinder {
int i;
for (i = 0; i < aBuffer.length; i++) {
if (aPacket.getData()[i] == '\n') {
- aCommand = new String(aPacket.getData(), 0, i, CHARSET);
+ aCommand = new String(aPacket.getData(), 0, i,
+ Protocol.CHARSET);
break;
}
}
@@ -69,7 +188,7 @@ public class ServerFinder {
for (int j = i + 1; j < aBuffer.length; j++) {
if (aPacket.getData()[j] == '\n') {
aName = new String(aPacket.getData(), i + 1, j - (i + 1),
- CHARSET);
+ Protocol.CHARSET);
break;
}
}
@@ -77,13 +196,12 @@ public class ServerFinder {
return;
}
Server aServer = new Server(Server.Protocol.NETWORK, aPacket
- .getAddress().getHostAddress(), aName,
- System.currentTimeMillis());
- mServerList.put(aServer.getAddress(), aServer);
- Log.i(Globals.TAG, "ServerFinder.listenForServer: contains " + aName);
+ .getAddress().getHostAddress(), aName,
+ System.currentTimeMillis());
+ mServers.put(aServer.getAddress(), aServer);
- notifyActivity();
- } catch (java.net.SocketTimeoutException e) {
+ callUpdatingServersList();
+ } catch (SocketTimeoutException e) {
// Ignore -- we want to timeout to enable checking whether we
// should stop listening periodically
} catch (IOException e) {
@@ -91,100 +209,17 @@ public class ServerFinder {
}
- public void startFinding() {
- if (mSocket != null)
- return;
-
- mFinishRequested = false;
-
+ public void stopSearch() {
if (mListenerThread == null) {
- mListenerThread = new Thread() {
- @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();
- }
-
- }
-
- public void stopFinding() {
- if (mListenerThread != null) {
- 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
+ return;
}
- }
- /**
- * 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);
+ mFinishRequested = true;
+ mListenerThread = null;
}
- public Collection<Server> getServerList() {
- return mServerList.values();
+ public Collection<Server> getServers() {
+ return mServers.values();
}
}