[Libreoffice-commits] core.git: Branch 'feature/android-remote-ng' - 4 commits - android/sdremote
Artur Dryomov
artur.dryomov at gmail.com
Thu Jun 20 09:05:46 PDT 2013
android/sdremote/src/org/libreoffice/impressremote/Preferences.java | 57 +
android/sdremote/src/org/libreoffice/impressremote/PresentationActivity.java | 12
android/sdremote/src/org/libreoffice/impressremote/SelectorActivity.java | 8
android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothClient.java | 115 ++--
android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java | 167 +++--
android/sdremote/src/org/libreoffice/impressremote/communication/Client.java | 176 +++---
android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java | 286 ++++------
android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java | 205 ++++---
android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java | 26
android/sdremote/src/org/libreoffice/impressremote/communication/Receiver.java | 4
android/sdremote/src/org/libreoffice/impressremote/communication/ServerFinder.java | 263 +++++----
android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java | 145 -----
android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java | 124 ++++
13 files changed, 895 insertions(+), 693 deletions(-)
New commits:
commit c23d743aa05fd2b4b4d38de4ef1f64a74b09dc44
Author: Artur Dryomov <artur.dryomov at gmail.com>
Date: Thu Jun 20 19:03:46 2013 +0300
Refactor CommunicationService.
Change-Id: I5107d18101a3d37e6df260563814a367c93ec10d
diff --git a/android/sdremote/src/org/libreoffice/impressremote/Preferences.java b/android/sdremote/src/org/libreoffice/impressremote/Preferences.java
index 35639da..7bc9e4b 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/Preferences.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/Preferences.java
@@ -17,6 +17,7 @@ public final class Preferences {
}
public static final String AUTHORIZED_REMOTES = "sdremote_authorisedremotes";
+ public static final String STORED_SERVERS = "sdremote_storedServers";
}
private Preferences() {
@@ -42,6 +43,15 @@ public final class Preferences {
aPreferencesEditor.commit();
}
+
+ public static void remove(Context aContext, String aLocation, String aKey) {
+ SharedPreferences.Editor aPreferencesEditor = getPreferences(aContext,
+ aLocation).edit();
+
+ aPreferencesEditor.remove(aKey);
+
+ aPreferencesEditor.commit();
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/SelectorActivity.java b/android/sdremote/src/org/libreoffice/impressremote/SelectorActivity.java
index 560e5d3..a3d88da 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/SelectorActivity.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/SelectorActivity.java
@@ -155,7 +155,7 @@ public class SelectorActivity extends SherlockActivity {
@Override
public void onBackPressed() {
if (mCommunicationService != null)
- mCommunicationService.stopSearching();
+ mCommunicationService.stopSearch();
Intent aIntent = new Intent(this, CommunicationService.class);
stopService(aIntent);
super.onBackPressed();
@@ -175,7 +175,7 @@ public class SelectorActivity extends SherlockActivity {
protected void onPause() {
super.onPause();
if (mCommunicationService != null) {
- mCommunicationService.stopSearching();
+ mCommunicationService.stopSearch();
}
doUnbindService();
if (mProgressDialog != null) {
@@ -202,7 +202,7 @@ public class SelectorActivity extends SherlockActivity {
IBinder aService) {
mCommunicationService = ((CommunicationService.CBinder) aService)
.getService();
- mCommunicationService.startSearching();
+ mCommunicationService.startSearch();
refreshLists();
}
@@ -345,7 +345,7 @@ public class SelectorActivity extends SherlockActivity {
@Override
public void onClick(View aView) {
- mCommunicationService.stopSearching();
+ mCommunicationService.stopSearch();
Server aDesiredServer = null;
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
index 00a9039..d87ef6f 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
@@ -15,27 +15,70 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.libreoffice.impressremote.Globals;
-import org.libreoffice.impressremote.communication.Server.Protocol;
-
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
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;
import android.support.v4.content.LocalBroadcastManager;
-public class CommunicationService extends Service implements Runnable {
+import org.libreoffice.impressremote.Preferences;
+import org.libreoffice.impressremote.communication.Server.Protocol;
+public class CommunicationService extends Service implements Runnable {
public static enum State {
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
}
+ public static final String MSG_SLIDESHOW_STARTED = "SLIDESHOW_STARTED";
+ public static final String MSG_SLIDE_CHANGED = "SLIDE_CHANGED";
+ public static final String MSG_SLIDE_PREVIEW = "SLIDE_PREVIEW";
+ public static final String MSG_SLIDE_NOTES = "SLIDE_NOTES";
+
+ public static final String MSG_SERVERLIST_CHANGED = "SERVERLIST_CHANGED";
+ public static final String MSG_PAIRING_STARTED = "PAIRING_STARTED";
+ public static final String MSG_PAIRING_SUCCESSFUL = "PAIRING_SUCCESSFUL";
+
+ public static final String STATUS_CONNECTED_SLIDESHOW_RUNNING = "STATUS_CONNECTED_SLIDESHOW_RUNNING";
+ public static final String STATUS_CONNECTED_NOSLIDESHOW = "STATUS_CONNECTED_NOSLIDESHOW";
+
+ public static final String STATUS_PAIRING_PINVALIDATION = "STATUS_PAIRING_PINVALIDATION";
+ public static final String STATUS_CONNECTION_FAILED = "STATUS_CONNECTION_FAILED";
+
+ /**
+ * Used to protect all writes to mState, mStateDesired, and mServerDesired.
+ */
+ private final Object mConnectionVariableMutex = new Object();
+
+ private State mState = State.DISCONNECTED;
+ private State mStateDesired = State.DISCONNECTED;
+
+ private Server mServerDesired = null;
+
+ private boolean mBluetoothPreviouslyEnabled;
+
+ private final IBinder mBinder = new CBinder();
+
+ private Transmitter mTransmitter;
+
+ private Client mClient;
+
+ private final Receiver mReceiver = new Receiver(this);
+
+ private final ServerFinder mNetworkFinder = new ServerFinder(this);
+ private final BluetoothFinder mBluetoothFinder = new BluetoothFinder(this);
+
+ private Thread mThread = null;
+
+ /**
+ * Key to use with getSharedPreferences to obtain a Map of stored servers.
+ * The keys are the ip/hostnames, the values are the friendly names.
+ */
+ private final Map<String, Server> mManualServers = new HashMap<String, Server>();
+
/**
* Get the publicly visible device name -- generally the bluetooth name,
* however for bluetoothless devices the device model name is used.
@@ -43,41 +86,23 @@ public class CommunicationService extends Service implements Runnable {
* @return The device name.
*/
public static String getDeviceName() {
- BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
- if (aAdapter != null) {
- String aName = aAdapter.getName();
- if (aName != null)
- return aName;
+ if (BluetoothAdapter.getDefaultAdapter() == null) {
+ return Build.MODEL;
}
- return Build.MODEL;
- }
-
- /**
- * Used to protect all writes to mState, mStateDesired, and mServerDesired.
- */
- private Object mConnectionVariableMutex = new Object();
-
- private State mState = State.DISCONNECTED;
- public State getState() {
- return mState;
- }
+ if (BluetoothAdapter.getDefaultAdapter().getName() == null) {
+ return Build.MODEL;
+ }
- public String getPairingPin() {
- return Client.getPin();
+ return BluetoothAdapter.getDefaultAdapter().getName();
}
public String getPairingDeviceName() {
return Client.getName();
}
- private State mStateDesired = State.DISCONNECTED;
-
- private Server mServerDesired = null;
-
@Override
public void run() {
- Log.i(Globals.TAG, "CommunicationService.run()");
synchronized (this) {
while (true) {
// Condition
@@ -87,57 +112,72 @@ public class CommunicationService extends Service implements Runnable {
// We have finished
return;
}
+
// Work
- Log.i(Globals.TAG, "CommunicationService.run: at \"Work\"");
synchronized (mConnectionVariableMutex) {
- if ((mStateDesired == State.CONNECTED && mState == State.CONNECTED)
- || (mStateDesired == State.DISCONNECTED && mState == State.CONNECTED)) {
- mClient.closeConnection();
- mClient = null;
- mState = State.DISCONNECTED;
+ if ((mStateDesired == State.CONNECTED) && (mState == State.CONNECTED)) {
+ closeConnection();
+ }
+
+ if ((mStateDesired == State.DISCONNECTED) && (mState == State.CONNECTED)) {
+ closeConnection();
}
+
if (mStateDesired == State.CONNECTED) {
mState = State.CONNECTING;
- try {
- switch (mServerDesired.getProtocol()) {
- case NETWORK:
- mClient = new NetworkClient(mServerDesired,
- this, mReceiver);
- mClient.validating();
- break;
- case BLUETOOTH:
- mClient = new BluetoothClient(mServerDesired,
- this, mReceiver,
- mBluetoothPreviouslyEnabled);
- mClient.validating();
- break;
- }
- mTransmitter = new Transmitter(mClient);
- mState = State.CONNECTED;
- } catch (IOException e) {
- Log.i(Globals.TAG, "CommunicationService.run: " + e);
- connextionFailed();
- }
+
+ openConnection();
}
}
- Log.i(Globals.TAG, "CommunicationService.finished work");
}
}
}
- private void connextionFailed() {
+ private void closeConnection() {
+ mClient.closeConnection();
+ mClient = null;
+
+ mState = State.DISCONNECTED;
+ }
+
+ private void openConnection() {
+ try {
+ mClient = buildClient();
+ mClient.validating();
+
+ mTransmitter = new Transmitter(mClient);
+
+ mState = State.CONNECTED;
+ } catch (IOException e) {
+ connectionFailed();
+ }
+ }
+
+ private Client buildClient() {
+ switch (mServerDesired.getProtocol()) {
+ case NETWORK:
+ return new NetworkClient(mServerDesired, this, mReceiver);
+
+ case BLUETOOTH:
+ return new BluetoothClient(mServerDesired, this, mReceiver,
+ mBluetoothPreviouslyEnabled);
+
+ default:
+ throw new RuntimeException("Unknown desired protocol.");
+ }
+ }
+
+ private void connectionFailed() {
mClient = null;
mState = State.DISCONNECTED;
Intent aIntent = new Intent(
- CommunicationService.STATUS_CONNECTION_FAILED);
+ CommunicationService.STATUS_CONNECTION_FAILED);
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
}
- private boolean mBluetoothPreviouslyEnabled;
-
- public void startSearching() {
- Log.i(Globals.TAG, "CommunicationService.startSearching()");
- SharedPreferences aPref = PreferenceManager.getDefaultSharedPreferences(this);
+ public void startSearch() {
+ SharedPreferences aPref = PreferenceManager
+ .getDefaultSharedPreferences(this);
boolean bEnableWifi = aPref.getBoolean("option_enablewifi", false);
if (bEnableWifi)
mNetworkFinder.startSearch();
@@ -150,8 +190,7 @@ public class CommunicationService extends Service implements Runnable {
}
}
- public void stopSearching() {
- Log.i(Globals.TAG, "CommunicationService.stopSearching()");
+ public void stopSearch() {
mNetworkFinder.stopSearch();
mBluetoothFinder.stopSearch();
BluetoothAdapter aAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -163,7 +202,6 @@ public class CommunicationService extends Service implements Runnable {
}
public void connectTo(Server aServer) {
- Log.i(Globals.TAG, "CommunicationService.connectTo(" + aServer + ")");
synchronized (mConnectionVariableMutex) {
if (mState == State.SEARCHING) {
mNetworkFinder.stopSearch();
@@ -181,7 +219,6 @@ public class CommunicationService extends Service implements Runnable {
}
public void disconnect() {
- Log.d(Globals.TAG, "Service Disconnected");
synchronized (mConnectionVariableMutex) {
mStateDesired = State.DISCONNECTED;
synchronized (this) {
@@ -190,63 +227,19 @@ public class CommunicationService extends Service implements Runnable {
}
}
- /**
- * Return the service to clients.
- */
public class CBinder extends Binder {
public CommunicationService getService() {
return CommunicationService.this;
}
}
- private final IBinder mBinder = new CBinder();
-
- public static final String MSG_SLIDESHOW_STARTED = "SLIDESHOW_STARTED";
- public static final String MSG_SLIDE_CHANGED = "SLIDE_CHANGED";
- public static final String MSG_SLIDE_PREVIEW = "SLIDE_PREVIEW";
- public static final String MSG_SLIDE_NOTES = "SLIDE_NOTES";
-
- public static final String MSG_SERVERLIST_CHANGED = "SERVERLIST_CHANGED";
- public static final String MSG_PAIRING_STARTED = "PAIRING_STARTED";
- public static final String MSG_PAIRING_SUCCESSFUL = "PAIRING_SUCCESSFUL";
-
- /**
- * Notify the UI that the service has connected to a server AND a slideshow
- * is running.
- * In this case the PresentationActivity should be started.
- */
- public static final String STATUS_CONNECTED_SLIDESHOW_RUNNING = "STATUS_CONNECTED_SLIDESHOW_RUNNING";
- /**
- * Notify the UI that the service has connected to a server AND no slideshow
- * is running.
- * In this case the StartPresentationActivity should be started.
- */
- public static final String STATUS_CONNECTED_NOSLIDESHOW = "STATUS_CONNECTED_NOSLIDESHOW";
-
- public static final String STATUS_PAIRING_PINVALIDATION = "STATUS_PAIRING_PINVALIDATION";
-
- public static final String STATUS_CONNECTION_FAILED = "STATUS_CONNECTION_FAILED";
-
- private Transmitter mTransmitter;
-
- private Client mClient;
-
- private Receiver mReceiver = new Receiver(this);
-
- private ServerFinder mNetworkFinder = new ServerFinder(this);
- private BluetoothFinder mBluetoothFinder = new BluetoothFinder(this);
-
@Override
public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
return mBinder;
}
- private Thread mThread = null;
-
@Override
public void onCreate() {
- // TODO Create a notification (if configured).
loadServersFromPreferences();
mThread = new Thread(this);
@@ -255,7 +248,6 @@ public class CommunicationService extends Service implements Runnable {
@Override
public void onDestroy() {
- // TODO Destroy the notification (as necessary).
mManualServers.clear();
mThread.interrupt();
@@ -267,10 +259,12 @@ public class CommunicationService extends Service implements Runnable {
}
public List<Server> getServers() {
- ArrayList<Server> aServers = new ArrayList<Server>();
+ List<Server> aServers = new ArrayList<Server>();
+
aServers.addAll(mNetworkFinder.getServers());
aServers.addAll(mBluetoothFinder.getServers());
aServers.addAll(mManualServers.values());
+
return aServers;
}
@@ -278,35 +272,23 @@ public class CommunicationService extends Service implements Runnable {
return mReceiver.getSlideShow();
}
- public boolean isSlideShowRunning() {
- return mReceiver.isSlideShowRunning();
- }
-
- /**
- * Key to use with getSharedPreferences to obtain a Map of stored servers.
- * The keys are the ip/hostnames, the values are the friendly names.
- */
- private static final String SERVERSTORAGE_KEY = "sdremote_storedServers";
- private HashMap<String, Server> mManualServers = new HashMap<String, Server>();
-
void loadServersFromPreferences() {
- SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
- MODE_PRIVATE);
+ SharedPreferences aPref = getSharedPreferences(
+ Preferences.Locations.STORED_SERVERS,
+ MODE_PRIVATE);
@SuppressWarnings("unchecked")
- Map<String, String> aStoredMap = (Map<String, String>) aPref.getAll();
+ Map<String, String> aStoredMap = (Map<String, String>) aPref.getAll();
for (Entry<String, String> aServerEntry : aStoredMap.entrySet()) {
mManualServers.put(aServerEntry.getKey(), new Server(
- Protocol.NETWORK, aServerEntry.getKey(),
- aServerEntry.getValue(), 0));
+ Protocol.NETWORK, aServerEntry.getKey(),
+ aServerEntry.getValue(), 0));
}
}
/**
* Manually add a new (network) server to the list of servers.
- * @param aAddress
- * @param aRemember
*/
public void addServer(String aAddress, String aName, boolean aRemember) {
for (String aServer : mManualServers.keySet()) {
@@ -314,31 +296,25 @@ public class CommunicationService extends Service implements Runnable {
return;
}
mManualServers.put(aAddress, new Server(Protocol.NETWORK, aAddress,
- aName, 0));
+ aName, 0));
if (aRemember) {
- SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
- MODE_PRIVATE);
- Editor aEditor = aPref.edit();
- aEditor.putString(aAddress, aName);
- aEditor.apply();
+
+ Preferences
+ .set(this, Preferences.Locations.STORED_SERVERS, aAddress,
+ aName);
}
}
public void removeServer(Server aServer) {
mManualServers.remove(aServer.getAddress());
- SharedPreferences aPref = getSharedPreferences(SERVERSTORAGE_KEY,
- MODE_PRIVATE);
- Editor aEditor = aPref.edit();
- aEditor.remove(aServer.getAddress());
- aEditor.apply();
-
+ Preferences.remove(this, Preferences.Locations.STORED_SERVERS,
+ aServer.getAddress());
}
public Client getClient() {
return mClient;
}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 215ba932b38420da5afa28efb4e2544dfb4fa03b
Author: Artur Dryomov <artur.dryomov at gmail.com>
Date: Thu Jun 20 18:23:40 2013 +0300
Refactor finders classes.
Change-Id: Icaf80e1ff13bca059f6ee42a56f36a4b3f65a3fb
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java b/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothFinder.java
index 972a8a4..4ed99a1 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 f7401fb..00a9039 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 abaaf58..4381480 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 11cf86e..6081669 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 f1726ad..9ac7037 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();
}
}
commit bc5ccdc2a5b3676da8061c0578d902d967bc04b2
Author: Artur Dryomov <artur.dryomov at gmail.com>
Date: Tue Jun 18 14:05:54 2013 +0300
Refactor clients classes
* Remove logging, it should not be running on users devices.
* Try to break long methods to small ones.
Change-Id: I6ee1f211b4c9d20ff9d04f0faf96b45393c067ef
diff --git a/android/sdremote/src/org/libreoffice/impressremote/Preferences.java b/android/sdremote/src/org/libreoffice/impressremote/Preferences.java
new file mode 100644
index 0000000..35639da
--- /dev/null
+++ b/android/sdremote/src/org/libreoffice/impressremote/Preferences.java
@@ -0,0 +1,47 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public final class Preferences {
+ public static final class Locations {
+ private Locations() {
+ }
+
+ public static final String AUTHORIZED_REMOTES = "sdremote_authorisedremotes";
+ }
+
+ private Preferences() {
+ }
+
+ public static boolean doContain(Context aContext, String aLocation, String aKey) {
+ return getPreferences(aContext, aLocation).contains(aKey);
+ }
+
+ private static SharedPreferences getPreferences(Context aContext, String aLocation) {
+ return aContext.getSharedPreferences(aLocation, Context.MODE_PRIVATE);
+ }
+
+ public static String getString(Context aContext, String aLocation, String aKey) {
+ return getPreferences(aContext, aLocation).getString(aKey, null);
+ }
+
+ public static void set(Context aContext, String aLocation, String aKey, String aValue) {
+ SharedPreferences.Editor aPreferencesEditor = getPreferences(aContext,
+ aLocation).edit();
+
+ aPreferencesEditor.putString(aKey, aValue);
+
+ aPreferencesEditor.commit();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothClient.java b/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothClient.java
index c2e7a61..4fea919 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothClient.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/BluetoothClient.java
@@ -8,99 +8,118 @@
*/
package org.libreoffice.impressremote.communication;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.UUID;
-import org.libreoffice.impressremote.Globals;
-
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-/**
- * Standard Network client. Connects to a server using Sockets.
- */
public class BluetoothClient extends Client {
+ // Standard UUID for the Serial Port Profile.
+ // https://www.bluetooth.org/en-us/specification/assigned-numbers-overview/service-discovery
+ private static final String STANDARD_SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
+
+ private final boolean mBluetoothWasEnabled;
- private boolean mBluetoothWasEnabled;
- private BluetoothAdapter mAdapter;
+ private final BluetoothAdapter mBluetoothAdapter;
private BluetoothSocket mSocket;
- public BluetoothClient(Server aServer,
- CommunicationService aCommunicationService,
- Receiver aReceiver, boolean aBluetoothWasEnabled)
- throws IOException {
+ public BluetoothClient(Server aServer, CommunicationService aCommunicationService, Receiver aReceiver, boolean aBluetoothWasEnabled) {
super(aServer, aCommunicationService, aReceiver);
- Log.i(Globals.TAG, "BluetoothClient(" + aServer + ")");
-
- mAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothWasEnabled = aBluetoothWasEnabled;
+
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
if (!mBluetoothWasEnabled) {
- mAdapter.enable();
+ mBluetoothAdapter.enable();
}
+ }
- BluetoothDevice aDevice = mAdapter
- .getRemoteDevice(aServer.getAddress());
- mAdapter.cancelDiscovery();
+ @Override
+ protected void setUpServerConnection() {
+ mSocket = buildServerConnection();
+ }
- // This is the "standard UUID for the Serial Port Profile".
- // I.e. the 16-bit SerialPort UUID 0x1101 inserted into the
- // Bluetooth BASE_UUID. See
- // https://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
- mSocket = aDevice.createRfcommSocketToServiceRecord(UUID
- .fromString("00001101-0000-1000-8000-00805F9B34FB"));
+ private BluetoothSocket buildServerConnection() {
+ try {
+ BluetoothDevice aBluetoothServer = mBluetoothAdapter
+ .getRemoteDevice(mServer.getAddress());
+
+ mBluetoothAdapter.cancelDiscovery();
+
+ BluetoothSocket aSocket = aBluetoothServer
+ .createRfcommSocketToServiceRecord(
+ UUID.fromString(STANDARD_SPP_UUID));
+
+ aSocket.connect();
- mSocket.connect();
- Log.i(Globals.TAG, "BluetoothClient: connected");
+ return aSocket;
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to connect to Bluetooth host");
+ }
+ }
+
+ protected InputStream buildMessagesStream() {
+ try {
+ return mSocket.getInputStream();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to open messages stream.");
+ }
+ }
+
+ protected OutputStream buildCommandsStream() {
+ try {
+ return mSocket.getOutputStream();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to open commands stream.");
+ }
}
@Override
public void closeConnection() {
try {
- if (mSocket != null)
- mSocket.close();
+ mSocket.close();
} catch (IOException e) {
- e.printStackTrace();
+ throw new RuntimeException("Unable to close Bluetooth socket.");
}
}
protected void onDisconnect() {
if (!mBluetoothWasEnabled) {
- mAdapter.disable();
+ mBluetoothAdapter.disable();
}
}
@Override
public void validating() throws IOException {
- // TODO Auto-generated method stub
+ String aMessage = mMessagesReader.readLine();
- mInputStream = mSocket.getInputStream();
- mReader = new BufferedReader(new InputStreamReader(mInputStream,
- CHARSET));
-
- mOutputStream = mSocket.getOutputStream();
-
- String aTemp = mReader.readLine();
- Log.i(Globals.TAG, "BluetoothClient: got line " + aTemp);
- if (!aTemp.equals("LO_SERVER_SERVER_PAIRED")) {
+ if (!aMessage.equals(Protocol.Messages.PAIRED)) {
return;
}
- while (mReader.readLine().length() != 0) {
+
+ while (mMessagesReader.readLine().length() != 0) {
// Get rid of extra lines
}
- Intent aIntent = new Intent(CommunicationService.MSG_PAIRING_SUCCESSFUL);
- LocalBroadcastManager.getInstance(mCommunicationService).sendBroadcast(
- aIntent);
- startListening();
+ callSuccessfulPairing();
+
+ startListening();
}
+ private void callSuccessfulPairing() {
+ Intent aSuccessfulPairingIntent = new Intent(
+ CommunicationService.MSG_PAIRING_SUCCESSFUL);
+
+ LocalBroadcastManager.getInstance(mCommunicationService)
+ .sendBroadcast(aSuccessfulPairingIntent);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Client.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Client.java
index ea6d4b9..10fa657 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/Client.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Client.java
@@ -11,136 +11,158 @@ package org.libreoffice.impressremote.communication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
-
-import org.libreoffice.impressremote.Globals;
-import org.libreoffice.impressremote.communication.CommunicationService.State;
+import java.util.List;
import android.content.Intent;
-import android.util.Log;
-
-/**
- * Generic Client for the remote control. To implement a Client for a specific
- * transport medium you must provide input and output streams (
- * <code>mInputStream</code> and <code>mOutputStream</code> before calling any
- * methods.
- */
-public abstract class Client {
+import android.text.TextUtils;
- protected static final String CHARSET = "UTF-8";
+public abstract class Client implements Runnable {
+ protected final BufferedReader mMessagesReader;
+ protected final OutputStream mCommandsStream;
- protected InputStream mInputStream;
- protected BufferedReader mReader;
- protected OutputStream mOutputStream;
protected String mPin = "";
protected String mName = "";
private static Client latestInstance = null;
- public abstract void closeConnection();
+ protected final Server mServer;
+ protected final CommunicationService mCommunicationService;
+ protected final Receiver mReceiver;
- public abstract void validating() throws IOException;
- private Receiver mReceiver;
-
- protected Server mServer;
-
- protected CommunicationService mCommunicationService;
-
- protected Client(Server aServer,
- CommunicationService aCommunicationService,
- Receiver aReceiver) {
+ protected Client(Server aServer, CommunicationService aCommunicationService, Receiver aReceiver) {
mServer = aServer;
mName = aServer.getName();
mCommunicationService = aCommunicationService;
mReceiver = aReceiver;
latestInstance = this;
+
+ setUpServerConnection();
+
+ mMessagesReader = buildMessagesReader(buildMessagesStream());
+ mCommandsStream = buildCommandsStream();
+ }
+
+ protected abstract void setUpServerConnection();
+
+ private BufferedReader buildMessagesReader(InputStream aMessagesStream) {
+ try {
+ return new BufferedReader(
+ new InputStreamReader(aMessagesStream, Protocol.CHARSET));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Unable to create messages reader.");
+ }
+ }
+
+ protected abstract InputStream buildMessagesStream();
+
+ protected abstract OutputStream buildCommandsStream();
+
+ public static String getPin() {
+ if (latestInstance == null) {
+ return "";
+ }
+
+ return latestInstance.mName;
+ }
+
+ public static String getName() {
+ if (latestInstance == null) {
+ return "";
+ }
+
+ return latestInstance.mName;
}
protected void startListening() {
+ Thread aListeningThread = new Thread(this);
- Thread t = new Thread() {
- public void run() {
- listen();
- }
+ aListeningThread.start();
+ }
- };
- t.start();
+ @Override
+ public void run() {
+ listen();
}
- private final void listen() {
+ private void listen() {
try {
while (true) {
- ArrayList<String> aList = new ArrayList<String>();
- String aTemp;
- // read until empty line
- while ((aTemp = mReader.readLine()) != null
- && aTemp.length() != 0) {
- aList.add(aTemp);
- }
- if (aTemp == null) {
- Intent aIntent = new Intent(
- mCommunicationService
- .getApplicationContext(),
- ReconnectionActivity.class);
- aIntent.putExtra("server", mServer);
- aIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mCommunicationService.getApplicationContext()
- .startActivity(aIntent);
+ List<String> aMessage = readMessage();
+
+ if (aMessage == null) {
return;
}
- mReceiver.parseCommand(aList);
+
+ mReceiver.parseCommand(aMessage);
}
- } catch (UnsupportedEncodingException e) {
+ } catch (IOException e) {
+ // TODO: stream couldn't be opened
e.printStackTrace();
- } catch (IOException e1) {
- // TODO stream couldn't be opened.
- e1.printStackTrace();
} finally {
onDisconnect();
}
-
}
- public static String getPin() {
- if (latestInstance != null) {
- return latestInstance.mPin;
- } else {
- return "";
+ private List<String> readMessage() throws IOException {
+ List<String> aMessage = new ArrayList<String>();
+
+ String aMessageParameter = mMessagesReader.readLine();
+
+ while ((aMessageParameter != null) && (!TextUtils
+ .isEmpty(aMessageParameter))) {
+ aMessage.add(aMessageParameter);
+
+ aMessageParameter = mMessagesReader.readLine();
}
- }
- public static String getName() {
- if (latestInstance != null) {
- return latestInstance.mName;
- } else {
- return "";
+ if (aMessageParameter == null) {
+ startReconnection();
+
+ return null;
}
+
+ return aMessage;
+ }
+
+ private void startReconnection() {
+ Intent aReconnectionIntent = new Intent(
+ mCommunicationService.getApplicationContext(),
+ ReconnectionActivity.class);
+ aReconnectionIntent.putExtra("server", mServer);
+ aReconnectionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ mCommunicationService.getApplicationContext()
+ .startActivity(aReconnectionIntent);
+ }
+
+ /**
+ * Called after the Client disconnects. Can be extended to allow for
+ * cleaning up bluetooth properties etc.
+ */
+ protected void onDisconnect() {
}
/**
* Send a valid command to the Server.
*/
- public void sendCommand(String command) {
+ public void sendCommand(String aCommand) {
try {
- mOutputStream.write(command.getBytes(CHARSET));
+ mCommandsStream.write(aCommand.getBytes(Protocol.CHARSET));
} catch (UnsupportedEncodingException e) {
- throw new Error("Specified network encoding [" + CHARSET
- + " not available.");
+ throw new RuntimeException("UTF-8 must be used for commands.");
} catch (IOException e) {
// I.e. connection closed. This will be dealt with by the listening
// loop.
}
}
- /**
- * Called after the Client disconnects. Can be extended to allow for
- * cleaning up bluetooth properties etc.
- */
- protected void onDisconnect() {
- }
+ public abstract void closeConnection();
+ public abstract void validating() throws IOException;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java b/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
index fbd51fa..abaaf58 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/NetworkClient.java
@@ -8,135 +8,174 @@
*/
package org.libreoffice.impressremote.communication;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
-import org.libreoffice.impressremote.Globals;
-
+import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-
-/**
- * Standard Network client. Connects to a server using Sockets.
- */
-public class NetworkClient extends Client {
- private static final int PORT = 1599;
+import org.libreoffice.impressremote.Preferences;
+public class NetworkClient extends Client {
private Socket mSocket;
- private Intent mIntent;
- private String mPin;
- private Server mServer;
- public NetworkClient(Server aServer,
- CommunicationService aCommunicationService, Receiver aReceiver)
- throws UnknownHostException, IOException {
+ private final String mPin;
+
+ public NetworkClient(Server aServer, CommunicationService aCommunicationService, Receiver aReceiver) {
super(aServer, aCommunicationService, aReceiver);
- mServer = aServer;
- mSocket = new Socket(mServer.getAddress(), PORT);
- mInputStream = mSocket.getInputStream();
- mReader = new BufferedReader(new InputStreamReader(mInputStream,
- CHARSET));
- mOutputStream = mSocket.getOutputStream();
-
- // Pairing.
- mPin = setupPin(mServer);
- mIntent = new Intent(CommunicationService.MSG_PAIRING_STARTED);
- mIntent.putExtra("PIN", mPin);
- LocalBroadcastManager.getInstance(mCommunicationService).sendBroadcast(
- mIntent);
- // Send out
- String aName = CommunicationService.getDeviceName(); // TODO: get the
- // proper name
- sendCommand("LO_SERVER_CLIENT_PAIR\n" + aName + "\n" + mPin + "\n\n");
+
+ mPin = loadPin();
+
+ startPairingActivity();
+ startPairing();
}
- private String setupPin(Server aServer) {
- // Get settings
- SharedPreferences aPreferences = mCommunicationService
- .getSharedPreferences("sdremote_authorisedremotes",
- android.content.Context.MODE_PRIVATE);
- if (aPreferences.contains(aServer.getName())) {
- return aPreferences.getString(aServer.getName(), "");
- } else {
- String aPin = generatePin();
-
- Editor aEdit = aPreferences.edit();
- aEdit.putString(aServer.getName(), aPin);
- aEdit.commit();
-
- return aPin;
+ private String loadPin() {
+ Context aContext = mCommunicationService.getApplicationContext();
+
+ if (Preferences
+ .doContain(aContext, Preferences.Locations.AUTHORIZED_REMOTES,
+ mServer.getName())) {
+ return Preferences
+ .getString(aContext, Preferences.Locations.AUTHORIZED_REMOTES,
+ mServer.getName());
}
+ String aPin = generatePin();
+
+ Preferences.set(aContext, Preferences.Locations.AUTHORIZED_REMOTES,
+ mServer.getName(), aPin);
+
+ return aPin;
}
private String generatePin() {
- Random aRandom = new Random();
- String aPin = "" + (aRandom.nextInt(9000) + 1000);
- while (aPin.length() < 4) {
- aPin = "0" + aPin; // Add leading zeros if necessary
+ return String.format("%04d", generatePinNumber());
+ }
+
+ private int generatePinNumber() {
+ Random aRandomGenerator = new Random();
+
+ int aMaximumPin = (int) Math.pow(10, Protocol.PIN_NUMBERS_COUNT) - 1;
+
+ return aRandomGenerator.nextInt(aMaximumPin);
+ }
+
+ private void startPairingActivity() {
+ Intent aPairingIntent = new Intent(
+ CommunicationService.MSG_PAIRING_STARTED);
+ aPairingIntent.putExtra("PIN", mPin);
+
+ LocalBroadcastManager.getInstance(mCommunicationService)
+ .sendBroadcast(aPairingIntent);
+ }
+
+ private void startPairing() {
+ // TODO: get the proper name
+ String aPhoneName = CommunicationService.getDeviceName();
+
+ sendCommand(Protocol.Commands
+ .prepareCommand(Protocol.Commands.PAIR, aPhoneName, mPin));
+ }
+
+ @Override
+ protected void setUpServerConnection() {
+ mSocket = buildServerConnection();
+ }
+
+ private Socket buildServerConnection() {
+ try {
+ return new Socket(mServer.getAddress(),
+ Protocol.Ports.CLIENT_CONNECTION);
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("Unable to connect to unknown host.");
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Unable to connect to host.");
+ }
+ }
+
+ @Override
+ protected InputStream buildMessagesStream() {
+ try {
+ return mSocket.getInputStream();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to open messages stream.");
+ }
+ }
+
+ @Override
+ protected OutputStream buildCommandsStream() {
+ try {
+ return mSocket.getOutputStream();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to open commands stream.");
}
- return aPin;
}
@Override
public void closeConnection() {
try {
- if (mSocket != null)
- mSocket.close();
+ mSocket.close();
} catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ throw new RuntimeException("Unable to close network socket.");
}
}
@Override
public void validating() throws IOException {
+ String aMessage = mMessagesReader.readLine();
- // Wait until we get the appropriate string back...
- String aTemp = mReader.readLine();
-
- if (aTemp == null) {
- throw new IOException(
- "End of stream reached before any data received.");
+ if (aMessage == null) {
+ throw new RuntimeException(
+ "End of stream reached before any data received.");
}
- while (!aTemp.equals("LO_SERVER_SERVER_PAIRED")) {
- if (aTemp.equals("LO_SERVER_VALIDATING_PIN")) {
- // Broadcast that we need a pin screen.
- mIntent = new Intent(
- CommunicationService.STATUS_PAIRING_PINVALIDATION);
- mIntent.putExtra("PIN", mPin);
- mIntent.putExtra("SERVERNAME", mServer.getName());
- LocalBroadcastManager.getInstance(mCommunicationService)
- .sendBroadcast(mIntent);
- while (mReader.readLine().length() != 0) {
+ while (!aMessage.equals(Protocol.Messages.PAIRED)) {
+ if (aMessage.equals(Protocol.Messages.VALIDATING)) {
+ startPinValidation();
+
+ while (mMessagesReader.readLine().length() != 0) {
// Read off empty lines
}
- aTemp = mReader.readLine();
+
+ aMessage = mMessagesReader.readLine();
} else {
return;
}
}
- mIntent = new Intent(CommunicationService.MSG_PAIRING_SUCCESSFUL);
- LocalBroadcastManager.getInstance(mCommunicationService).sendBroadcast(
- mIntent);
+ callSuccessfulPairing();
- while (mReader.readLine().length() != 0) {
+ while (mMessagesReader.readLine().length() != 0) {
// Get rid of extra lines
- Log.i(Globals.TAG, "NetworkClient: extra line");
}
- Log.i(Globals.TAG, "NetworkClient: calling startListening");
+
startListening();
}
+
+ private void startPinValidation() {
+ Intent aPairingIntent = new Intent(
+ CommunicationService.STATUS_PAIRING_PINVALIDATION);
+ aPairingIntent.putExtra("PIN", mPin);
+ aPairingIntent.putExtra("SERVERNAME", mServer.getName());
+
+ LocalBroadcastManager.getInstance(mCommunicationService)
+ .sendBroadcast(aPairingIntent);
+ }
+
+ private void callSuccessfulPairing() {
+ Intent aSuccessfulPairingIntent = new Intent(
+ CommunicationService.MSG_PAIRING_SUCCESSFUL);
+
+ LocalBroadcastManager.getInstance(mCommunicationService)
+ .sendBroadcast(aSuccessfulPairingIntent);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
index 5227ee6..11cf86e 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Protocol.java
@@ -14,10 +14,24 @@ final class Protocol {
private Protocol() {
}
+ public static final String CHARSET = "UTF-8";
+
+ public static final int PIN_NUMBERS_COUNT = 4;
+
+ public static final class Ports {
+ private Ports() {
+ }
+
+ public static final int CLIENT_CONNECTION = 1599;
+ }
+
public static final class Messages {
private Messages() {
}
+ public static final String PAIRED = "LO_SERVER_SERVER_PAIRED";
+ public static final String VALIDATING = "LO_SERVER_VALIDATING_PIN";
+
public static final String SLIDESHOW_STARTED = "slideshow_started";
public static final String SLIDESHOW_FINISHED = "slideshow_finished";
public static final String SLIDE_UPDATED = "slide_updated";
@@ -29,6 +43,8 @@ final class Protocol {
private Commands() {
}
+ public static final String PAIR = "LO_SERVER_CLIENT_PAIR";
+
public static final String TRANSITION_NEXT = "transition_next";
public static final String TRANSITION_PREVIOUS = "transition_previous";
public static final String GOTO_SLIDE = "goto_slide";
commit 8e97f28fe299a34a8f456d4762e6cebdb41fc311
Author: Artur Dryomov <artur.dryomov at gmail.com>
Date: Mon Jun 17 18:43:33 2013 +0300
Refactor the SlideShow class.
* Move the Timer class to a separate file.
* Remove drawing shadows for slides, it would be better to draw shadow
only for the ViewPager in the future.
Change-Id: I4373bdcf83f31ab08dccf96fd09a0a60f5d085b6
diff --git a/android/sdremote/src/org/libreoffice/impressremote/PresentationActivity.java b/android/sdremote/src/org/libreoffice/impressremote/PresentationActivity.java
index 22c2f18..ccbbfc6 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/PresentationActivity.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/PresentationActivity.java
@@ -13,7 +13,7 @@ import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.libreoffice.impressremote.communication.CommunicationService;
-import org.libreoffice.impressremote.communication.SlideShow.Timer;
+import org.libreoffice.impressremote.communication.Timer;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -459,22 +459,22 @@ public class PresentationActivity extends SherlockFragmentActivity {
// ------------------------------------- TIMER BUTTONS
else if (aSource == mStopwatchButtonRun) {
if (aTimer.isRunning()) {
- aTimer.stopTimer();
+ aTimer.stop();
} else {
- aTimer.startTimer();
+ aTimer.start();
}
updateClockBar();
} else if (aSource == mStopwatchButtonReset) {
if (aTimer.isRunning()) {
aTimer.reset();
- aTimer.startTimer();
+ aTimer.start();
} else {
aTimer.reset();
}
updateClockBar();
} else if (aSource == mCountdownButton) {
if (aTimer.isRunning()) {
- aTimer.stopTimer();
+ aTimer.stop();
mCountdownButton.setTag(Boolean.valueOf(true));
updateClockBar();
} else {
@@ -485,7 +485,7 @@ public class PresentationActivity extends SherlockFragmentActivity {
editor.putString(COUNTDOWN_KEY, time);
editor.commit();
aTimer.setCountdownTime(aTime);
- aTimer.startTimer();
+ aTimer.start();
mCountdownButton.setTag(Boolean.valueOf(true));
updateClockBar();
} catch (ParseException e) {
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Receiver.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Receiver.java
index 91a10e5..1ecb53e 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/Receiver.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Receiver.java
@@ -22,7 +22,7 @@ public class Receiver {
public Receiver(Context aContext) {
this.mContext = aContext;
- this.mSlideShow = new SlideShow(mContext);
+ this.mSlideShow = new SlideShow();
}
public SlideShow getSlideShow() {
@@ -89,7 +89,7 @@ public class Receiver {
}
private void finishSlideShow() {
- this.mSlideShow = new SlideShow(mContext);
+ this.mSlideShow = new SlideShow();
Intent aStatusConnectedNoSlideShowIntent = new Intent(
CommunicationService.STATUS_CONNECTED_NOSLIDESHOW);
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
index dbb5c56..347a92c 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
@@ -8,35 +8,28 @@
*/
package org.libreoffice.impressremote.communication;
-import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.RectF;
import android.util.SparseArray;
-import org.libreoffice.impressremote.R;
-
public class SlideShow {
- private final Context mContext;
-
private int mSlidesCount;
private int mCurrentSlideIndex;
private final SparseArray<Bitmap> mSlidePreviews;
private final SparseArray<String> mSlideNotes;
- public SlideShow(Context aContext) {
- this.mContext = aContext;
+ private final Timer mTimer;
+ public SlideShow() {
this.mSlidesCount = 0;
this.mCurrentSlideIndex = 0;
this.mSlidePreviews = new SparseArray<Bitmap>();
this.mSlideNotes = new SparseArray<String>();
+
+ this.mTimer = new Timer();
}
public void setSlidesCount(int aSlidesCount) {
@@ -55,26 +48,11 @@ public class SlideShow {
return mCurrentSlideIndex;
}
- public void setSlidePreview(int aSlideIndex, byte[] aSlidePreview) {
- Bitmap aBitmap = BitmapFactory
- .decodeByteArray(aSlidePreview, 0, aSlidePreview.length);
- final int borderWidth = 8;
-
- Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
- p.setShadowLayer(borderWidth, 0, 0, Color.BLACK);
-
- RectF aRect = new RectF(borderWidth, borderWidth, borderWidth
- + aBitmap.getWidth(), borderWidth
- + aBitmap.getHeight());
- Bitmap aOut = Bitmap.createBitmap(aBitmap.getWidth() + 2
- * borderWidth, aBitmap.getHeight() + 2
- * borderWidth, aBitmap.getConfig());
- Canvas canvas = new Canvas(aOut);
- canvas.drawColor(mContext.getResources().getColor(R.color.light_grey));
- canvas.drawRect(aRect, p);
- canvas.drawBitmap(aBitmap, null, aRect, null);
-
- mSlidePreviews.put(aSlideIndex, aOut);
+ public void setSlidePreview(int aSlideIndex, byte[] aSlidePreviewBytes) {
+ Bitmap aSlidePreview = BitmapFactory
+ .decodeByteArray(aSlidePreviewBytes, 0, aSlidePreviewBytes.length);
+
+ mSlidePreviews.put(aSlideIndex, aSlidePreview);
}
public Bitmap getSlidePreview(int aSlideIndex) {
@@ -95,114 +73,9 @@ public class SlideShow {
}
}
- // ---------------------------------------------------- TIMER --------------
- private Timer mTimer = new Timer();
-
public Timer getTimer() {
return mTimer;
}
-
- public class Timer {
- /**
- * This stores the starting time of the timer if running.
- * <p/>
- * If paused this stores how long the timer was previously running.
- */
- private long aTime = 0;
-
- private long mCountdownTime = 0;
-
- private boolean mIsRunning = false;
-
- private boolean mIsCountdown = false;
-
- /**
- * Set whether this timer should be a normal or a countdown timer.
- *
- * @param aIsCountdown Whether this should be a countdown timer.
- */
- public void setCountdown(boolean aIsCountdown) {
- mIsCountdown = aIsCountdown;
- if (mIsRunning) {
- mIsRunning = false;
- aTime = 0;
- }
- }
-
- /**
- * Set the countdown time. Can be set, and isn't lost, whatever mode
- * the timer is running in.
- *
- * @param aCountdownTime The countdown time.
- */
- public void setCountdownTime(long aCountdownTime) {
- mCountdownTime = aCountdownTime;
- }
-
- public long getCountdownTime() {
- return mCountdownTime;
- }
-
- public boolean isCountdown() {
- return mIsCountdown;
- }
-
- public boolean isRunning() {
- return mIsRunning;
- }
-
- /**
- * Reset the timer, and stop it it was running.
- */
- public void reset() {
- mIsRunning = false;
- aTime = 0;
- }
-
- public void startTimer() {
- if (mIsRunning)
- return;
-
- aTime = System.currentTimeMillis() - aTime;
- mIsRunning = true;
- }
-
- public void stopTimer() {
- if (!mIsRunning)
- return;
-
- aTime = System.currentTimeMillis() - aTime;
- mIsRunning = false;
- }
-
- /**
- * Get either how long this timer has been running, or how long the
- * timer still has left to run.
- *
- * @return
- */
- public long getTimeMillis() {
- long aTimeRunning;
- // Determine how long we've been going.
- if (mIsRunning) {
- aTimeRunning = System.currentTimeMillis() - aTime;
- } else {
- aTimeRunning = aTime;
- }
- // And give the time going, or time left
- if (!mIsCountdown) {
- return aTimeRunning;
- } else {
- long aRet = mCountdownTime - aTimeRunning;
- if (aRet < 0) { // We have completed!
- mIsRunning = false;
- aRet = 0;
- }
- return aRet;
- }
-
- }
- }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java
new file mode 100644
index 0000000..84a7932
--- /dev/null
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java
@@ -0,0 +1,124 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.communication;
+
+public class Timer {
+ /**
+ * This stores the starting time of the timer if running.
+ * <p/>
+ * If paused this stores how long the timer was previously running.
+ */
+ private long mTime;
+ private long mCountdownTime;
+
+ private boolean mIsRunning;
+ private boolean mIsCountdown;
+
+ public Timer() {
+ mTime = 0;
+ mCountdownTime = 0;
+
+ mIsRunning = false;
+ mIsCountdown = false;
+ }
+
+ /**
+ * Set whether this timer should be a normal or a countdown timer.
+ *
+ * @param aIsCountdown Whether this should be a countdown timer.
+ */
+ public void setCountdown(boolean aIsCountdown) {
+ mIsCountdown = aIsCountdown;
+
+ if (mIsRunning) {
+ reset();
+ }
+ }
+
+ public boolean isCountdown() {
+ return mIsCountdown;
+ }
+
+ /**
+ * Set the countdown time. Can be set, and isn't lost, whatever mode
+ * the timer is running in.
+ *
+ * @param aCountdownTime The countdown time.
+ */
+ public void setCountdownTime(long aCountdownTime) {
+ mCountdownTime = aCountdownTime;
+ }
+
+ public long getCountdownTime() {
+ return mCountdownTime;
+ }
+
+ public boolean isRunning() {
+ return mIsRunning;
+ }
+
+ /**
+ * Reset the timer, and stop it it was running.
+ */
+ public void reset() {
+ mIsRunning = false;
+ mTime = 0;
+ }
+
+ public void start() {
+ if (mIsRunning) {
+ return;
+ }
+
+ mTime = System.currentTimeMillis() - mTime;
+ mIsRunning = true;
+ }
+
+ public void stop() {
+ if (!mIsRunning)
+ return;
+
+ mTime = System.currentTimeMillis() - mTime;
+ mIsRunning = false;
+ }
+
+ /**
+ * Get either how long this timer has been running, or how long the
+ * timer still has left to run.
+ *
+ * @return running time in millis.
+ */
+ public long getTimeMillis() {
+ if (mIsCountdown) {
+ return calculateCountdownRunningTime();
+ }
+
+ return calculateRunningTime();
+ }
+
+ private long calculateCountdownRunningTime() {
+ long aRunningTime = mCountdownTime - calculateRunningTime();
+
+ if (aRunningTime < 0) {
+ reset();
+ }
+
+ return aRunningTime;
+ }
+
+ private long calculateRunningTime() {
+ if (mIsRunning) {
+ return System.currentTimeMillis() - mTime;
+ }
+
+ return mTime;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list