From 656939390d72b1e13e65409b64e2c04f564bfe73 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Fri, 16 May 2014 13:34:13 +0300 Subject: [PATCH] Service --- .../src/net/osmand/plus/osmo/OsMoPlugin.java | 62 +--------- .../src/net/osmand/plus/osmo/OsMoService.java | 115 +++++++++++++++++- .../src/net/osmand/plus/osmo/OsMoThread.java | 85 ++++++------- .../src/net/osmand/plus/osmo/OsMoTracker.java | 7 +- 4 files changed, 159 insertions(+), 110 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index e134fcdf2e..b805a3419d 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -1,55 +1,29 @@ package net.osmand.plus.osmo; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - import net.osmand.Location; -import net.osmand.PlatformUtil; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; -import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.views.MonitoringInfoControl; import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices; import net.osmand.plus.views.OsmandMapTileView; - -import org.apache.commons.logging.Log; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.json.JSONException; -import org.json.JSONObject; - -import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; -import android.os.Build; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; -import android.provider.Settings.Secure; public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices { private OsmandApplication app; public static final String ID = "osmand.osmo"; - private static final Log log = PlatformUtil.getLog(OsMoPlugin.class); private OsMoService service; private OsMoTracker tracker; @@ -113,45 +87,11 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer @Override protected Exception doInBackground(Void... params) { - return registerOsmoDeviceKey(); + return service.registerOsmoDeviceKey(); } }; } - private Exception registerOsmoDeviceKey() { - HttpClient httpclient = new DefaultHttpClient(); - HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); - try { - // Add your data - List nameValuePairs = new ArrayList(2); - nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); - nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); - nameValuePairs.add(new BasicNameValuePair("imei", "0")); - nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); - nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); - httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - - // Execute HTTP Post Request - HttpResponse response = httpclient.execute(httppost); - InputStream cm = response.getEntity().getContent(); - BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); - String r = reader.readLine(); - reader.close(); - log.info("Authorization key : " + r); - final JSONObject obj = new JSONObject(r); - if(obj.has("error")) { - return new RuntimeException(obj.getString("error")); - } - app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); - return null; - } catch (ClientProtocolException e) { - return e; - } catch (IOException e) { - return e; - } catch (JSONException e) { - return e; - } - } @Override diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 8abe32501a..1850e37bc1 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -1,16 +1,38 @@ package net.osmand.plus.osmo; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONException; import org.json.JSONObject; +import android.os.Build; +import android.provider.Settings.Secure; + +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.Version; public class OsMoService { private OsMoThread thread; private List listSenders = new java.util.concurrent.CopyOnWriteArrayList(); private List listReactors = new java.util.concurrent.CopyOnWriteArrayList(); private OsmandApplication app; + private static final Log log = PlatformUtil.getLog(OsMoService.class); public interface OsMoSender { @@ -38,7 +60,7 @@ public class OsMoService { } thread.stopConnection(); } - thread = new OsMoThread(app, listSenders, listReactors); + thread = new OsMoThread(this, listSenders, listReactors); return true; } @@ -69,4 +91,95 @@ public class OsMoService { } + public Exception registerOsmoDeviceKey() { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); + nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); + nameValuePairs.add(new BasicNameValuePair("imei", "0")); + nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); + nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + return new RuntimeException(obj.getString("error")); + } + app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); + return null; + } catch (ClientProtocolException e) { + return e; + } catch (IOException e) { + return e; + } catch (JSONException e) { + return e; + } + } + + public static class SessionInfo { + public String hostName; + public String port; + public String token; + } + + + public SessionInfo getSessionToken() throws IOException { + String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get(); + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("key", deviceKey)); + nameValuePairs.add(new BasicNameValuePair("protocol", "1")); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + throw new RuntimeException(obj.getString("error")); + } + if(!obj.has("port")) { + throw new RuntimeException("Port not specified"); + } + if(!obj.has("address")) { + throw new RuntimeException("Host name not specified"); + } + if(!obj.has("token")) { + throw new RuntimeException("Token not specified"); + } + SessionInfo si = new SessionInfo(); + si.hostName = obj.getString("address"); + si.port = obj.getString("port"); + si.token = obj.getString("token"); + return si; + } catch (ClientProtocolException e) { + throw new IOException(e); + } catch (IOException e) { + throw e; + } catch (JSONException e) { + throw new IOException(e); + } + } + + public void showErrorMessage(String string) { + app.showToastMessage(app.getString(R.string.osmo_io_error) + string); + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index 76777bc432..b5feb85ac7 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -13,13 +13,11 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.TreeMap; import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; import net.osmand.plus.osmo.OsMoService.OsMoReactor; import net.osmand.plus.osmo.OsMoService.OsMoSender; +import net.osmand.plus.osmo.OsMoService.SessionInfo; import org.apache.commons.logging.Log; import org.json.JSONException; @@ -28,25 +26,21 @@ import org.json.JSONObject; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; -import android.provider.Settings.Secure; public class OsMoThread { - private static String TRACKER_SERVER = "srv.osmo.mobi"; - private static int TRACKER_PORT = 4242; +// private static String TRACKER_SERVER = "srv.osmo.mobi"; +// private static int TRACKER_PORT = 3245; protected final static Log log = PlatformUtil.getLog(OsMoThread.class); private static final long HEARTBEAT_DELAY = 100; private static final long HEARTBEAT_FAILED_DELAY = 10000; private static final long LIMIT_OF_FAILURES_RECONNECT = 10; - private static final long CONNECTION_DELAY = 25000; private static final long SELECT_TIMEOUT = 500; private static int HEARTBEAT_MSG = 3; private Handler serviceThread; private int failures = 0; private int activeConnectionId = 0; - // -1 means connected, 0 needs to reconnect, > 0 when connection initiated - private long connectionStarted = 0; private boolean stopThread; private Selector selector; @@ -54,7 +48,8 @@ public class OsMoThread { private List listReactors; private boolean authorized; - private OsmandApplication ctx; + private OsMoService service; + private SessionInfo token = null; private String authorizationCommand = null; private SocketChannel activeChannel; private ByteBuffer pendingSendCommand; @@ -62,9 +57,10 @@ public class OsMoThread { private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048); private LinkedList queueOfMessages = new LinkedList(); + - public OsMoThread(OsmandApplication ctx, List listSenders, List listReactors) { - this.ctx = ctx; + public OsMoThread(OsMoService service, List listSenders, List listReactors) { + this.service = service; this.listSenders = listSenders; this.listReactors = listReactors; // start thread to receive events from OSMO @@ -90,19 +86,22 @@ public class OsMoThread { } protected void initConnection() throws IOException { - try { - authorized = false; - authorizationCommand = getAuthorizationCmd(); - selector = Selector.open(); - connectionStarted = System.currentTimeMillis(); - activeChannel = SocketChannel.open(); - activeChannel.configureBlocking(false); - SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); - key.attach(new Integer(++activeConnectionId)); - activeChannel.connect(new InetSocketAddress(TRACKER_SERVER, TRACKER_PORT)); - } catch (IOException e) { - throw e; + if (token == null) { + token = service.getSessionToken(); } + authorized = false; + selector = Selector.open(); + SocketChannel activeChannel = SocketChannel.open(); + activeChannel.configureBlocking(true); + activeChannel.connect(new InetSocketAddress(token.hostName, Integer.parseInt(token.port))); + activeChannel.configureBlocking(false); + SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); + if (this.activeChannel != null) { + stopChannel(); + } + this.activeChannel = activeChannel; + key.attach(new Integer(++activeConnectionId)); + } public String format(String cmd, Map params) { @@ -120,13 +119,6 @@ public class OsMoThread { } } - private String getAuthorizationCmd() { - Map params = new TreeMap(); - params.put("protocol_version", 1); - params.put("key", ctx.getSettings().OSMO_DEVICE_KEY.get()); - return format("AUTH", params); - } - public void scheduleHeartbeat(long delay) { Message msg = serviceThread.obtainMessage(); msg.what = HEARTBEAT_MSG; @@ -139,7 +131,7 @@ public class OsMoThread { } public boolean isConnected() { - return connectionStarted == -1; + return activeChannel != null; } protected void checkAsyncSocket() { @@ -148,12 +140,7 @@ public class OsMoThread { if (selector == null) { stopThread = true; } else { - if (activeChannel != null && connectionStarted != -1 && !activeChannel.isConnectionPending()) { - // connection ready - connectionStarted = -1; - } - if ((connectionStarted != -1 && System.currentTimeMillis() - connectionStarted > CONNECTION_DELAY) - || activeChannel == null) { + if(activeChannel == null) { initConnection(); } else { checkSelectedKeys(); @@ -265,16 +252,20 @@ public class OsMoThread { e.printStackTrace(); } } - if(cmd.equalsIgnoreCase("AUTH")) { - if(obj != null && !obj.has("error")) { - try { - ctx.showToastMessage(ctx.getString(R.string.osmo_io_error) + obj.getString("error")); - } catch (JSONException e) { - e.printStackTrace(); - } - } else { + boolean error = false; + if(obj != null && !obj.has("error")) { + error = true; + try { + service.showErrorMessage(obj.getString("error")); + } catch (JSONException e) { + e.printStackTrace(); + } + } + if(cmd.equalsIgnoreCase("TOKEN")) { + if(!error){ authorized = true; - ctx.showToastMessage("OSMo authorization successfull"); + // TODO delete + service.showErrorMessage("OSMo authorization successfull"); } continue; } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index c96680c987..25078a0d27 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -6,7 +6,8 @@ import net.osmand.Location; import net.osmand.plus.osmo.OsMoService.OsMoSender; public class OsMoTracker implements OsMoSender { - private LinkedList bufferOfLocations = new LinkedList(); + private LinkedList bufferOfLocations = new LinkedList(); + private boolean start; public OsMoTracker(OsMoService service) { service.registerSender(this); @@ -14,6 +15,10 @@ public class OsMoTracker implements OsMoSender { @Override public String nextSendCommand(OsMoThread thread) { + if(!start) { + start = true; + return "TRACKER_SESSION_OPEN"; + } if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|");