diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb6828..5d19981 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index eceecb5..d82c1b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ android { } } compileSdkVersion 23 - buildToolsVersion "23.0.3" + buildToolsVersion '25.0.0' defaultConfig { applicationId "us.keithirwin.tracman" minSdkVersion 14 @@ -45,8 +45,10 @@ dependencies { compile ('com.github.nkzawa:socket.io-client:0.4.1'){ exclude group: 'org.json', module: 'json' } - compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3' - compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3' + compile 'com.squareup.retrofit2:retrofit:2.2.0' +// compile 'com.squareup.retrofit2:converter-gson:2.2.0' +// compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3' +// compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/src/main/java/us/keithirwin/tracman/BootReceiver.java b/app/src/main/java/us/keithirwin/tracman/BootReceiver.java index 703d718..6faa15c 100644 --- a/app/src/main/java/us/keithirwin/tracman/BootReceiver.java +++ b/app/src/main/java/us/keithirwin/tracman/BootReceiver.java @@ -13,7 +13,7 @@ public class BootReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { // Starts location service on boot SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (prefs.getBoolean("pref_start_boot", true)) { + if (prefs.getBoolean("pref_start_boot", false)) { context.startService(new Intent(context, LocationService.class)); } } diff --git a/app/src/main/java/us/keithirwin/tracman/LocationService.java b/app/src/main/java/us/keithirwin/tracman/LocationService.java index a625d41..73a0c32 100644 --- a/app/src/main/java/us/keithirwin/tracman/LocationService.java +++ b/app/src/main/java/us/keithirwin/tracman/LocationService.java @@ -42,7 +42,8 @@ import java.net.URISyntaxException; public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { public LocationService() {} - private String TAG = "LocationService"; +// private String TAG = "LocationService"; + final String SERVER_ADDRESS = "https://dev.tracman.org/"; private Socket mSocket; private String mUserID; @@ -128,7 +129,6 @@ public class LocationService extends Service implements GoogleApiClient.Connecti mUserID = sharedPref.getString("loggedInUserId", null); mUserSK = sharedPref.getString("loggedInUserSk", null); - final String SERVER_ADDRESS = "https://tracman.org/"; // Connect to socket try { diff --git a/app/src/main/java/us/keithirwin/tracman/LoginActivity.java b/app/src/main/java/us/keithirwin/tracman/LoginActivity.java index fbbf368..5020239 100644 --- a/app/src/main/java/us/keithirwin/tracman/LoginActivity.java +++ b/app/src/main/java/us/keithirwin/tracman/LoginActivity.java @@ -25,18 +25,31 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; +import java.security.KeyStore; +import java.util.Arrays; +import java.util.Collections; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import okhttp3.Call; +import okhttp3.CipherSuite; +import okhttp3.ConnectionSpec; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Callback; import okhttp3.Response; +import okhttp3.TlsVersion; public class LoginActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { private static final String TAG = "LoginActivity"; private static final int RC_SIGN_IN = 9001; - private final String SERVER_ADDRESS = "https://tracman.org/"; + private final String SERVER_ADDRESS = "https://dev.tracman.org/"; private static final String GOOGLE_WEB_CLIENT_ID = "483494341936-hrn0ms1tebgdtfs5f4i6ebmkt3qmo16o.apps.googleusercontent.com"; private GoogleApiClient mGoogleApiClient; @@ -122,23 +135,36 @@ public class LoginActivity extends AppCompatActivity implements } private void AuthenticateGoogle(final String token) throws Exception { - final OkHttpClient client = new OkHttpClient(); + + // Needed to support TLS 1.1 and 1.2 + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException("Unexpected default trust managers:" + + Arrays.toString(trustManagers)); + } + X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; + + OkHttpClient client = new OkHttpClient.Builder() + .sslSocketFactory(new TLSSocketFactory(), trustManager) + .build(); Request request = new Request.Builder() .url(SERVER_ADDRESS+"auth/google/idtoken?id_token="+token) .build(); -// Log.d(TAG, "Attempting Tracman signin with token: " + token); client.newCall(request).enqueue(new Callback() { @Override - public void onFailure(Request request, IOException throwable) { -// Log.e(TAG, "Failed to connect to server: " + SERVER_ADDRESS + "auth/google/idtoken?id_token=" + token); + public void onFailure(Call call, IOException e) { + Log.e(TAG, "Failed to connect to server: " + SERVER_ADDRESS + "auth/google/idtoken?id_token=" + token); showError(R.string.server_connection_error); - throwable.printStackTrace(); + e.printStackTrace(); } @Override - public void onResponse(Response res) throws IOException { + public void onResponse(Call call, Response res) throws IOException { if (!res.isSuccessful()) { showError(R.string.login_no_user_error); res.body().close(); @@ -173,9 +199,11 @@ public class LoginActivity extends AppCompatActivity implements editor.commit(); startActivity(new Intent(getBaseContext(), SettingsActivity.class)); - } } + } + }); + } private void handleSignInResult(GoogleSignInResult result) { diff --git a/app/src/main/java/us/keithirwin/tracman/SettingsActivity.java b/app/src/main/java/us/keithirwin/tracman/SettingsActivity.java index 003d5f7..f6474e9 100644 --- a/app/src/main/java/us/keithirwin/tracman/SettingsActivity.java +++ b/app/src/main/java/us/keithirwin/tracman/SettingsActivity.java @@ -6,7 +6,6 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; @@ -14,7 +13,6 @@ import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; @@ -68,6 +66,37 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } }; + /** + * A preference value change listener that restarts the location service + * after something relevant is changed. + */ + private Preference.OnPreferenceChangeListener sRestartLocationServiceOnChangeListener = new Preference.OnPreferenceChangeListener() { + + @Override + public boolean onPreferenceChange(Preference preference, Object obj) { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(SettingsActivity.this); + + stopService(new Intent(SettingsActivity.this, LocationService.class)); + + if (sharedPref.getBoolean("gps_switch", false)) { + + // Ask for location permissions (can't be done in service, only activity) + if (!LocationService.checkLocationPermission(SettingsActivity.this)) { + ActivityCompat.requestPermissions( + SettingsActivity.this, + new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, + MY_FINE_LOCATION_PERMISSION); + } + +// Log.d(TAG, "Starting LocationService"); + startService(new Intent(SettingsActivity.this, LocationService.class)); + + } + + return true; + } + }; + /** * Helper method to determine if the device has an extra-large screen. For * example, 10" tablets are extra-large. @@ -103,6 +132,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity { setupActionBar(); // Log.d(TAG, "activity onCreate called"); + // Restart LocationService when any related preference is changed +// findPreference("gps_switch").setOnPreferenceChangeListener(sRestartLocationServiceOnChangeListener); + // Get User ID SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); String mUserID = sharedPref.getString("loggedInUserId", null); @@ -111,34 +143,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } } - private void showLocationPermissionDialog() { - if (!LocationService.checkLocationPermission(this)) { - ActivityCompat.requestPermissions( - this, - new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, - MY_FINE_LOCATION_PERMISSION); - } - } - @Override protected void onStop() { - // Log.d(TAG, "onStop called"); super.onStop(); - - // Restart service so settings can take effect - stopService(new Intent(this, LocationService.class)); - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - if (sharedPref.getBoolean("gps_switch", false)) { - - // Ask for location permissions (can't be done in service, only activity) - showLocationPermissionDialog(); - - // Start location tracking service -// Log.d(TAG, "Starting LocationService"); - startService(new Intent(this, LocationService.class)); - - } } /** @@ -207,6 +215,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity { addPreferencesFromResource(R.xml.pref_general); setHasOptionsMenu(true); +// // Restart LocationService when any related preference is changed +// findPreference("gps_switch").setOnPreferenceChangeListener(sRestartLocationServiceOnChangeListener); + // Bind the summary of preferences to their value bindPreferenceSummaryToValue(findPreference("broadcast_frequency")); bindPreferenceSummaryToValue(findPreference("broadcast_priority")); diff --git a/app/src/main/java/us/keithirwin/tracman/TLSSocketFactory.java b/app/src/main/java/us/keithirwin/tracman/TLSSocketFactory.java new file mode 100644 index 0000000..6adc423 --- /dev/null +++ b/app/src/main/java/us/keithirwin/tracman/TLSSocketFactory.java @@ -0,0 +1,75 @@ +package us.keithirwin.tracman; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +/** + * @author fkrauthan + * From: https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ + */ +public class TLSSocketFactory extends SSLSocketFactory { + + private SSLSocketFactory internalSSLSocketFactory; + + public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, null, null); + internalSSLSocketFactory = context.getSocketFactory(); + } + + @Override + public String[] getDefaultCipherSuites() { + return internalSSLSocketFactory.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return internalSSLSocketFactory.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket() throws IOException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket()); + } + + @Override + public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); + } + + private Socket enableTLSOnSocket(Socket socket) { + if(socket != null && (socket instanceof SSLSocket)) { + ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); + } + return socket; + } + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 26d3e05..3afcd7f 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:2.3.0' classpath 'com.google.gms:google-services:3.0.0' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 33dbdc9..c627fba 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,2 +1,2 @@ -#Tue Sep 27 15:34:22 EDT 2016 -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +#Fri Mar 03 16:00:54 EST 2017 +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip