From 261dc90595e583914161e5e9011f5f5dd4a9740c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 12 Nov 2014 01:30:09 +0100 Subject: eip package, EIP constants to interface. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 81 ++-- app/src/main/java/se/leap/bitmaskclient/EIP.java | 524 --------------------- .../se/leap/bitmaskclient/EipServiceFragment.java | 92 ++-- .../java/se/leap/bitmaskclient/OnBootReceiver.java | 7 +- .../se/leap/bitmaskclient/VoidVpnLauncher.java | 37 -- .../java/se/leap/bitmaskclient/VoidVpnService.java | 36 -- .../se/leap/bitmaskclient/VpnConfigGenerator.java | 146 ------ .../java/se/leap/bitmaskclient/eip/Constants.java | 50 ++ .../main/java/se/leap/bitmaskclient/eip/EIP.java | 486 +++++++++++++++++++ .../se/leap/bitmaskclient/eip/VoidVpnLauncher.java | 37 ++ .../se/leap/bitmaskclient/eip/VoidVpnService.java | 37 ++ .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 145 ++++++ 12 files changed, 827 insertions(+), 851 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/EIP.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/VpnConfigGenerator.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/Constants.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/EIP.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 364a79af..473cd5ec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -14,38 +14,21 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package se.leap.bitmaskclient; +package se.leap.bitmaskclient; -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; -import se.leap.bitmaskclient.FragmentManagerEnhanced; -import se.leap.bitmaskclient.SignUpDialog; +import se.leap.bitmaskclient.*; +import se.leap.bitmaskclient.eip.*; import de.blinkt.openvpn.activities.LogWindow; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.app.FragmentTransaction; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; +import android.app.*; +import android.content.*; import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; +import android.os.*; import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; +import android.view.*; +import android.widget.*; +import org.json.*; /** * The main user facing Activity of LEAP Android, consisting of status, controls, @@ -54,7 +37,7 @@ import android.widget.Toast; * @author Sean Leonard * @author parmegv */ -public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface, SignUpDialog.SignUpDialogInterface, Receiver { +public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface, SignUpDialog.SignUpDialogInterface, ProviderAPIResultReceiver.Receiver { protected static final int CONFIGURE_LEAP = 0; protected static final int SWITCH_PROVIDER = 1; @@ -95,7 +78,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); + authed_eip = preferences.getBoolean(Constants.AUTHED_EIP, false); if (preferences.getString(Provider.KEY, "").isEmpty()) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else @@ -113,9 +96,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(versionCode) { case 91: // 0.6.0 without Bug #5999 case 101: // 0.8.0 - if(!preferences.getString(EIP.KEY, "").isEmpty()) { + if(!preferences.getString(Constants.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); - rebuildVpnProfiles.setAction(EIP.ACTION_REBUILD_PROFILES); + rebuildVpnProfiles.setAction(Constants.ACTION_REBUILD_PROFILES); startService(rebuildVpnProfiles); } break; @@ -139,23 +122,21 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { if ( resultCode == RESULT_OK ){ - preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit(); - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - + preferences.edit().putInt(Constants.PARSED_SERIAL, 0).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); Intent updateEIP = new Intent(getApplicationContext(), EIP.class); - updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + updateEIP.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); startService(updateEIP); - buildDashboard(false); invalidateOptionsMenu(); if(data != null && data.hasExtra(LogInDialog.TAG)) { View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); } - } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { - finish(); - } else - configErrorDialog(); + } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { + finish(); + } else + configErrorDialog(); } } @@ -227,7 +208,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); boolean authed_eip = !LeapSRPSession.getToken().isEmpty(); boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); - preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); + preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, allow_registered_eip); if(allow_registered_eip) { if(authed_eip) { @@ -268,7 +249,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf return true; case R.id.switch_provider: if (Provider.getInstance().hasEIP()){ - if (preferences.getBoolean(EIP.AUTHED_EIP, false)){ + if (preferences.getBoolean(Constants.AUTHED_EIP, false)){ logOut(); } eipStop(); @@ -426,7 +407,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf invalidateOptionsMenu(); authed_eip = true; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); downloadAuthedUserCertificate(); } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { @@ -441,7 +422,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf invalidateOptionsMenu(); authed_eip = false; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { changeStatusMessage(resultCode); @@ -457,7 +438,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf ResultReceiver eip_receiver = new ResultReceiver(new Handler()){ protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(EIP.REQUEST_TAG); + String request = resultData.getString(Constants.REQUEST_TAG); if (resultCode == Activity.RESULT_OK){ if(authed_eip) eipStart(); @@ -466,8 +447,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } } }; - updateEIP.putExtra(EIP.RECEIVER_TAG, eip_receiver); - updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + updateEIP.putExtra(Constants.RECEIVER_TAG, eip_receiver); + updateEIP.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); startService(updateEIP); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); @@ -481,9 +462,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf ResultReceiver eip_status_receiver = new ResultReceiver(new Handler()){ protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(EIP.REQUEST_TAG); + String request = resultData.getString(Constants.REQUEST_TAG); if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - if (request.equalsIgnoreCase(EIP.ACTION_IS_EIP_RUNNING)){ + if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){ if (resultCode == Activity.RESULT_OK){ switch(previous_result_code){ @@ -544,8 +525,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private void eipIsRunning(ResultReceiver eip_receiver){ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_IS_EIP_RUNNING); - eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver); + eip_intent.setAction(Constants.ACTION_IS_EIP_RUNNING); + eip_intent.putExtra(Constants.RECEIVER_TAG, eip_receiver); startService(eip_intent); } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java deleted file mode 100644 index 2f06def3..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ /dev/null @@ -1,524 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.IntentService; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.ResultReceiver; -import android.util.Log; -import de.blinkt.openvpn.LaunchVPN; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.core.ConfigParser; -import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; -import java.io.IOException; -import java.io.StringReader; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.X509Certificate; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Locale; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.TreeMap; -import java.util.Vector; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.Provider; -import se.leap.bitmaskclient.R; - -/** - * EIP is the abstract base class for interacting with and managing the Encrypted - * Internet Proxy connection. Connections are started, stopped, and queried through - * this IntentService. - * Contains logic for parsing eip-service.json from the provider, configuring and selecting - * gateways, and controlling {@link de.blinkt.openvpn.core.OpenVPNService} connections. - * - * @author Sean Leonard - * @author Parménides GV - */ -public final class EIP extends IntentService { - - public final static String AUTHED_EIP = "authed eip"; - public final static String ACTION_CHECK_CERT_VALIDITY = "se.leap.bitmaskclient.CHECK_CERT_VALIDITY"; - public final static String ACTION_START_EIP = "se.leap.bitmaskclient.START_EIP"; - public final static String ACTION_STOP_EIP = "se.leap.bitmaskclient.STOP_EIP"; - public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.bitmaskclient.UPDATE_EIP_SERVICE"; - public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING"; - public final static String ACTION_REBUILD_PROFILES = "se.leap.bitmaskclient.REBUILD_PROFILES"; - public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION"; - public final static String STATUS = "eip status"; - public final static String DATE_FROM_CERTIFICATE = "date from certificate"; - public final static String ALLOWED_ANON = "allow_anonymous"; - public final static String ALLOWED_REGISTERED = "allow_registration"; - public final static String CERTIFICATE = "cert"; - public final static String PRIVATE_KEY = "private_key"; - public final static String KEY = "eip"; - public final static String PARSED_SERIAL = "eip_parsed_serial"; - public final static String SERVICE_API_PATH = "config/eip-service.json"; - public final static String RECEIVER_TAG = "receiverTag"; - public final static String REQUEST_TAG = "requestTag"; - public final static String TAG = EIP.class.getSimpleName(); - private static SharedPreferences preferences; - - private static Context context; - private static ResultReceiver mReceiver; - private static boolean mBound = false; - - private static JSONObject eipDefinition = null; - - private static OVPNGateway activeGateway = null; - - protected static ConnectionStatus lastConnectionStatusLevel; - protected static boolean mIsDisconnecting = false; - protected static boolean mIsStarting = false; - - public static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - public EIP(){ - super("LEAPEIP"); - } - - @Override - public void onCreate() { - super.onCreate(); - - context = getApplicationContext(); - - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); - } - - @Override - public void onDestroy() { - - mBound = false; - - super.onDestroy(); - } - - - @Override - protected void onHandleIntent(Intent intent) { - String action = intent.getAction(); - mReceiver = intent.getParcelableExtra(RECEIVER_TAG); - - if ( action == ACTION_START_EIP ) - startEIP(); - else if ( action == ACTION_STOP_EIP ) - stopEIP(); - else if ( action == ACTION_IS_EIP_RUNNING ) - isRunning(); - else if ( action == ACTION_UPDATE_EIP_SERVICE ) - updateEIPService(); - else if ( action == ACTION_CHECK_CERT_VALIDITY ) - checkCertValidity(); - else if ( action == ACTION_REBUILD_PROFILES ) - updateGateways(); - } - - /** - * Initiates an EIP connection by selecting a gateway and preparing and sending an - * Intent to {@link se.leap.openvpn.LaunchVPN}. - * It also sets up early routes. - */ - private void startEIP() { - earlyRoutes(); - activeGateway = selectGateway(); - - if(activeGateway != null && activeGateway.mVpnProfile != null) { - mReceiver = EipServiceFragment.getReceiver(); - launchActiveGateway(); - } - } - - /** - * Early routes are routes that block traffic until a new - * VpnService is started properly. - */ - private void earlyRoutes() { - Intent void_vpn_launcher = new Intent(context, VoidVpnLauncher.class); - void_vpn_launcher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(void_vpn_launcher); - } - - /** - * Choose a gateway to connect to based on timezone from system locale data - * - * @return The gateway to connect to - */ - private OVPNGateway selectGateway() { - String closest_location = closestGateway(); - String chosen_host = chooseHost(closest_location); - - return new OVPNGateway(chosen_host); - } - - private String closestGateway() { - TreeMap> offsets = calculateOffsets(); - return offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); - } - - private TreeMap> calculateOffsets() { - TreeMap> offsets = new TreeMap>(); - - int localOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; - - JSONObject locations = availableLocations(); - Iterator locations_names = locations.keys(); - while(locations_names.hasNext()) { - try { - String location_name = locations_names.next(); - JSONObject location = locations.getJSONObject(location_name); - - int dist = timezoneDistance(localOffset, location.optInt("timezone")); - - Set set = (offsets.get(dist) != null) ? - offsets.get(dist) : new HashSet(); - - set.add(location_name); - offsets.put(dist, set); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - return offsets; - } - - private JSONObject availableLocations() { - JSONObject locations = null; - try { - if(eipDefinition == null) updateEIPService(); - locations = eipDefinition.getJSONObject("locations"); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - return locations; - } - - private int timezoneDistance(int local_timezone, int remote_timezone) { - // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 - int dist = Math.abs(local_timezone - remote_timezone); - - // Farther than 12 timezones and it's shorter around the "back" - if (dist > 12) - dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. - - return dist; - } - - private String chooseHost(String location) { - String chosen_host = ""; - try { - JSONArray gateways = eipDefinition.getJSONArray("gateways"); - for (int i = 0; i < gateways.length(); i++) { - JSONObject gw = gateways.getJSONObject(i); - if ( gw.getString("location").equalsIgnoreCase(location) || location.isEmpty()){ - chosen_host = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); - break; - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return chosen_host; - } - - private void launchActiveGateway() { - Intent intent = new Intent(this,LaunchVPN.class); - intent.setAction(Intent.ACTION_MAIN); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); - intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); - intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); - intent.putExtra(RECEIVER_TAG, mReceiver); - startActivity(intent); - } - - /** - * Disconnects the EIP connection gracefully through the bound service or forcefully - * if there is no bound service. Sends a message to the requesting ResultReceiver. - */ - private void stopEIP() { - if(isConnected()) { - Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); - disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(disconnect_vpn); - mIsDisconnecting = true; - lastConnectionStatusLevel = ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user - Log.d(TAG, "mIsDisconnecting = true"); - } - - tellToReceiver(ACTION_STOP_EIP, Activity.RESULT_OK); - } - - private void tellToReceiver(String action, int resultCode) { - if (mReceiver != null){ - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, action); - mReceiver.send(resultCode, resultData); - } - } - - /** - * Checks the last stored status notified by ics-openvpn - * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the - * request if it's not connected, Activity.RESULT_OK otherwise. - */ - - private void isRunning() { - int resultCode = Activity.RESULT_CANCELED; - boolean is_connected = isConnected(); - - resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - - tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); - } - - protected static boolean isConnected() { - return lastConnectionStatusLevel != null && lastConnectionStatusLevel.equals(ConnectionStatus.LEVEL_CONNECTED) && !mIsDisconnecting; - } - - /** - * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} - * to parse gateway definitions. - * TODO Implement API call to refresh eip-service.json from the provider - */ - private void updateEIPService() { - try { - String eip_definition_string = preferences.getString(KEY, ""); - if(eip_definition_string.isEmpty() == false) { - eipDefinition = new JSONObject(eip_definition_string); - } - deleteAllVpnProfiles(); - updateGateways(); - if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - private void deleteAllVpnProfiles() { - ProfileManager vpl = ProfileManager.getInstance(context); - Collection profiles = vpl.getProfiles(); - profiles.removeAll(profiles); - } - - /** - * Walk the list of gateways defined in eip-service.json and parse them into - * OVPNGateway objects. - * TODO Store the OVPNGateways (as Serializable) in SharedPreferences - */ - private void updateGateways(){ - JSONArray gatewaysDefined = null; - try { - if(eipDefinition == null) updateEIPService(); - gatewaysDefined = eipDefinition.getJSONArray("gateways"); - for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ - JSONObject gw = null; - gw = gatewaysDefined.getJSONObject(i); - - if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) - new OVPNGateway(gw); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - preferences.edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); - } - - private void checkCertValidity() { - String certificate = preferences.getString(CERTIFICATE, ""); - checkCertValidity(certificate); - } - - private void checkCertValidity(String certificate_string) { - if(!certificate_string.isEmpty()) { - X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificate_string); - - Calendar offset_date = calculateOffsetCertificateValidity(certificate); - Bundle result = new Bundle(); - result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); - try { - Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); - certificate.checkValidity(offset_date.getTime()); - mReceiver.send(Activity.RESULT_OK, result); - Log.d(TAG, "Valid certificate"); - } catch(CertificateExpiredException e) { - mReceiver.send(Activity.RESULT_CANCELED, result); - Log.d(TAG, "Updating certificate"); - } catch(CertificateNotYetValidException e) { - mReceiver.send(Activity.RESULT_CANCELED, result); - } - } - } - - private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { - String current_date = certificate_date_format.format(Calendar.getInstance().getTime()).toString(); - - String date_string = preferences.getString(DATE_FROM_CERTIFICATE, current_date); - - Calendar offset_date = Calendar.getInstance(); - try { - Date date = certificate_date_format.parse(date_string); - long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; - long current_date_millis = offset_date.getTimeInMillis(); - offset_date.setTimeInMillis(current_date_millis + difference); - Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); - } catch(ParseException e) { - e.printStackTrace(); - } - - return offset_date; - } - - /** - * OVPNGateway provides objects defining gateways and their options and metadata. - * Each instance contains a VpnProfile for OpenVPN specific data and member - * variables describing capabilities and location - * - * @author Sean Leonard - */ - private class OVPNGateway { - - private String TAG = "OVPNGateway"; - - private String mName; - private VpnProfile mVpnProfile; - private JSONObject mGateway; - private HashMap>> options = new HashMap>>(); - - - /** - * Attempts to retrieve a VpnProfile by name and build an OVPNGateway around it. - * FIXME This needs to become a findGatewayByName() method - * - * @param name The hostname of the gateway to inflate - */ - private OVPNGateway(String name){ - mName = name; - - this.loadVpnProfile(); - } - - private void loadVpnProfile() { - ProfileManager vpl = ProfileManager.getInstance(context); - try { - if ( mName == null ) - mVpnProfile = vpl.getProfiles().iterator().next(); - else - mVpnProfile = vpl.getProfileByName(mName); - } catch (NoSuchElementException e) { - updateEIPService(); - this.loadVpnProfile(); // FIXME catch infinite loops - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json - * and create a VpnProfile belonging to it. - * - * @param gateway The JSON OpenVPN gateway definition to parse - */ - protected OVPNGateway(JSONObject gateway){ - - mGateway = gateway; - - // Currently deletes VpnProfile for host, if there already is one, and builds new - ProfileManager vpl = ProfileManager.getInstance(context); - Collection profiles = vpl.getProfiles(); - for (Iterator it = profiles.iterator(); it.hasNext(); ){ - VpnProfile p = it.next(); - - if ( p.mName.equalsIgnoreCase( mName ) ) { - it.remove(); - vpl.removeProfile(context, p); - } - } - - this.createVPNProfile(); - - vpl.addProfile(mVpnProfile); - vpl.saveProfile(context, mVpnProfile); - vpl.saveProfileList(context); - } - - /** - * Create and attach the VpnProfile to our gateway object - */ - protected void createVPNProfile(){ - try { - ConfigParser cp = new ConfigParser(); - - JSONObject openvpn_configuration = eipDefinition.getJSONObject("openvpn_configuration"); - VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, openvpn_configuration, mGateway); - String configuration = vpn_configuration_generator.generate(); - - cp.parseConfig(new StringReader(configuration)); - mVpnProfile = cp.convertProfile(); - mVpnProfile.mName = mName = locationAsName(); - Log.v(TAG,"Created VPNProfile"); - - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ConfigParseError e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } catch (IOException e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } - } - - - public String locationAsName() { - try { - return eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); - } catch (JSONException e) { - Log.v(TAG,"Couldn't read gateway name for profile creation! Returning original name = " + mName); - e.printStackTrace(); - return (mName != null) ? mName : ""; - } - } - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 6d223dd6..f35a3cfa 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -3,34 +3,18 @@ package se.leap.bitmaskclient; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.ProviderAPIResultReceiver; import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; -import se.leap.bitmaskclient.Dashboard; - -import de.blinkt.openvpn.activities.LogWindow; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; -import de.blinkt.openvpn.core.VpnStatus.StateListener; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; +import se.leap.bitmaskclient.eip.*; + +import de.blinkt.openvpn.activities.*; +import de.blinkt.openvpn.core.*; +import android.app.*; +import android.content.*; +import android.os.*; import android.util.Log; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.CompoundButton; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.Switch; -import android.widget.TextView; - -public class EipServiceFragment extends Fragment implements StateListener, OnCheckedChangeListener { +import android.view.*; +import android.widget.*; + +public class EipServiceFragment extends Fragment implements VpnStatus.StateListener, CompoundButton.OnCheckedChangeListener { protected static final String IS_EIP_PENDING = "is_eip_pending"; public static final String START_ON_BOOT = "start on boot"; @@ -85,8 +69,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe super.onResume(); VpnStatus.addStateListener(this); - - eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); + + eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); } @Override @@ -139,13 +123,13 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } private boolean canStartEIP() { - boolean certificateExists = !Dashboard.preferences.getString(EIP.CERTIFICATE, "").isEmpty(); - boolean isAllowedAnon = Dashboard.preferences.getBoolean(EIP.ALLOWED_ANON, false); + boolean certificateExists = !Dashboard.preferences.getString(Constants.CERTIFICATE, "").isEmpty(); + boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); return (isAllowedAnon || certificateExists) && !EIP.mIsStarting && !EIP.isConnected(); } private boolean canLogInToStartEIP() { - boolean isAllowedRegistered = Dashboard.preferences.getBoolean(EIP.ALLOWED_REGISTERED, false); + boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.ALLOWED_REGISTERED, false); boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); Log.d(TAG, "Allow registered? " + isAllowedRegistered); Log.d(TAG, "Is logged in? " + isLoggedIn); @@ -192,7 +176,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe eipSwitch.setChecked(true); saveEipStatus(); } - eipCommand(EIP.ACTION_START_EIP); + eipCommand(Constants.ACTION_START_EIP); } protected void stopEIP() { @@ -203,7 +187,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe String status = getResources().getString(R.string.eip_state_not_connected); setEipStatus(status); - eipCommand(EIP.ACTION_STOP_EIP); + eipCommand(Constants.ACTION_STOP_EIP); } /** @@ -216,16 +200,16 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? Intent vpn_intent = new Intent(getActivity().getApplicationContext(), EIP.class); vpn_intent.setAction(action); - vpn_intent.putExtra(EIP.RECEIVER_TAG, mEIPReceiver); + vpn_intent.putExtra(Constants.RECEIVER_TAG, mEIPReceiver); getActivity().startService(vpn_intent); } @Override - public void updateState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { + public void updateState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { boolean isNewLevel = EIP.lastConnectionStatusLevel != level; - boolean justDecidedOnDisconnect = EIP.lastConnectionStatusLevel == ConnectionStatus.UNKNOWN_LEVEL; + boolean justDecidedOnDisconnect = EIP.lastConnectionStatusLevel == VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; Log.d(TAG, "update state with level " + level); - if(!justDecidedOnDisconnect && (isNewLevel || level == ConnectionStatus.LEVEL_CONNECTED)) { + if(!justDecidedOnDisconnect && (isNewLevel || level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED)) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { @@ -233,28 +217,28 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe handleNewState(state, logmessage, localizedResId, level); } }); - } else if(justDecidedOnDisconnect && level == ConnectionStatus.LEVEL_CONNECTED) { - EIP.lastConnectionStatusLevel = ConnectionStatus.LEVEL_NOTCONNECTED; + } else if(justDecidedOnDisconnect && level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED) { + EIP.lastConnectionStatusLevel = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; updateState(state, logmessage, localizedResId, level); } // else if(isNewLevel || level == ConnectionStatus.LEVEL_AUTH_FAILED) // handleNewState(state, logmessage, localizedResId, level); } - private void handleNewState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { - if (level == ConnectionStatus.LEVEL_CONNECTED) + private void handleNewState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { + if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED) setConnectedUI(); else if (isDisconnectedLevel(level) && !EIP.mIsStarting) setDisconnectedUI(); - else if (level == ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) + else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) setNoServerReplyUI(localizedResId, logmessage); - else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) + else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) setServerReplyUI(state, localizedResId, logmessage); - // else if (level == ConnectionStatus.LEVEL_AUTH_FAILED) + // else if (level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED) // handleSwitchOn(); } - private boolean isDisconnectedLevel(final ConnectionStatus level) { - return level == ConnectionStatus.LEVEL_NOTCONNECTED || level == ConnectionStatus.LEVEL_AUTH_FAILED; + private boolean isDisconnectedLevel(final VpnStatus.ConnectionStatus level) { + return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED || level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED; } private void setConnectedUI() { @@ -331,10 +315,10 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(EIP.REQUEST_TAG); + String request = resultData.getString(Constants.REQUEST_TAG); boolean checked = false; - if (request == EIP.ACTION_IS_EIP_RUNNING) { + if (request == Constants.ACTION_IS_EIP_RUNNING) { switch (resultCode){ case Activity.RESULT_OK: checked = true; @@ -343,7 +327,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe checked = false; break; } - } else if (request == EIP.ACTION_START_EIP) { + } else if (request == Constants.ACTION_START_EIP) { switch (resultCode){ case Activity.RESULT_OK: Log.d(TAG, "Action start eip = Result OK"); @@ -356,7 +340,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); break; } - } else if (request == EIP.ACTION_STOP_EIP) { + } else if (request == Constants.ACTION_STOP_EIP) { switch (resultCode){ case Activity.RESULT_OK: checked = false; @@ -365,7 +349,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe checked = true; break; } - } else if (request == EIP.EIP_NOTIFICATION) { + } else if (request == Constants.EIP_NOTIFICATION) { switch (resultCode){ case Activity.RESULT_OK: checked = true; @@ -374,7 +358,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe checked = false; break; } - } else if (request == EIP.ACTION_CHECK_CERT_VALIDITY) { + } else if (request == Constants.ACTION_CHECK_CERT_VALIDITY) { checked = eipSwitch.isChecked(); switch (resultCode) { @@ -387,7 +371,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe String status = getResources().getString(R.string.updating_certificate_message); setEipStatus(status); - if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(EIP.ALLOWED_ANON, false)) { + if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { dashboard.logInDialog(Bundle.EMPTY); } else { diff --git a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java index eb196d46..74f89ab8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java @@ -1,10 +1,9 @@ package se.leap.bitmaskclient; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; +import android.content.*; import android.util.Log; +import se.leap.bitmaskclient.eip.Constants; public class OnBootReceiver extends BroadcastReceiver { @@ -14,7 +13,7 @@ public class OnBootReceiver extends BroadcastReceiver { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { if (!context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Context.MODE_PRIVATE).getString(Provider.KEY, "").isEmpty() && context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Context.MODE_PRIVATE).getBoolean(Dashboard.START_ON_BOOT, false)) { Intent dashboard_intent = new Intent(context, Dashboard.class); - dashboard_intent.setAction(EIP.ACTION_START_EIP); + dashboard_intent.setAction(Constants.ACTION_START_EIP); dashboard_intent.putExtra(Dashboard.ON_BOOT, true); dashboard_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(dashboard_intent); diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java deleted file mode 100644 index 3b286fbf..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java +++ /dev/null @@ -1,37 +0,0 @@ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.content.Intent; -import android.net.VpnService; -import android.os.Bundle; - -public class VoidVpnLauncher extends Activity { - - private static final int VPN_USER_PERMISSION = 71; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setUp(); - } - - public void setUp() { - Intent blocking_intent = VpnService.prepare(getApplicationContext()); // stops the VPN connection created by another application. - if(blocking_intent != null) - startActivityForResult(blocking_intent, VPN_USER_PERMISSION); - else { - onActivityResult(VPN_USER_PERMISSION, RESULT_OK, null); - } - } - - protected void onActivityResult(int requestCode, int resultCode, Intent data){ - if(requestCode == VPN_USER_PERMISSION) { - if(resultCode == RESULT_OK) { - Intent void_vpn_service = new Intent(getApplicationContext(), VoidVpnService.class); - void_vpn_service.setAction(VoidVpnService.START_BLOCKING_VPN_PROFILE); - startService(void_vpn_service); - } - } - finish(); - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java deleted file mode 100644 index 7b597554..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java +++ /dev/null @@ -1,36 +0,0 @@ -package se.leap.bitmaskclient; - -import android.content.Intent; -import android.os.Process; -import android.net.VpnService; -import android.util.Log; - -public class VoidVpnService extends VpnService { - - static final String START_BLOCKING_VPN_PROFILE = "se.leap.bitmaskclient.START_BLOCKING_VPN_PROFILE"; - static final String TAG = VoidVpnService.class.getSimpleName(); - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - String action = intent.getAction(); - if (action == START_BLOCKING_VPN_PROFILE) { - new Thread(new Runnable() { - public void run() { - Builder builder = new Builder(); - builder.setSession("Blocking until running"); - builder.addAddress("10.42.0.8",16); - builder.addRoute("0.0.0.0", 1); - builder.addRoute("192.168.1.0", 24); - builder.addDnsServer("10.42.0.1"); - try { - builder.establish(); - } catch (Exception e) { - e.printStackTrace(); - } - android.util.Log.d(TAG, "VoidVpnService set up"); - } - }).run(); - } - return 0; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/VpnConfigGenerator.java deleted file mode 100644 index ef049a3c..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/VpnConfigGenerator.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package se.leap.bitmaskclient; - -import android.content.SharedPreferences; -import android.util.Log; -import java.util.Iterator; -import java.util.Vector; -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONException; - -import se.leap.bitmaskclient.Provider; -import se.leap.bitmaskclient.EIP; - -public class VpnConfigGenerator { - - private JSONObject general_configuration; - private JSONObject gateway; - - private static SharedPreferences preferences; - public final static String TAG = VpnConfigGenerator.class.getSimpleName(); - private final String new_line = System.getProperty("line.separator"); // Platform new line - - public VpnConfigGenerator(SharedPreferences preferences, JSONObject general_configuration, JSONObject gateway) { - this.general_configuration = general_configuration; - this.gateway = gateway; - this.preferences = preferences; - } - - public String generate() { - return - generalConfiguration() - + new_line - + gatewayConfiguration() - + new_line - + secretsConfiguration() - + new_line - + androidCustomizations(); - } - - private String generalConfiguration() { - String common_options = ""; - try { - Iterator keys = general_configuration.keys(); - Vector> value = new Vector>(); - while ( keys.hasNext() ){ - String key = keys.next().toString(); - - common_options += key + " "; - for ( String word : general_configuration.getString(key).split(" ") ) - common_options += word + " "; - common_options += new_line; - - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - common_options += "client"; - - return common_options; - } - - private String gatewayConfiguration() { - String remotes = ""; - - String remote = "ip_address"; - String remote_openvpn_keyword = "remote"; - String ports = "ports"; - String protos = "protocols"; - String capabilities = "capabilities"; - String udp = "udp"; - - try { - JSONArray protocolsJSON = gateway.getJSONObject(capabilities).getJSONArray(protos); - for ( int i=0; i" - + new_line - + preferences.getString(Provider.CA_CERT, "") - + new_line - + ""; - - String key = - "" - + new_line - + preferences.getString(EIP.PRIVATE_KEY, "") - + new_line - + ""; - - String openvpn_cert = - "" - + new_line - + preferences.getString(EIP.CERTIFICATE, "") - + new_line - + ""; - - return ca + new_line + key + new_line + openvpn_cert; - } - - private String androidCustomizations() { - return - "remote-cert-tls server" - + new_line - + "persist-tun" - + new_line - + "auth-retry nointeract"; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java new file mode 100644 index 00000000..719fff6d --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +/** + * + * Constants for intent passing, shared preferences + * + * @author Parménides GV + * + */ +public interface Constants { + + public final static String TAG = Constants.class.getSimpleName(); + + public final static String AUTHED_EIP = TAG + ".AUTHED_EIP"; + public final static String ACTION_CHECK_CERT_VALIDITY = TAG + ".CHECK_CERT_VALIDITY"; + public final static String ACTION_START_EIP = TAG + ".START_EIP"; + public final static String ACTION_STOP_EIP = TAG + ".STOP_EIP"; + public final static String ACTION_UPDATE_EIP_SERVICE = TAG + ".UPDATE_EIP_SERVICE"; + public final static String ACTION_IS_EIP_RUNNING = TAG + ".IS_RUNNING"; + public final static String ACTION_REBUILD_PROFILES = TAG + ".REBUILD_PROFILES"; + public final static String EIP_NOTIFICATION = TAG + ".EIP_NOTIFICATION"; + public final static String STATUS = TAG + ".STATUS"; + public final static String DATE_FROM_CERTIFICATE = TAG + ".DATE_FROM_CERTIFICATE"; + public final static String ALLOWED_ANON = TAG + ".ALLOW_ANONYMOUS"; + public final static String ALLOWED_REGISTERED = TAG + ".ALLOW_REGISTRATION"; + public final static String CERTIFICATE = TAG + ".CERTIFICATE"; + public final static String PRIVATE_KEY = TAG + ".PRIVATE_KEY"; + public final static String KEY = TAG + ".KEY"; + public final static String PARSED_SERIAL = TAG + ".PARSED_SERIAL"; + public final static String RECEIVER_TAG = TAG + ".RECEIVER_TAG"; + public final static String REQUEST_TAG = TAG + ".REQUEST_TAG"; + public final static String START_BLOCKING_VPN_PROFILE = TAG + ".START_BLOCKING_VPN_PROFILE"; + +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java new file mode 100644 index 00000000..b668ce64 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -0,0 +1,486 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +import android.app.*; +import android.content.*; +import android.os.*; +import android.util.Log; +import java.io.*; +import java.security.cert.*; +import java.text.*; +import java.util.*; +import org.json.*; + +import de.blinkt.openvpn.*; +import de.blinkt.openvpn.activities.*; +import de.blinkt.openvpn.core.*; +import se.leap.bitmaskclient.*; + +import static se.leap.bitmaskclient.eip.Constants.*; + +/** + * EIP is the abstract base class for interacting with and managing the Encrypted + * Internet Proxy connection. Connections are started, stopped, and queried through + * this IntentService. + * Contains logic for parsing eip-service.json from the provider, configuring and selecting + * gateways, and controlling {@link de.blinkt.openvpn.core.OpenVPNService} connections. + * + * @author Sean Leonard + * @author Parménides GV + */ +public final class EIP extends IntentService { + + public final static String TAG = EIP.class.getSimpleName(); + + public final static String SERVICE_API_PATH = "config/eip-service.json"; + + private static SharedPreferences preferences; + + private static Context context; + private static ResultReceiver mReceiver; + private static boolean mBound = false; + + private static JSONObject eipDefinition = null; + + private static OVPNGateway activeGateway = null; + + public static VpnStatus.ConnectionStatus lastConnectionStatusLevel; + public static boolean mIsDisconnecting = false; + public static boolean mIsStarting = false; + + public static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + + public EIP(){ + super("LEAPEIP"); + } + + @Override + public void onCreate() { + super.onCreate(); + + context = getApplicationContext(); + + preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + } + + @Override + public void onDestroy() { + + mBound = false; + + super.onDestroy(); + } + + + @Override + protected void onHandleIntent(Intent intent) { + String action = intent.getAction(); + mReceiver = intent.getParcelableExtra(RECEIVER_TAG); + + if ( action == ACTION_START_EIP ) + startEIP(); + else if ( action == ACTION_STOP_EIP ) + stopEIP(); + else if ( action == ACTION_IS_EIP_RUNNING ) + isRunning(); + else if ( action == ACTION_UPDATE_EIP_SERVICE ) + updateEIPService(); + else if ( action == ACTION_CHECK_CERT_VALIDITY ) + checkCertValidity(); + else if ( action == ACTION_REBUILD_PROFILES ) + updateGateways(); + } + + /** + * Initiates an EIP connection by selecting a gateway and preparing and sending an + * Intent to {@link se.leap.openvpn.LaunchVPN}. + * It also sets up early routes. + */ + private void startEIP() { + earlyRoutes(); + activeGateway = selectGateway(); + + if(activeGateway != null && activeGateway.mVpnProfile != null) { + mReceiver = EipServiceFragment.getReceiver(); + launchActiveGateway(); + } + } + + /** + * Early routes are routes that block traffic until a new + * VpnService is started properly. + */ + private void earlyRoutes() { + Intent void_vpn_launcher = new Intent(context, VoidVpnLauncher.class); + void_vpn_launcher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(void_vpn_launcher); + } + + /** + * Choose a gateway to connect to based on timezone from system locale data + * + * @return The gateway to connect to + */ + private OVPNGateway selectGateway() { + String closest_location = closestGateway(); + String chosen_host = chooseHost(closest_location); + + return new OVPNGateway(chosen_host); + } + + private String closestGateway() { + TreeMap> offsets = calculateOffsets(); + return offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); + } + + private TreeMap> calculateOffsets() { + TreeMap> offsets = new TreeMap>(); + + int localOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; + + JSONObject locations = availableLocations(); + Iterator locations_names = locations.keys(); + while(locations_names.hasNext()) { + try { + String location_name = locations_names.next(); + JSONObject location = locations.getJSONObject(location_name); + + int dist = timezoneDistance(localOffset, location.optInt("timezone")); + + Set set = (offsets.get(dist) != null) ? + offsets.get(dist) : new HashSet(); + + set.add(location_name); + offsets.put(dist, set); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return offsets; + } + + private JSONObject availableLocations() { + JSONObject locations = null; + try { + if(eipDefinition == null) updateEIPService(); + locations = eipDefinition.getJSONObject("locations"); + } catch (JSONException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + return locations; + } + + private int timezoneDistance(int local_timezone, int remote_timezone) { + // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 + int dist = Math.abs(local_timezone - remote_timezone); + + // Farther than 12 timezones and it's shorter around the "back" + if (dist > 12) + dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. + + return dist; + } + + private String chooseHost(String location) { + String chosen_host = ""; + try { + JSONArray gateways = eipDefinition.getJSONArray("gateways"); + for (int i = 0; i < gateways.length(); i++) { + JSONObject gw = gateways.getJSONObject(i); + if ( gw.getString("location").equalsIgnoreCase(location) || location.isEmpty()){ + chosen_host = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); + break; + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return chosen_host; + } + + private void launchActiveGateway() { + Intent intent = new Intent(this,LaunchVPN.class); + intent.setAction(Intent.ACTION_MAIN); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); + intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); + intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); + intent.putExtra(RECEIVER_TAG, mReceiver); + startActivity(intent); + } + + /** + * Disconnects the EIP connection gracefully through the bound service or forcefully + * if there is no bound service. Sends a message to the requesting ResultReceiver. + */ + private void stopEIP() { + if(isConnected()) { + Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); + disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(disconnect_vpn); + mIsDisconnecting = true; + lastConnectionStatusLevel = VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user + Log.d(TAG, "mIsDisconnecting = true"); + } + + tellToReceiver(ACTION_STOP_EIP, Activity.RESULT_OK); + } + + private void tellToReceiver(String action, int resultCode) { + if (mReceiver != null){ + Bundle resultData = new Bundle(); + resultData.putString(REQUEST_TAG, action); + mReceiver.send(resultCode, resultData); + } + } + + /** + * Checks the last stored status notified by ics-openvpn + * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the + * request if it's not connected, Activity.RESULT_OK otherwise. + */ + + private void isRunning() { + int resultCode = Activity.RESULT_CANCELED; + boolean is_connected = isConnected(); + + resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; + + tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); + } + + public static boolean isConnected() { + return lastConnectionStatusLevel != null && lastConnectionStatusLevel.equals(VpnStatus.ConnectionStatus.LEVEL_CONNECTED) && !mIsDisconnecting; + } + + /** + * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} + * to parse gateway definitions. + * TODO Implement API call to refresh eip-service.json from the provider + */ + private void updateEIPService() { + try { + String eip_definition_string = preferences.getString(KEY, ""); + if(eip_definition_string.isEmpty() == false) { + eipDefinition = new JSONObject(eip_definition_string); + } + deleteAllVpnProfiles(); + updateGateways(); + if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void deleteAllVpnProfiles() { + ProfileManager vpl = ProfileManager.getInstance(context); + Collection profiles = vpl.getProfiles(); + profiles.removeAll(profiles); + } + + /** + * Walk the list of gateways defined in eip-service.json and parse them into + * OVPNGateway objects. + * TODO Store the OVPNGateways (as Serializable) in SharedPreferences + */ + private void updateGateways(){ + JSONArray gatewaysDefined = null; + try { + if(eipDefinition == null) updateEIPService(); + gatewaysDefined = eipDefinition.getJSONArray("gateways"); + for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ + JSONObject gw = null; + gw = gatewaysDefined.getJSONObject(i); + + if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) + new OVPNGateway(gw); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + preferences.edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); + } + + private void checkCertValidity() { + String certificate = preferences.getString(CERTIFICATE, ""); + checkCertValidity(certificate); + } + + private void checkCertValidity(String certificate_string) { + if(!certificate_string.isEmpty()) { + X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificate_string); + + Calendar offset_date = calculateOffsetCertificateValidity(certificate); + Bundle result = new Bundle(); + result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); + try { + Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); + certificate.checkValidity(offset_date.getTime()); + mReceiver.send(Activity.RESULT_OK, result); + Log.d(TAG, "Valid certificate"); + } catch(CertificateExpiredException e) { + mReceiver.send(Activity.RESULT_CANCELED, result); + Log.d(TAG, "Updating certificate"); + } catch(CertificateNotYetValidException e) { + mReceiver.send(Activity.RESULT_CANCELED, result); + } + } + } + + private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { + String current_date = certificate_date_format.format(Calendar.getInstance().getTime()).toString(); + + String date_string = preferences.getString(DATE_FROM_CERTIFICATE, current_date); + + Calendar offset_date = Calendar.getInstance(); + try { + Date date = certificate_date_format.parse(date_string); + long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; + long current_date_millis = offset_date.getTimeInMillis(); + offset_date.setTimeInMillis(current_date_millis + difference); + Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); + } catch(ParseException e) { + e.printStackTrace(); + } + + return offset_date; + } + + /** + * OVPNGateway provides objects defining gateways and their options and metadata. + * Each instance contains a VpnProfile for OpenVPN specific data and member + * variables describing capabilities and location + * + * @author Sean Leonard + */ + private class OVPNGateway { + + private String TAG = "OVPNGateway"; + + private String mName; + private VpnProfile mVpnProfile; + private JSONObject mGateway; + private HashMap>> options = new HashMap>>(); + + + /** + * Attempts to retrieve a VpnProfile by name and build an OVPNGateway around it. + * FIXME This needs to become a findGatewayByName() method + * + * @param name The hostname of the gateway to inflate + */ + private OVPNGateway(String name){ + mName = name; + + this.loadVpnProfile(); + } + + private void loadVpnProfile() { + ProfileManager vpl = ProfileManager.getInstance(context); + try { + if ( mName == null ) + mVpnProfile = vpl.getProfiles().iterator().next(); + else + mVpnProfile = vpl.getProfileByName(mName); + } catch (NoSuchElementException e) { + updateEIPService(); + this.loadVpnProfile(); // FIXME catch infinite loops + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json + * and create a VpnProfile belonging to it. + * + * @param gateway The JSON OpenVPN gateway definition to parse + */ + protected OVPNGateway(JSONObject gateway){ + + mGateway = gateway; + + // Currently deletes VpnProfile for host, if there already is one, and builds new + ProfileManager vpl = ProfileManager.getInstance(context); + Collection profiles = vpl.getProfiles(); + for (Iterator it = profiles.iterator(); it.hasNext(); ){ + VpnProfile p = it.next(); + + if ( p.mName.equalsIgnoreCase( mName ) ) { + it.remove(); + vpl.removeProfile(context, p); + } + } + + this.createVPNProfile(); + + vpl.addProfile(mVpnProfile); + vpl.saveProfile(context, mVpnProfile); + vpl.saveProfileList(context); + } + + /** + * Create and attach the VpnProfile to our gateway object + */ + protected void createVPNProfile(){ + try { + ConfigParser cp = new ConfigParser(); + + JSONObject openvpn_configuration = eipDefinition.getJSONObject("openvpn_configuration"); + VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, openvpn_configuration, mGateway); + String configuration = vpn_configuration_generator.generate(); + + cp.parseConfig(new StringReader(configuration)); + mVpnProfile = cp.convertProfile(); + mVpnProfile.mName = mName = locationAsName(); + Log.v(TAG,"Created VPNProfile"); + + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConfigParser.ConfigParseError e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + } catch (IOException e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + } + } + + + public String locationAsName() { + try { + return eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); + } catch (JSONException e) { + Log.v(TAG,"Couldn't read gateway name for profile creation! Returning original name = " + mName); + e.printStackTrace(); + return (mName != null) ? mName : ""; + } + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java new file mode 100644 index 00000000..9814c167 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java @@ -0,0 +1,37 @@ +package se.leap.bitmaskclient.eip; + +import android.app.Activity; +import android.content.Intent; +import android.net.VpnService; +import android.os.Bundle; + +public class VoidVpnLauncher extends Activity { + + private static final int VPN_USER_PERMISSION = 71; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setUp(); + } + + public void setUp() { + Intent blocking_intent = VpnService.prepare(getApplicationContext()); // stops the VPN connection created by another application. + if(blocking_intent != null) + startActivityForResult(blocking_intent, VPN_USER_PERMISSION); + else { + onActivityResult(VPN_USER_PERMISSION, RESULT_OK, null); + } + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data){ + if(requestCode == VPN_USER_PERMISSION) { + if(resultCode == RESULT_OK) { + Intent void_vpn_service = new Intent(getApplicationContext(), VoidVpnService.class); + void_vpn_service.setAction(Constants.START_BLOCKING_VPN_PROFILE); + startService(void_vpn_service); + } + } + finish(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java new file mode 100644 index 00000000..224e3bd4 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -0,0 +1,37 @@ +package se.leap.bitmaskclient.eip; + +import android.content.Intent; +import android.os.Process; +import android.net.VpnService; +import android.util.Log; + +import static se.leap.bitmaskclient.eip.Constants.*; + +public class VoidVpnService extends VpnService { + + static final String TAG = VoidVpnService.class.getSimpleName(); + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String action = intent.getAction(); + if (action == Constants.START_BLOCKING_VPN_PROFILE) { + new Thread(new Runnable() { + public void run() { + Builder builder = new Builder(); + builder.setSession("Blocking until running"); + builder.addAddress("10.42.0.8",16); + builder.addRoute("0.0.0.0", 1); + builder.addRoute("192.168.1.0", 24); + builder.addDnsServer("10.42.0.1"); + try { + builder.establish(); + } catch (Exception e) { + e.printStackTrace(); + } + android.util.Log.d(TAG, "VoidVpnService set up"); + } + }).run(); + } + return 0; + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java new file mode 100644 index 00000000..8e36f53c --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +import android.content.SharedPreferences; +import android.util.Log; +import java.util.Iterator; +import java.util.Vector; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; + +import se.leap.bitmaskclient.*; + +public class VpnConfigGenerator { + + private JSONObject general_configuration; + private JSONObject gateway; + + private static SharedPreferences preferences; + public final static String TAG = VpnConfigGenerator.class.getSimpleName(); + private final String new_line = System.getProperty("line.separator"); // Platform new line + + public VpnConfigGenerator(SharedPreferences preferences, JSONObject general_configuration, JSONObject gateway) { + this.general_configuration = general_configuration; + this.gateway = gateway; + this.preferences = preferences; + } + + public String generate() { + return + generalConfiguration() + + new_line + + gatewayConfiguration() + + new_line + + secretsConfiguration() + + new_line + + androidCustomizations(); + } + + private String generalConfiguration() { + String common_options = ""; + try { + Iterator keys = general_configuration.keys(); + Vector> value = new Vector>(); + while ( keys.hasNext() ){ + String key = keys.next().toString(); + + common_options += key + " "; + for ( String word : general_configuration.getString(key).split(" ") ) + common_options += word + " "; + common_options += new_line; + + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + common_options += "client"; + + return common_options; + } + + private String gatewayConfiguration() { + String remotes = ""; + + String remote = "ip_address"; + String remote_openvpn_keyword = "remote"; + String ports = "ports"; + String protos = "protocols"; + String capabilities = "capabilities"; + String udp = "udp"; + + try { + JSONArray protocolsJSON = gateway.getJSONObject(capabilities).getJSONArray(protos); + for ( int i=0; i" + + new_line + + preferences.getString(Provider.CA_CERT, "") + + new_line + + ""; + + String key = + "" + + new_line + + preferences.getString(Constants.PRIVATE_KEY, "") + + new_line + + ""; + + String openvpn_cert = + "" + + new_line + + preferences.getString(Constants.CERTIFICATE, "") + + new_line + + ""; + + return ca + new_line + key + new_line + openvpn_cert; + } + + private String androidCustomizations() { + return + "remote-cert-tls server" + + new_line + + "persist-tun" + + new_line + + "auth-retry nointeract"; + } +} -- cgit v1.2.3 From b8087831f7db9fbc7806c58e632bda448b3b9e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 12 Nov 2014 03:44:14 +0100 Subject: More refactoring, fixed problems from previous commit. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 31 ++-- .../java/se/leap/bitmaskclient/eip/Constants.java | 6 +- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 182 +++++---------------- .../bitmaskclient/eip/VpnCertificateValidator.java | 59 +++++++ 4 files changed, 116 insertions(+), 162 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 473cd5ec..e4e575e4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -42,6 +42,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected static final int CONFIGURE_LEAP = 0; protected static final int SWITCH_PROVIDER = 1; + final public static String TAG = Dashboard.class.getSimpleName(); final public static String SHARED_PREFERENCES = "LEAPPreferences"; final public static String ACTION_QUIT = "quit"; public static final String REQUEST_CODE = "request_code"; @@ -49,21 +50,19 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public static final String START_ON_BOOT = "dashboard start on boot"; final public static String ON_BOOT = "dashboard on boot"; public static final String APP_VERSION = "bitmask version"; - final public static String TAG = Dashboard.class.getSimpleName(); - + private static Context app; + protected static SharedPreferences preferences; + private FragmentManagerEnhanced fragment_manager; + private EipServiceFragment eipFragment; - private ProgressBar mProgressBar; - private TextView eipStatus; - private static Context app; - protected static SharedPreferences preferences; - private static Provider provider; - - private boolean authed_eip = false; - + private ProgressBar mProgressBar; + private TextView eipStatus; public ProviderAPIResultReceiver providerAPI_result_receiver; - private FragmentManagerEnhanced fragment_manager; + private static Provider provider; + private static boolean authed_eip; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -78,11 +77,11 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - authed_eip = preferences.getBoolean(Constants.AUTHED_EIP, false); - if (preferences.getString(Provider.KEY, "").isEmpty()) - startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); - else - buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); + boolean provider_configured = preferences.getString(Constants.KEY, "").isEmpty(); + if (provider_configured) + startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); + else + buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); } private void handleVersion() { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java index 719fff6d..3b43282b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -37,9 +37,9 @@ public interface Constants { public final static String EIP_NOTIFICATION = TAG + ".EIP_NOTIFICATION"; public final static String STATUS = TAG + ".STATUS"; public final static String DATE_FROM_CERTIFICATE = TAG + ".DATE_FROM_CERTIFICATE"; - public final static String ALLOWED_ANON = TAG + ".ALLOW_ANONYMOUS"; - public final static String ALLOWED_REGISTERED = TAG + ".ALLOW_REGISTRATION"; - public final static String CERTIFICATE = TAG + ".CERTIFICATE"; + public final static String ALLOWED_ANON = "allow_anonymous"; + public final static String ALLOWED_REGISTERED = "allow_registration"; + public final static String CERTIFICATE = "cert"; public final static String PRIVATE_KEY = TAG + ".PRIVATE_KEY"; public final static String KEY = TAG + ".KEY"; public final static String PARSED_SERIAL = TAG + ".PARSED_SERIAL"; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index b668ce64..92eba23c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -51,20 +51,19 @@ public final class EIP extends IntentService { private static SharedPreferences preferences; - private static Context context; - private static ResultReceiver mReceiver; - private static boolean mBound = false; + private static Context context; + private static ResultReceiver mReceiver; + private static boolean mBound = false; - private static JSONObject eipDefinition = null; + private static int parsedEipSerial; + private static JSONObject eip_definition = null; - private static OVPNGateway activeGateway = null; + private static OVPNGateway activeGateway = null; public static VpnStatus.ConnectionStatus lastConnectionStatusLevel; public static boolean mIsDisconnecting = false; public static boolean mIsStarting = false; - public static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - public EIP(){ super("LEAPEIP"); } @@ -76,6 +75,7 @@ public final class EIP extends IntentService { context = getApplicationContext(); preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + refreshEipDefinition(); } @Override @@ -113,8 +113,10 @@ public final class EIP extends IntentService { */ private void startEIP() { earlyRoutes(); - activeGateway = selectGateway(); - + GatewaySelector gateway_selector = new GatewaySelector(eip_definition); + String selected_gateway = gateway_selector.select(); + + activeGateway = new OVPNGateway(selected_gateway); if(activeGateway != null && activeGateway.mVpnProfile != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); @@ -131,93 +133,6 @@ public final class EIP extends IntentService { startActivity(void_vpn_launcher); } - /** - * Choose a gateway to connect to based on timezone from system locale data - * - * @return The gateway to connect to - */ - private OVPNGateway selectGateway() { - String closest_location = closestGateway(); - String chosen_host = chooseHost(closest_location); - - return new OVPNGateway(chosen_host); - } - - private String closestGateway() { - TreeMap> offsets = calculateOffsets(); - return offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); - } - - private TreeMap> calculateOffsets() { - TreeMap> offsets = new TreeMap>(); - - int localOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; - - JSONObject locations = availableLocations(); - Iterator locations_names = locations.keys(); - while(locations_names.hasNext()) { - try { - String location_name = locations_names.next(); - JSONObject location = locations.getJSONObject(location_name); - - int dist = timezoneDistance(localOffset, location.optInt("timezone")); - - Set set = (offsets.get(dist) != null) ? - offsets.get(dist) : new HashSet(); - - set.add(location_name); - offsets.put(dist, set); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - return offsets; - } - - private JSONObject availableLocations() { - JSONObject locations = null; - try { - if(eipDefinition == null) updateEIPService(); - locations = eipDefinition.getJSONObject("locations"); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - return locations; - } - - private int timezoneDistance(int local_timezone, int remote_timezone) { - // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 - int dist = Math.abs(local_timezone - remote_timezone); - - // Farther than 12 timezones and it's shorter around the "back" - if (dist > 12) - dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. - - return dist; - } - - private String chooseHost(String location) { - String chosen_host = ""; - try { - JSONArray gateways = eipDefinition.getJSONArray("gateways"); - for (int i = 0; i < gateways.length(); i++) { - JSONObject gw = gateways.getJSONObject(i); - if ( gw.getString("location").equalsIgnoreCase(location) || location.isEmpty()){ - chosen_host = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); - break; - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return chosen_host; - } - private void launchActiveGateway() { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); @@ -292,7 +207,22 @@ public final class EIP extends IntentService { e.printStackTrace(); } } + if (eip_definition != null && eip_definition.optInt("serial") >= parsedEipSerial) + updateGateways(); + } + private void refreshEipDefinition() { + try { + String eip_definition_string = preferences.getString(KEY, ""); + if(!eip_definition_string.isEmpty()) { + eip_definition = new JSONObject(eip_definition_string); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + private void deleteAllVpnProfiles() { ProfileManager vpl = ProfileManager.getInstance(context); Collection profiles = vpl.getProfiles(); @@ -307,8 +237,8 @@ public final class EIP extends IntentService { private void updateGateways(){ JSONArray gatewaysDefined = null; try { - if(eipDefinition == null) updateEIPService(); - gatewaysDefined = eipDefinition.getJSONArray("gateways"); + if(eip_definition == null) updateEIPService(); + gatewaysDefined = eip_definition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ JSONObject gw = null; gw = gatewaysDefined.getJSONObject(i); @@ -320,52 +250,18 @@ public final class EIP extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - preferences.edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); + preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).commit(); } private void checkCertValidity() { - String certificate = preferences.getString(CERTIFICATE, ""); - checkCertValidity(certificate); - } - - private void checkCertValidity(String certificate_string) { - if(!certificate_string.isEmpty()) { - X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificate_string); - - Calendar offset_date = calculateOffsetCertificateValidity(certificate); - Bundle result = new Bundle(); - result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); - try { - Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); - certificate.checkValidity(offset_date.getTime()); - mReceiver.send(Activity.RESULT_OK, result); - Log.d(TAG, "Valid certificate"); - } catch(CertificateExpiredException e) { - mReceiver.send(Activity.RESULT_CANCELED, result); - Log.d(TAG, "Updating certificate"); - } catch(CertificateNotYetValidException e) { - mReceiver.send(Activity.RESULT_CANCELED, result); - } - } - } - - private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { - String current_date = certificate_date_format.format(Calendar.getInstance().getTime()).toString(); - - String date_string = preferences.getString(DATE_FROM_CERTIFICATE, current_date); - - Calendar offset_date = Calendar.getInstance(); - try { - Date date = certificate_date_format.parse(date_string); - long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; - long current_date_millis = offset_date.getTimeInMillis(); - offset_date.setTimeInMillis(current_date_millis + difference); - Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); - } catch(ParseException e) { - e.printStackTrace(); - } - - return offset_date; + Bundle result = new Bundle(); + result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); + + VpnCertificateValidator validator = new VpnCertificateValidator(); + if(validator.isValid(preferences.getString(CERTIFICATE, ""))) + mReceiver.send(Activity.RESULT_OK, result); + else + mReceiver.send(Activity.RESULT_CANCELED, result); } /** @@ -449,7 +345,7 @@ public final class EIP extends IntentService { try { ConfigParser cp = new ConfigParser(); - JSONObject openvpn_configuration = eipDefinition.getJSONObject("openvpn_configuration"); + JSONObject openvpn_configuration = eip_definition.getJSONObject("openvpn_configuration"); VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, openvpn_configuration, mGateway); String configuration = vpn_configuration_generator.generate(); @@ -475,7 +371,7 @@ public final class EIP extends IntentService { public String locationAsName() { try { - return eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); + return eip_definition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); } catch (JSONException e) { Log.v(TAG,"Couldn't read gateway name for profile creation! Returning original name = " + mName); e.printStackTrace(); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java new file mode 100644 index 00000000..a5f04368 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +import android.util.Log; +import java.util.*; +import java.security.cert.*; +import java.text.*; + +import se.leap.bitmaskclient.ConfigHelper; +import static se.leap.bitmaskclient.eip.Constants.*; + +public class VpnCertificateValidator { + public final static String TAG = VpnCertificateValidator.class.getSimpleName(); + + public boolean isValid(String certificate) { + if(!certificate.isEmpty()) { + X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate); + return isValid(certificate_x509); + } else return false; + } + + private boolean isValid(X509Certificate certificate) { + Calendar offset_date = calculateOffsetCertificateValidity(certificate); + try { + Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); + certificate.checkValidity(offset_date.getTime()); + return true; + } catch(CertificateExpiredException e) { + return false; + } catch(CertificateNotYetValidException e) { + return false; + } + } + + private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { + Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); + long preventive_time = Math.abs(certificate.getNotBefore().getTime() - certificate.getNotAfter().getTime())/2; + long current_date_millis = Calendar.getInstance().getTimeInMillis(); + + Calendar limit_date = Calendar.getInstance(); + limit_date.setTimeInMillis(current_date_millis + preventive_time); + return limit_date; + } +} -- cgit v1.2.3 From 1fcf003abf27b58047d59a3f8ac4787987de2ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 12 Nov 2014 03:58:03 +0100 Subject: Smaller method. --- app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 92eba23c..94027491 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -73,7 +73,6 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); refreshEipDefinition(); } @@ -254,14 +253,9 @@ public final class EIP extends IntentService { } private void checkCertValidity() { - Bundle result = new Bundle(); - result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); - VpnCertificateValidator validator = new VpnCertificateValidator(); - if(validator.isValid(preferences.getString(CERTIFICATE, ""))) - mReceiver.send(Activity.RESULT_OK, result); - else - mReceiver.send(Activity.RESULT_CANCELED, result); + boolean is_valid = validator.isValid(preferences.getString(CERTIFICATE, "")); + tellToReceiver(ACTION_CHECK_CERT_VALIDITY, is_valid); } /** -- cgit v1.2.3 From ba3362c6779e3b89533b1a132d67b4916a9976d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 13 Nov 2014 19:22:35 +0100 Subject: GatewaySelector is back. Had to rewrite the class, forgot to add the java file to git. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- .../java/se/leap/bitmaskclient/eip/Constants.java | 1 - .../main/java/se/leap/bitmaskclient/eip/EIP.java | 82 +++++++++------------- 3 files changed, 36 insertions(+), 49 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index e4e575e4..395e9987 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -97,7 +97,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf case 101: // 0.8.0 if(!preferences.getString(Constants.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); - rebuildVpnProfiles.setAction(Constants.ACTION_REBUILD_PROFILES); + rebuildVpnProfiles.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); startService(rebuildVpnProfiles); } break; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java index 3b43282b..b710d780 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -33,7 +33,6 @@ public interface Constants { public final static String ACTION_STOP_EIP = TAG + ".STOP_EIP"; public final static String ACTION_UPDATE_EIP_SERVICE = TAG + ".UPDATE_EIP_SERVICE"; public final static String ACTION_IS_EIP_RUNNING = TAG + ".IS_RUNNING"; - public final static String ACTION_REBUILD_PROFILES = TAG + ".REBUILD_PROFILES"; public final static String EIP_NOTIFICATION = TAG + ".EIP_NOTIFICATION"; public final static String STATUS = TAG + ".STATUS"; public final static String DATE_FROM_CERTIFICATE = TAG + ".DATE_FROM_CERTIFICATE"; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 94027491..2b9f120d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -101,8 +101,6 @@ public final class EIP extends IntentService { updateEIPService(); else if ( action == ACTION_CHECK_CERT_VALIDITY ) checkCertValidity(); - else if ( action == ACTION_REBUILD_PROFILES ) - updateGateways(); } /** @@ -175,39 +173,28 @@ public final class EIP extends IntentService { */ private void isRunning() { - int resultCode = Activity.RESULT_CANCELED; - boolean is_connected = isConnected(); - - resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - + int resultCode = (isConnected()) ? + Activity.RESULT_OK : + Activity.RESULT_CANCELED; tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); } public static boolean isConnected() { - return lastConnectionStatusLevel != null && lastConnectionStatusLevel.equals(VpnStatus.ConnectionStatus.LEVEL_CONNECTED) && !mIsDisconnecting; + return lastConnectionStatusLevel != null + && lastConnectionStatusLevel.equals(VpnStatus.ConnectionStatus.LEVEL_CONNECTED) + && !mIsDisconnecting; } - /** - * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} - * to parse gateway definitions. - * TODO Implement API call to refresh eip-service.json from the provider - */ - private void updateEIPService() { - try { - String eip_definition_string = preferences.getString(KEY, ""); - if(eip_definition_string.isEmpty() == false) { - eipDefinition = new JSONObject(eip_definition_string); - } - deleteAllVpnProfiles(); - updateGateways(); - if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - if (eip_definition != null && eip_definition.optInt("serial") >= parsedEipSerial) - updateGateways(); + /** + * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} + * to parse gateway definitions. + * TODO Implement API call to refresh eip-service.json from the provider + */ + private void updateEIPService() { + refreshEipDefinition(); + deleteAllVpnProfiles(); + updateGateways(); + if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); } private void refreshEipDefinition() { @@ -233,29 +220,30 @@ public final class EIP extends IntentService { * OVPNGateway objects. * TODO Store the OVPNGateways (as Serializable) in SharedPreferences */ - private void updateGateways(){ - JSONArray gatewaysDefined = null; - try { - if(eip_definition == null) updateEIPService(); - gatewaysDefined = eip_definition.getJSONArray("gateways"); - for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ - JSONObject gw = null; - gw = gatewaysDefined.getJSONObject(i); + private void updateGateways(){ + JSONArray gatewaysDefined = null; + try { + gatewaysDefined = eip_definition.getJSONArray("gateways"); + for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ + JSONObject gw = null; + gw = gatewaysDefined.getJSONObject(i); - if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) - new OVPNGateway(gw); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).commit(); + if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) + new OVPNGateway(gw); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).commit(); + } private void checkCertValidity() { VpnCertificateValidator validator = new VpnCertificateValidator(); - boolean is_valid = validator.isValid(preferences.getString(CERTIFICATE, "")); - tellToReceiver(ACTION_CHECK_CERT_VALIDITY, is_valid); + int resultCode = validator.isValid(preferences.getString(CERTIFICATE, "")) ? + Activity.RESULT_OK : + Activity.RESULT_CANCELED; + tellToReceiver(ACTION_CHECK_CERT_VALIDITY, resultCode); } /** -- cgit v1.2.3 From 301adeab4b1630645e53baa982b35cba394e52b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 17 Nov 2014 18:44:36 +0100 Subject: Update vpn certificate and store it correctly. One more onReceiveResult for Dashboard, that method needs a rethink: a statemachine class, and a simple "next()" method? The reality is that the onReceiveResult specifies a linked process, and that should have a better model than a series of if/else cases with strings comparisons hehehe --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 36 ++++++++++++---------- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 2 +- 2 files changed, 21 insertions(+), 17 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 395e9987..b139f73f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -433,22 +433,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf hideProgressBar(); setResult(RESULT_OK); - Intent updateEIP = new Intent(getApplicationContext(), EIP.class); - ResultReceiver eip_receiver = new ResultReceiver(new Handler()){ - protected void onReceiveResult(int resultCode, Bundle resultData){ - super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(Constants.REQUEST_TAG); - if (resultCode == Activity.RESULT_OK){ - if(authed_eip) - eipStart(); - else - eipStatus.setText("Certificate updated"); - } - } - }; - updateEIP.putExtra(Constants.RECEIVER_TAG, eip_receiver); - updateEIP.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); - startService(updateEIP); + + updateEipService(); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); hideProgressBar(); @@ -456,6 +442,24 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } } + private void updateEipService() { + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + updateEIP.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); + ResultReceiver receiver = new ResultReceiver(new Handler()) { + protected void onReceiveResult(int resultCode, Bundle resultData) { + String request = resultData.getString(Constants.REQUEST_TAG); + if(request.equalsIgnoreCase(Constants.ACTION_UPDATE_EIP_SERVICE)) { + if(resultCode == Activity.RESULT_OK) { + if(authed_eip) + eipStart(); + } + } + } + }; + updateEIP.putExtra(Constants.RECEIVER_TAG, receiver); + startService(updateEIP); + } + private void changeStatusMessage(final int previous_result_code) { // TODO Auto-generated method stub ResultReceiver eip_status_receiver = new ResultReceiver(new Handler()){ diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 2b9f120d..9f81f263 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -194,7 +194,7 @@ public final class EIP extends IntentService { refreshEipDefinition(); deleteAllVpnProfiles(); updateGateways(); - if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); + tellToReceiver(ACTION_UPDATE_EIP_SERVICE, Activity.RESULT_OK); } private void refreshEipDefinition() { -- cgit v1.2.3 From 5d28fc6602a214da51931e428112825117b2509f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 17 Nov 2014 19:54:51 +0100 Subject: An empty certificate is valid. If there is no certificate, there is no need to fix it. Right now, we use this class just to know if we need to update the certificate or redownload it. In case the certificate is corrupted, then it won't be empty but will contain an error message. If there is no certificate (e.g., because the user hasn't logged in and the provider doesn't provide anon vpn), then the "certificate" is ok but an upper layer of the code will have to handle the situation (in this case, eip will detect that there is no certificate and that the user needs to log in, prompting it to do so). --- .../main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java index a5f04368..16ae6a85 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java @@ -31,7 +31,7 @@ public class VpnCertificateValidator { if(!certificate.isEmpty()) { X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate); return isValid(certificate_x509); - } else return false; + } else return true; } private boolean isValid(X509Certificate certificate) { -- cgit v1.2.3 From 06bc3b1898e1a419693c7fc3d6a48322ad6881e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 17 Nov 2014 22:17:01 +0100 Subject: OVPNGateway extracted from EIP. Fixed a silly typo on .gitignore which was ignoring "G*"!. --- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 172 +++++---------------- .../java/se/leap/bitmaskclient/eip/Gateway.java | 151 ++++++++++++++++++ .../se/leap/bitmaskclient/eip/GatewaySelector.java | 44 ++++++ 3 files changed, 230 insertions(+), 137 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 9f81f263..876ad172 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -58,7 +58,9 @@ public final class EIP extends IntentService { private static int parsedEipSerial; private static JSONObject eip_definition = null; - private static OVPNGateway activeGateway = null; + private static Gateway activeGateway = null; + private static List gateways = new ArrayList(); + ProfileManager profile_manager; public static VpnStatus.ConnectionStatus lastConnectionStatusLevel; public static boolean mIsDisconnecting = false; @@ -73,6 +75,8 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); + profile_manager = ProfileManager.getInstance(context); + preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); refreshEipDefinition(); } @@ -110,11 +114,10 @@ public final class EIP extends IntentService { */ private void startEIP() { earlyRoutes(); - GatewaySelector gateway_selector = new GatewaySelector(eip_definition); - String selected_gateway = gateway_selector.select(); + GatewaySelector gateway_selector = new GatewaySelector(gateways); - activeGateway = new OVPNGateway(selected_gateway); - if(activeGateway != null && activeGateway.mVpnProfile != null) { + activeGateway = gateway_selector.select(); + if(activeGateway != null && activeGateway.getProfile() != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } @@ -134,8 +137,8 @@ public final class EIP extends IntentService { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); - intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); + intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.getProfile().getUUID().toString() ); + intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.getProfile().getName() ); intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); intent.putExtra(RECEIVER_TAG, mReceiver); startActivity(intent); @@ -210,26 +213,23 @@ public final class EIP extends IntentService { } private void deleteAllVpnProfiles() { - ProfileManager vpl = ProfileManager.getInstance(context); - Collection profiles = vpl.getProfiles(); + Collection profiles = profile_manager.getProfiles(); profiles.removeAll(profiles); } - /** - * Walk the list of gateways defined in eip-service.json and parse them into - * OVPNGateway objects. - * TODO Store the OVPNGateways (as Serializable) in SharedPreferences - */ + /** + * Walk the list of gateways defined in eip-service.json and parse them into + * Gateway objects. + * TODO Store the Gateways (as Serializable) in SharedPreferences + */ private void updateGateways(){ - JSONArray gatewaysDefined = null; try { - gatewaysDefined = eip_definition.getJSONArray("gateways"); + JSONArray gatewaysDefined = eip_definition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ - JSONObject gw = null; - gw = gatewaysDefined.getJSONObject(i); - - if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) - new OVPNGateway(gw); + JSONObject gw = gatewaysDefined.getJSONObject(i); + if(isOpenVpnGateway(gw)) { + addGateway(new Gateway(eip_definition, context, gw)); + } } } catch (JSONException e) { // TODO Auto-generated catch block @@ -238,6 +238,20 @@ public final class EIP extends IntentService { preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).commit(); } + private boolean isOpenVpnGateway(JSONObject gateway) { + try { + String transport = gateway.getJSONObject("capabilities").getJSONArray("transport").toString(); + return transport.contains("openvpn"); + } catch (JSONException e) { + return false; + } + } + + private void addGateway(Gateway gateway) { + profile_manager.addProfile(gateway.getProfile()); + gateways.add(gateway); + } + private void checkCertValidity() { VpnCertificateValidator validator = new VpnCertificateValidator(); int resultCode = validator.isValid(preferences.getString(CERTIFICATE, "")) ? @@ -245,120 +259,4 @@ public final class EIP extends IntentService { Activity.RESULT_CANCELED; tellToReceiver(ACTION_CHECK_CERT_VALIDITY, resultCode); } - - /** - * OVPNGateway provides objects defining gateways and their options and metadata. - * Each instance contains a VpnProfile for OpenVPN specific data and member - * variables describing capabilities and location - * - * @author Sean Leonard - */ - private class OVPNGateway { - - private String TAG = "OVPNGateway"; - - private String mName; - private VpnProfile mVpnProfile; - private JSONObject mGateway; - private HashMap>> options = new HashMap>>(); - - - /** - * Attempts to retrieve a VpnProfile by name and build an OVPNGateway around it. - * FIXME This needs to become a findGatewayByName() method - * - * @param name The hostname of the gateway to inflate - */ - private OVPNGateway(String name){ - mName = name; - - this.loadVpnProfile(); - } - - private void loadVpnProfile() { - ProfileManager vpl = ProfileManager.getInstance(context); - try { - if ( mName == null ) - mVpnProfile = vpl.getProfiles().iterator().next(); - else - mVpnProfile = vpl.getProfileByName(mName); - } catch (NoSuchElementException e) { - updateEIPService(); - this.loadVpnProfile(); // FIXME catch infinite loops - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json - * and create a VpnProfile belonging to it. - * - * @param gateway The JSON OpenVPN gateway definition to parse - */ - protected OVPNGateway(JSONObject gateway){ - - mGateway = gateway; - - // Currently deletes VpnProfile for host, if there already is one, and builds new - ProfileManager vpl = ProfileManager.getInstance(context); - Collection profiles = vpl.getProfiles(); - for (Iterator it = profiles.iterator(); it.hasNext(); ){ - VpnProfile p = it.next(); - - if ( p.mName.equalsIgnoreCase( mName ) ) { - it.remove(); - vpl.removeProfile(context, p); - } - } - - this.createVPNProfile(); - - vpl.addProfile(mVpnProfile); - vpl.saveProfile(context, mVpnProfile); - vpl.saveProfileList(context); - } - - /** - * Create and attach the VpnProfile to our gateway object - */ - protected void createVPNProfile(){ - try { - ConfigParser cp = new ConfigParser(); - - JSONObject openvpn_configuration = eip_definition.getJSONObject("openvpn_configuration"); - VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, openvpn_configuration, mGateway); - String configuration = vpn_configuration_generator.generate(); - - cp.parseConfig(new StringReader(configuration)); - mVpnProfile = cp.convertProfile(); - mVpnProfile.mName = mName = locationAsName(); - Log.v(TAG,"Created VPNProfile"); - - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ConfigParser.ConfigParseError e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } catch (IOException e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } - } - - - public String locationAsName() { - try { - return eip_definition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); - } catch (JSONException e) { - Log.v(TAG,"Couldn't read gateway name for profile creation! Returning original name = " + mName); - e.printStackTrace(); - return (mName != null) ? mName : ""; - } - } - } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java new file mode 100644 index 00000000..6aa66ac0 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +import android.app.Activity; +import android.content.*; +import android.util.Log; +import java.io.*; +import java.util.*; +import org.json.*; + +import de.blinkt.openvpn.*; +import de.blinkt.openvpn.activities.*; +import de.blinkt.openvpn.core.*; +import se.leap.bitmaskclient.*; + +/** + * Gateway provides objects defining gateways and their metadata. + * Each instance contains a VpnProfile for OpenVPN specific data and member + * variables describing capabilities and location (name) + * + * @author Sean Leonard + * @author Parménides GV + */ +public class Gateway { + + private String TAG = Gateway.class.getSimpleName(); + + private String mName; + private int timezone; + private JSONObject general_configuration; + private Context context; + private VpnProfile mVpnProfile; + private JSONObject mGateway; + + /** + * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json + * and create a VpnProfile belonging to it. + * + * @param gateway The JSON OpenVPN gateway definition to parse + */ + protected Gateway(JSONObject eip_definition, Context context, JSONObject gateway){ + + mGateway = gateway; + + this.context = context; + general_configuration = getGeneralConfiguration(eip_definition); + timezone = getTimezone(eip_definition); + mName = locationAsName(eip_definition); + + // Currently deletes VpnProfile for host, if there already is one, and builds new + ProfileManager vpl = ProfileManager.getInstance(context); + Collection profiles = vpl.getProfiles(); + for (Iterator it = profiles.iterator(); it.hasNext(); ){ + VpnProfile p = it.next(); + + if ( p.mName.equalsIgnoreCase( mName ) ) { + it.remove(); + vpl.removeProfile(context, p); + } + } + + mVpnProfile = createVPNProfile(); + mVpnProfile.mName = mName; + + vpl.addProfile(mVpnProfile); + vpl.saveProfile(context, mVpnProfile); + vpl.saveProfileList(context); + } + + private JSONObject getGeneralConfiguration(JSONObject eip_definition) { + try { + return eip_definition.getJSONObject("openvpn_configuration"); + } catch (JSONException e) { + return new JSONObject(); + } + } + + private int getTimezone(JSONObject eip_definition) { + JSONObject location = getLocationInfo(eip_definition); + return location.optInt("timezone"); + } + + private String locationAsName(JSONObject eip_definition) { + JSONObject location = getLocationInfo(eip_definition); + return location.optString("name"); + } + + private JSONObject getLocationInfo(JSONObject eip_definition) { + try { + JSONObject locations = eip_definition.getJSONObject("locations"); + JSONObject location = locations.getJSONObject(mGateway.getString("location")); + + return location; + } catch (JSONException e) { + return new JSONObject(); + } + } + + /** + * Create and attach the VpnProfile to our gateway object + */ + private VpnProfile createVPNProfile(){ + try { + ConfigParser cp = new ConfigParser(); + + SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE); + VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, general_configuration, mGateway); + String configuration = vpn_configuration_generator.generate(); + + cp.parseConfig(new StringReader(configuration)); + return cp.convertProfile(); + } catch (ConfigParser.ConfigParseError e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + return null; + } catch (IOException e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + return null; + } + } + + public String getName() { + return mName; + } + + public VpnProfile getProfile() { + return mVpnProfile; + } + + public int getTimezone() { + return timezone; + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java new file mode 100644 index 00000000..36b5fb41 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java @@ -0,0 +1,44 @@ +package se.leap.bitmaskclient.eip; + +import java.security.cert.*; +import java.util.*; +import org.json.*; + +public class GatewaySelector { + List gateways; + + public GatewaySelector(List gateways) { + this.gateways = gateways; + } + + public Gateway select() { + return closestGateway(); + } + + private Gateway closestGateway() { + TreeMap> offsets = calculateOffsets(); + return offsets.isEmpty() ? null : offsets.firstEntry().getValue().iterator().next(); + } + + private TreeMap> calculateOffsets() { + TreeMap> offsets = new TreeMap>(); + int localOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; + for(Gateway gateway : gateways) { + int dist = timezoneDistance(localOffset, gateway.getTimezone()); + Set set = (offsets.get(dist) != null) ? + offsets.get(dist) : new HashSet(); + set.add(gateway); + offsets.put(dist, set); + } + return offsets; + } + + private int timezoneDistance(int local_timezone, int remote_timezone) { + // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 + int dist = Math.abs(local_timezone - remote_timezone); + // Farther than 12 timezones and it's shorter around the "back" + if (dist > 12) + dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. + return dist; + } +} -- cgit v1.2.3 From bc3af9b45a962721002e249806e0e9edd01e3e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 18 Nov 2014 18:38:06 +0100 Subject: Extracted EipStatus, centralizing new state notifications. Observer pattern. The only notification is being received properly on EipServiceFragment is the connected one. I need to fix the other UI methods. --- .../se/leap/bitmaskclient/EipServiceFragment.java | 80 +++++-------- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 22 +--- .../java/se/leap/bitmaskclient/eip/EipStatus.java | 133 +++++++++++++++++++++ 3 files changed, 169 insertions(+), 66 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index f35a3cfa..675619ca 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -13,8 +13,9 @@ import android.os.*; import android.util.Log; import android.view.*; import android.widget.*; +import java.util.*; -public class EipServiceFragment extends Fragment implements VpnStatus.StateListener, CompoundButton.OnCheckedChangeListener { +public class EipServiceFragment extends Fragment implements Observer, CompoundButton.OnCheckedChangeListener { protected static final String IS_EIP_PENDING = "is_eip_pending"; public static final String START_ON_BOOT = "start on boot"; @@ -23,6 +24,7 @@ public class EipServiceFragment extends Fragment implements VpnStatus.StateListe private static Switch eipSwitch; private View eipDetail; private TextView eipStatus; + private EipStatus eip_status; private static EIPReceiver mEIPReceiver; @@ -57,7 +59,7 @@ public class EipServiceFragment extends Fragment implements VpnStatus.StateListe @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + EipStatus.getInstance().addObserver(this); mEIPReceiver = new EIPReceiver(new Handler()); if (savedInstanceState != null) @@ -66,18 +68,8 @@ public class EipServiceFragment extends Fragment implements VpnStatus.StateListe @Override public void onResume() { - super.onResume(); - - VpnStatus.addStateListener(this); - - eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); - } - - @Override - public void onPause() { - super.onPause(); - - VpnStatus.removeStateListener(this); + super.onResume(); + eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); } @Override @@ -205,47 +197,43 @@ public class EipServiceFragment extends Fragment implements VpnStatus.StateListe } @Override - public void updateState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { - boolean isNewLevel = EIP.lastConnectionStatusLevel != level; - boolean justDecidedOnDisconnect = EIP.lastConnectionStatusLevel == VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; - Log.d(TAG, "update state with level " + level); - if(!justDecidedOnDisconnect && (isNewLevel || level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED)) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - EIP.lastConnectionStatusLevel = level; - handleNewState(state, logmessage, localizedResId, level); - } - }); - } else if(justDecidedOnDisconnect && level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED) { - EIP.lastConnectionStatusLevel = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; - updateState(state, logmessage, localizedResId, level); - } // else if(isNewLevel || level == ConnectionStatus.LEVEL_AUTH_FAILED) - // handleNewState(state, logmessage, localizedResId, level); + public void update (Observable observable, Object data) { + if(observable instanceof EipStatus) { + final EipStatus eip_status = (EipStatus) observable; + EipStatus previous_status = eip_status.getPreviousStatus(); + boolean isNewLevel = eip_status.getLevel() != previous_status.getLevel(); + if(!eip_status.wantsToDisconnect() && (isNewLevel || eip_status.isConnected())) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + handleNewState(eip_status); + } + }); + } else if(eip_status.wantsToDisconnect() && eip_status.isConnected()) { + setDisconnectedUI(); + // EIP.lastConnectionStatusLevel = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; + // updateState(state, logmessage, localizedResId, level); + } + } } - private void handleNewState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { + private void handleNewState(EipStatus eip_status) { + final String state = eip_status.getState(); + final String logmessage = eip_status.getLogMessage(); + final int localizedResId = eip_status.getLocalizedResId(); + final VpnStatus.ConnectionStatus level = eip_status.getLevel(); if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED) setConnectedUI(); - else if (isDisconnectedLevel(level) && !EIP.mIsStarting) + else if (eip_status.isDisconnected() && !eip_status.isConnecting()) setDisconnectedUI(); else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) setNoServerReplyUI(localizedResId, logmessage); else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) setServerReplyUI(state, localizedResId, logmessage); - // else if (level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED) - // handleSwitchOn(); - } - - private boolean isDisconnectedLevel(final VpnStatus.ConnectionStatus level) { - return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED || level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED; } private void setConnectedUI() { hideProgressBar(); - Log.d(TAG, "mIsDisconnecting = false in setConnectedUI"); - EIP.mIsStarting = false; //TODO This should be done in the onReceiveResult from START_EIP command, but right now LaunchVPN isn't notifying anybody the resultcode of the request so we need to listen the states with this listener. - EIP.mIsDisconnecting = false; //TODO See comment above String status = getString(R.string.eip_state_connected); setEipStatus(status); adjustSwitch(); @@ -253,17 +241,15 @@ public class EipServiceFragment extends Fragment implements VpnStatus.StateListe private void setDisconnectedUI(){ hideProgressBar(); - EIP.mIsStarting = false; //TODO See comment in setConnectedUI() - Log.d(TAG, "mIsDisconnecting = false in setDisconnectedUI"); - EIP.mIsDisconnecting = false; //TODO See comment in setConnectedUI() String status = getString(R.string.eip_state_not_connected); setEipStatus(status); adjustSwitch(); } - private void adjustSwitch() { - if(EIP.isConnected()) { + private void adjustSwitch() { + EipStatus eip_status = EipStatus.getInstance(); + if(eip_status.isConnected()) { if(!eipSwitch.isChecked()) { eipSwitch.setChecked(true); } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 876ad172..97ef485a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -46,21 +46,16 @@ import static se.leap.bitmaskclient.eip.Constants.*; public final class EIP extends IntentService { public final static String TAG = EIP.class.getSimpleName(); - public final static String SERVICE_API_PATH = "config/eip-service.json"; - private static SharedPreferences preferences; - private static Context context; private static ResultReceiver mReceiver; - private static boolean mBound = false; + private static SharedPreferences preferences; - private static int parsedEipSerial; private static JSONObject eip_definition = null; - - private static Gateway activeGateway = null; private static List gateways = new ArrayList(); - ProfileManager profile_manager; + private static ProfileManager profile_manager; + private static Gateway activeGateway = null; public static VpnStatus.ConnectionStatus lastConnectionStatusLevel; public static boolean mIsDisconnecting = false; @@ -81,15 +76,6 @@ public final class EIP extends IntentService { refreshEipDefinition(); } - @Override - public void onDestroy() { - - mBound = false; - - super.onDestroy(); - } - - @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); @@ -115,7 +101,6 @@ public final class EIP extends IntentService { private void startEIP() { earlyRoutes(); GatewaySelector gateway_selector = new GatewaySelector(gateways); - activeGateway = gateway_selector.select(); if(activeGateway != null && activeGateway.getProfile() != null) { mReceiver = EipServiceFragment.getReceiver(); @@ -137,7 +122,6 @@ public final class EIP extends IntentService { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.getProfile().getUUID().toString() ); intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.getProfile().getName() ); intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); intent.putExtra(RECEIVER_TAG, mReceiver); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java new file mode 100644 index 00000000..c58650ba --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient.eip; + +import android.util.Log; +import java.util.*; + +import de.blinkt.openvpn.core.*; + +public class EipStatus extends Observable implements VpnStatus.StateListener { + public static String TAG = EipStatus.class.getSimpleName(); + private static EipStatus current_status; + + private static EipStatus previous_status; + private static VpnStatus.ConnectionStatus level = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; + private static boolean wants_to_disconnect = false; + private static boolean is_disconnecting = false; + private static boolean is_connecting = false; + + private String state, log_message; + private int localized_res_id; + + public static EipStatus getInstance() { + if(current_status == null) { + current_status = new EipStatus(); + VpnStatus.addStateListener(current_status); + } + return current_status; + } + + private EipStatus() { } + + @Override + public void updateState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { + current_status = getInstance(); + previous_status = current_status; + current_status.setState(state); + current_status.setLogMessage(logmessage); + current_status.setLocalizedResId(localizedResId); + current_status.setLevel(level); + current_status.setChanged(); + Log.d(TAG, "update state with level " + level); + current_status.notifyObservers(); + } + + public boolean isDisconnecting() { + return is_disconnecting; + } + + public boolean isConnecting() { + return is_connecting; + } + + public boolean wantsToDisconnect() { + return wants_to_disconnect; + } + + public boolean isConnected() { + return level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED; + } + + public boolean isDisconnected() { + return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED || level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED; + } + + public void setConnecting() { + is_connecting = true; + is_disconnecting = false; + wants_to_disconnect = false; + } + + public void setDisconnecting() { + is_disconnecting = true; + is_connecting = false; + wants_to_disconnect = false; + level = VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user + } + + public void setWantsToDisconnect() { + wants_to_disconnect = true; + } + + public String getState() { + return state; + } + + public String getLogMessage() { + return log_message; + } + + public int getLocalizedResId() { + return localized_res_id; + } + + public VpnStatus.ConnectionStatus getLevel() { + return level; + } + + public EipStatus getPreviousStatus() { + return previous_status; + } + + private void setState(String state) { + this.state = state; + } + + private void setLogMessage(String log_message) { + this.log_message = log_message; + } + + private void setLocalizedResId(int localized_res_id) { + this.localized_res_id = localized_res_id; + } + + private void setLevel(VpnStatus.ConnectionStatus level) { + this.level = level; + } + +} -- cgit v1.2.3 From 50949530a8453e1aa62c0ff277849d6f83fe0f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 19 Nov 2014 20:20:31 +0100 Subject: Eip status messages refactored. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 80 ++++----- .../se/leap/bitmaskclient/EipServiceFragment.java | 181 +++++++++------------ .../main/java/se/leap/bitmaskclient/eip/EIP.java | 28 +--- .../java/se/leap/bitmaskclient/eip/EipStatus.java | 13 +- 4 files changed, 138 insertions(+), 164 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index b139f73f..fe3c3f23 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -57,7 +57,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private EipServiceFragment eipFragment; private ProgressBar mProgressBar; - private TextView eipStatus; + private TextView status_message; public ProviderAPIResultReceiver providerAPI_result_receiver; private static Provider provider; @@ -116,28 +116,29 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf super.onPause(); } - @Override - protected void onActivityResult(int requestCode, int resultCode, final Intent data){ - if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { - // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { - if ( resultCode == RESULT_OK ){ - preferences.edit().putInt(Constants.PARSED_SERIAL, 0).commit(); - preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); - Intent updateEIP = new Intent(getApplicationContext(), EIP.class); - updateEIP.setAction(Constants.ACTION_UPDATE_EIP_SERVICE); - startService(updateEIP); - buildDashboard(false); - invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.TAG)) { - View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(Bundle.EMPTY); - } - } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { - finish(); - } else - configErrorDialog(); + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data){ + Log.d(TAG, "onActivityResult: requestCode = " + requestCode); + if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { + // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { + if ( resultCode == RESULT_OK ){ + preferences.edit().putInt(Constants.PARSED_SERIAL, 0).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); + updateEipService(); + buildDashboard(false); + invalidateOptionsMenu(); + if(data != null && data.hasExtra(LogInDialog.TAG)) { + View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); + logInDialog(Bundle.EMPTY); } + } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { + finish(); + } else + configErrorDialog(); + } else if(requestCode == 33) { + EipStatus.getInstance().setConnectedOrDisconnected(); } + } /** * Dialog shown when encountering a configuration error. Such errors require @@ -273,7 +274,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private Intent prepareProviderAPICommand() { mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - eipStatus = (TextView) findViewById(R.id.eipStatus); + status_message = (TextView) findViewById(R.id.status_message); providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); @@ -307,7 +308,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf parameters.putString(SessionDialogInterface.PASSWORD, password); mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.authenticating_message); + status_message.setText(R.string.authenticating_message); provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.setAction(ProviderAPI.SRP_AUTH); @@ -331,8 +332,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); mProgressBar.setVisibility(ProgressBar.VISIBLE); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - eipStatus.setText(R.string.logout_message); + if(status_message == null) status_message = (TextView) findViewById(R.id.status_message); + status_message.setText(R.string.logout_message); provider_API_command.setAction(ProviderAPI.LOG_OUT); startService(provider_API_command); @@ -362,7 +363,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf parameters.putString(SessionDialogInterface.PASSWORD, password); mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.signingup_message); + status_message.setText(R.string.signingup_message); provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.setAction(ProviderAPI.SRP_REGISTER); @@ -390,6 +391,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf @Override public void onReceiveResult(int resultCode, Bundle resultData) { + Log.d(TAG, "onReceiveResult"); if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL) { String username = resultData.getString(SessionDialogInterface.USERNAME); String password = resultData.getString(SessionDialogInterface.PASSWORD); @@ -466,17 +468,17 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); String request = resultData.getString(Constants.REQUEST_TAG); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); + if(status_message == null) status_message = (TextView) findViewById(R.id.status_message); if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){ if (resultCode == Activity.RESULT_OK){ switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; - case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.authed_secured_status); break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; + case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.SRP_AUTHENTICATION_FAILED: status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.authed_secured_status); break; + case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.LOGOUT_FAILED: status_message.setText(R.string.log_out_failed_message); break; } } @@ -484,13 +486,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; - case ProviderAPI.SRP_REGISTRATION_FAILED: eipStatus.setText(R.string.registration_failed_message); break; + case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.SRP_AUTHENTICATION_FAILED: status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.SRP_REGISTRATION_FAILED: status_message.setText(R.string.registration_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; + case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.LOGOUT_FAILED: status_message.setText(R.string.log_out_failed_message); break; } } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 675619ca..7dfb628d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -17,70 +17,70 @@ import java.util.*; public class EipServiceFragment extends Fragment implements Observer, CompoundButton.OnCheckedChangeListener { - protected static final String IS_EIP_PENDING = "is_eip_pending"; + protected static final String IS_EIP_PENDING = "is_eip_pending"; public static final String START_ON_BOOT = "start on boot"; - private View eipFragment; - private static Switch eipSwitch; - private View eipDetail; - private TextView eipStatus; - private EipStatus eip_status; + private View eipFragment; + private static Switch eipSwitch; + private View eipDetail; + private TextView status_message; private static EIPReceiver mEIPReceiver; - + private static EipStatus eip_status; public static String TAG = "se.leap.bitmask.EipServiceFragment"; - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + eip_status = EipStatus.getInstance(); + eip_status.addObserver(this); + mEIPReceiver = new EIPReceiver(new Handler()); + + if (savedInstanceState != null && savedInstanceState.getBoolean(IS_EIP_PENDING)) + eip_status.setConnecting(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { - eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); - eipDetail = ((RelativeLayout) eipFragment.findViewById(R.id.eipDetail)); - eipDetail.setVisibility(View.VISIBLE); + eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); + eipDetail = ((RelativeLayout) eipFragment.findViewById(R.id.eipDetail)); + eipDetail.setVisibility(View.VISIBLE); - View eipSettings = eipFragment.findViewById(R.id.eipSettings); - eipSettings.setVisibility(View.GONE); // FIXME too! + View eipSettings = eipFragment.findViewById(R.id.eipSettings); + eipSettings.setVisibility(View.GONE); // FIXME too! - if (EIP.mIsStarting) - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + if (eip_status.isConnecting()) + eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - eipStatus = (TextView) eipFragment.findViewById(R.id.eipStatus); + status_message = (TextView) eipFragment.findViewById(R.id.status_message); - eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch); - eipSwitch.setOnCheckedChangeListener(this); + eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch); + eipSwitch.setOnCheckedChangeListener(this); - if(getArguments() != null && getArguments().containsKey(START_ON_BOOT) && getArguments().getBoolean(START_ON_BOOT)) - startEipFromScratch(); + if(getArguments() != null && getArguments().containsKey(START_ON_BOOT) && getArguments().getBoolean(START_ON_BOOT)) + startEipFromScratch(); - return eipFragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - EipStatus.getInstance().addObserver(this); - mEIPReceiver = new EIPReceiver(new Handler()); - - if (savedInstanceState != null) - EIP.mIsStarting = savedInstanceState.getBoolean(IS_EIP_PENDING); - } + return eipFragment; + } - @Override - public void onResume() { - super.onResume(); - eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); - } + @Override + public void onResume() { + super.onResume(); + eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_EIP_PENDING, EIP.mIsStarting); - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_EIP_PENDING, eip_status.isConnecting()); + } protected void saveEipStatus() { boolean eip_is_on = false; - Log.d("bitmask", "saveEipStatus"); + Log.d(TAG, "saveEipStatus"); if(eipSwitch.isChecked()) { eip_is_on = true; } @@ -88,6 +88,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu if(getActivity() != null) Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); } + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (buttonView.equals(eipSwitch)){ @@ -117,7 +118,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu private boolean canStartEIP() { boolean certificateExists = !Dashboard.preferences.getString(Constants.CERTIFICATE, "").isEmpty(); boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); - return (isAllowedAnon || certificateExists) && !EIP.mIsStarting && !EIP.isConnected(); + return (isAllowedAnon || certificateExists) && !eip_status.isConnected(); } private boolean canLogInToStartEIP() { @@ -125,14 +126,13 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); Log.d(TAG, "Allow registered? " + isAllowedRegistered); Log.d(TAG, "Is logged in? " + isLoggedIn); - return isAllowedRegistered && !isLoggedIn && !EIP.mIsStarting && !EIP.isConnected(); + return isAllowedRegistered && !isLoggedIn && !eip_status.isConnecting() && !eip_status.isConnected(); } private void handleSwitchOff() { - if(EIP.mIsStarting) { + if(eip_status.isConnecting()) { askPendingStartCancellation(); - } else if(EIP.isConnected()) { - Log.d(TAG, "Stopping EIP"); + } else if(eip_status.isConnected()) { stopEIP(); } } @@ -150,7 +150,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu .setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Log.d(TAG, "askPendingStartCancellation checks the switch to true"); eipSwitch.setChecked(true); } }) @@ -158,13 +157,12 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } public void startEipFromScratch() { - EIP.mIsStarting = true; + eip_status.setConnecting(); eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); String status = getResources().getString(R.string.eip_status_start_pending); setEipStatus(status); if(!eipSwitch.isChecked()) { - Log.d(TAG, "startEipFromScratch checks the switch to true"); eipSwitch.setChecked(true); saveEipStatus(); } @@ -172,7 +170,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } protected void stopEIP() { - EIP.mIsStarting = false; View eipProgressBar = getActivity().findViewById(R.id.eipProgress); if(eipProgressBar != null) eipProgressBar.setVisibility(View.GONE); @@ -199,56 +196,42 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public void update (Observable observable, Object data) { if(observable instanceof EipStatus) { + this.eip_status = (EipStatus) observable; final EipStatus eip_status = (EipStatus) observable; - EipStatus previous_status = eip_status.getPreviousStatus(); - boolean isNewLevel = eip_status.getLevel() != previous_status.getLevel(); - if(!eip_status.wantsToDisconnect() && (isNewLevel || eip_status.isConnected())) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - handleNewState(eip_status); - } - }); - } else if(eip_status.wantsToDisconnect() && eip_status.isConnected()) { - setDisconnectedUI(); - // EIP.lastConnectionStatusLevel = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; - // updateState(state, logmessage, localizedResId, level); - } + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + handleNewState(eip_status); + } + }); } } private void handleNewState(EipStatus eip_status) { final String state = eip_status.getState(); - final String logmessage = eip_status.getLogMessage(); - final int localizedResId = eip_status.getLocalizedResId(); - final VpnStatus.ConnectionStatus level = eip_status.getLevel(); - if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED) + if(eip_status.wantsToDisconnect()) + setDisconnectedUI(); + else if (eip_status.isConnected()) setConnectedUI(); else if (eip_status.isDisconnected() && !eip_status.isConnecting()) setDisconnectedUI(); - else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) - setNoServerReplyUI(localizedResId, logmessage); - else if (level == VpnStatus.ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) - setServerReplyUI(state, localizedResId, logmessage); + else + setInProgressUI(eip_status); } private void setConnectedUI() { hideProgressBar(); - String status = getString(R.string.eip_state_connected); - setEipStatus(status); adjustSwitch(); + setEipStatus(getString(R.string.eip_state_connected)); } private void setDisconnectedUI(){ hideProgressBar(); - - String status = getString(R.string.eip_state_not_connected); - setEipStatus(status); adjustSwitch(); + setEipStatus(getString(R.string.eip_state_not_connected)); } private void adjustSwitch() { - EipStatus eip_status = EipStatus.getInstance(); if(eip_status.isConnected()) { if(!eipSwitch.isChecked()) { eipSwitch.setChecked(true); @@ -260,25 +243,18 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } } - private void setNoServerReplyUI(int localizedResId, String logmessage) { - if(eipStatus != null) { - String prefix = getString(localizedResId); - setEipStatus(prefix + " " + logmessage); - } - } - - private void setServerReplyUI(String state, int localizedResId, String logmessage) { - if(eipStatus != null) - if(state.equals("AUTH") || state.equals("GET_CONFIG")) { - String prefix = getString(localizedResId); - setEipStatus(prefix + " " + logmessage); - } + private void setInProgressUI(EipStatus eip_status) { + int localizedResId = eip_status.getLocalizedResId(); + String logmessage = eip_status.getLogMessage(); + String prefix = getString(localizedResId); + + setEipStatus(prefix + " " + logmessage); } protected void setEipStatus(String status) { - if(eipStatus == null) - eipStatus = (TextView) getActivity().findViewById(R.id.eipStatus); - eipStatus.setText(status); + if(status_message == null) + status_message = (TextView) getActivity().findViewById(R.id.status_message); + status_message.setText(status); } private void hideProgressBar() { @@ -319,7 +295,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu Log.d(TAG, "Action start eip = Result OK"); checked = true; eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - EIP.mIsStarting = false; break; case Activity.RESULT_CANCELED: checked = false; @@ -329,8 +304,10 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } else if (request == Constants.ACTION_STOP_EIP) { switch (resultCode){ case Activity.RESULT_OK: - checked = false; - break; + Intent disconnect_vpn = new Intent(getActivity(), DisconnectVPN.class); + getActivity().startActivityForResult(disconnect_vpn, 33); + eip_status.setDisconnecting(); + break; case Activity.RESULT_CANCELED: checked = true; break; @@ -388,7 +365,5 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu public void checkEipSwitch(boolean checked) { eipSwitch.setChecked(checked); - // Log.d(TAG, "checkEipSwitch"); - // onCheckedChanged(eipSwitch, checked); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 97ef485a..577f42a3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -57,10 +57,6 @@ public final class EIP extends IntentService { private static ProfileManager profile_manager; private static Gateway activeGateway = null; - public static VpnStatus.ConnectionStatus lastConnectionStatusLevel; - public static boolean mIsDisconnecting = false; - public static boolean mIsStarting = false; - public EIP(){ super("LEAPEIP"); } @@ -133,16 +129,13 @@ public final class EIP extends IntentService { * if there is no bound service. Sends a message to the requesting ResultReceiver. */ private void stopEIP() { - if(isConnected()) { - Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); - disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(disconnect_vpn); - mIsDisconnecting = true; - lastConnectionStatusLevel = VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user - Log.d(TAG, "mIsDisconnecting = true"); - } + EipStatus eip_status = EipStatus.getInstance(); + Log.d(TAG, "stopEip(): eip is connected? " + eip_status.isConnected()); + int result_code = Activity.RESULT_CANCELED; + if(eip_status.isConnected()) + result_code = Activity.RESULT_OK; - tellToReceiver(ACTION_STOP_EIP, Activity.RESULT_OK); + tellToReceiver(ACTION_STOP_EIP, result_code); } private void tellToReceiver(String action, int resultCode) { @@ -160,17 +153,12 @@ public final class EIP extends IntentService { */ private void isRunning() { - int resultCode = (isConnected()) ? + EipStatus eip_status = EipStatus.getInstance(); + int resultCode = (eip_status.isConnected()) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); } - - public static boolean isConnected() { - return lastConnectionStatusLevel != null - && lastConnectionStatusLevel.equals(VpnStatus.ConnectionStatus.LEVEL_CONNECTED) - && !mIsDisconnecting; - } /** * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java index c58650ba..ee14f2db 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -53,6 +53,8 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { current_status.setLocalizedResId(localizedResId); current_status.setLevel(level); current_status.setChanged(); + if(isConnected() || isDisconnected()) + setConnectedOrDisconnected(); Log.d(TAG, "update state with level " + level); current_status.notifyObservers(); } @@ -74,7 +76,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } public boolean isDisconnected() { - return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED || level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED; + return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; } public void setConnecting() { @@ -83,11 +85,18 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { wants_to_disconnect = false; } + public void setConnectedOrDisconnected() { + is_connecting = false; + is_disconnecting = false; + wants_to_disconnect = false; + current_status.setChanged(); + current_status.notifyObservers(); + } + public void setDisconnecting() { is_disconnecting = true; is_connecting = false; wants_to_disconnect = false; - level = VpnStatus.ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user } public void setWantsToDisconnect() { -- cgit v1.2.3 From f314ade4e20b3c801ece7f0ad4328af38a264b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 20 Nov 2014 12:45:12 +0100 Subject: Changing orientation, fixing... --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 30 +-- .../se/leap/bitmaskclient/EipServiceFragment.java | 266 +++++++++++---------- .../java/se/leap/bitmaskclient/LogInDialog.java | 36 ++- .../java/se/leap/bitmaskclient/SignUpDialog.java | 35 ++- 4 files changed, 183 insertions(+), 184 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index fe3c3f23..4bebf14a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -54,8 +54,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private static Context app; protected static SharedPreferences preferences; private FragmentManagerEnhanced fragment_manager; - - private EipServiceFragment eipFragment; + private ProgressBar mProgressBar; private TextView status_message; public ProviderAPIResultReceiver providerAPI_result_receiver; @@ -180,21 +179,24 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf providerNameTV.setText(provider.getDomain()); providerNameTV.setTextSize(28); - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); if ( provider.hasEIP()){ - eipFragment = new EipServiceFragment(); - if (hide_and_turn_on_eip) { - preferences.edit().remove(Dashboard.START_ON_BOOT).commit(); - Bundle arguments = new Bundle(); - arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); - eipFragment.setArguments(arguments); - } - fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); - if (hide_and_turn_on_eip) { - onBackPressed(); - } + EipServiceFragment previous_eip_fragment = (EipServiceFragment)fragment_manager.findFragmentByTag(EipServiceFragment.TAG); + EipServiceFragment eipFragment = previous_eip_fragment == null ? + new EipServiceFragment() : previous_eip_fragment; + if (hide_and_turn_on_eip) { + preferences.edit().remove(Dashboard.START_ON_BOOT).commit(); + Bundle arguments = new Bundle(); + arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); + eipFragment.setArguments(arguments); + } + fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); + + if (hide_and_turn_on_eip) { + onBackPressed(); + } } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 7dfb628d..3650079a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -17,7 +17,11 @@ import java.util.*; public class EipServiceFragment extends Fragment implements Observer, CompoundButton.OnCheckedChangeListener { - protected static final String IS_EIP_PENDING = "is_eip_pending"; + public static String TAG = "se.leap.bitmask.EipServiceFragment"; + + protected static final String IS_PENDING = TAG + ".is_pending"; + protected static final String IS_CONNECTED = TAG + ".is_connected"; + protected static final String STATUS_MESSAGE = TAG + ".status_message"; public static final String START_ON_BOOT = "start on boot"; private View eipFragment; @@ -25,25 +29,26 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu private View eipDetail; private TextView status_message; + private static Activity parent_activity; private static EIPReceiver mEIPReceiver; private static EipStatus eip_status; - - public static String TAG = "se.leap.bitmask.EipServiceFragment"; + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + parent_activity = activity; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); eip_status = EipStatus.getInstance(); eip_status.addObserver(this); mEIPReceiver = new EIPReceiver(new Handler()); - - if (savedInstanceState != null && savedInstanceState.getBoolean(IS_EIP_PENDING)) - eip_status.setConnecting(); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); eipDetail = ((RelativeLayout) eipFragment.findViewById(R.id.eipDetail)); @@ -58,14 +63,27 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu status_message = (TextView) eipFragment.findViewById(R.id.status_message); eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch); + Log.d(TAG, "onCreateView, eipSwitch is checked? " + eipSwitch.isChecked()); eipSwitch.setOnCheckedChangeListener(this); if(getArguments() != null && getArguments().containsKey(START_ON_BOOT) && getArguments().getBoolean(START_ON_BOOT)) startEipFromScratch(); - + return eipFragment; } + public void onViewStateRestored (Bundle savedInstanceState) { + super.onViewStateRestored(savedInstanceState); + if (savedInstanceState != null) { + setStatusMessage(savedInstanceState.getString(STATUS_MESSAGE)); + if(savedInstanceState.getBoolean(IS_PENDING)) + eip_status.setConnecting(); + else if(savedInstanceState.getBoolean(IS_CONNECTED)) { + eip_status.setConnectedOrDisconnected(); + } + } + } + @Override public void onResume() { super.onResume(); @@ -74,8 +92,11 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public void onSaveInstanceState(Bundle outState) { + outState.putBoolean(IS_PENDING, eip_status.isConnecting()); + outState.putBoolean(IS_CONNECTED, eip_status.isConnected()); + Log.d(TAG, "status message onSaveInstanceState = " + status_message.getText().toString()); + outState.putString(STATUS_MESSAGE, status_message.getText().toString()); super.onSaveInstanceState(outState); - outState.putBoolean(IS_EIP_PENDING, eip_status.isConnecting()); } protected void saveEipStatus() { @@ -85,7 +106,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu eip_is_on = true; } - if(getActivity() != null) + if(parent_activity != null) Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); } @@ -110,7 +131,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu startEipFromScratch(); else if(canLogInToStartEIP()) { Log.d(TAG, "Can Log In to start EIP"); - Dashboard dashboard = (Dashboard) getActivity(); + Dashboard dashboard = (Dashboard) parent_activity; dashboard.logInDialog(Bundle.EMPTY); } } @@ -138,16 +159,16 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } private void askPendingStartCancellation() { - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity()); - alertBuilder.setTitle(getResources().getString(R.string.eip_cancel_connect_title)) - .setMessage(getResources().getString(R.string.eip_cancel_connect_text)) + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(parent_activity); + alertBuilder.setTitle(parent_activity.getString(R.string.eip_cancel_connect_title)) + .setMessage(parent_activity.getString(R.string.eip_cancel_connect_text)) .setPositiveButton((R.string.yes), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { stopEIP(); } }) - .setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener() { + .setNegativeButton(parent_activity.getString(R.string.no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { eipSwitch.setChecked(true); @@ -159,8 +180,8 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu public void startEipFromScratch() { eip_status.setConnecting(); eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - String status = getResources().getString(R.string.eip_status_start_pending); - setEipStatus(status); + String status = parent_activity.getString(R.string.eip_status_start_pending); + setStatusMessage(status); if(!eipSwitch.isChecked()) { eipSwitch.setChecked(true); @@ -170,37 +191,37 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } protected void stopEIP() { - View eipProgressBar = getActivity().findViewById(R.id.eipProgress); + View eipProgressBar = parent_activity.findViewById(R.id.eipProgress); if(eipProgressBar != null) eipProgressBar.setVisibility(View.GONE); - String status = getResources().getString(R.string.eip_state_not_connected); - setEipStatus(status); + String status = parent_activity.getString(R.string.eip_state_not_connected); + setStatusMessage(status); eipCommand(Constants.ACTION_STOP_EIP); } - /** - * Send a command to EIP - * - * @param action A valid String constant from EIP class representing an Intent - * filter for the EIP class - */ - private void eipCommand(String action){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent vpn_intent = new Intent(getActivity().getApplicationContext(), EIP.class); - vpn_intent.setAction(action); - vpn_intent.putExtra(Constants.RECEIVER_TAG, mEIPReceiver); - getActivity().startService(vpn_intent); - } + /** + * Send a command to EIP + * + * @param action A valid String constant from EIP class representing an Intent + * filter for the EIP class + */ + private void eipCommand(String action){ + // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? + Intent vpn_intent = new Intent(parent_activity.getApplicationContext(), EIP.class); + vpn_intent.setAction(action); + vpn_intent.putExtra(Constants.RECEIVER_TAG, mEIPReceiver); + parent_activity.startService(vpn_intent); + } @Override public void update (Observable observable, Object data) { if(observable instanceof EipStatus) { this.eip_status = (EipStatus) observable; final EipStatus eip_status = (EipStatus) observable; - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { + parent_activity.runOnUiThread(new Runnable() { + @Override + public void run() { handleNewState(eip_status); } }); @@ -208,7 +229,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } private void handleNewState(EipStatus eip_status) { - final String state = eip_status.getState(); if(eip_status.wantsToDisconnect()) setDisconnectedUI(); else if (eip_status.isConnected()) @@ -221,18 +241,20 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu private void setConnectedUI() { hideProgressBar(); + Log.d(TAG, "setConnectedUi? " + eip_status.isConnected()); adjustSwitch(); - setEipStatus(getString(R.string.eip_state_connected)); + setStatusMessage(parent_activity.getString(R.string.eip_state_connected)); } private void setDisconnectedUI(){ hideProgressBar(); adjustSwitch(); - setEipStatus(getString(R.string.eip_state_not_connected)); + setStatusMessage(parent_activity.getString(R.string.eip_state_not_connected)); } private void adjustSwitch() { if(eip_status.isConnected()) { + Log.d(TAG, "adjustSwitch, isConnected, is checked? " + eipSwitch.isChecked()); if(!eipSwitch.isChecked()) { eipSwitch.setChecked(true); } @@ -246,113 +268,96 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu private void setInProgressUI(EipStatus eip_status) { int localizedResId = eip_status.getLocalizedResId(); String logmessage = eip_status.getLogMessage(); - String prefix = getString(localizedResId); + String prefix = parent_activity.getString(localizedResId); - setEipStatus(prefix + " " + logmessage); + setStatusMessage(prefix + " " + logmessage); } - protected void setEipStatus(String status) { + protected void setStatusMessage(String status) { if(status_message == null) - status_message = (TextView) getActivity().findViewById(R.id.status_message); + status_message = (TextView) parent_activity.findViewById(R.id.status_message); status_message.setText(status); } private void hideProgressBar() { - if(getActivity() != null && getActivity().findViewById(R.id.eipProgress) != null) - getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); + if(parent_activity != null && parent_activity.findViewById(R.id.eipProgress) != null) + parent_activity.findViewById(R.id.eipProgress).setVisibility(View.GONE); } - /** - * Inner class for handling messages related to EIP status and control requests - * - * @author Sean Leonard - */ - protected class EIPReceiver extends ResultReceiver { + protected class EIPReceiver extends ResultReceiver { - protected EIPReceiver(Handler handler){ - super(handler); - } + protected EIPReceiver(Handler handler){ + super(handler); + } - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - super.onReceiveResult(resultCode, resultData); + @Override + protected void onReceiveResult(int resultCode, Bundle resultData) { + super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(Constants.REQUEST_TAG); - boolean checked = false; + String request = resultData.getString(Constants.REQUEST_TAG); + boolean checked = false; - if (request == Constants.ACTION_IS_EIP_RUNNING) { - switch (resultCode){ - case Activity.RESULT_OK: - checked = true; - break; - case Activity.RESULT_CANCELED: - checked = false; - break; - } - } else if (request == Constants.ACTION_START_EIP) { - switch (resultCode){ - case Activity.RESULT_OK: - Log.d(TAG, "Action start eip = Result OK"); - checked = true; - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - break; - case Activity.RESULT_CANCELED: - checked = false; - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); - break; - } - } else if (request == Constants.ACTION_STOP_EIP) { - switch (resultCode){ - case Activity.RESULT_OK: - Intent disconnect_vpn = new Intent(getActivity(), DisconnectVPN.class); - getActivity().startActivityForResult(disconnect_vpn, 33); - eip_status.setDisconnecting(); - break; - case Activity.RESULT_CANCELED: - checked = true; - break; - } - } else if (request == Constants.EIP_NOTIFICATION) { - switch (resultCode){ - case Activity.RESULT_OK: - checked = true; - break; - case Activity.RESULT_CANCELED: - checked = false; - break; - } - } else if (request == Constants.ACTION_CHECK_CERT_VALIDITY) { - checked = eipSwitch.isChecked(); - - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - Dashboard dashboard = (Dashboard) getActivity(); - - dashboard.showProgressBar(); - String status = getResources().getString(R.string.updating_certificate_message); - setEipStatus(status); - - if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { - dashboard.logInDialog(Bundle.EMPTY); - } else { - - Intent provider_API_command = new Intent(getActivity(), ProviderAPI.class); - if (dashboard.providerAPI_result_receiver == null) { - dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - dashboard.providerAPI_result_receiver.setReceiver(dashboard); - } - - provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); - getActivity().startService(provider_API_command); - } - break; - } + if (request == Constants.ACTION_START_EIP) { + switch (resultCode){ + case Activity.RESULT_OK: + Log.d(TAG, "Action start eip = Result OK"); + checked = true; + eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + break; + case Activity.RESULT_CANCELED: + checked = false; + eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); + break; + } + } else if (request == Constants.ACTION_STOP_EIP) { + switch (resultCode){ + case Activity.RESULT_OK: + Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); + parent_activity.startActivityForResult(disconnect_vpn, 33); + eip_status.setDisconnecting(); + break; + case Activity.RESULT_CANCELED: + checked = true; + break; + } + } else if (request == Constants.EIP_NOTIFICATION) { + switch (resultCode){ + case Activity.RESULT_OK: + checked = true; + break; + case Activity.RESULT_CANCELED: + checked = false; + break; + } + } else if (request == Constants.ACTION_CHECK_CERT_VALIDITY) { + checked = eipSwitch.isChecked(); + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + Dashboard dashboard = (Dashboard) parent_activity; + + dashboard.showProgressBar(); + String status = parent_activity.getString(R.string.updating_certificate_message); + setStatusMessage(status); + if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { + dashboard.logInDialog(Bundle.EMPTY); + } else { + Intent provider_API_command = new Intent(parent_activity, ProviderAPI.class); + if(dashboard.providerAPI_result_receiver == null) { + dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + dashboard.providerAPI_result_receiver.setReceiver(dashboard); } + + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); + parent_activity.startService(provider_API_command); + } + break; } + } } + } public static EIPReceiver getReceiver() { @@ -366,4 +371,5 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu public void checkEipSwitch(boolean checked) { eipSwitch.setChecked(checked); } + } diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java index 5a0c9a6d..cede9bfb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java @@ -55,32 +55,28 @@ public class LogInDialog extends SessionDialogInterface { View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); - if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) { - user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); - } else { - user_message.setVisibility(View.GONE); - } - final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); - if(getArguments() != null && getArguments().containsKey(USERNAME)) { - String username = getArguments().getString(USERNAME); - username_field.setText(username); - } - if (getArguments() != null && getArguments().containsKey(USERNAME_MISSING)) { - username_field.setError(getResources().getString(R.string.username_ask)); - } - final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); + if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { password_field.requestFocus(); } - if (getArguments() != null && getArguments().containsKey(PASSWORD_INVALID_LENGTH)) { - password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); - } - if(getArguments() != null && getArguments().getBoolean(EipServiceFragment.IS_EIP_PENDING, false)) { - is_eip_pending = true; + if (getArguments() != null) { + is_eip_pending = getArguments().getBoolean(EipServiceFragment.IS_PENDING, false); + if (getArguments().containsKey(PASSWORD_INVALID_LENGTH)) + password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); + if (getArguments().containsKey(USERNAME)) { + String username = getArguments().getString(USERNAME); + username_field.setText(username); } - + if (getArguments().containsKey(USERNAME_MISSING)) { + username_field.setError(getResources().getString(R.string.username_ask)); + } + if(getArguments().containsKey(getResources().getString(R.string.user_message))) + user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); + else + user_message.setVisibility(View.GONE); + } builder.setView(log_in_dialog_view) .setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java index 3cb41f4f..16ad2d19 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java @@ -54,32 +54,27 @@ public class SignUpDialog extends SessionDialogInterface { View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); - if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) { - user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); - } else { - user_message.setVisibility(View.GONE); - } - final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); - if(getArguments() != null && getArguments().containsKey(USERNAME)) { - String username = getArguments().getString(USERNAME); - username_field.setText(username); - } - if (getArguments() != null && getArguments().containsKey(USERNAME_MISSING)) { - username_field.setError(getResources().getString(R.string.username_ask)); - } - final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); + if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { password_field.requestFocus(); } - if (getArguments() != null && getArguments().containsKey(PASSWORD_INVALID_LENGTH)) { - password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); - } - if(getArguments() != null && getArguments().getBoolean(EipServiceFragment.IS_EIP_PENDING, false)) { - is_eip_pending = true; + if (getArguments() != null) { + is_eip_pending = getArguments().getBoolean(EipServiceFragment.IS_PENDING, false); + if (getArguments().containsKey(PASSWORD_INVALID_LENGTH)) + password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); + if(getArguments().containsKey(USERNAME_MISSING)) + username_field.setError(getResources().getString(R.string.username_ask)); + if(getArguments().containsKey(USERNAME)) { + String username = getArguments().getString(USERNAME); + username_field.setText(username); } - + if(getArguments().containsKey(getResources().getString(R.string.user_message))) + user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); + else + user_message.setVisibility(View.GONE); + } builder.setView(log_in_dialog_view) .setPositiveButton(R.string.signup_button, new DialogInterface.OnClickListener() { -- cgit v1.2.3 From 2681e877c6c2e871247cf5e42269d1b867422f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 20 Nov 2014 12:55:22 +0100 Subject: OnViewStateRestore is available just from api 17. We support from api 14. --- .../se/leap/bitmaskclient/EipServiceFragment.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 3650079a..0cdc8c75 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -69,21 +69,17 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu if(getArguments() != null && getArguments().containsKey(START_ON_BOOT) && getArguments().getBoolean(START_ON_BOOT)) startEipFromScratch(); + if (savedInstanceState != null) { + setStatusMessage(savedInstanceState.getString(STATUS_MESSAGE)); + if(savedInstanceState.getBoolean(IS_PENDING)) + eip_status.setConnecting(); + else if(savedInstanceState.getBoolean(IS_CONNECTED)) { + eip_status.setConnectedOrDisconnected(); + } + } return eipFragment; } - public void onViewStateRestored (Bundle savedInstanceState) { - super.onViewStateRestored(savedInstanceState); - if (savedInstanceState != null) { - setStatusMessage(savedInstanceState.getString(STATUS_MESSAGE)); - if(savedInstanceState.getBoolean(IS_PENDING)) - eip_status.setConnecting(); - else if(savedInstanceState.getBoolean(IS_CONNECTED)) { - eip_status.setConnectedOrDisconnected(); - } - } - } - @Override public void onResume() { super.onResume(); -- cgit v1.2.3 From e4d4c07be386f809a8ac028df8146916fc0f7597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 22 Nov 2014 00:10:46 +0100 Subject: EipStatus detects and notifies changes by itself. Initial status message is "not connected", rather than "unknown". --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 9 ++----- .../se/leap/bitmaskclient/EipServiceFragment.java | 31 ++++++++++++---------- .../java/se/leap/bitmaskclient/LogInDialog.java | 3 +-- .../java/se/leap/bitmaskclient/SignUpDialog.java | 3 +-- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 5 +++- .../java/se/leap/bitmaskclient/eip/EipStatus.java | 29 ++++++++++++++------ .../se/leap/bitmaskclient/eip/VoidVpnLauncher.java | 2 +- 7 files changed, 47 insertions(+), 35 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 4bebf14a..4f6c6285 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -134,7 +134,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf finish(); } else configErrorDialog(); - } else if(requestCode == 33) { + } else if(requestCode == EIP.DISCONNECT) { EipStatus.getInstance().setConnectedOrDisconnected(); } } @@ -317,13 +317,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(provider_API_command); } - public void cancelAuthedEipOn() { - EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); - eipFragment.checkEipSwitch(false); - } - public void cancelLoginOrSignup() { - hideProgressBar(); + EipStatus.getInstance().setConnectedOrDisconnected(); } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 0cdc8c75..f29d1338 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -23,7 +23,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu protected static final String IS_CONNECTED = TAG + ".is_connected"; protected static final String STATUS_MESSAGE = TAG + ".status_message"; public static final String START_ON_BOOT = "start on boot"; - + private View eipFragment; private static Switch eipSwitch; private View eipDetail; @@ -174,7 +174,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } public void startEipFromScratch() { - eip_status.setConnecting(); eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); String status = parent_activity.getString(R.string.eip_status_start_pending); setStatusMessage(status); @@ -212,6 +211,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public void update (Observable observable, Object data) { + Log.d(TAG, "handleNewState?"); if(observable instanceof EipStatus) { this.eip_status = (EipStatus) observable; final EipStatus eip_status = (EipStatus) observable; @@ -225,6 +225,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } private void handleNewState(EipStatus eip_status) { + Log.d(TAG, "handleNewState: " + eip_status.toString()); if(eip_status.wantsToDisconnect()) setDisconnectedUI(); else if (eip_status.isConnected()) @@ -249,12 +250,14 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } private void adjustSwitch() { - if(eip_status.isConnected()) { - Log.d(TAG, "adjustSwitch, isConnected, is checked? " + eipSwitch.isChecked()); + if(eip_status.isConnected() || eip_status.isConnecting()) { + Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked? " + eipSwitch.isChecked()); if(!eipSwitch.isChecked()) { eipSwitch.setChecked(true); } } else { + Log.d(TAG, "adjustSwitch, !isConnected && !isConnecting? " + eip_status.toString()); + if(eipSwitch.isChecked()) { eipSwitch.setChecked(false); } @@ -267,6 +270,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu String prefix = parent_activity.getString(localizedResId); setStatusMessage(prefix + " " + logmessage); + adjustSwitch(); } protected void setStatusMessage(String status) { @@ -280,6 +284,14 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu parent_activity.findViewById(R.id.eipProgress).setVisibility(View.GONE); } + public static EipStatus getEipStatus() { + return eip_status; + } + + public void checkEipSwitch(boolean activated) { + eipSwitch.setChecked(activated); + } + protected class EIPReceiver extends ResultReceiver { protected EIPReceiver(Handler handler){ @@ -309,7 +321,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu switch (resultCode){ case Activity.RESULT_OK: Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); - parent_activity.startActivityForResult(disconnect_vpn, 33); + parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); eip_status.setDisconnecting(); break; case Activity.RESULT_CANCELED: @@ -359,13 +371,4 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu public static EIPReceiver getReceiver() { return mEIPReceiver; } - - public static boolean isEipSwitchChecked() { - return eipSwitch.isChecked(); - } - - public void checkEipSwitch(boolean checked) { - eipSwitch.setChecked(checked); - } - } diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java index cede9bfb..97a9aecc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java @@ -112,7 +112,6 @@ public class LogInDialog extends SessionDialogInterface { */ public interface LogInDialogInterface { public void logIn(String username, String password); - public void cancelAuthedEipOn(); public void signUp(String username, String password); public void cancelLoginOrSignup(); } @@ -142,6 +141,6 @@ public class LogInDialog extends SessionDialogInterface { public void onCancel(DialogInterface dialog) { super.onCancel(dialog); if(is_eip_pending) - interface_with_Dashboard.cancelAuthedEipOn(); + interface_with_Dashboard.cancelLoginOrSignup(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java index 16ad2d19..d197e589 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java @@ -103,7 +103,6 @@ public class SignUpDialog extends SessionDialogInterface { */ public interface SignUpDialogInterface { public void signUp(String username, String password); - public void cancelAuthedEipOn(); public void cancelLoginOrSignup(); } @@ -131,7 +130,7 @@ public class SignUpDialog extends SessionDialogInterface { @Override public void onCancel(DialogInterface dialog) { if(is_eip_pending) - interface_with_Dashboard.cancelAuthedEipOn(); + interface_with_Dashboard.cancelLoginOrSignup(); super.onCancel(dialog); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 577f42a3..379fb246 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -47,6 +47,9 @@ public final class EIP extends IntentService { public final static String TAG = EIP.class.getSimpleName(); public final static String SERVICE_API_PATH = "config/eip-service.json"; + + + public static final int DISCONNECT = 15; private static Context context; private static ResultReceiver mReceiver; @@ -95,13 +98,13 @@ public final class EIP extends IntentService { * It also sets up early routes. */ private void startEIP() { - earlyRoutes(); GatewaySelector gateway_selector = new GatewaySelector(gateways); activeGateway = gateway_selector.select(); if(activeGateway != null && activeGateway.getProfile() != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } + earlyRoutes(); } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java index ee14f2db..82c3ceb8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -29,7 +29,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { private static VpnStatus.ConnectionStatus level = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; private static boolean wants_to_disconnect = false; private static boolean is_disconnecting = false; - private static boolean is_connecting = false; private String state, log_message; private int localized_res_id; @@ -55,6 +54,8 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { current_status.setChanged(); if(isConnected() || isDisconnected()) setConnectedOrDisconnected(); + else if(isConnecting()) + setConnecting(); Log.d(TAG, "update state with level " + level); current_status.notifyObservers(); } @@ -63,14 +64,17 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { return is_disconnecting; } - public boolean isConnecting() { - return is_connecting; - } - public boolean wantsToDisconnect() { return wants_to_disconnect; } + public boolean isConnecting() { + return + !isConnected() && + !isDisconnected() && + !isPaused(); + } + public boolean isConnected() { return level == VpnStatus.ConnectionStatus.LEVEL_CONNECTED; } @@ -79,14 +83,19 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { return level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; } + public boolean isPaused() { + return level == VpnStatus.ConnectionStatus.LEVEL_VPNPAUSED; + } + public void setConnecting() { - is_connecting = true; is_disconnecting = false; wants_to_disconnect = false; + current_status.setChanged(); + current_status.notifyObservers(); } public void setConnectedOrDisconnected() { - is_connecting = false; + Log.d(TAG, "setConnectedOrDisconnected()"); is_disconnecting = false; wants_to_disconnect = false; current_status.setChanged(); @@ -95,7 +104,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { public void setDisconnecting() { is_disconnecting = true; - is_connecting = false; wants_to_disconnect = false; } @@ -139,4 +147,9 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { this.level = level; } + @Override + public String toString() { + return "State: " + state + " Level: " + level.toString(); + } + } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java index 9814c167..d79d8003 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnLauncher.java @@ -8,7 +8,7 @@ import android.os.Bundle; public class VoidVpnLauncher extends Activity { private static final int VPN_USER_PERMISSION = 71; - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); -- cgit v1.2.3 From 2fc73d6bfe8d86464571258f008d8bcf6db0cc2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 27 Nov 2014 20:09:05 +0100 Subject: Removed unused imports and unused .eip variables --- .../java/se/leap/bitmaskclient/AboutActivity.java | 5 -- .../java/se/leap/bitmaskclient/ConfigHelper.java | 13 ++--- .../main/java/se/leap/bitmaskclient/Dashboard.java | 68 +++++++++++++--------- .../leap/bitmaskclient/DownloadFailedDialog.java | 3 - .../se/leap/bitmaskclient/EipServiceFragment.java | 67 ++++++++++----------- .../java/se/leap/bitmaskclient/LeapSRPSession.java | 3 +- .../java/se/leap/bitmaskclient/LogInDialog.java | 14 ++--- .../java/se/leap/bitmaskclient/OnBootReceiver.java | 5 +- .../main/java/se/leap/bitmaskclient/Provider.java | 12 ++-- .../se/leap/bitmaskclient/ProviderListAdapter.java | 4 +- .../leap/bitmaskclient/ProviderListFragment.java | 11 ++-- .../leap/bitmaskclient/SessionDialogInterface.java | 2 - .../java/se/leap/bitmaskclient/SignUpDialog.java | 12 ++-- .../java/se/leap/bitmaskclient/eip/Constants.java | 2 - .../main/java/se/leap/bitmaskclient/eip/EIP.java | 61 ++++++++++++------- .../java/se/leap/bitmaskclient/eip/EipStatus.java | 25 ++------ .../java/se/leap/bitmaskclient/eip/Gateway.java | 25 ++++---- .../se/leap/bitmaskclient/eip/GatewaySelector.java | 8 ++- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 4 -- .../bitmaskclient/eip/VpnCertificateValidator.java | 9 +-- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 12 ++-- 21 files changed, 177 insertions(+), 188 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/AboutActivity.java b/app/src/main/java/se/leap/bitmaskclient/AboutActivity.java index 6d025422..6c4e517b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/AboutActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/AboutActivity.java @@ -1,15 +1,10 @@ package se.leap.bitmaskclient; import android.app.Activity; -import android.app.Fragment; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; -import se.leap.bitmaskclient.R; public class AboutActivity extends Activity { diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index c95d0c8b..c0f0b0c3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -16,11 +16,15 @@ */ package se.leap.bitmaskclient; +import android.util.Base64; + +import org.json.JSONException; +import org.json.JSONObject; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; -import java.lang.IllegalArgumentException; import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; @@ -33,13 +37,6 @@ import java.security.interfaces.RSAPrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Base64; - /** * Stores constants, and implements auxiliary methods used across all LEAP Android classes. * diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 4f6c6285..6288fd1f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -16,19 +16,31 @@ */ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.*; -import se.leap.bitmaskclient.eip.*; - -import de.blinkt.openvpn.activities.LogWindow; - -import android.app.*; -import android.content.*; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.app.FragmentTransaction; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; -import android.os.*; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; import android.util.Log; -import android.view.*; -import android.widget.*; -import org.json.*; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ProgressBar; +import android.widget.TextView; + +import org.json.JSONException; +import org.json.JSONObject; + +import de.blinkt.openvpn.activities.LogWindow; +import se.leap.bitmaskclient.eip.Constants; +import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; /** * The main user facing Activity of LEAP Android, consisting of status, controls, @@ -59,7 +71,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private TextView status_message; public ProviderAPIResultReceiver providerAPI_result_receiver; - private static Provider provider; private static boolean authed_eip; @Override @@ -87,7 +98,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf try { int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; int lastDetectedVersion = preferences.getInt(APP_VERSION, 0); - preferences.edit().putInt(APP_VERSION, versionCode); + preferences.edit().putInt(APP_VERSION, versionCode).apply(); Log.d("Dashboard", "detected version code: " + versionCode); Log.d("Dashboard", "last detected version code: " + lastDetectedVersion); @@ -102,6 +113,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf break; } } catch (NameNotFoundException e) { + Log.d(TAG, "Handle version didn't find any " + getPackageName() + " package"); } } @@ -121,13 +133,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { if ( resultCode == RESULT_OK ){ - preferences.edit().putInt(Constants.PARSED_SERIAL, 0).commit(); - preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); + preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); updateEipService(); buildDashboard(false); invalidateOptionsMenu(); if(data != null && data.hasExtra(LogInDialog.TAG)) { - View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); } } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { @@ -158,7 +169,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - preferences.edit().remove(Provider.KEY).commit(); + preferences.edit().remove(Provider.KEY).apply(); finish(); } }) @@ -170,7 +181,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * service dependent UI elements to include. */ private void buildDashboard(boolean hide_and_turn_on_eip) { - provider = Provider.getInstance(); + Provider provider = Provider.getInstance(); provider.init( this ); setContentView(R.layout.client_dashboard); @@ -183,16 +194,17 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( provider.hasEIP()){ - EipServiceFragment previous_eip_fragment = (EipServiceFragment)fragment_manager.findFragmentByTag(EipServiceFragment.TAG); - EipServiceFragment eipFragment = previous_eip_fragment == null ? - new EipServiceFragment() : previous_eip_fragment; + EipServiceFragment eipFragment = new EipServiceFragment(); + if (hide_and_turn_on_eip) { - preferences.edit().remove(Dashboard.START_ON_BOOT).commit(); + preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); Bundle arguments = new Bundle(); arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); eipFragment.setArguments(arguments); } - fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); + + fragment_manager.removePreviousFragment(EipServiceFragment.TAG); + fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); if (hide_and_turn_on_eip) { onBackPressed(); @@ -205,12 +217,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf JSONObject provider_json; try { String provider_json_string = preferences.getString(Provider.KEY, ""); - if(provider_json_string.isEmpty() == false) { + if(!provider_json_string.isEmpty()) { provider_json = new JSONObject(provider_json_string); JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); boolean authed_eip = !LeapSRPSession.getToken().isEmpty(); boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); - preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, allow_registered_eip); + preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, allow_registered_eip).apply(); if(allow_registered_eip) { if(authed_eip) { @@ -256,7 +268,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } eipStop(); } - preferences.edit().clear().commit(); + preferences.edit().clear().apply(); startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); return true; case R.id.login_button: @@ -405,7 +417,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf invalidateOptionsMenu(); authed_eip = true; - preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); downloadAuthedUserCertificate(); } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { @@ -420,7 +432,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf invalidateOptionsMenu(); authed_eip = false; - preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).commit(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { changeStatusMessage(resultCode); diff --git a/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java b/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java index f78002b0..a44253c6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java @@ -16,9 +16,6 @@ */ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index f29d1338..b896c00f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -1,19 +1,28 @@ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.ProviderAPIResultReceiver; -import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; -import se.leap.bitmaskclient.eip.*; - -import de.blinkt.openvpn.activities.*; -import de.blinkt.openvpn.core.*; -import android.app.*; -import android.content.*; -import android.os.*; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; import android.util.Log; -import android.view.*; -import android.widget.*; -import java.util.*; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.Switch; +import android.widget.TextView; + +import java.util.Observable; +import java.util.Observer; + +import de.blinkt.openvpn.activities.DisconnectVPN; +import se.leap.bitmaskclient.eip.Constants; +import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; public class EipServiceFragment extends Fragment implements Observer, CompoundButton.OnCheckedChangeListener { @@ -26,7 +35,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu private View eipFragment; private static Switch eipSwitch; - private View eipDetail; private TextView status_message; private static Activity parent_activity; @@ -50,8 +58,8 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); - eipDetail = ((RelativeLayout) eipFragment.findViewById(R.id.eipDetail)); + eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); + View eipDetail = eipFragment.findViewById(R.id.eipDetail); eipDetail.setVisibility(View.VISIBLE); View eipSettings = eipFragment.findViewById(R.id.eipSettings); @@ -213,7 +221,7 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu public void update (Observable observable, Object data) { Log.d(TAG, "handleNewState?"); if(observable instanceof EipStatus) { - this.eip_status = (EipStatus) observable; + eip_status = (EipStatus) observable; final EipStatus eip_status = (EipStatus) observable; parent_activity.runOnUiThread(new Runnable() { @Override @@ -284,14 +292,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu parent_activity.findViewById(R.id.eipProgress).setVisibility(View.GONE); } - public static EipStatus getEipStatus() { - return eip_status; - } - - public void checkEipSwitch(boolean activated) { - eipSwitch.setChecked(activated); - } - protected class EIPReceiver extends ResultReceiver { protected EIPReceiver(Handler handler){ @@ -303,21 +303,18 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu super.onReceiveResult(resultCode, resultData); String request = resultData.getString(Constants.REQUEST_TAG); - boolean checked = false; - - if (request == Constants.ACTION_START_EIP) { + + if (request.equals(Constants.ACTION_START_EIP)) { switch (resultCode){ case Activity.RESULT_OK: Log.d(TAG, "Action start eip = Result OK"); - checked = true; eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); break; case Activity.RESULT_CANCELED: - checked = false; eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); break; } - } else if (request == Constants.ACTION_STOP_EIP) { + } else if (request.equals(Constants.ACTION_STOP_EIP)) { switch (resultCode){ case Activity.RESULT_OK: Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); @@ -325,20 +322,16 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu eip_status.setDisconnecting(); break; case Activity.RESULT_CANCELED: - checked = true; break; } - } else if (request == Constants.EIP_NOTIFICATION) { + } else if (request.equals(Constants.EIP_NOTIFICATION)) { switch (resultCode){ case Activity.RESULT_OK: - checked = true; break; case Activity.RESULT_CANCELED: - checked = false; break; } - } else if (request == Constants.ACTION_CHECK_CERT_VALIDITY) { - checked = eipSwitch.isChecked(); + } else if (request.equals(Constants.ACTION_CHECK_CERT_VALIDITY)) { switch (resultCode) { case Activity.RESULT_OK: break; diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java index a953a710..989dc395 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java +++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java @@ -17,13 +17,14 @@ package se.leap.bitmaskclient; +import org.jboss.security.srp.SRPParameters; + import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; -import org.jboss.security.srp.SRPParameters; /** * Implements all SRP algorithm logic. diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java index 97a9aecc..5263392e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java @@ -16,19 +16,13 @@ */ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.R; -import android.R.color; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; import android.content.DialogInterface; -import android.content.res.ColorStateList; import android.os.Bundle; -import android.provider.CalendarContract.Colors; import android.view.LayoutInflater; import android.view.View; -import android.view.animation.AlphaAnimation; -import android.view.animation.BounceInterpolator; import android.widget.EditText; import android.widget.TextView; @@ -47,6 +41,8 @@ public class LogInDialog extends SessionDialogInterface { final public static String TAG = LogInDialog.class.getSimpleName(); + private static LogInDialog dialog; + private static boolean is_eip_pending = false; public AlertDialog onCreateDialog(Bundle savedInstanceState) { @@ -122,8 +118,10 @@ public class LogInDialog extends SessionDialogInterface { * @return a new instance of this DialogFragment. */ public static DialogFragment newInstance() { - LogInDialog dialog_fragment = new LogInDialog(); - return dialog_fragment; + if(dialog == null) + dialog = new LogInDialog(); + + return dialog; } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java index 74f89ab8..07ed6c8f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java @@ -1,7 +1,8 @@ package se.leap.bitmaskclient; -import android.content.*; -import android.util.Log; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; import se.leap.bitmaskclient.eip.Constants; diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 8d6385e0..fa1a4fb5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -16,17 +16,17 @@ */ package se.leap.bitmaskclient; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Locale; +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import android.content.Context; -import android.app.Activity; -import android.content.SharedPreferences; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Locale; /** * @author Sean Leonard diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 43bba085..1148e65e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -1,7 +1,5 @@ package se.leap.bitmaskclient; -import java.util.List; - import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -9,6 +7,8 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TwoLineListItem; +import java.util.List; + public class ProviderListAdapter extends ArrayAdapter { private static boolean[] hidden = null; diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java index db414d87..e5baebc0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java @@ -16,8 +16,6 @@ */ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; import android.app.Activity; import android.app.ListFragment; import android.os.Bundle; @@ -26,11 +24,12 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ListView; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; + /** * A list fragment representing a list of Providers. This fragment * also supports tablet devices by allowing list items to be given an - * 'activated' state upon selection. This helps indicate which item is - * currently being viewed in a {@link DashboardFragment}. + * 'activated' state upon selection. *

* Activities containing this fragment MUST implement the {@link Callbacks} * interface. @@ -123,7 +122,7 @@ public class ProviderListFragment extends ListFragment { if(getArguments() != null && getArguments().containsKey(TOP_PADDING)) { int topPadding = getArguments().getInt(TOP_PADDING); View current_view = getView(); - getView().setPadding(current_view.getPaddingLeft(), topPadding, current_view.getPaddingRight(), current_view.getPaddingBottom()); + current_view.setPadding(current_view.getPaddingLeft(), topPadding, current_view.getPaddingRight(), current_view.getPaddingBottom()); } } @@ -215,7 +214,7 @@ public class ProviderListFragment extends ListFragment { real_count--; } else { i++; - } + } } public void unhideAll() { diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java index 7b08a4d1..66b86ccd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java @@ -17,10 +17,8 @@ package se.leap.bitmaskclient; import android.app.Activity; -import android.app.AlertDialog; import android.app.DialogFragment; import android.content.DialogInterface; -import android.os.Bundle; /** * @author parmegv diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java index d197e589..f6d6cc3f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java @@ -16,19 +16,13 @@ */ package se.leap.bitmaskclient; -import se.leap.bitmaskclient.R; -import android.R.color; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; import android.content.DialogInterface; -import android.content.res.ColorStateList; import android.os.Bundle; -import android.provider.CalendarContract.Colors; import android.view.LayoutInflater; import android.view.View; -import android.view.animation.AlphaAnimation; -import android.view.animation.BounceInterpolator; import android.widget.EditText; import android.widget.TextView; @@ -46,6 +40,7 @@ public class SignUpDialog extends SessionDialogInterface { final public static String TAG = SignUpDialog.class.getSimpleName(); + private static SignUpDialog dialog; private static boolean is_eip_pending = false; public AlertDialog onCreateDialog(Bundle savedInstanceState) { @@ -112,8 +107,9 @@ public class SignUpDialog extends SessionDialogInterface { * @return a new instance of this DialogFragment. */ public static DialogFragment newInstance() { - SignUpDialog dialog_fragment = new SignUpDialog(); - return dialog_fragment; + if(dialog == null) + dialog = new SignUpDialog(); + return dialog; } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java index b710d780..e1a7e616 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -34,8 +34,6 @@ public interface Constants { public final static String ACTION_UPDATE_EIP_SERVICE = TAG + ".UPDATE_EIP_SERVICE"; public final static String ACTION_IS_EIP_RUNNING = TAG + ".IS_RUNNING"; public final static String EIP_NOTIFICATION = TAG + ".EIP_NOTIFICATION"; - public final static String STATUS = TAG + ".STATUS"; - public final static String DATE_FROM_CERTIFICATE = TAG + ".DATE_FROM_CERTIFICATE"; public final static String ALLOWED_ANON = "allow_anonymous"; public final static String ALLOWED_REGISTERED = "allow_registration"; public final static String CERTIFICATE = "cert"; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 379fb246..5169ef62 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -16,22 +16,40 @@ */ package se.leap.bitmaskclient.eip; -import android.app.*; -import android.content.*; -import android.os.*; +import android.app.Activity; +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.ResultReceiver; import android.util.Log; -import java.io.*; -import java.security.cert.*; -import java.text.*; -import java.util.*; -import org.json.*; -import de.blinkt.openvpn.*; -import de.blinkt.openvpn.activities.*; -import de.blinkt.openvpn.core.*; -import se.leap.bitmaskclient.*; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; -import static se.leap.bitmaskclient.eip.Constants.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.blinkt.openvpn.LaunchVPN; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ProfileManager; +import se.leap.bitmaskclient.Dashboard; +import se.leap.bitmaskclient.EipServiceFragment; +import se.leap.bitmaskclient.Provider; + +import static se.leap.bitmaskclient.eip.Constants.ACTION_CHECK_CERT_VALIDITY; +import static se.leap.bitmaskclient.eip.Constants.ACTION_IS_EIP_RUNNING; +import static se.leap.bitmaskclient.eip.Constants.ACTION_START_EIP; +import static se.leap.bitmaskclient.eip.Constants.ACTION_STOP_EIP; +import static se.leap.bitmaskclient.eip.Constants.ACTION_UPDATE_EIP_SERVICE; +import static se.leap.bitmaskclient.eip.Constants.CERTIFICATE; +import static se.leap.bitmaskclient.eip.Constants.KEY; +import static se.leap.bitmaskclient.eip.Constants.PARSED_SERIAL; +import static se.leap.bitmaskclient.eip.Constants.RECEIVER_TAG; +import static se.leap.bitmaskclient.eip.Constants.REQUEST_TAG; /** * EIP is the abstract base class for interacting with and managing the Encrypted @@ -80,21 +98,21 @@ public final class EIP extends IntentService { String action = intent.getAction(); mReceiver = intent.getParcelableExtra(RECEIVER_TAG); - if ( action == ACTION_START_EIP ) + if ( action.equals(ACTION_START_EIP)) startEIP(); - else if ( action == ACTION_STOP_EIP ) + else if (action.equals(ACTION_STOP_EIP)) stopEIP(); - else if ( action == ACTION_IS_EIP_RUNNING ) + else if (action.equals(ACTION_IS_EIP_RUNNING)) isRunning(); - else if ( action == ACTION_UPDATE_EIP_SERVICE ) + else if (action.equals(ACTION_UPDATE_EIP_SERVICE)) updateEIPService(); - else if ( action == ACTION_CHECK_CERT_VALIDITY ) + else if (action.equals(ACTION_CHECK_CERT_VALIDITY)) checkCertValidity(); } /** * Initiates an EIP connection by selecting a gateway and preparing and sending an - * Intent to {@link se.leap.openvpn.LaunchVPN}. + * Intent to {@link de.blinkt.openvpn.LaunchVPN}. * It also sets up early routes. */ private void startEIP() { @@ -164,8 +182,7 @@ public final class EIP extends IntentService { } /** - * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} - * to parse gateway definitions. + * Loads eip-service.json from SharedPreferences, delete previous vpn profiles and add new gateways. * TODO Implement API call to refresh eip-service.json from the provider */ private void updateEIPService() { @@ -210,7 +227,7 @@ public final class EIP extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).commit(); + preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).apply(); } private boolean isOpenVpnGateway(JSONObject gateway) { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java index 82c3ceb8..4ac3bd6a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -17,18 +17,17 @@ package se.leap.bitmaskclient.eip; import android.util.Log; -import java.util.*; -import de.blinkt.openvpn.core.*; +import java.util.Observable; + +import de.blinkt.openvpn.core.VpnStatus; public class EipStatus extends Observable implements VpnStatus.StateListener { public static String TAG = EipStatus.class.getSimpleName(); private static EipStatus current_status; - private static EipStatus previous_status; private static VpnStatus.ConnectionStatus level = VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED; private static boolean wants_to_disconnect = false; - private static boolean is_disconnecting = false; private String state, log_message; private int localized_res_id; @@ -46,7 +45,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { @Override public void updateState(final String state, final String logmessage, final int localizedResId, final VpnStatus.ConnectionStatus level) { current_status = getInstance(); - previous_status = current_status; current_status.setState(state); current_status.setLogMessage(logmessage); current_status.setLocalizedResId(localizedResId); @@ -60,10 +58,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { current_status.notifyObservers(); } - public boolean isDisconnecting() { - return is_disconnecting; - } - public boolean wantsToDisconnect() { return wants_to_disconnect; } @@ -88,7 +82,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } public void setConnecting() { - is_disconnecting = false; wants_to_disconnect = false; current_status.setChanged(); current_status.notifyObservers(); @@ -96,21 +89,15 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { public void setConnectedOrDisconnected() { Log.d(TAG, "setConnectedOrDisconnected()"); - is_disconnecting = false; wants_to_disconnect = false; current_status.setChanged(); current_status.notifyObservers(); } public void setDisconnecting() { - is_disconnecting = true; wants_to_disconnect = false; } - public void setWantsToDisconnect() { - wants_to_disconnect = true; - } - public String getState() { return state; } @@ -127,10 +114,6 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { return level; } - public EipStatus getPreviousStatus() { - return previous_status; - } - private void setState(String state) { this.state = state; } @@ -144,7 +127,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } private void setLevel(VpnStatus.ConnectionStatus level) { - this.level = level; + EipStatus.level = level; } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java index 6aa66ac0..3ee9443c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -17,16 +17,22 @@ package se.leap.bitmaskclient.eip; import android.app.Activity; -import android.content.*; +import android.content.Context; +import android.content.SharedPreferences; import android.util.Log; -import java.io.*; -import java.util.*; -import org.json.*; -import de.blinkt.openvpn.*; -import de.blinkt.openvpn.activities.*; -import de.blinkt.openvpn.core.*; -import se.leap.bitmaskclient.*; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Collection; +import java.util.Iterator; + +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ConfigParser; +import de.blinkt.openvpn.core.ProfileManager; +import se.leap.bitmaskclient.Dashboard; /** * Gateway provides objects defining gateways and their metadata. @@ -103,9 +109,8 @@ public class Gateway { private JSONObject getLocationInfo(JSONObject eip_definition) { try { JSONObject locations = eip_definition.getJSONObject("locations"); - JSONObject location = locations.getJSONObject(mGateway.getString("location")); - return location; + return locations.getJSONObject(mGateway.getString("location")); } catch (JSONException e) { return new JSONObject(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java index 36b5fb41..39ae7ca6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java @@ -1,8 +1,10 @@ package se.leap.bitmaskclient.eip; -import java.security.cert.*; -import java.util.*; -import org.json.*; +import java.util.Calendar; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeMap; public class GatewaySelector { List gateways; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index 224e3bd4..a6f9fe76 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -1,11 +1,7 @@ package se.leap.bitmaskclient.eip; import android.content.Intent; -import android.os.Process; import android.net.VpnService; -import android.util.Log; - -import static se.leap.bitmaskclient.eip.Constants.*; public class VoidVpnService extends VpnService { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java index 16ae6a85..6487f6c1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java @@ -17,12 +17,13 @@ package se.leap.bitmaskclient.eip; import android.util.Log; -import java.util.*; -import java.security.cert.*; -import java.text.*; + +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Calendar; import se.leap.bitmaskclient.ConfigHelper; -import static se.leap.bitmaskclient.eip.Constants.*; public class VpnCertificateValidator { public final static String TAG = VpnCertificateValidator.class.getSimpleName(); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index 8e36f53c..0c8e9a04 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -18,13 +18,14 @@ package se.leap.bitmaskclient.eip; import android.content.SharedPreferences; import android.util.Log; -import java.util.Iterator; -import java.util.Vector; + import org.json.JSONArray; -import org.json.JSONObject; import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Iterator; -import se.leap.bitmaskclient.*; +import se.leap.bitmaskclient.Provider; public class VpnConfigGenerator { @@ -38,7 +39,7 @@ public class VpnConfigGenerator { public VpnConfigGenerator(SharedPreferences preferences, JSONObject general_configuration, JSONObject gateway) { this.general_configuration = general_configuration; this.gateway = gateway; - this.preferences = preferences; + VpnConfigGenerator.preferences = preferences; } public String generate() { @@ -56,7 +57,6 @@ public class VpnConfigGenerator { String common_options = ""; try { Iterator keys = general_configuration.keys(); - Vector> value = new Vector>(); while ( keys.hasNext() ){ String key = keys.next().toString(); -- cgit v1.2.3 From ba682a453c4f188d57562d764635f1db7e2e1cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 1 Dec 2014 17:13:26 +0100 Subject: Refresh gateways if the list is empty while starting eip. --- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 1 - app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index b896c00f..592a9552 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -219,7 +219,6 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public void update (Observable observable, Object data) { - Log.d(TAG, "handleNewState?"); if(observable instanceof EipStatus) { eip_status = (EipStatus) observable; final EipStatus eip_status = (EipStatus) observable; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 5169ef62..a67eaccd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -116,6 +116,8 @@ public final class EIP extends IntentService { * It also sets up early routes. */ private void startEIP() { + if(gateways.isEmpty()) + updateEIPService(); GatewaySelector gateway_selector = new GatewaySelector(gateways); activeGateway = gateway_selector.select(); if(activeGateway != null && activeGateway.getProfile() != null) { -- cgit v1.2.3 From b32fdf11b0ef473d489f9fb23f136fecf7051354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 1 Dec 2014 17:45:24 +0100 Subject: Restore eip fragment on screen orientation. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 6288fd1f..8143d8d6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -194,17 +194,19 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( provider.hasEIP()){ - EipServiceFragment eipFragment = new EipServiceFragment(); + EipServiceFragment eip_fragment = (EipServiceFragment) fragment_manager.findFragmentByTag(EipServiceFragment.TAG); + if(eip_fragment == null) + eip_fragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); Bundle arguments = new Bundle(); arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); - eipFragment.setArguments(arguments); + eip_fragment.setArguments(arguments); } fragment_manager.removePreviousFragment(EipServiceFragment.TAG); - fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); + fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipServiceFragment.TAG); if (hide_and_turn_on_eip) { onBackPressed(); -- cgit v1.2.3 From a59f2e0083b05fd94e2d0d2c1fcfeaa42b851531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 1 Dec 2014 19:52:54 +0100 Subject: Reordered EIP methods. Written basic skeleton for testEIP, renamed testDashboard to start, in the future, unit tests. --- app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index a67eaccd..b4208556 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -160,21 +160,12 @@ public final class EIP extends IntentService { tellToReceiver(ACTION_STOP_EIP, result_code); } - - private void tellToReceiver(String action, int resultCode) { - if (mReceiver != null){ - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, action); - mReceiver.send(resultCode, resultData); - } - } /** * Checks the last stored status notified by ics-openvpn * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the * request if it's not connected, Activity.RESULT_OK otherwise. */ - private void isRunning() { EipStatus eip_status = EipStatus.getInstance(); int resultCode = (eip_status.isConnected()) ? @@ -253,4 +244,12 @@ public final class EIP extends IntentService { Activity.RESULT_CANCELED; tellToReceiver(ACTION_CHECK_CERT_VALIDITY, resultCode); } + + private void tellToReceiver(String action, int resultCode) { + if (mReceiver != null){ + Bundle resultData = new Bundle(); + resultData.putString(REQUEST_TAG, action); + mReceiver.send(resultCode, resultData); + } + } } -- cgit v1.2.3 From 63a16b8c4e6d67910000b78c7f4a2a5709d498ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 3 Dec 2014 17:46:02 +0100 Subject: First orientation change doesn't crash. Update gradle to 2.2.1. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 3 --- app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 8143d8d6..94de2fe8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -86,7 +86,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - boolean provider_configured = preferences.getString(Constants.KEY, "").isEmpty(); if (provider_configured) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); @@ -136,7 +135,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); updateEipService(); - buildDashboard(false); invalidateOptionsMenu(); if(data != null && data.hasExtra(LogInDialog.TAG)) { logInDialog(Bundle.EMPTY); @@ -205,7 +203,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf eip_fragment.setArguments(arguments); } - fragment_manager.removePreviousFragment(EipServiceFragment.TAG); fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipServiceFragment.TAG); if (hide_and_turn_on_eip) { diff --git a/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java index c4844be9..49af9274 100644 --- a/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java +++ b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java @@ -45,6 +45,10 @@ public class FragmentManagerEnhanced { transaction.replace(containerViewId, fragment, tag).commit(); } + public FragmentTransaction beginTransaction() { + return generic_fragment_manager.beginTransaction(); + } + public Fragment findFragmentByTag(String tag) { return generic_fragment_manager.findFragmentByTag(tag); } -- cgit v1.2.3 From 6c79290b1783a303fad5ea8be3c3583cc79dad84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Dec 2014 00:46:25 +0100 Subject: Learning to use Butterknife, refactoring small things. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 5 +- .../main/java/se/leap/bitmaskclient/Provider.java | 66 ++++++---------------- 2 files changed, 19 insertions(+), 52 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 94de2fe8..c4f845b8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -86,8 +86,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - boolean provider_configured = preferences.getString(Constants.KEY, "").isEmpty(); - if (provider_configured) + boolean no_provider_configured = preferences.getString(Constants.KEY, "").isEmpty(); + if (no_provider_configured) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); @@ -135,6 +135,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); updateEipService(); + buildDashboard(false); invalidateOptionsMenu(); if(data != null && data.hasExtra(LogInDialog.TAG)) { logInDialog(Bundle.EMPTY); diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index fa1a4fb5..bb30905c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -110,11 +110,10 @@ public final class Provider implements Serializable { } protected String getDomain(){ - String domain = "Null"; + String domain = ""; try { domain = definition.getString(API_TERM_DOMAIN); } catch (JSONException e) { - domain = "Null"; e.printStackTrace(); } return domain; @@ -157,58 +156,25 @@ public final class Provider implements Serializable { } protected boolean hasEIP() { - JSONArray services = null; try { - services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"] + JSONArray services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"] + for (int i=0;i Date: Thu, 4 Dec 2014 01:14:03 +0100 Subject: CW loads, but no provider list appears. --- app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java index e5baebc0..6d40bf9f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java @@ -24,6 +24,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ListView; +import butterknife.ButterKnife; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; /** @@ -107,7 +108,9 @@ public class ProviderListFragment extends ListFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - return inflater.inflate(R.layout.provider_list_fragment, container, false); + View view = inflater.inflate(R.layout.provider_list_fragment, container, false); + ButterKnife.inject(this, view); + return view; } @Override -- cgit v1.2.3 From f9a200a7004b74cb2d64e37129e6234427c84c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Dec 2014 16:38:21 +0100 Subject: Renderers and dagger, refactoring CW. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 15 +-- .../main/java/se/leap/bitmaskclient/Provider.java | 116 ++++++++++---------- .../se/leap/bitmaskclient/ProviderManager.java | 120 +++++++++++++++++++++ .../se/leap/bitmaskclient/ProviderRenderer.java | 55 ++++++++++ .../bitmaskclient/ProviderRendererBuilder.java | 25 +++++ 5 files changed, 264 insertions(+), 67 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderManager.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index c4f845b8..e1d08d08 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -71,9 +71,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private TextView status_message; public ProviderAPIResultReceiver providerAPI_result_receiver; + private Provider provider; private static boolean authed_eip; - - @Override + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -137,9 +138,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf updateEipService(); buildDashboard(false); invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.TAG)) { + if(data != null) + if(data.hasExtra(LogInDialog.TAG)) { logInDialog(Bundle.EMPTY); } + if(data.hasExtra(Provider.KEY)) + provider = data.getParcelableExtra(Provider.KEY); } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { finish(); } else @@ -180,9 +184,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * service dependent UI elements to include. */ private void buildDashboard(boolean hide_and_turn_on_eip) { - Provider provider = Provider.getInstance(); - provider.init( this ); - setContentView(R.layout.client_dashboard); TextView providerNameTV = (TextView) findViewById(R.id.providerName); @@ -262,7 +263,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startActivity(startLW); return true; case R.id.switch_provider: - if (Provider.getInstance().hasEIP()){ + if (provider.hasEIP()){ if (preferences.getBoolean(Constants.AUTHED_EIP, false)){ logOut(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index bb30905c..5dd54175 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -19,12 +19,16 @@ package se.leap.bitmaskclient; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; +import android.os.Parcel; +import android.os.Parcelable; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Arrays; import java.util.Locale; @@ -32,16 +36,11 @@ import java.util.Locale; * @author Sean Leonard * */ -public final class Provider implements Serializable { +public final class Provider implements Parcelable { - private static final long serialVersionUID = 6003835972151761353L; - - private static Provider instance = null; - - // We'll access our preferences here - private static SharedPreferences preferences = null; - // Represents our Provider's provider.json - private static JSONObject definition = null; + private JSONObject definition; // Represents our Provider's provider.json + private URL main_url; + private boolean is_custom = false; final public static String API_URL = "api_uri", @@ -69,54 +68,39 @@ public final class Provider implements Serializable { private static final String API_TERM_DEFAULT_LANGUAGE = "default_language"; protected static final String[] API_EIP_TYPES = {"openvpn"}; - private static final String PREFS_EIP_NAME = null; + public Provider(URL main_url) { + this.main_url = main_url; + } + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public Provider createFromParcel(Parcel in) { + return new Provider(in); + } - - // What, no individual fields?! We're going to gamble on org.json.JSONObject and JSONArray - // Supporting multiple API versions will probably break this paradigm, - // Forcing me to write a real constructor and rewrite getters/setters - // Also will refactor if i'm instantiating the same local variables all the time - - /** - * - */ - private Provider() {} - - protected static Provider getInstance(){ - if(instance==null){ - instance = new Provider(); - } - return instance; - } + public Provider[] newArray(int size) { + return new Provider[size]; + } + }; - protected void init(Activity activity) { - - // Load our preferences from SharedPreferences - // If there's nothing there, we will end up returning a rather empty object - // to whoever called getInstance() and they can run the First Run Wizard - //preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... - - // Load SharedPreferences - preferences = activity.getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); - // Inflate our provider.json data - try { - definition = new JSONObject( preferences.getString(Provider.KEY, "") ); - } catch (JSONException e) { - // TODO: handle exception - - // FIXME!! We want "real" data!! - } - } + private Provider(Parcel in) { + try { + main_url = new URL(in.readString()); + definition = new JSONObject((in.readString())); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + + protected void define(JSONObject provider_json) { + definition = provider_json; + } protected String getDomain(){ - String domain = ""; - try { - domain = definition.getString(API_TERM_DOMAIN); - } catch (JSONException e) { - e.printStackTrace(); - } - return domain; + return main_url.getHost(); } protected String getName(){ @@ -124,15 +108,12 @@ public final class Provider implements Serializable { String lang = Locale.getDefault().getLanguage(); String name = "Null"; // Should it actually /be/ null, for error conditions? try { - name = definition.getJSONObject(API_TERM_NAME).getString(lang); + if(definition != null) + name = definition.getJSONObject(API_TERM_NAME).getString(lang); + else throw new JSONException("Provider not defined"); } catch (JSONException e) { - // TODO: Nesting try/catch blocks? Crazy - // Maybe you should actually handle exception? - try { - name = definition.getJSONObject(API_TERM_NAME).getString( definition.getString(API_TERM_DEFAULT_LANGUAGE) ); - } catch (JSONException e2) { - // TODO: Will you handle the exception already? - } + String host = main_url.getHost(); + name = host.substring(0, host.indexOf(".")); } return name; @@ -177,4 +158,19 @@ public final class Provider implements Serializable { } return false; } + + protected boolean isCustom() { + return is_custom; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(main_url.toString()); + parcel.writeString(definition.toString()); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java new file mode 100644 index 00000000..59507d9c --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java @@ -0,0 +1,120 @@ +package se.leap.bitmaskclient; + +import android.content.res.AssetManager; + +import com.pedrogomez.renderers.AdapteeCollection; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Created by parmegv on 4/12/14. + */ +public class ProviderManager implements AdapteeCollection { + + private AssetManager assets_manager; + private Set default_providers; + private Set custom_providers; + + final protected static String URLS = "urls"; + + public ProviderManager(AssetManager assets_manager) { + this.assets_manager = assets_manager; + default_providers = default_providers(); + custom_providers = new HashSet(); + } + + /** + * Loads providers data from url files contained in the assets folder + * @return true if the files were correctly read + */ + private Set default_providers() { + Set providers = new HashSet(); + try { + for(String file : assets_manager.list(URLS)) { + String main_url = extractProviderMainUrlFromAssetsFile(URLS + "/" + file); + providers.add(new Provider(new URL(main_url))); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return providers; + } + + private String extractProviderMainUrlFromAssetsFile(String file_path) { + String provider_main_url = ""; + try { + InputStream input_stream_file_contents = assets_manager.open(file_path); + byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; + if(input_stream_file_contents.read(urls_file_bytes) > 0) { + String urls_file_content = new String(urls_file_bytes); + JSONObject file_contents = new JSONObject(urls_file_content); + provider_main_url = file_contents.getString(Provider.MAIN_URL); + } + } catch (JSONException e) { + } catch (IOException e) { + } + return provider_main_url; + } + + public Set providers() { + Set all_providers = new HashSet(); + all_providers.addAll(default_providers); + all_providers.addAll(custom_providers); + return all_providers; + } + + @Override + public int size() { + return providers().size(); + } + + @Override + public Provider get(int index) { + Iterator iterator = providers().iterator(); + while(iterator.hasNext() && index > 0) { + iterator.next(); + index--; + } + return iterator.next(); + } + + @Override + public void add(Provider element) { + custom_providers.add(element); + } + + @Override + public void remove(Provider element) { + custom_providers.remove(element); + } + + @Override + public void addAll(Collection elements) { + custom_providers.addAll(elements); + } + + @Override + public void removeAll(Collection elements) { + custom_providers.removeAll(elements); + default_providers.removeAll(elements); + } + + @Override + public void clear() { + default_providers.clear(); + custom_providers.clear(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java new file mode 100644 index 00000000..2e376dee --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java @@ -0,0 +1,55 @@ +package se.leap.bitmaskclient; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.pedrogomez.renderers.Renderer; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Created by parmegv on 4/12/14. + */ +public class ProviderRenderer extends Renderer { + private final Context context; + + @InjectView(R.id.provider_name) + TextView name; + @InjectView(R.id.provider_domain) + TextView domain; + + public ProviderRenderer(Context context) { + this.context = context; + } + + @Override + protected View inflate(LayoutInflater inflater, ViewGroup parent) { + View view = inflater.inflate(R.layout.provider_list_item, parent, false); + ButterKnife.inject(this, view); + return view; + } + + @Override + protected void setUpView(View rootView) { + /* + * Empty implementation substituted with the usage of ButterKnife library by Jake Wharton. + */ + } + + @Override + protected void hookListeners(View rootView) { + //Empty + } + + @Override + public void render() { + Provider provider = getContent(); + name.setText(provider.getName()); + domain.setText(provider.getDomain()); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java b/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java new file mode 100644 index 00000000..7366e68e --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java @@ -0,0 +1,25 @@ +package se.leap.bitmaskclient; + +import android.content.Context; + +import com.pedrogomez.renderers.Renderer; +import com.pedrogomez.renderers.RendererBuilder; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import javax.inject.Inject; + +/** + * Created by parmegv on 4/12/14. + */ + public class ProviderRendererBuilder extends RendererBuilder { + public ProviderRendererBuilder(Collection> prototypes) { + super(prototypes); + } + @Override + protected Class getPrototypeClass(Provider content) { + return ProviderRenderer.class; + } +} -- cgit v1.2.3 From 202036aa6befcb1c74a76803f22e020404d4ba34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Dec 2014 18:42:06 +0100 Subject: Click on an item, no UI but functional. --- app/src/main/java/se/leap/bitmaskclient/Provider.java | 4 ++++ app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java | 2 ++ 2 files changed, 6 insertions(+) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 5dd54175..0d584310 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -102,6 +102,10 @@ public final class Provider implements Parcelable { protected String getDomain(){ return main_url.getHost(); } + + protected URL mainUrl() { + return main_url; + } protected String getName(){ // Should we pass the locale in, or query the system here? diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java index 2e376dee..6e194e84 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java @@ -11,6 +11,8 @@ import com.pedrogomez.renderers.Renderer; import butterknife.ButterKnife; import butterknife.InjectView; +import butterknife.OnItemClick; +import butterknife.OnItemSelected; /** * Created by parmegv on 4/12/14. -- cgit v1.2.3 From 84f71ca604abb2b4aeb410dcec2c3cc5dff9bc39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 11:20:31 +0100 Subject: Switching provider doesn't refresh provider list. It shows just one provider, and it's not the one that gets configured if selected. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 32 ++++----- .../main/java/se/leap/bitmaskclient/Provider.java | 16 ++++- .../se/leap/bitmaskclient/ProviderListAdapter.java | 79 ++++++++++++++-------- .../leap/bitmaskclient/ProviderListFragment.java | 26 +------ 4 files changed, 82 insertions(+), 71 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index e1d08d08..e277221b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -87,8 +87,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - boolean no_provider_configured = preferences.getString(Constants.KEY, "").isEmpty(); - if (no_provider_configured) + + if (provider == null) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); @@ -132,21 +132,21 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf Log.d(TAG, "onActivityResult: requestCode = " + requestCode); if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { - if ( resultCode == RESULT_OK ){ - preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); - preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); - updateEipService(); - buildDashboard(false); - invalidateOptionsMenu(); - if(data != null) - if(data.hasExtra(LogInDialog.TAG)) { - logInDialog(Bundle.EMPTY); - } - if(data.hasExtra(Provider.KEY)) + if ( resultCode == RESULT_OK ) { + preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); + preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); + updateEipService(); + + if (data.hasExtra(Provider.KEY)) provider = data.getParcelableExtra(Provider.KEY); - } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { - finish(); - } else + buildDashboard(false); + invalidateOptionsMenu(); + if (data.hasExtra(LogInDialog.TAG)) { + logInDialog(Bundle.EMPTY); + } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { + finish(); + } + } else configErrorDialog(); } else if(requestCode == EIP.DISCONNECT) { EipStatus.getInstance().setConnectedOrDisconnected(); diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 0d584310..dd679bb2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -86,7 +86,9 @@ public final class Provider implements Parcelable { private Provider(Parcel in) { try { main_url = new URL(in.readString()); - definition = new JSONObject((in.readString())); + String definition_string = in.readString(); + if(definition_string != null) + definition = new JSONObject((definition_string)); } catch (MalformedURLException e) { e.printStackTrace(); } catch (JSONException e) { @@ -94,7 +96,6 @@ public final class Provider implements Parcelable { } } - protected void define(JSONObject provider_json) { definition = provider_json; } @@ -175,6 +176,15 @@ public final class Provider implements Parcelable { @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(main_url.toString()); - parcel.writeString(definition.toString()); + if(definition != null) + parcel.writeString(definition.toString()); + } + + @Override + public boolean equals(Object o) { + if(o instanceof Provider) { + Provider p = (Provider) o; + return p.mainUrl().equals(mainUrl()); + } else return false; } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 1148e65e..92b2ae2e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -7,9 +7,15 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TwoLineListItem; +import com.pedrogomez.renderers.AdapteeCollection; +import com.pedrogomez.renderers.RendererAdapter; +import com.pedrogomez.renderers.RendererBuilder; + +import java.util.Collection; import java.util.List; +import java.util.Set; -public class ProviderListAdapter extends ArrayAdapter { +public class ProviderListAdapter extends RendererAdapter { private static boolean[] hidden = null; public void hide(int position) { @@ -23,10 +29,23 @@ public class ProviderListAdapter extends ArrayAdapter { notifyDataSetChanged(); notifyDataSetInvalidated(); } + + public void showAllProviders() { + for(int i = 0; i < hidden.length; i++) + hidden[i] = false; + notifyDataSetChanged(); + notifyDataSetInvalidated(); + } - public void unHideAll() { - for (int provider_index = 0; provider_index < hidden.length; provider_index++) - hidden[provider_index] = false; + public void hideAllBut(int position) { + for (int i = 0; i < hidden.length; i++) { + if (i != position) + hidden[i] = true; + else + hidden[i] = false; + } + notifyDataSetChanged(); + notifyDataSetInvalidated(); } private int getRealPosition(int position) { @@ -60,26 +79,28 @@ public class ProviderListAdapter extends ArrayAdapter { return (hidden.length - getHiddenCount()); } - public ProviderListAdapter(Context mContext, int layout, List objects) { - super(mContext, layout, objects); + public ProviderListAdapter(LayoutInflater layoutInflater, RendererBuilder rendererBuilder, + AdapteeCollection collection) { + super(layoutInflater, rendererBuilder, collection); if(hidden == null) { - hidden = new boolean[objects.size()]; - for (int i = 0; i < objects.size(); i++) + hidden = new boolean[collection.size()]; + for (int i = 0; i < collection.size(); i++) hidden[i] = false; } } - public ProviderListAdapter(Context mContext, int layout, List objects, boolean show_all_providers) { - super(mContext, layout, objects); + public ProviderListAdapter(LayoutInflater layoutInflater, RendererBuilder rendererBuilder, + AdapteeCollection collection, boolean show_all_providers) { + super(layoutInflater, rendererBuilder, collection); if(show_all_providers) { - hidden = new boolean[objects.size()]; - for (int i = 0; i < objects.size(); i++) + hidden = new boolean[collection.size()]; + for (int i = 0; i < collection.size(); i++) hidden[i] = false; } } @Override - public void add(T item) { + public void add(Provider item) { super.add(item); boolean[] new_hidden = new boolean[hidden.length+1]; System.arraycopy(hidden, 0, new_hidden, 0, hidden.length); @@ -88,27 +109,27 @@ public class ProviderListAdapter extends ArrayAdapter { } @Override - public void remove(T item) { + public void remove(Provider item) { super.remove(item); boolean[] new_hidden = new boolean[hidden.length-1]; System.arraycopy(hidden, 0, new_hidden, 0, hidden.length-1); hidden = new_hidden; } - @Override - public View getView(int index, View convertView, ViewGroup parent) { - TwoLineListItem row; - int position = getRealPosition(index); - if (convertView == null) { - LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - row = (TwoLineListItem)inflater.inflate(R.layout.provider_list_item, null); - } else { - row = (TwoLineListItem)convertView; - } - ProviderListContent.ProviderItem data = ProviderListContent.ITEMS.get(position); - row.getText1().setText(data.domain()); - row.getText2().setText(data.name()); + protected int indexOf(Provider item) { + int index = 0; + ProviderManager provider_manager = (ProviderManager) getCollection(); + Set providers = provider_manager.providers(); + for (Provider provider : providers) { + if (provider.equals(item)) { + break; + } else index++; + } + return index; + } - return row; - } + @Override + public View getView(int position, View convertView, ViewGroup parent) { + return super.getView(getRealPosition(position), convertView, parent); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java index 6d40bf9f..875b76d7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java @@ -40,7 +40,7 @@ public class ProviderListFragment extends ListFragment { public static String TAG = "provider_list_fragment"; public static String SHOW_ALL_PROVIDERS = "show_all_providers"; public static String TOP_PADDING = "top padding from providerlistfragment"; - private ProviderListAdapter content_adapter; + private ProviderListAdapter content_adapter; /** * The serialization (saved instance state) Bundle key representing the @@ -91,19 +91,7 @@ public class ProviderListFragment extends ListFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if(getArguments().containsKey(SHOW_ALL_PROVIDERS)) - content_adapter = new ProviderListAdapter( - getActivity(), - R.layout.provider_list_item, - ProviderListContent.ITEMS, getArguments().getBoolean(SHOW_ALL_PROVIDERS)); - else - content_adapter = new ProviderListAdapter( - getActivity(), - R.layout.provider_list_item, - ProviderListContent.ITEMS); - - - setListAdapter(content_adapter); + } @Override @@ -198,12 +186,11 @@ public class ProviderListFragment extends ListFragment { } public void removeLastItem() { - unhideAll(); content_adapter.remove(content_adapter.getItem(content_adapter.getCount()-1)); content_adapter.notifyDataSetChanged(); } - public void addItem(ProviderItem provider) { + public void addItem(Provider provider) { content_adapter.add(provider); content_adapter.notifyDataSetChanged(); } @@ -219,13 +206,6 @@ public class ProviderListFragment extends ListFragment { i++; } } - - public void unhideAll() { - if(content_adapter != null) { - content_adapter.unHideAll(); - content_adapter.notifyDataSetChanged(); - } - } /** * @return a new instance of this ListFragment. -- cgit v1.2.3 From 7da04dc635505c0bcfdcc2c86d186a7a6f0535f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 12:08:40 +0100 Subject: Release flavor updated, back button works. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 4 ++-- app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index e277221b..e3bd9b7d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -143,9 +143,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf invalidateOptionsMenu(); if (data.hasExtra(LogInDialog.TAG)) { logInDialog(Bundle.EMPTY); - } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { - finish(); } + } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { + finish(); } else configErrorDialog(); } else if(requestCode == EIP.DISCONNECT) { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index b4208556..4363dd13 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -47,7 +47,6 @@ import static se.leap.bitmaskclient.eip.Constants.ACTION_STOP_EIP; import static se.leap.bitmaskclient.eip.Constants.ACTION_UPDATE_EIP_SERVICE; import static se.leap.bitmaskclient.eip.Constants.CERTIFICATE; import static se.leap.bitmaskclient.eip.Constants.KEY; -import static se.leap.bitmaskclient.eip.Constants.PARSED_SERIAL; import static se.leap.bitmaskclient.eip.Constants.RECEIVER_TAG; import static se.leap.bitmaskclient.eip.Constants.REQUEST_TAG; @@ -209,18 +208,19 @@ public final class EIP extends IntentService { */ private void updateGateways(){ try { - JSONArray gatewaysDefined = eip_definition.getJSONArray("gateways"); - for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ - JSONObject gw = gatewaysDefined.getJSONObject(i); - if(isOpenVpnGateway(gw)) { - addGateway(new Gateway(eip_definition, context, gw)); - } - } + if(eip_definition != null) { + JSONArray gatewaysDefined = eip_definition.getJSONArray("gateways"); + for (int i = 0; i < gatewaysDefined.length(); i++) { + JSONObject gw = gatewaysDefined.getJSONObject(i); + if (isOpenVpnGateway(gw)) { + addGateway(new Gateway(eip_definition, context, gw)); + } + } + } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } - preferences.edit().putInt(PARSED_SERIAL, eip_definition.optInt(Provider.API_RETURN_SERIAL)).apply(); } private boolean isOpenVpnGateway(JSONObject gateway) { -- cgit v1.2.3 From afc9998ebefb19fcb2f9e3c46c6430fd69262e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 12:14:58 +0100 Subject: Show all providers onCreate CW. --- .../se/leap/bitmaskclient/ProviderListAdapter.java | 24 ++++++---------------- 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 92b2ae2e..8360954b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -79,25 +79,13 @@ public class ProviderListAdapter extends RendererAdapter { return (hidden.length - getHiddenCount()); } - public ProviderListAdapter(LayoutInflater layoutInflater, RendererBuilder rendererBuilder, + public ProviderListAdapter(LayoutInflater layoutInflater, RendererBuilder rendererBuilder, AdapteeCollection collection) { - super(layoutInflater, rendererBuilder, collection); - if(hidden == null) { - hidden = new boolean[collection.size()]; - for (int i = 0; i < collection.size(); i++) - hidden[i] = false; - } - } - - public ProviderListAdapter(LayoutInflater layoutInflater, RendererBuilder rendererBuilder, - AdapteeCollection collection, boolean show_all_providers) { - super(layoutInflater, rendererBuilder, collection); - if(show_all_providers) { - hidden = new boolean[collection.size()]; - for (int i = 0; i < collection.size(); i++) - hidden[i] = false; - } - } + super(layoutInflater, rendererBuilder, collection); + hidden = new boolean[collection.size()]; + for (int i = 0; i < collection.size(); i++) + hidden[i] = false; + } @Override public void add(Provider item) { -- cgit v1.2.3 From 5978db9bf758b7b229616d0575e327c58ad8cf94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 14:08:17 +0100 Subject: EIP fragment shown correctly. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 47 ++++++++++++++-------- .../main/java/se/leap/bitmaskclient/Provider.java | 10 +++-- .../java/se/leap/bitmaskclient/eip/Constants.java | 1 + 3 files changed, 39 insertions(+), 19 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index e3bd9b7d..b84b834c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -37,6 +37,9 @@ import android.widget.TextView; import org.json.JSONException; import org.json.JSONObject; +import java.net.MalformedURLException; +import java.net.URL; + import de.blinkt.openvpn.activities.LogWindow; import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; @@ -74,6 +77,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private Provider provider; private static boolean authed_eip; + @Override + protected void onSaveInstanceState(Bundle outState) { + if(provider != null) + outState.putParcelable(Provider.KEY, provider); + super.onSaveInstanceState(outState); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -88,7 +98,19 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - if (provider == null) + if(savedInstanceState != null) + provider = savedInstanceState.getParcelable(Provider.KEY); + if(provider == null && preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) + try { + provider = new Provider(new URL(preferences.getString(Provider.MAIN_URL, ""))); + provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (provider == null || provider.getName().isEmpty()) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); @@ -116,16 +138,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf Log.d(TAG, "Handle version didn't find any " + getPackageName() + " package"); } } - - @Override - protected void onDestroy() { - - super.onDestroy(); - } - - protected void onPause() { - super.onPause(); - } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ @@ -137,8 +149,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); updateEipService(); - if (data.hasExtra(Provider.KEY)) + if (data.hasExtra(Provider.KEY)) { provider = data.getParcelableExtra(Provider.KEY); + preferences.edit().putBoolean(Constants.PROVIDER_CONFIGURED, true).commit(); + preferences.edit().putString(Provider.MAIN_URL, provider.mainUrl().toString()).apply(); + preferences.edit().putString(Provider.KEY, provider.definition().toString()).apply(); + } buildDashboard(false); invalidateOptionsMenu(); if (data.hasExtra(LogInDialog.TAG)) { @@ -172,7 +188,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - preferences.edit().remove(Provider.KEY).apply(); + preferences.edit().remove(Provider.KEY).remove(Constants.PROVIDER_CONFIGURED).apply(); finish(); } }) @@ -194,9 +210,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( provider.hasEIP()){ - EipServiceFragment eip_fragment = (EipServiceFragment) fragment_manager.findFragmentByTag(EipServiceFragment.TAG); - if(eip_fragment == null) - eip_fragment = new EipServiceFragment(); + fragment_manager.removePreviousFragment(EipServiceFragment.TAG); + EipServiceFragment eip_fragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index dd679bb2..0b021b84 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -100,6 +100,8 @@ public final class Provider implements Parcelable { definition = provider_json; } + protected JSONObject definition() { return definition; } + protected String getDomain(){ return main_url.getHost(); } @@ -111,14 +113,16 @@ public final class Provider implements Parcelable { protected String getName(){ // Should we pass the locale in, or query the system here? String lang = Locale.getDefault().getLanguage(); - String name = "Null"; // Should it actually /be/ null, for error conditions? + String name = ""; try { if(definition != null) name = definition.getJSONObject(API_TERM_NAME).getString(lang); else throw new JSONException("Provider not defined"); } catch (JSONException e) { - String host = main_url.getHost(); - name = host.substring(0, host.indexOf(".")); + if(main_url != null) { + String host = main_url.getHost(); + name = host.substring(0, host.indexOf(".")); + } } return name; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java index e1a7e616..01a83d5f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -43,5 +43,6 @@ public interface Constants { public final static String RECEIVER_TAG = TAG + ".RECEIVER_TAG"; public final static String REQUEST_TAG = TAG + ".REQUEST_TAG"; public final static String START_BLOCKING_VPN_PROFILE = TAG + ".START_BLOCKING_VPN_PROFILE"; + public final static String PROVIDER_CONFIGURED = TAG + ".PROVIDER_CONFIGURED"; } -- cgit v1.2.3 From 7bbb5b69717393d87869ae6f16d6aff0578a81bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 15:58:09 +0100 Subject: Save custom providers to sdcard. --- .../main/java/se/leap/bitmaskclient/Provider.java | 19 +++-- .../se/leap/bitmaskclient/ProviderListAdapter.java | 5 ++ .../se/leap/bitmaskclient/ProviderManager.java | 98 +++++++++++++++++----- 3 files changed, 97 insertions(+), 25 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 0b021b84..a7ede2d1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -26,6 +26,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; @@ -40,7 +41,6 @@ public final class Provider implements Parcelable { private JSONObject definition; // Represents our Provider's provider.json private URL main_url; - private boolean is_custom = false; final public static String API_URL = "api_uri", @@ -72,6 +72,9 @@ public final class Provider implements Parcelable { this.main_url = main_url; } + public Provider(File provider_file) { + + } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public Provider createFromParcel(Parcel in) { @@ -168,10 +171,6 @@ public final class Provider implements Parcelable { return false; } - protected boolean isCustom() { - return is_custom; - } - @Override public int describeContents() { return 0; @@ -191,4 +190,14 @@ public final class Provider implements Parcelable { return p.mainUrl().equals(mainUrl()); } else return false; } + + public JSONObject toJson() { + JSONObject json = new JSONObject(); + try { + json.put(Provider.MAIN_URL, main_url); + } catch (JSONException e) { + e.printStackTrace(); + } + return json; + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 8360954b..72ca15c7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -120,4 +120,9 @@ public class ProviderListAdapter extends RendererAdapter { public View getView(int position, View convertView, ViewGroup parent) { return super.getView(getRealPosition(position), convertView, parent); } + + public void saveProviders() { + ProviderManager provider_manager = (ProviderManager) getCollection(); + provider_manager.saveCustomProvidersToFile(); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java index 59507d9c..911144f7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java @@ -7,6 +7,11 @@ import com.pedrogomez.renderers.AdapteeCollection; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; @@ -22,51 +27,89 @@ import java.util.Set; public class ProviderManager implements AdapteeCollection { private AssetManager assets_manager; + private File external_files_dir; private Set default_providers; private Set custom_providers; + private static ProviderManager instance; + final protected static String URLS = "urls"; + public static ProviderManager getInstance(AssetManager assets_manager, File external_files_dir) { + if(instance == null) + instance = new ProviderManager(assets_manager); + + instance.addCustomProviders(external_files_dir); + return instance; + } + public ProviderManager(AssetManager assets_manager) { this.assets_manager = assets_manager; - default_providers = default_providers(); - custom_providers = new HashSet(); + addDefaultProviders(assets_manager); } - /** - * Loads providers data from url files contained in the assets folder - * @return true if the files were correctly read - */ - private Set default_providers() { + private void addDefaultProviders(AssetManager assets_manager) { + try { + default_providers = providersFromAssets(URLS, assets_manager.list(URLS)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private Set providersFromAssets(String directory, String[] relative_file_paths) { Set providers = new HashSet(); try { - for(String file : assets_manager.list(URLS)) { - String main_url = extractProviderMainUrlFromAssetsFile(URLS + "/" + file); + for(String file : relative_file_paths) { + String main_url = extractMainUrlFromInputStream(assets_manager.open(directory + "/" + file)); providers.add(new Provider(new URL(main_url))); - } + } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } + return providers; + } + + + private void addCustomProviders(File external_files_dir) { + this.external_files_dir = external_files_dir; + custom_providers = external_files_dir.isDirectory() ? + providersFromFiles(external_files_dir.list()) : + new HashSet(); + } + + private Set providersFromFiles(String[] files) { + Set providers = new HashSet(); + try { + for(String file : files) { + String main_url = extractMainUrlFromInputStream(new FileInputStream(external_files_dir.getAbsolutePath() + "/" + file)); + providers.add(new Provider(new URL(main_url))); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } return providers; } - private String extractProviderMainUrlFromAssetsFile(String file_path) { - String provider_main_url = ""; + private String extractMainUrlFromInputStream(InputStream input_stream_file_contents) { + String main_url = ""; + byte[] bytes = new byte[0]; try { - InputStream input_stream_file_contents = assets_manager.open(file_path); - byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; - if(input_stream_file_contents.read(urls_file_bytes) > 0) { - String urls_file_content = new String(urls_file_bytes); - JSONObject file_contents = new JSONObject(urls_file_content); - provider_main_url = file_contents.getString(Provider.MAIN_URL); + bytes = new byte[input_stream_file_contents.available()]; + if(input_stream_file_contents.read(bytes) > 0) { + JSONObject file_contents = new JSONObject(new String(bytes)); + main_url = file_contents.getString(Provider.MAIN_URL); } - } catch (JSONException e) { } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); } - return provider_main_url; + return main_url; } public Set providers() { @@ -117,4 +160,19 @@ public class ProviderManager implements AdapteeCollection { default_providers.clear(); custom_providers.clear(); } + + protected void saveCustomProvidersToFile() { + try { + for (Provider provider : custom_providers) { + File provider_file = new File(external_files_dir, provider.getName() + ".json"); + if(!provider_file.exists()) { + FileWriter writer = new FileWriter(provider_file); + writer.write(provider.toJson().toString()); + writer.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } } -- cgit v1.2.3 From e980e1f888f29806ab0933495fdb0dd383c944e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 16:22:28 +0100 Subject: No duplicated providers. --- app/src/main/java/se/leap/bitmaskclient/Provider.java | 5 +++++ .../main/java/se/leap/bitmaskclient/ProviderListAdapter.java | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index a7ede2d1..f22a4bfb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -200,4 +200,9 @@ public final class Provider implements Parcelable { } return json; } + + @Override + public int hashCode() { + return main_url.hashCode(); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 72ca15c7..19a9a089 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -90,10 +90,12 @@ public class ProviderListAdapter extends RendererAdapter { @Override public void add(Provider item) { super.add(item); - boolean[] new_hidden = new boolean[hidden.length+1]; - System.arraycopy(hidden, 0, new_hidden, 0, hidden.length); - new_hidden[hidden.length] = false; - hidden = new_hidden; + if(getCollection().size() < hidden.length) { + boolean[] new_hidden = new boolean[hidden.length + 1]; + System.arraycopy(hidden, 0, new_hidden, 0, hidden.length); + new_hidden[hidden.length] = false; + hidden = new_hidden; + } } @Override -- cgit v1.2.3 From 062e4c4597f947816282b1c9c5e63c034549f057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 18:57:35 +0100 Subject: Final refactoring for this bug. Removed the sign up dialog, log in one is enough with the third button I added some time ago to sign up. Removed classes we don't need due to the libraries I have recently introduced. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 148 ++++++-------- .../se/leap/bitmaskclient/EipServiceFragment.java | 107 +++++----- .../java/se/leap/bitmaskclient/LogInDialog.java | 144 -------------- .../leap/bitmaskclient/ProviderListFragment.java | 216 --------------------- .../java/se/leap/bitmaskclient/SessionDialog.java | 159 +++++++++++++++ .../leap/bitmaskclient/SessionDialogInterface.java | 37 ---- .../java/se/leap/bitmaskclient/SignUpDialog.java | 132 ------------- 7 files changed, 270 insertions(+), 673 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/LogInDialog.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/SessionDialog.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index b84b834c..c7691ed4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -40,6 +40,8 @@ import org.json.JSONObject; import java.net.MalformedURLException; import java.net.URL; +import butterknife.ButterKnife; +import butterknife.InjectView; import de.blinkt.openvpn.activities.LogWindow; import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; @@ -52,7 +54,7 @@ import se.leap.bitmaskclient.eip.EipStatus; * @author Sean Leonard * @author parmegv */ -public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface, SignUpDialog.SignUpDialogInterface, ProviderAPIResultReceiver.Receiver { +public class Dashboard extends Activity implements SessionDialog.LogInDialogInterface, ProviderAPIResultReceiver.Receiver { protected static final int CONFIGURE_LEAP = 0; protected static final int SWITCH_PROVIDER = 1; @@ -70,12 +72,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected static SharedPreferences preferences; private FragmentManagerEnhanced fragment_manager; - private ProgressBar mProgressBar; - private TextView status_message; - public ProviderAPIResultReceiver providerAPI_result_receiver; + @InjectView(R.id.providerName) + TextView provider_name; + EipServiceFragment eip_fragment; private Provider provider; private static boolean authed_eip; + public ProviderAPIResultReceiver providerAPI_result_receiver; @Override protected void onSaveInstanceState(Bundle outState) { @@ -91,8 +94,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf app = this; PRNGFixes.apply(); - - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); @@ -157,7 +158,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } buildDashboard(false); invalidateOptionsMenu(); - if (data.hasExtra(LogInDialog.TAG)) { + if (data.hasExtra(SessionDialog.TAG)) { logInDialog(Bundle.EMPTY); } } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { @@ -200,24 +201,21 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * service dependent UI elements to include. */ private void buildDashboard(boolean hide_and_turn_on_eip) { - setContentView(R.layout.client_dashboard); - - TextView providerNameTV = (TextView) findViewById(R.id.providerName); - providerNameTV.setText(provider.getDomain()); - providerNameTV.setTextSize(28); - - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + setContentView(R.layout.dashboard); + ButterKnife.inject(this); + + provider_name.setText(provider.getDomain()); if ( provider.hasEIP()){ fragment_manager.removePreviousFragment(EipServiceFragment.TAG); - EipServiceFragment eip_fragment = new EipServiceFragment(); + eip_fragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); Bundle arguments = new Bundle(); arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); - eip_fragment.setArguments(arguments); + if(eip_fragment != null) eip_fragment.setArguments(arguments); } fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipServiceFragment.TAG); @@ -279,10 +277,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf return true; case R.id.switch_provider: if (provider.hasEIP()){ - if (preferences.getBoolean(Constants.AUTHED_EIP, false)){ - logOut(); - } - eipStop(); + if (preferences.getBoolean(Constants.AUTHED_EIP, false)) { + logOut(); + } + eip_fragment.stopEIP(); } preferences.edit().clear().apply(); startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); @@ -302,10 +300,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } - private Intent prepareProviderAPICommand() { - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - status_message = (TextView) findViewById(R.id.status_message); - + private Intent prepareProviderAPICommand() { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); @@ -319,12 +314,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the log in dialog. */ public void logInDialog(Bundle resultData) { - FragmentTransaction transaction = fragment_manager.removePreviousFragment(LogInDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(SessionDialog.TAG); - DialogFragment newFragment = LogInDialog.newInstance(); + DialogFragment newFragment = SessionDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) newFragment.setArguments(resultData); - newFragment.show(transaction, LogInDialog.TAG); + newFragment.show(transaction, SessionDialog.TAG); } @Override @@ -334,12 +329,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if(parameters == null) parameters = new Bundle(); - parameters.putString(SessionDialogInterface.USERNAME, username); - parameters.putString(SessionDialogInterface.PASSWORD, password); - - mProgressBar.setVisibility(ProgressBar.VISIBLE); - status_message.setText(R.string.authenticating_message); + parameters.putString(SessionDialog.USERNAME, username); + parameters.putString(SessionDialog.PASSWORD, password); + if(eip_fragment != null) { + eip_fragment.progress_bar.setVisibility(ProgressBar.VISIBLE); + eip_fragment.status_message.setText(R.string.authenticating_message); + } provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.setAction(ProviderAPI.SRP_AUTH); startService(provider_API_command); @@ -354,12 +350,11 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf */ public void logOut() { Intent provider_API_command = prepareProviderAPICommand(); - - if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - if(status_message == null) status_message = (TextView) findViewById(R.id.status_message); - status_message.setText(R.string.logout_message); - + if(eip_fragment != null) { + + eip_fragment.progress_bar.setVisibility(ProgressBar.VISIBLE); + eip_fragment.status_message.setText(R.string.logout_message); + } provider_API_command.setAction(ProviderAPI.LOG_OUT); startService(provider_API_command); } @@ -368,13 +363,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the sign up dialog. */ public void signUpDialog(Bundle resultData) { - FragmentTransaction transaction = fragment_manager.removePreviousFragment(SignUpDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(SessionDialog.TAG); - DialogFragment newFragment = SignUpDialog.newInstance(); + DialogFragment newFragment = SessionDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) { newFragment.setArguments(resultData); } - newFragment.show(transaction, SignUpDialog.TAG); + newFragment.show(transaction, SessionDialog.TAG); } @Override @@ -384,12 +379,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if(parameters == null) parameters = new Bundle(); - parameters.putString(SessionDialogInterface.USERNAME, username); - parameters.putString(SessionDialogInterface.PASSWORD, password); - - mProgressBar.setVisibility(ProgressBar.VISIBLE); - status_message.setText(R.string.signingup_message); - + parameters.putString(SessionDialog.USERNAME, username); + parameters.putString(SessionDialog.PASSWORD, password); + if(eip_fragment != null) { + eip_fragment.progress_bar.setVisibility(ProgressBar.VISIBLE); + eip_fragment.status_message.setText(R.string.signingup_message); + } provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.setAction(ProviderAPI.SRP_REGISTER); startService(provider_API_command); @@ -418,8 +413,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public void onReceiveResult(int resultCode, Bundle resultData) { Log.d(TAG, "onReceiveResult"); if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL) { - String username = resultData.getString(SessionDialogInterface.USERNAME); - String password = resultData.getString(SessionDialogInterface.PASSWORD); + String username = resultData.getString(SessionDialog.USERNAME); + String password = resultData.getString(SessionDialog.PASSWORD); logIn(username, password); } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED) { changeStatusMessage(resultCode); @@ -477,8 +472,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf String request = resultData.getString(Constants.REQUEST_TAG); if(request.equalsIgnoreCase(Constants.ACTION_UPDATE_EIP_SERVICE)) { if(resultCode == Activity.RESULT_OK) { - if(authed_eip) - eipStart(); + if(authed_eip && eip_fragment != null) eip_fragment.startEipFromScratch(); } } } @@ -493,17 +487,16 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); String request = resultData.getString(Constants.REQUEST_TAG); - if(status_message == null) status_message = (TextView) findViewById(R.id.status_message); - if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){ + if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){ if (resultCode == Activity.RESULT_OK){ switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: status_message.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: status_message.setText(R.string.authentication_failed_message); break; - case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.authed_secured_status); break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: status_message.setText(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: status_message.setText(R.string.log_out_failed_message); break; + case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.SRP_AUTHENTICATION_FAILED: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.authed_secured_status); break; + case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: eip_fragment.status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.LOGOUT_FAILED: eip_fragment.status_message.setText(R.string.log_out_failed_message); break; } } @@ -511,13 +504,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: status_message.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: status_message.setText(R.string.authentication_failed_message); break; - case ProviderAPI.SRP_REGISTRATION_FAILED: status_message.setText(R.string.registration_failed_message); break; + case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.SRP_AUTHENTICATION_FAILED: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.SRP_REGISTRATION_FAILED: eip_fragment.status_message.setText(R.string.registration_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; - case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: status_message.setText(R.string.logged_out_message); break; - case ProviderAPI.LOGOUT_FAILED: status_message.setText(R.string.log_out_failed_message); break; + case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: eip_fragment.status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.LOGOUT_FAILED: eip_fragment.status_message.setText(R.string.log_out_failed_message); break; } } } @@ -528,11 +521,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } private void hideProgressBar() { - if(mProgressBar == null) - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - - mProgressBar.setProgress(0); - mProgressBar.setVisibility(ProgressBar.GONE); + if(eip_fragment != null) { + eip_fragment.progress_bar.setProgress(0); + eip_fragment.progress_bar.setVisibility(ProgressBar.GONE); + } } /** @@ -559,20 +551,4 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf eip_intent.putExtra(Constants.RECEIVER_TAG, eip_receiver); startService(eip_intent); } - - private void eipStop(){ - EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); - eipFragment.stopEIP(); - } - - private void eipStart() { - EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); - eipFragment.startEipFromScratch(); - } - - protected void showProgressBar() { - if(mProgressBar == null) - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 592a9552..a8ffda72 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -12,19 +12,22 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CompoundButton; +import android.widget.ProgressBar; import android.widget.Switch; import android.widget.TextView; import java.util.Observable; import java.util.Observer; +import butterknife.ButterKnife; +import butterknife.InjectView; +import butterknife.OnCheckedChanged; import de.blinkt.openvpn.activities.DisconnectVPN; import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipStatus; -public class EipServiceFragment extends Fragment implements Observer, CompoundButton.OnCheckedChangeListener { +public class EipServiceFragment extends Fragment implements Observer { public static String TAG = "se.leap.bitmask.EipServiceFragment"; @@ -33,9 +36,13 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu protected static final String STATUS_MESSAGE = TAG + ".status_message"; public static final String START_ON_BOOT = "start on boot"; - private View eipFragment; - private static Switch eipSwitch; - private TextView status_message; + private View view; + @InjectView(R.id.eipSwitch) + Switch eip_switch; + @InjectView(R.id.status_message) + TextView status_message; + @InjectView(R.id.eipProgress) + ProgressBar progress_bar; private static Activity parent_activity; private static EIPReceiver mEIPReceiver; @@ -57,35 +64,27 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); - View eipDetail = eipFragment.findViewById(R.id.eipDetail); - eipDetail.setVisibility(View.VISIBLE); - - View eipSettings = eipFragment.findViewById(R.id.eipSettings); - eipSettings.setVisibility(View.GONE); // FIXME too! + view = inflater.inflate(R.layout.eip_service_fragment, container, false); + ButterKnife.inject(this, view); if (eip_status.isConnecting()) - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - - status_message = (TextView) eipFragment.findViewById(R.id.status_message); + eip_switch.setVisibility(View.VISIBLE); - eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch); - Log.d(TAG, "onCreateView, eipSwitch is checked? " + eipSwitch.isChecked()); - eipSwitch.setOnCheckedChangeListener(this); - - if(getArguments() != null && getArguments().containsKey(START_ON_BOOT) && getArguments().getBoolean(START_ON_BOOT)) + Log.d(TAG, "onCreateView, eip_switch is checked? " + eip_switch.isChecked()); + + Bundle arguments = getArguments(); + if(arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT)) startEipFromScratch(); if (savedInstanceState != null) { - setStatusMessage(savedInstanceState.getString(STATUS_MESSAGE)); + status_message.setText(savedInstanceState.getString(STATUS_MESSAGE)); if(savedInstanceState.getBoolean(IS_PENDING)) eip_status.setConnecting(); else if(savedInstanceState.getBoolean(IS_CONNECTED)) { eip_status.setConnectedOrDisconnected(); } } - return eipFragment; + return view; } @Override @@ -106,22 +105,16 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu protected void saveEipStatus() { boolean eip_is_on = false; Log.d(TAG, "saveEipStatus"); - if(eipSwitch.isChecked()) { + if(eip_switch.isChecked()) { eip_is_on = true; } if(parent_activity != null) Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (buttonView.equals(eipSwitch)){ - handleSwitch(isChecked); - } - } - - private void handleSwitch(boolean isChecked) { + + @OnCheckedChanged(R.id.eipSwitch) + void handleSwitch(boolean isChecked) { if(isChecked) handleSwitchOn(); else @@ -175,31 +168,30 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu .setNegativeButton(parent_activity.getString(R.string.no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - eipSwitch.setChecked(true); + eip_switch.setChecked(true); } }) .show(); } public void startEipFromScratch() { - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + progress_bar.setVisibility(View.VISIBLE); + eip_switch.setVisibility(View.VISIBLE); String status = parent_activity.getString(R.string.eip_status_start_pending); - setStatusMessage(status); + status_message.setText(status); - if(!eipSwitch.isChecked()) { - eipSwitch.setChecked(true); + if(!eip_switch.isChecked()) { + eip_switch.setChecked(true); saveEipStatus(); } eipCommand(Constants.ACTION_START_EIP); } protected void stopEIP() { - View eipProgressBar = parent_activity.findViewById(R.id.eipProgress); - if(eipProgressBar != null) - eipProgressBar.setVisibility(View.GONE); - + hideProgressBar(); + String status = parent_activity.getString(R.string.eip_state_not_connected); - setStatusMessage(status); + status_message.setText(status); eipCommand(Constants.ACTION_STOP_EIP); } @@ -247,26 +239,26 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu hideProgressBar(); Log.d(TAG, "setConnectedUi? " + eip_status.isConnected()); adjustSwitch(); - setStatusMessage(parent_activity.getString(R.string.eip_state_connected)); + status_message.setText(parent_activity.getString(R.string.eip_state_connected)); } private void setDisconnectedUI(){ hideProgressBar(); adjustSwitch(); - setStatusMessage(parent_activity.getString(R.string.eip_state_not_connected)); + status_message.setText(parent_activity.getString(R.string.eip_state_not_connected)); } private void adjustSwitch() { if(eip_status.isConnected() || eip_status.isConnecting()) { - Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked? " + eipSwitch.isChecked()); - if(!eipSwitch.isChecked()) { - eipSwitch.setChecked(true); + Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked? " + eip_switch.isChecked()); + if(!eip_switch.isChecked()) { + eip_switch.setChecked(true); } } else { Log.d(TAG, "adjustSwitch, !isConnected && !isConnecting? " + eip_status.toString()); - if(eipSwitch.isChecked()) { - eipSwitch.setChecked(false); + if(eip_switch.isChecked()) { + eip_switch.setChecked(false); } } } @@ -275,8 +267,8 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu int localizedResId = eip_status.getLocalizedResId(); String logmessage = eip_status.getLogMessage(); String prefix = parent_activity.getString(localizedResId); - - setStatusMessage(prefix + " " + logmessage); + + status_message.setText(prefix + " " + logmessage); adjustSwitch(); } @@ -287,8 +279,8 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu } private void hideProgressBar() { - if(parent_activity != null && parent_activity.findViewById(R.id.eipProgress) != null) - parent_activity.findViewById(R.id.eipProgress).setVisibility(View.GONE); + if(progress_bar != null) + progress_bar.setVisibility(View.GONE); } protected class EIPReceiver extends ResultReceiver { @@ -307,10 +299,10 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu switch (resultCode){ case Activity.RESULT_OK: Log.d(TAG, "Action start eip = Result OK"); - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + progress_bar.setVisibility(View.VISIBLE); break; case Activity.RESULT_CANCELED: - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); + progress_bar.setVisibility(View.GONE); break; } } else if (request.equals(Constants.ACTION_STOP_EIP)) { @@ -337,9 +329,8 @@ public class EipServiceFragment extends Fragment implements Observer, CompoundBu case Activity.RESULT_CANCELED: Dashboard dashboard = (Dashboard) parent_activity; - dashboard.showProgressBar(); - String status = parent_activity.getString(R.string.updating_certificate_message); - setStatusMessage(status); + progress_bar.setVisibility(View.VISIBLE); + status_message.setText(getString(R.string.updating_certificate_message)); if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { dashboard.logInDialog(Bundle.EMPTY); } else { diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java deleted file mode 100644 index 5263392e..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.EditText; -import android.widget.TextView; - -/** - * Implements the log in dialog, currently without progress dialog. - * - * It returns to the previous fragment when finished, and sends username and password to the authenticate method. - * - * It also notifies the user if the password is not valid. - * - * @author parmegv - * - */ -public class LogInDialog extends SessionDialogInterface { - - - final public static String TAG = LogInDialog.class.getSimpleName(); - - private static LogInDialog dialog; - - private static boolean is_eip_pending = false; - - public AlertDialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - LayoutInflater inflater = getActivity().getLayoutInflater(); - View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); - - final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); - final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); - final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); - - if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { - password_field.requestFocus(); - } - if (getArguments() != null) { - is_eip_pending = getArguments().getBoolean(EipServiceFragment.IS_PENDING, false); - if (getArguments().containsKey(PASSWORD_INVALID_LENGTH)) - password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); - if (getArguments().containsKey(USERNAME)) { - String username = getArguments().getString(USERNAME); - username_field.setText(username); - } - if (getArguments().containsKey(USERNAME_MISSING)) { - username_field.setError(getResources().getString(R.string.username_ask)); - } - if(getArguments().containsKey(getResources().getString(R.string.user_message))) - user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); - else - user_message.setVisibility(View.GONE); - } - - builder.setView(log_in_dialog_view) - .setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - String username = username_field.getText().toString(); - String password = password_field.getText().toString(); - dialog.dismiss(); - interface_with_Dashboard.logIn(username, password); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - interface_with_Dashboard.cancelLoginOrSignup(); - } - }) - .setNeutralButton(R.string.signup_button, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - String username = username_field.getText().toString(); - String password = password_field.getText().toString(); - interface_with_Dashboard.signUp(username, password); - } - }); - - return builder.create(); - } - - /** - * Interface used to communicate LogInDialog with Dashboard. - * - * @author parmegv - * - */ - public interface LogInDialogInterface { - public void logIn(String username, String password); - public void signUp(String username, String password); - public void cancelLoginOrSignup(); - } - - LogInDialogInterface interface_with_Dashboard; - - /** - * @return a new instance of this DialogFragment. - */ - public static DialogFragment newInstance() { - if(dialog == null) - dialog = new LogInDialog(); - - return dialog; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - interface_with_Dashboard = (LogInDialogInterface) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() - + " must implement LogInDialogListener"); - } - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - if(is_eip_pending) - interface_with_Dashboard.cancelLoginOrSignup(); - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java deleted file mode 100644 index 875b76d7..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListFragment.java +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.ListFragment; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListView; - -import butterknife.ButterKnife; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; - -/** - * A list fragment representing a list of Providers. This fragment - * also supports tablet devices by allowing list items to be given an - * 'activated' state upon selection. - *

- * Activities containing this fragment MUST implement the {@link Callbacks} - * interface. - */ -public class ProviderListFragment extends ListFragment { - - public static String TAG = "provider_list_fragment"; - public static String SHOW_ALL_PROVIDERS = "show_all_providers"; - public static String TOP_PADDING = "top padding from providerlistfragment"; - private ProviderListAdapter content_adapter; - - /** - * The serialization (saved instance state) Bundle key representing the - * activated item position. Only used on tablets. - */ - private static final String STATE_ACTIVATED_POSITION = "activated_position"; - - /** - * The fragment's current callback object, which is notified of list item - * clicks. - */ - private Callbacks mCallbacks = sDummyCallbacks; - - /** - * The current activated item position. Only used on tablets. - */ - private int mActivatedPosition = ListView.INVALID_POSITION; - - /** - * A callback interface that all activities containing this fragment must - * implement. This mechanism allows activities to be notified of item - * selections. - */ - public interface Callbacks { - /** - * Callback for when an item has been selected. - */ - public void onItemSelected(String id); - } - - /** - * A dummy implementation of the {@link Callbacks} interface that does - * nothing. Used only when this fragment is not attached to an activity. - */ - private static Callbacks sDummyCallbacks = new Callbacks() { - @Override - public void onItemSelected(String id) { - } - }; - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public ProviderListFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - View view = inflater.inflate(R.layout.provider_list_fragment, container, false); - ButterKnife.inject(this, view); - return view; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - // Restore the previously serialized activated item position. - if (savedInstanceState != null - && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { - setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); - } - if(getArguments() != null && getArguments().containsKey(TOP_PADDING)) { - int topPadding = getArguments().getInt(TOP_PADDING); - View current_view = getView(); - current_view.setPadding(current_view.getPaddingLeft(), topPadding, current_view.getPaddingRight(), current_view.getPaddingBottom()); - } - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - // Activities containing this fragment must implement its callbacks. - if (!(activity instanceof Callbacks)) { - throw new IllegalStateException("Activity must implement fragment's callbacks."); - } - - mCallbacks = (Callbacks) activity; - } - - @Override - public void onDetach() { - super.onDetach(); - - // Reset the active callbacks interface to the dummy implementation. - mCallbacks = sDummyCallbacks; - } - - @Override - public void onListItemClick(ListView listView, View view, int position, long id) { - super.onListItemClick(listView, view, position, id); - - // Notify the active callbacks interface (the activity, if the - // fragment is attached to one) that an item has been selected. - mCallbacks.onItemSelected(ProviderListContent.ITEMS.get(position).name()); - - for(int item_position = 0; item_position < listView.getCount(); item_position++) { - if(item_position != position) - content_adapter.hide(item_position); - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - if (mActivatedPosition != ListView.INVALID_POSITION) { - // Serialize and persist the activated item position. - outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); - } - } - - public void notifyAdapter() { - content_adapter.notifyDataSetChanged(); - } - /** - * Turns on activate-on-click mode. When this mode is on, list items will be - * given the 'activated' state when touched. - */ - public void setActivateOnItemClick(boolean activateOnItemClick) { - // When setting CHOICE_MODE_SINGLE, ListView will automatically - // give items the 'activated' state when touched. - getListView().setChoiceMode(activateOnItemClick - ? ListView.CHOICE_MODE_SINGLE - : ListView.CHOICE_MODE_NONE); - } - - private void setActivatedPosition(int position) { - if (position == ListView.INVALID_POSITION) { - getListView().setItemChecked(mActivatedPosition, false); - } else { - getListView().setItemChecked(position, true); - } - - mActivatedPosition = position; - } - - public void removeLastItem() { - content_adapter.remove(content_adapter.getItem(content_adapter.getCount()-1)); - content_adapter.notifyDataSetChanged(); - } - - public void addItem(Provider provider) { - content_adapter.add(provider); - content_adapter.notifyDataSetChanged(); - } - - public void hideAllBut(int position) { - int real_count = content_adapter.getCount(); - for(int i = 0; i < real_count;) - if(i != position) { - content_adapter.hide(i); - position--; - real_count--; - } else { - i++; - } - } - - /** - * @return a new instance of this ListFragment. - */ - public static ProviderListFragment newInstance() { - return new ProviderListFragment(); - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java new file mode 100644 index 00000000..9676faa8 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Implements the log in dialog, currently without progress dialog. + * + * It returns to the previous fragment when finished, and sends username and password to the authenticate method. + * + * It also notifies the user if the password is not valid. + * + * @author parmegv + * + */ +public class SessionDialog extends DialogFragment{ + + + final public static String TAG = SessionDialog.class.getSimpleName(); + + final public static String USERNAME = "username"; + final public static String PASSWORD = "password"; + final public static String USERNAME_MISSING = "username missing"; + final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; + + @InjectView(R.id.user_message) + TextView user_message; + @InjectView(R.id.username_entered) + EditText username_field; + @InjectView(R.id.password_entered) + EditText password_field; + + private static SessionDialog dialog; + + private static boolean is_eip_pending = false; + + public AlertDialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + View view = inflater.inflate(R.layout.session_dialog, null); + ButterKnife.inject(this, view); + + if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { + password_field.requestFocus(); + } + + Bundle arguments = getArguments(); + if (arguments != null) { + is_eip_pending = arguments.getBoolean(EipServiceFragment.IS_PENDING, false); + if (arguments.containsKey(PASSWORD_INVALID_LENGTH)) + password_field.setError(getString(R.string.error_not_valid_password_user_message)); + if (arguments.containsKey(USERNAME)) { + String username = arguments.getString(USERNAME); + username_field.setText(username); + } + if (arguments.containsKey(USERNAME_MISSING)) { + username_field.setError(getString(R.string.username_ask)); + } + if(arguments.containsKey(getString(R.string.user_message))) + user_message.setText(arguments.getString(getString(R.string.user_message))); + else + user_message.setVisibility(View.GONE); + } + + builder.setView(view) + .setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + String username = username_field.getText().toString(); + String password = password_field.getText().toString(); + dialog.dismiss(); + interface_with_Dashboard.logIn(username, password); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + interface_with_Dashboard.cancelLoginOrSignup(); + } + }) + .setNeutralButton(R.string.signup_button, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + String username = username_field.getText().toString(); + String password = password_field.getText().toString(); + interface_with_Dashboard.signUp(username, password); + } + }); + + return builder.create(); + } + + + /** + * Interface used to communicate SessionDialog with Dashboard. + * + * @author parmegv + * + */ + public interface LogInDialogInterface { + public void logIn(String username, String password); + public void signUp(String username, String password); + public void cancelLoginOrSignup(); + } + + LogInDialogInterface interface_with_Dashboard; + + /** + * @return a new instance of this DialogFragment. + */ + public static DialogFragment newInstance() { + if(dialog == null) + dialog = new SessionDialog(); + + return dialog; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + interface_with_Dashboard = (LogInDialogInterface) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement LogInDialogListener"); + } + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + if(is_eip_pending) + interface_with_Dashboard.cancelLoginOrSignup(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java deleted file mode 100644 index 66b86ccd..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.DialogFragment; -import android.content.DialogInterface; - -/** - * @author parmegv - */ -public abstract class SessionDialogInterface extends DialogFragment { - final public static String USERNAME = "username"; - final public static String PASSWORD = "password"; - final public static String USERNAME_MISSING = "username missing"; - final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; - - @Override - public void onAttach(Activity activity) { super.onAttach(activity); } - - @Override - public void onCancel(DialogInterface dialog) { super.onCancel(dialog); } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java deleted file mode 100644 index f6d6cc3f..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.EditText; -import android.widget.TextView; - -/** - * Implements the sign up dialog, currently without progress dialog. - * - * It returns to the previous fragment when finished, and sends username and password to the registration method. - * - * It also notifies the user if the password is not valid. - * - * @author parmegv - * - */ -public class SignUpDialog extends SessionDialogInterface { - - final public static String TAG = SignUpDialog.class.getSimpleName(); - - private static SignUpDialog dialog; - private static boolean is_eip_pending = false; - - public AlertDialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - LayoutInflater inflater = getActivity().getLayoutInflater(); - View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); - - final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); - final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); - final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); - - if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { - password_field.requestFocus(); - } - if (getArguments() != null) { - is_eip_pending = getArguments().getBoolean(EipServiceFragment.IS_PENDING, false); - if (getArguments().containsKey(PASSWORD_INVALID_LENGTH)) - password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); - if(getArguments().containsKey(USERNAME_MISSING)) - username_field.setError(getResources().getString(R.string.username_ask)); - if(getArguments().containsKey(USERNAME)) { - String username = getArguments().getString(USERNAME); - username_field.setText(username); - } - if(getArguments().containsKey(getResources().getString(R.string.user_message))) - user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); - else - user_message.setVisibility(View.GONE); - } - - builder.setView(log_in_dialog_view) - .setPositiveButton(R.string.signup_button, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - String username = username_field.getText().toString(); - String password = password_field.getText().toString(); - dialog.dismiss(); - interface_with_Dashboard.signUp(username, password); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - interface_with_Dashboard.cancelLoginOrSignup(); - } - }); - - return builder.create(); - } - - /** - * Interface used to communicate SignUpDialog with Dashboard. - * - * @author parmegv - * - */ - public interface SignUpDialogInterface { - public void signUp(String username, String password); - public void cancelLoginOrSignup(); - } - - SignUpDialogInterface interface_with_Dashboard; - - /** - * @return a new instance of this DialogFragment. - */ - public static DialogFragment newInstance() { - if(dialog == null) - dialog = new SignUpDialog(); - return dialog; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - interface_with_Dashboard = (SignUpDialogInterface) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() - + " must implement SignUpDialogListener"); - } - } - - @Override - public void onCancel(DialogInterface dialog) { - if(is_eip_pending) - interface_with_Dashboard.cancelLoginOrSignup(); - super.onCancel(dialog); - } -} -- cgit v1.2.3 From 2d764ff0261e902e3b41f7f5e1d79df52e51a1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 21:01:50 +0100 Subject: Bug in the add provider to the adapter fixed. Refactored the new provider dialog too. --- app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java index 19a9a089..c63e2edb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListAdapter.java @@ -90,7 +90,7 @@ public class ProviderListAdapter extends RendererAdapter { @Override public void add(Provider item) { super.add(item); - if(getCollection().size() < hidden.length) { + if(getCollection().size() > hidden.length) { boolean[] new_hidden = new boolean[hidden.length + 1]; System.arraycopy(hidden, 0, new_hidden, 0, hidden.length); new_hidden[hidden.length] = false; -- cgit v1.2.3 From 56a998deef38a635e2a2e61dd1f516b78d24c9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 21:30:25 +0100 Subject: SessionDialog restores eip switch if necessary. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 4 +++- app/src/main/java/se/leap/bitmaskclient/SessionDialog.java | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index c7691ed4..3ecf5e52 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -54,7 +54,7 @@ import se.leap.bitmaskclient.eip.EipStatus; * @author Sean Leonard * @author parmegv */ -public class Dashboard extends Activity implements SessionDialog.LogInDialogInterface, ProviderAPIResultReceiver.Receiver { +public class Dashboard extends Activity implements SessionDialog.SessionDialogInterface, ProviderAPIResultReceiver.Receiver { protected static final int CONFIGURE_LEAP = 0; protected static final int SWITCH_PROVIDER = 1; diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index a8ffda72..507cfe74 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -129,7 +129,9 @@ public class EipServiceFragment extends Fragment implements Observer { else if(canLogInToStartEIP()) { Log.d(TAG, "Can Log In to start EIP"); Dashboard dashboard = (Dashboard) parent_activity; - dashboard.logInDialog(Bundle.EMPTY); + Bundle bundle = new Bundle(); + bundle.putBoolean(IS_PENDING, true); + dashboard.logInDialog(bundle); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java index 9676faa8..60382cf0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java @@ -121,13 +121,13 @@ public class SessionDialog extends DialogFragment{ * @author parmegv * */ - public interface LogInDialogInterface { + public interface SessionDialogInterface { public void logIn(String username, String password); public void signUp(String username, String password); public void cancelLoginOrSignup(); } - LogInDialogInterface interface_with_Dashboard; + SessionDialogInterface interface_with_Dashboard; /** * @return a new instance of this DialogFragment. @@ -143,7 +143,7 @@ public class SessionDialog extends DialogFragment{ public void onAttach(Activity activity) { super.onAttach(activity); try { - interface_with_Dashboard = (LogInDialogInterface) activity; + interface_with_Dashboard = (SessionDialogInterface) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement LogInDialogListener"); -- cgit v1.2.3 From 60adae615458f42fe7a36fe9c4faf90e3e463f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 9 Dec 2014 21:46:26 +0100 Subject: Restore eip service UI onResume. --- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 507cfe74..904aa31d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -91,6 +91,7 @@ public class EipServiceFragment extends Fragment implements Observer { public void onResume() { super.onResume(); eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); + handleNewState(eip_status); } @Override -- cgit v1.2.3 From 582758a34f6fd82ad1071bf9a196f0fa048689e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 15 Dec 2014 11:30:28 +0100 Subject: Working on Android 5. Beware! https://code.google.com/p/android/issues/detail?id=80074: Wrong VpnService.prepare() behavior after re-installation of the VPN app on Android 5.0 "The following steps will cause incorrect behavior of the VpnService.prepare(): 1. Establish VPN connection using any VPN app. VpnService.prepare() will return an intent for the "Connection request" system activity. Once user accepts it, VPN connection can be established successfully. 2. Uninstall VPN app. 3. Re-install the same VPN app. 4. Now VpnService.prepare() returns null, as if the VPN service has been already prepared. 5. Now VpnService.protect() returns false and VPN connection fails. Device reboot is needed in order to be able to establish VPN connection again." --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 72 +++++++++++++--------- .../se/leap/bitmaskclient/EipServiceFragment.java | 21 ++----- .../java/se/leap/bitmaskclient/eip/Constants.java | 1 - .../main/java/se/leap/bitmaskclient/eip/EIP.java | 28 ++++----- 4 files changed, 60 insertions(+), 62 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 3ecf5e52..862086eb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -16,6 +16,7 @@ */ package se.leap.bitmaskclient; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; @@ -34,6 +35,7 @@ import android.view.MenuItem; import android.widget.ProgressBar; import android.widget.TextView; +import org.jetbrains.annotations.NotNull; import org.json.JSONException; import org.json.JSONObject; @@ -48,7 +50,7 @@ import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipStatus; /** - * The main user facing Activity of LEAP Android, consisting of status, controls, + * The main user facing Activity of Bitmask Android, consisting of status, controls, * and access to preferences. * * @author Sean Leonard @@ -81,7 +83,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn public ProviderAPIResultReceiver providerAPI_result_receiver; @Override - protected void onSaveInstanceState(Bundle outState) { + protected void onSaveInstanceState(@NotNull Bundle outState) { if(provider != null) outState.putParcelable(Provider.KEY, provider); super.onSaveInstanceState(outState); @@ -99,24 +101,36 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); - if(savedInstanceState != null) - provider = savedInstanceState.getParcelable(Provider.KEY); - if(provider == null && preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) - try { - provider = new Provider(new URL(preferences.getString(Provider.MAIN_URL, ""))); - provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } - + provider = getSavedProvider(savedInstanceState); if (provider == null || provider.getName().isEmpty()) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); } + private Provider getSavedProvider(Bundle savedInstanceState) { + Provider provider = null; + if(savedInstanceState != null) + provider = savedInstanceState.getParcelable(Provider.KEY); + else if(preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) + provider = getSavedProviderFromSharedPreferences(); + + return provider; + } + + private Provider getSavedProviderFromSharedPreferences() { + Provider provider = null; + try { + provider = new Provider(new URL(preferences.getString(Provider.MAIN_URL, ""))); + provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); + } catch (MalformedURLException | JSONException e) { + e.printStackTrace(); + } + + return provider; + } + + private void handleVersion() { try { int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; @@ -140,13 +154,12 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } } + @SuppressLint("CommitPrefEdits") @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ Log.d(TAG, "onActivityResult: requestCode = " + requestCode); if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { - // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { if ( resultCode == RESULT_OK ) { - preferences.edit().putInt(Constants.PARSED_SERIAL, 0).apply(); preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); updateEipService(); @@ -205,7 +218,6 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn ButterKnife.inject(this); provider_name.setText(provider.getDomain()); - if ( provider.hasEIP()){ fragment_manager.removePreviousFragment(EipServiceFragment.TAG); @@ -412,16 +424,16 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn @Override public void onReceiveResult(int resultCode, Bundle resultData) { Log.d(TAG, "onReceiveResult"); - if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL) { + if(resultCode == ProviderAPI.SUCCESSFUL_SIGNUP) { String username = resultData.getString(SessionDialog.USERNAME); String password = resultData.getString(SessionDialog.PASSWORD); logIn(username, password); - } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED) { + } else if(resultCode == ProviderAPI.FAILED_SIGNUP) { changeStatusMessage(resultCode); hideProgressBar(); signUpDialog(resultData); - } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL) { + } else if(resultCode == ProviderAPI.SUCCESSFUL_LOGIN) { changeStatusMessage(resultCode); hideProgressBar(); @@ -431,12 +443,12 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn preferences.edit().putBoolean(Constants.AUTHED_EIP, authed_eip).apply(); downloadAuthedUserCertificate(); - } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { + } else if(resultCode == ProviderAPI.FAILED_LOGIN) { changeStatusMessage(resultCode); hideProgressBar(); logInDialog(resultData); - } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { + } else if(resultCode == ProviderAPI.SUCCESSFUL_LOGOUT) { changeStatusMessage(resultCode); hideProgressBar(); @@ -477,7 +489,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } } }; - updateEIP.putExtra(Constants.RECEIVER_TAG, receiver); + //updateEIP.putExtra(Constants.RECEIVER_TAG, receiver); startService(updateEIP); } @@ -491,11 +503,11 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn if (resultCode == Activity.RESULT_OK){ switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.SUCCESSFUL_LOGIN: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.FAILED_LOGIN: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.authed_secured_status); break; case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: eip_fragment.status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.SUCCESSFUL_LOGOUT: eip_fragment.status_message.setText(R.string.logged_out_message); break; case ProviderAPI.LOGOUT_FAILED: eip_fragment.status_message.setText(R.string.log_out_failed_message); break; } @@ -504,12 +516,12 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn switch(previous_result_code){ - case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; - case ProviderAPI.SRP_AUTHENTICATION_FAILED: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; - case ProviderAPI.SRP_REGISTRATION_FAILED: eip_fragment.status_message.setText(R.string.registration_failed_message); break; + case ProviderAPI.SUCCESSFUL_LOGIN: eip_fragment.status_message.setText(R.string.succesful_authentication_message); break; + case ProviderAPI.FAILED_LOGIN: eip_fragment.status_message.setText(R.string.authentication_failed_message); break; + case ProviderAPI.FAILED_SIGNUP: eip_fragment.status_message.setText(R.string.registration_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eip_fragment.status_message.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: eip_fragment.status_message.setText(R.string.logged_out_message); break; + case ProviderAPI.SUCCESSFUL_LOGOUT: eip_fragment.status_message.setText(R.string.logged_out_message); break; case ProviderAPI.LOGOUT_FAILED: eip_fragment.status_message.setText(R.string.log_out_failed_message); break; } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 904aa31d..acfc967b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -139,7 +139,7 @@ public class EipServiceFragment extends Fragment implements Observer { private boolean canStartEIP() { boolean certificateExists = !Dashboard.preferences.getString(Constants.CERTIFICATE, "").isEmpty(); boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); - return (isAllowedAnon || certificateExists) && !eip_status.isConnected(); + return (isAllowedAnon || certificateExists) && !eip_status.isConnected() && !eip_status.isConnecting(); } private boolean canLogInToStartEIP() { @@ -275,19 +275,13 @@ public class EipServiceFragment extends Fragment implements Observer { adjustSwitch(); } - protected void setStatusMessage(String status) { - if(status_message == null) - status_message = (TextView) parent_activity.findViewById(R.id.status_message); - status_message.setText(status); - } - private void hideProgressBar() { if(progress_bar != null) progress_bar.setVisibility(View.GONE); } protected class EIPReceiver extends ResultReceiver { - + protected EIPReceiver(Handler handler){ super(handler); } @@ -295,17 +289,14 @@ public class EipServiceFragment extends Fragment implements Observer { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - + String request = resultData.getString(Constants.REQUEST_TAG); if (request.equals(Constants.ACTION_START_EIP)) { switch (resultCode){ case Activity.RESULT_OK: - Log.d(TAG, "Action start eip = Result OK"); - progress_bar.setVisibility(View.VISIBLE); break; case Activity.RESULT_CANCELED: - progress_bar.setVisibility(View.GONE); break; } } else if (request.equals(Constants.ACTION_STOP_EIP)) { @@ -336,13 +327,13 @@ public class EipServiceFragment extends Fragment implements Observer { status_message.setText(getString(R.string.updating_certificate_message)); if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { dashboard.logInDialog(Bundle.EMPTY); - } else { + } else { Intent provider_API_command = new Intent(parent_activity, ProviderAPI.class); if(dashboard.providerAPI_result_receiver == null) { dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); dashboard.providerAPI_result_receiver.setReceiver(dashboard); } - + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); parent_activity.startService(provider_API_command); @@ -352,7 +343,7 @@ public class EipServiceFragment extends Fragment implements Observer { } } } - + public static EIPReceiver getReceiver() { return mEIPReceiver; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java index 01a83d5f..12c2e015 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Constants.java @@ -39,7 +39,6 @@ public interface Constants { public final static String CERTIFICATE = "cert"; public final static String PRIVATE_KEY = TAG + ".PRIVATE_KEY"; public final static String KEY = TAG + ".KEY"; - public final static String PARSED_SERIAL = TAG + ".PARSED_SERIAL"; public final static String RECEIVER_TAG = TAG + ".RECEIVER_TAG"; public final static String REQUEST_TAG = TAG + ".REQUEST_TAG"; public final static String START_BLOCKING_VPN_PROFILE = TAG + ".START_BLOCKING_VPN_PROFILE"; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 4363dd13..0713e521 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; import android.os.ResultReceiver; import android.util.Log; @@ -38,7 +39,6 @@ import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ProfileManager; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.EipServiceFragment; -import se.leap.bitmaskclient.Provider; import static se.leap.bitmaskclient.eip.Constants.ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.eip.Constants.ACTION_IS_EIP_RUNNING; @@ -65,20 +65,19 @@ public final class EIP extends IntentService { public final static String TAG = EIP.class.getSimpleName(); public final static String SERVICE_API_PATH = "config/eip-service.json"; - public static final int DISCONNECT = 15; private static Context context; private static ResultReceiver mReceiver; private static SharedPreferences preferences; - private static JSONObject eip_definition = null; + private static JSONObject eip_definition; private static List gateways = new ArrayList(); private static ProfileManager profile_manager; - private static Gateway activeGateway = null; + private static Gateway gateway; public EIP(){ - super("LEAPEIP"); + super(TAG); } @Override @@ -117,13 +116,15 @@ public final class EIP extends IntentService { private void startEIP() { if(gateways.isEmpty()) updateEIPService(); - GatewaySelector gateway_selector = new GatewaySelector(gateways); - activeGateway = gateway_selector.select(); - if(activeGateway != null && activeGateway.getProfile() != null) { + earlyRoutes(); + + GatewaySelector gateway_selector = new GatewaySelector(gateways); + gateway = gateway_selector.select(); + if(gateway != null && gateway.getProfile() != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } - earlyRoutes(); + tellToReceiver(ACTION_START_EIP, Activity.RESULT_OK); } /** @@ -140,16 +141,11 @@ public final class EIP extends IntentService { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.getProfile().getName() ); + intent.putExtra(LaunchVPN.EXTRA_NAME, gateway.getProfile().getName()); intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); - intent.putExtra(RECEIVER_TAG, mReceiver); startActivity(intent); } - - /** - * Disconnects the EIP connection gracefully through the bound service or forcefully - * if there is no bound service. Sends a message to the requesting ResultReceiver. - */ + private void stopEIP() { EipStatus eip_status = EipStatus.getInstance(); Log.d(TAG, "stopEip(): eip is connected? " + eip_status.isConnected()); -- cgit v1.2.3 From ceb9128fcd03aba3454faa3979f45490252749b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 15 Dec 2014 12:45:50 +0100 Subject: Starting to connect EIP means ConnectedUI --- .../java/se/leap/bitmaskclient/EipServiceFragment.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index acfc967b..1b40c94c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -47,6 +47,7 @@ public class EipServiceFragment extends Fragment implements Observer { private static Activity parent_activity; private static EIPReceiver mEIPReceiver; private static EipStatus eip_status; + private boolean is_starting_to_connect; @Override public void onAttach(Activity activity) { @@ -178,6 +179,7 @@ public class EipServiceFragment extends Fragment implements Observer { } public void startEipFromScratch() { + is_starting_to_connect = true; progress_bar.setVisibility(View.VISIBLE); eip_switch.setVisibility(View.VISIBLE); String status = parent_activity.getString(R.string.eip_status_start_pending); @@ -230,18 +232,19 @@ public class EipServiceFragment extends Fragment implements Observer { Log.d(TAG, "handleNewState: " + eip_status.toString()); if(eip_status.wantsToDisconnect()) setDisconnectedUI(); + else if(eip_status.isConnecting() || is_starting_to_connect) + setInProgressUI(eip_status); else if (eip_status.isConnected()) setConnectedUI(); else if (eip_status.isDisconnected() && !eip_status.isConnecting()) setDisconnectedUI(); - else - setInProgressUI(eip_status); } private void setConnectedUI() { hideProgressBar(); Log.d(TAG, "setConnectedUi? " + eip_status.isConnected()); adjustSwitch(); + is_starting_to_connect = false; status_message.setText(parent_activity.getString(R.string.eip_state_connected)); } @@ -252,14 +255,14 @@ public class EipServiceFragment extends Fragment implements Observer { } private void adjustSwitch() { - if(eip_status.isConnected() || eip_status.isConnecting()) { - Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked? " + eip_switch.isChecked()); + if(eip_status.isConnected() || eip_status.isConnecting() || is_starting_to_connect) { + Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked"); if(!eip_switch.isChecked()) { eip_switch.setChecked(true); } } else { Log.d(TAG, "adjustSwitch, !isConnected && !isConnecting? " + eip_status.toString()); - + if(eip_switch.isChecked()) { eip_switch.setChecked(false); } @@ -272,6 +275,7 @@ public class EipServiceFragment extends Fragment implements Observer { String prefix = parent_activity.getString(localizedResId); status_message.setText(prefix + " " + logmessage); + is_starting_to_connect = false; adjustSwitch(); } -- cgit v1.2.3 From 8cad9be37713870882541ddd382cb94640142879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 11 Dec 2014 12:59:33 +0100 Subject: No duplicates between preseeded and custom --- app/src/main/java/se/leap/bitmaskclient/Provider.java | 5 +++-- app/src/main/java/se/leap/bitmaskclient/ProviderManager.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index f22a4bfb..d7ff6633 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -35,6 +35,7 @@ import java.util.Locale; /** * @author Sean Leonard + * @author Parménides GV * */ public final class Provider implements Parcelable { @@ -187,7 +188,7 @@ public final class Provider implements Parcelable { public boolean equals(Object o) { if(o instanceof Provider) { Provider p = (Provider) o; - return p.mainUrl().equals(mainUrl()); + return p.mainUrl().getHost().equals(mainUrl().getHost()); } else return false; } @@ -203,6 +204,6 @@ public final class Provider implements Parcelable { @Override public int hashCode() { - return main_url.hashCode(); + return mainUrl().getHost().hashCode(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java index 911144f7..69bd7c1e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java @@ -136,7 +136,8 @@ public class ProviderManager implements AdapteeCollection { @Override public void add(Provider element) { - custom_providers.add(element); + if(!default_providers.contains(element)) + custom_providers.add(element); } @Override -- cgit v1.2.3 From 9f146deb3448815fccc1637c00588e0dfb23293e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 15 Dec 2014 20:45:55 +0100 Subject: Delete gateways from profilemanager and from list. --- app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 0713e521..7db35c17 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -195,6 +195,7 @@ public final class EIP extends IntentService { private void deleteAllVpnProfiles() { Collection profiles = profile_manager.getProfiles(); profiles.removeAll(profiles); + gateways.clear(); } /** -- cgit v1.2.3 From 132b62695b021b61d1774944a7bfa6e9166d3ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 16 Dec 2014 16:58:07 +0100 Subject: Update eip-service.json each EipFragment.onAttach --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 19 +- .../java/se/leap/bitmaskclient/EipFragment.java | 354 ++++++++++++++++++++ .../se/leap/bitmaskclient/EipServiceFragment.java | 355 --------------------- .../java/se/leap/bitmaskclient/SessionDialog.java | 2 +- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 5 +- 5 files changed, 370 insertions(+), 365 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/EipFragment.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 862086eb..cca9c63c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -77,7 +77,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn @InjectView(R.id.providerName) TextView provider_name; - EipServiceFragment eip_fragment; + EipFragment eip_fragment; private Provider provider; private static boolean authed_eip; public ProviderAPIResultReceiver providerAPI_result_receiver; @@ -220,17 +220,17 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn provider_name.setText(provider.getDomain()); if ( provider.hasEIP()){ - fragment_manager.removePreviousFragment(EipServiceFragment.TAG); - eip_fragment = new EipServiceFragment(); + fragment_manager.removePreviousFragment(EipFragment.TAG); + eip_fragment = new EipFragment(); if (hide_and_turn_on_eip) { preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); Bundle arguments = new Bundle(); - arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); + arguments.putBoolean(EipFragment.START_ON_BOOT, true); if(eip_fragment != null) eip_fragment.setArguments(arguments); } - fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipServiceFragment.TAG); + fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); if (hide_and_turn_on_eip) { onBackPressed(); @@ -312,7 +312,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn } - private Intent prepareProviderAPICommand() { + protected Intent prepareProviderAPICommand() { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); @@ -474,6 +474,13 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn hideProgressBar(); setResult(RESULT_CANCELED); } + else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) { + setResult(RESULT_OK); + + updateEipService(); + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) { + setResult(RESULT_CANCELED); + } } private void updateEipService() { diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java new file mode 100644 index 00000000..92d2a8bd --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -0,0 +1,354 @@ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.Switch; +import android.widget.TextView; + +import java.util.Observable; +import java.util.Observer; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import butterknife.OnCheckedChanged; +import de.blinkt.openvpn.activities.DisconnectVPN; +import se.leap.bitmaskclient.eip.Constants; +import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; + +public class EipFragment extends Fragment implements Observer { + + public static String TAG = EipFragment.class.getSimpleName(); + + protected static final String IS_PENDING = TAG + ".is_pending"; + protected static final String IS_CONNECTED = TAG + ".is_connected"; + protected static final String STATUS_MESSAGE = TAG + ".status_message"; + public static final String START_ON_BOOT = "start on boot"; + + private View view; + @InjectView(R.id.eipSwitch) + Switch eip_switch; + @InjectView(R.id.status_message) + TextView status_message; + @InjectView(R.id.eipProgress) + ProgressBar progress_bar; + + private static Activity parent_activity; + private static EIPReceiver mEIPReceiver; + private static EipStatus eip_status; + private boolean is_starting_to_connect; + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + parent_activity = activity; + + Dashboard dashboard = (Dashboard) parent_activity; + Intent provider_API_command = dashboard.prepareProviderAPICommand(); + provider_API_command.setAction(ProviderAPI.DOWNLOAD_EIP_SERVICE); + parent_activity.startService(provider_API_command); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + eip_status = EipStatus.getInstance(); + eip_status.addObserver(this); + mEIPReceiver = new EIPReceiver(new Handler()); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + view = inflater.inflate(R.layout.eip_service_fragment, container, false); + ButterKnife.inject(this, view); + + if (eip_status.isConnecting()) + eip_switch.setVisibility(View.VISIBLE); + + Log.d(TAG, "onCreateView, eip_switch is checked? " + eip_switch.isChecked()); + + Bundle arguments = getArguments(); + if(arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT)) + startEipFromScratch(); + + if (savedInstanceState != null) { + status_message.setText(savedInstanceState.getString(STATUS_MESSAGE)); + if(savedInstanceState.getBoolean(IS_PENDING)) + eip_status.setConnecting(); + else if(savedInstanceState.getBoolean(IS_CONNECTED)) { + eip_status.setConnectedOrDisconnected(); + } + } + return view; + } + + @Override + public void onResume() { + super.onResume(); + eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); + handleNewState(eip_status); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putBoolean(IS_PENDING, eip_status.isConnecting()); + outState.putBoolean(IS_CONNECTED, eip_status.isConnected()); + Log.d(TAG, "status message onSaveInstanceState = " + status_message.getText().toString()); + outState.putString(STATUS_MESSAGE, status_message.getText().toString()); + super.onSaveInstanceState(outState); + } + + protected void saveEipStatus() { + boolean eip_is_on = false; + Log.d(TAG, "saveEipStatus"); + if(eip_switch.isChecked()) { + eip_is_on = true; + } + + if(parent_activity != null) + Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); + } + + @OnCheckedChanged(R.id.eipSwitch) + void handleSwitch(boolean isChecked) { + if(isChecked) + handleSwitchOn(); + else + handleSwitchOff(); + + saveEipStatus(); + } + + private void handleSwitchOn() { + if(canStartEIP()) + startEipFromScratch(); + else if(canLogInToStartEIP()) { + Log.d(TAG, "Can Log In to start EIP"); + Dashboard dashboard = (Dashboard) parent_activity; + Bundle bundle = new Bundle(); + bundle.putBoolean(IS_PENDING, true); + dashboard.logInDialog(bundle); + } + } + + private boolean canStartEIP() { + boolean certificateExists = !Dashboard.preferences.getString(Constants.CERTIFICATE, "").isEmpty(); + boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); + return (isAllowedAnon || certificateExists) && !eip_status.isConnected() && !eip_status.isConnecting(); + } + + private boolean canLogInToStartEIP() { + boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.ALLOWED_REGISTERED, false); + boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); + Log.d(TAG, "Allow registered? " + isAllowedRegistered); + Log.d(TAG, "Is logged in? " + isLoggedIn); + return isAllowedRegistered && !isLoggedIn && !eip_status.isConnecting() && !eip_status.isConnected(); + } + + private void handleSwitchOff() { + if(eip_status.isConnecting()) { + askPendingStartCancellation(); + } else if(eip_status.isConnected()) { + stopEIP(); + } + } + + private void askPendingStartCancellation() { + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(parent_activity); + alertBuilder.setTitle(parent_activity.getString(R.string.eip_cancel_connect_title)) + .setMessage(parent_activity.getString(R.string.eip_cancel_connect_text)) + .setPositiveButton((R.string.yes), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + stopEIP(); + } + }) + .setNegativeButton(parent_activity.getString(R.string.no), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + eip_switch.setChecked(true); + } + }) + .show(); + } + + public void startEipFromScratch() { + is_starting_to_connect = true; + progress_bar.setVisibility(View.VISIBLE); + eip_switch.setVisibility(View.VISIBLE); + String status = parent_activity.getString(R.string.eip_status_start_pending); + status_message.setText(status); + + if(!eip_switch.isChecked()) { + eip_switch.setChecked(true); + saveEipStatus(); + } + eipCommand(Constants.ACTION_START_EIP); + } + + protected void stopEIP() { + hideProgressBar(); + + String status = parent_activity.getString(R.string.eip_state_not_connected); + status_message.setText(status); + eipCommand(Constants.ACTION_STOP_EIP); + } + + /** + * Send a command to EIP + * + * @param action A valid String constant from EIP class representing an Intent + * filter for the EIP class + */ + private void eipCommand(String action){ + // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? + Intent vpn_intent = new Intent(parent_activity.getApplicationContext(), EIP.class); + vpn_intent.setAction(action); + vpn_intent.putExtra(Constants.RECEIVER_TAG, mEIPReceiver); + parent_activity.startService(vpn_intent); + } + + @Override + public void update (Observable observable, Object data) { + if(observable instanceof EipStatus) { + eip_status = (EipStatus) observable; + final EipStatus eip_status = (EipStatus) observable; + parent_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + handleNewState(eip_status); + } + }); + } + } + + private void handleNewState(EipStatus eip_status) { + Log.d(TAG, "handleNewState: " + eip_status.toString()); + if(eip_status.wantsToDisconnect()) + setDisconnectedUI(); + else if(eip_status.isConnecting() || is_starting_to_connect) + setInProgressUI(eip_status); + else if (eip_status.isConnected()) + setConnectedUI(); + else if (eip_status.isDisconnected() && !eip_status.isConnecting()) + setDisconnectedUI(); + } + + private void setConnectedUI() { + hideProgressBar(); + Log.d(TAG, "setConnectedUi? " + eip_status.isConnected()); + adjustSwitch(); + is_starting_to_connect = false; + status_message.setText(parent_activity.getString(R.string.eip_state_connected)); + } + + private void setDisconnectedUI(){ + hideProgressBar(); + adjustSwitch(); + status_message.setText(parent_activity.getString(R.string.eip_state_not_connected)); + } + + private void adjustSwitch() { + if(eip_status.isConnected() || eip_status.isConnecting() || is_starting_to_connect) { + Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked"); + if(!eip_switch.isChecked()) { + eip_switch.setChecked(true); + } + } else { + Log.d(TAG, "adjustSwitch, !isConnected && !isConnecting? " + eip_status.toString()); + + if(eip_switch.isChecked()) { + eip_switch.setChecked(false); + } + } + } + + private void setInProgressUI(EipStatus eip_status) { + int localizedResId = eip_status.getLocalizedResId(); + String logmessage = eip_status.getLogMessage(); + String prefix = parent_activity.getString(localizedResId); + + status_message.setText(prefix + " " + logmessage); + is_starting_to_connect = false; + adjustSwitch(); + } + + private void hideProgressBar() { + if(progress_bar != null) + progress_bar.setVisibility(View.GONE); + } + + protected class EIPReceiver extends ResultReceiver { + + protected EIPReceiver(Handler handler){ + super(handler); + } + + @Override + protected void onReceiveResult(int resultCode, Bundle resultData) { + super.onReceiveResult(resultCode, resultData); + + String request = resultData.getString(Constants.REQUEST_TAG); + + if (request.equals(Constants.ACTION_START_EIP)) { + switch (resultCode){ + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + } else if (request.equals(Constants.ACTION_STOP_EIP)) { + switch (resultCode){ + case Activity.RESULT_OK: + Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); + parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); + eip_status.setDisconnecting(); + break; + case Activity.RESULT_CANCELED: + break; + } + } else if (request.equals(Constants.EIP_NOTIFICATION)) { + switch (resultCode){ + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + } else if (request.equals(Constants.ACTION_CHECK_CERT_VALIDITY)) { + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + Dashboard dashboard = (Dashboard) parent_activity; + + progress_bar.setVisibility(View.VISIBLE); + status_message.setText(getString(R.string.updating_certificate_message)); + if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { + dashboard.logInDialog(Bundle.EMPTY); + } else { + Intent provider_API_command = dashboard.prepareProviderAPICommand(); + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + parent_activity.startService(provider_API_command); + } + break; + } + } + } + } + + + public static EIPReceiver getReceiver() { + return mEIPReceiver; + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java deleted file mode 100644 index 1b40c94c..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ /dev/null @@ -1,355 +0,0 @@ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.Switch; -import android.widget.TextView; - -import java.util.Observable; -import java.util.Observer; - -import butterknife.ButterKnife; -import butterknife.InjectView; -import butterknife.OnCheckedChanged; -import de.blinkt.openvpn.activities.DisconnectVPN; -import se.leap.bitmaskclient.eip.Constants; -import se.leap.bitmaskclient.eip.EIP; -import se.leap.bitmaskclient.eip.EipStatus; - -public class EipServiceFragment extends Fragment implements Observer { - - public static String TAG = "se.leap.bitmask.EipServiceFragment"; - - protected static final String IS_PENDING = TAG + ".is_pending"; - protected static final String IS_CONNECTED = TAG + ".is_connected"; - protected static final String STATUS_MESSAGE = TAG + ".status_message"; - public static final String START_ON_BOOT = "start on boot"; - - private View view; - @InjectView(R.id.eipSwitch) - Switch eip_switch; - @InjectView(R.id.status_message) - TextView status_message; - @InjectView(R.id.eipProgress) - ProgressBar progress_bar; - - private static Activity parent_activity; - private static EIPReceiver mEIPReceiver; - private static EipStatus eip_status; - private boolean is_starting_to_connect; - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - parent_activity = activity; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - eip_status = EipStatus.getInstance(); - eip_status.addObserver(this); - mEIPReceiver = new EIPReceiver(new Handler()); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - view = inflater.inflate(R.layout.eip_service_fragment, container, false); - ButterKnife.inject(this, view); - - if (eip_status.isConnecting()) - eip_switch.setVisibility(View.VISIBLE); - - Log.d(TAG, "onCreateView, eip_switch is checked? " + eip_switch.isChecked()); - - Bundle arguments = getArguments(); - if(arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT)) - startEipFromScratch(); - - if (savedInstanceState != null) { - status_message.setText(savedInstanceState.getString(STATUS_MESSAGE)); - if(savedInstanceState.getBoolean(IS_PENDING)) - eip_status.setConnecting(); - else if(savedInstanceState.getBoolean(IS_CONNECTED)) { - eip_status.setConnectedOrDisconnected(); - } - } - return view; - } - - @Override - public void onResume() { - super.onResume(); - eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); - handleNewState(eip_status); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putBoolean(IS_PENDING, eip_status.isConnecting()); - outState.putBoolean(IS_CONNECTED, eip_status.isConnected()); - Log.d(TAG, "status message onSaveInstanceState = " + status_message.getText().toString()); - outState.putString(STATUS_MESSAGE, status_message.getText().toString()); - super.onSaveInstanceState(outState); - } - - protected void saveEipStatus() { - boolean eip_is_on = false; - Log.d(TAG, "saveEipStatus"); - if(eip_switch.isChecked()) { - eip_is_on = true; - } - - if(parent_activity != null) - Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); - } - - @OnCheckedChanged(R.id.eipSwitch) - void handleSwitch(boolean isChecked) { - if(isChecked) - handleSwitchOn(); - else - handleSwitchOff(); - - saveEipStatus(); - } - - private void handleSwitchOn() { - if(canStartEIP()) - startEipFromScratch(); - else if(canLogInToStartEIP()) { - Log.d(TAG, "Can Log In to start EIP"); - Dashboard dashboard = (Dashboard) parent_activity; - Bundle bundle = new Bundle(); - bundle.putBoolean(IS_PENDING, true); - dashboard.logInDialog(bundle); - } - } - - private boolean canStartEIP() { - boolean certificateExists = !Dashboard.preferences.getString(Constants.CERTIFICATE, "").isEmpty(); - boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false); - return (isAllowedAnon || certificateExists) && !eip_status.isConnected() && !eip_status.isConnecting(); - } - - private boolean canLogInToStartEIP() { - boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.ALLOWED_REGISTERED, false); - boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); - Log.d(TAG, "Allow registered? " + isAllowedRegistered); - Log.d(TAG, "Is logged in? " + isLoggedIn); - return isAllowedRegistered && !isLoggedIn && !eip_status.isConnecting() && !eip_status.isConnected(); - } - - private void handleSwitchOff() { - if(eip_status.isConnecting()) { - askPendingStartCancellation(); - } else if(eip_status.isConnected()) { - stopEIP(); - } - } - - private void askPendingStartCancellation() { - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(parent_activity); - alertBuilder.setTitle(parent_activity.getString(R.string.eip_cancel_connect_title)) - .setMessage(parent_activity.getString(R.string.eip_cancel_connect_text)) - .setPositiveButton((R.string.yes), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - stopEIP(); - } - }) - .setNegativeButton(parent_activity.getString(R.string.no), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - eip_switch.setChecked(true); - } - }) - .show(); - } - - public void startEipFromScratch() { - is_starting_to_connect = true; - progress_bar.setVisibility(View.VISIBLE); - eip_switch.setVisibility(View.VISIBLE); - String status = parent_activity.getString(R.string.eip_status_start_pending); - status_message.setText(status); - - if(!eip_switch.isChecked()) { - eip_switch.setChecked(true); - saveEipStatus(); - } - eipCommand(Constants.ACTION_START_EIP); - } - - protected void stopEIP() { - hideProgressBar(); - - String status = parent_activity.getString(R.string.eip_state_not_connected); - status_message.setText(status); - eipCommand(Constants.ACTION_STOP_EIP); - } - - /** - * Send a command to EIP - * - * @param action A valid String constant from EIP class representing an Intent - * filter for the EIP class - */ - private void eipCommand(String action){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent vpn_intent = new Intent(parent_activity.getApplicationContext(), EIP.class); - vpn_intent.setAction(action); - vpn_intent.putExtra(Constants.RECEIVER_TAG, mEIPReceiver); - parent_activity.startService(vpn_intent); - } - - @Override - public void update (Observable observable, Object data) { - if(observable instanceof EipStatus) { - eip_status = (EipStatus) observable; - final EipStatus eip_status = (EipStatus) observable; - parent_activity.runOnUiThread(new Runnable() { - @Override - public void run() { - handleNewState(eip_status); - } - }); - } - } - - private void handleNewState(EipStatus eip_status) { - Log.d(TAG, "handleNewState: " + eip_status.toString()); - if(eip_status.wantsToDisconnect()) - setDisconnectedUI(); - else if(eip_status.isConnecting() || is_starting_to_connect) - setInProgressUI(eip_status); - else if (eip_status.isConnected()) - setConnectedUI(); - else if (eip_status.isDisconnected() && !eip_status.isConnecting()) - setDisconnectedUI(); - } - - private void setConnectedUI() { - hideProgressBar(); - Log.d(TAG, "setConnectedUi? " + eip_status.isConnected()); - adjustSwitch(); - is_starting_to_connect = false; - status_message.setText(parent_activity.getString(R.string.eip_state_connected)); - } - - private void setDisconnectedUI(){ - hideProgressBar(); - adjustSwitch(); - status_message.setText(parent_activity.getString(R.string.eip_state_not_connected)); - } - - private void adjustSwitch() { - if(eip_status.isConnected() || eip_status.isConnecting() || is_starting_to_connect) { - Log.d(TAG, "adjustSwitch, isConnected || isConnecting, is checked"); - if(!eip_switch.isChecked()) { - eip_switch.setChecked(true); - } - } else { - Log.d(TAG, "adjustSwitch, !isConnected && !isConnecting? " + eip_status.toString()); - - if(eip_switch.isChecked()) { - eip_switch.setChecked(false); - } - } - } - - private void setInProgressUI(EipStatus eip_status) { - int localizedResId = eip_status.getLocalizedResId(); - String logmessage = eip_status.getLogMessage(); - String prefix = parent_activity.getString(localizedResId); - - status_message.setText(prefix + " " + logmessage); - is_starting_to_connect = false; - adjustSwitch(); - } - - private void hideProgressBar() { - if(progress_bar != null) - progress_bar.setVisibility(View.GONE); - } - - protected class EIPReceiver extends ResultReceiver { - - protected EIPReceiver(Handler handler){ - super(handler); - } - - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - super.onReceiveResult(resultCode, resultData); - - String request = resultData.getString(Constants.REQUEST_TAG); - - if (request.equals(Constants.ACTION_START_EIP)) { - switch (resultCode){ - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - } else if (request.equals(Constants.ACTION_STOP_EIP)) { - switch (resultCode){ - case Activity.RESULT_OK: - Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); - parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); - eip_status.setDisconnecting(); - break; - case Activity.RESULT_CANCELED: - break; - } - } else if (request.equals(Constants.EIP_NOTIFICATION)) { - switch (resultCode){ - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - } else if (request.equals(Constants.ACTION_CHECK_CERT_VALIDITY)) { - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - Dashboard dashboard = (Dashboard) parent_activity; - - progress_bar.setVisibility(View.VISIBLE); - status_message.setText(getString(R.string.updating_certificate_message)); - if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(Constants.ALLOWED_ANON, false)) { - dashboard.logInDialog(Bundle.EMPTY); - } else { - Intent provider_API_command = new Intent(parent_activity, ProviderAPI.class); - if(dashboard.providerAPI_result_receiver == null) { - dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - dashboard.providerAPI_result_receiver.setReceiver(dashboard); - } - - provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); - parent_activity.startService(provider_API_command); - } - break; - } - } - } - } - - - public static EIPReceiver getReceiver() { - return mEIPReceiver; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java index 60382cf0..22e0f128 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialog.java @@ -72,7 +72,7 @@ public class SessionDialog extends DialogFragment{ Bundle arguments = getArguments(); if (arguments != null) { - is_eip_pending = arguments.getBoolean(EipServiceFragment.IS_PENDING, false); + is_eip_pending = arguments.getBoolean(EipFragment.IS_PENDING, false); if (arguments.containsKey(PASSWORD_INVALID_LENGTH)) password_field.setError(getString(R.string.error_not_valid_password_user_message)); if (arguments.containsKey(USERNAME)) { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 7db35c17..7017e874 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; import android.os.ResultReceiver; import android.util.Log; @@ -38,7 +37,7 @@ import de.blinkt.openvpn.LaunchVPN; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ProfileManager; import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.EipServiceFragment; +import se.leap.bitmaskclient.EipFragment; import static se.leap.bitmaskclient.eip.Constants.ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.eip.Constants.ACTION_IS_EIP_RUNNING; @@ -121,7 +120,7 @@ public final class EIP extends IntentService { GatewaySelector gateway_selector = new GatewaySelector(gateways); gateway = gateway_selector.select(); if(gateway != null && gateway.getProfile() != null) { - mReceiver = EipServiceFragment.getReceiver(); + mReceiver = EipFragment.getReceiver(); launchActiveGateway(); } tellToReceiver(ACTION_START_EIP, Activity.RESULT_OK); -- cgit v1.2.3 From 63ae29d808da4c85c223f2e2b6824322b8fc45df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 17 Dec 2014 12:25:31 +0100 Subject: Stop normal and blocking VPNs correctly --- .../java/se/leap/bitmaskclient/EipFragment.java | 10 ++++++--- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 2 +- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 24 ++++++++++++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index 92d2a8bd..fc412449 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -26,6 +26,7 @@ import de.blinkt.openvpn.activities.DisconnectVPN; import se.leap.bitmaskclient.eip.Constants; import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipStatus; +import se.leap.bitmaskclient.eip.VoidVpnService; public class EipFragment extends Fragment implements Observer { @@ -306,14 +307,17 @@ public class EipFragment extends Fragment implements Observer { case Activity.RESULT_OK: break; case Activity.RESULT_CANCELED: + break; } } else if (request.equals(Constants.ACTION_STOP_EIP)) { switch (resultCode){ case Activity.RESULT_OK: - Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); - parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); - eip_status.setDisconnecting(); + if(eip_status.isConnecting()) + VoidVpnService.stop(); + Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); + parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); + eip_status.setDisconnecting(); break; case Activity.RESULT_CANCELED: break; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 7017e874..3d3070c8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -149,7 +149,7 @@ public final class EIP extends IntentService { EipStatus eip_status = EipStatus.getInstance(); Log.d(TAG, "stopEip(): eip is connected? " + eip_status.isConnected()); int result_code = Activity.RESULT_CANCELED; - if(eip_status.isConnected()) + if(eip_status.isConnected() || eip_status.isConnecting()) result_code = Activity.RESULT_OK; tellToReceiver(ACTION_STOP_EIP, result_code); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index a6f9fe76..0c773208 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -2,14 +2,18 @@ package se.leap.bitmaskclient.eip; import android.content.Intent; import android.net.VpnService; +import android.os.ParcelFileDescriptor; + +import java.io.IOException; public class VoidVpnService extends VpnService { static final String TAG = VoidVpnService.class.getSimpleName(); + static ParcelFileDescriptor fd; @Override public int onStartCommand(Intent intent, int flags, int startId) { - String action = intent.getAction(); + String action = intent != null ? intent.getAction() : ""; if (action == Constants.START_BLOCKING_VPN_PROFILE) { new Thread(new Runnable() { public void run() { @@ -20,7 +24,7 @@ public class VoidVpnService extends VpnService { builder.addRoute("192.168.1.0", 24); builder.addDnsServer("10.42.0.1"); try { - builder.establish(); + fd = builder.establish(); } catch (Exception e) { e.printStackTrace(); } @@ -30,4 +34,20 @@ public class VoidVpnService extends VpnService { } return 0; } + + @Override + public void onRevoke() { + super.onRevoke(); + } + + public static boolean stop() { + try { + fd.close(); + return true; + } catch (IOException | NullPointerException e) { + android.util.Log.d(TAG, "VoidVpnService didn't stop"); + e.printStackTrace(); + return false; + } + } } -- cgit v1.2.3 From 5d05a628fbd833860abfc85bb450186ec8dedf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 17 Dec 2014 12:39:41 +0100 Subject: Small refactor to stop EIP methods. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- .../main/java/se/leap/bitmaskclient/EipFragment.java | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index cca9c63c..e32dbdee 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -292,7 +292,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn if (preferences.getBoolean(Constants.AUTHED_EIP, false)) { logOut(); } - eip_fragment.stopEIP(); + eip_fragment.askToStopEIP(); } preferences.edit().clear().apply(); startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index fc412449..420da7a1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -161,7 +161,7 @@ public class EipFragment extends Fragment implements Observer { if(eip_status.isConnecting()) { askPendingStartCancellation(); } else if(eip_status.isConnected()) { - stopEIP(); + askToStopEIP(); } } @@ -172,7 +172,7 @@ public class EipFragment extends Fragment implements Observer { .setPositiveButton((R.string.yes), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - stopEIP(); + askToStopEIP(); } }) .setNegativeButton(parent_activity.getString(R.string.no), new DialogInterface.OnClickListener() { @@ -198,7 +198,15 @@ public class EipFragment extends Fragment implements Observer { eipCommand(Constants.ACTION_START_EIP); } - protected void stopEIP() { + private void stopEIP() { + if(eip_status.isConnecting()) + VoidVpnService.stop(); + Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); + parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); + eip_status.setDisconnecting(); + } + + protected void askToStopEIP() { hideProgressBar(); String status = parent_activity.getString(R.string.eip_state_not_connected); @@ -313,11 +321,7 @@ public class EipFragment extends Fragment implements Observer { } else if (request.equals(Constants.ACTION_STOP_EIP)) { switch (resultCode){ case Activity.RESULT_OK: - if(eip_status.isConnecting()) - VoidVpnService.stop(); - Intent disconnect_vpn = new Intent(parent_activity, DisconnectVPN.class); - parent_activity.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); - eip_status.setDisconnecting(); + stopEIP(); break; case Activity.RESULT_CANCELED: break; -- cgit v1.2.3