diff options
Diffstat (limited to 'app/src/main/java/se/leap')
4 files changed, 161 insertions, 139 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 8aa09de5..851cd3c4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -66,11 +66,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf final public static String ON_BOOT = "dashboard on boot"; public static final String APP_VERSION = "bitmask version"; - + + private EipServiceFragment eipFragment; private ProgressBar mProgressBar; private TextView eipStatus; private static Context app; - private static SharedPreferences preferences; + protected static SharedPreferences preferences; private static Provider provider; private TextView providerNameTV; @@ -86,9 +87,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf app = this; PRNGFixes.apply(); - // mProgressBar = (ProgressBar) findViewById(R.id.progressbar_dashboard); - // mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - // eipStatus = (TextView) findViewById(R.id.eipStatus); mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); @@ -109,7 +107,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if(lastDetectedVersion == 0) // New install getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(APP_VERSION, versionCode); else if(lastDetectedVersion < versionCode) { - preferences.edit().remove(EIP.STATUS).commit(); } } catch (NameNotFoundException e) { } @@ -193,7 +190,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf FragmentManager fragMan = getFragmentManager(); if ( provider.hasEIP()){ - EipServiceFragment eipFragment = new EipServiceFragment(); + eipFragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().remove(Dashboard.START_ON_BOOT).commit(); Bundle arguments = new Bundle(); @@ -596,10 +593,4 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); mProgressBar.setVisibility(visibility); } - - protected void setEipStatus(int status) { - if(eipStatus == null) - eipStatus = (TextView) findViewById(R.id.eipStatus); - eipStatus.setText(status); - } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 07bc7f9a..7b2a6d95 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -41,6 +41,7 @@ import de.blinkt.openvpn.core.OpenVpnManagementThread; import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; import de.blinkt.openvpn.core.OpenVpnService; 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; @@ -109,6 +110,10 @@ public final class EIP extends IntentService { 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 EIP(){ super("LEAPEIP"); @@ -169,10 +174,6 @@ public final class EIP extends IntentService { Log.d(TAG, "isRunning() = " + is_connected); } - - private boolean isConnected() { - return getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").equalsIgnoreCase("LEVEL_CONNECTED"); - } /** * Initiates an EIP connection by selecting a gateway and preparing and sending an @@ -207,7 +208,9 @@ public final class EIP extends IntentService { Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(disconnect_vpn); - // getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit().remove(EIP.STATUS).commit(); + mIsDisconnecting = true; + lastConnectionStatusLevel = ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user + Log.d(TAG, "mIsDisconnecting = true"); } if (mReceiver != null){ @@ -217,6 +220,10 @@ public final class EIP extends IntentService { } } + 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. diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 04cf18b2..a41f0d19 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -40,10 +40,6 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe private View eipDetail; private TextView eipStatus; - // private boolean eipAutoSwitched = true; - - private boolean mEipStartPending = false; - private static EIPReceiver mEIPReceiver; @@ -60,8 +56,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe View eipSettings = eipFragment.findViewById(R.id.eipSettings); eipSettings.setVisibility(View.GONE); // FIXME too! - if (mEipStartPending) - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + if (EIP.mIsStarting) + eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); eipStatus = (TextView) eipFragment.findViewById(R.id.eipStatus); @@ -81,7 +77,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe mEIPReceiver = new EIPReceiver(new Handler()); if (savedInstanceState != null) - mEipStartPending = savedInstanceState.getBoolean(IS_EIP_PENDING); + EIP.mIsStarting = savedInstanceState.getBoolean(IS_EIP_PENDING); } @Override @@ -91,11 +87,19 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe VpnStatus.addStateListener(this); eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); - - if(isEipConnected()) { - eipSwitch.setChecked(true); - } } + + private void adjustSwitch() { + if(EIP.isConnected()) { + if(!eipSwitch.isChecked()) { + eipSwitch.setChecked(true); + } + } else { + if(eipSwitch.isChecked()) { + eipSwitch.setChecked(false); + } + } + } @Override public void onPause() { @@ -107,7 +111,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putBoolean(IS_EIP_PENDING, mEipStartPending); + outState.putBoolean(IS_EIP_PENDING, EIP.mIsStarting); } protected void saveEipStatus() { @@ -118,87 +122,86 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } if(getActivity() != null) - getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); + Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, eip_is_on).commit(); } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (buttonView.equals(eipSwitch)){ - handleEipSwitch(isChecked); + handleSwitch(isChecked); } } - - private boolean isAllowedAnon() { - return getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getBoolean(EIP.ALLOWED_ANON, false); - } - private boolean isEipConnected() { - return getEIPString(EIP.STATUS).equalsIgnoreCase("LEVEL_CONNECTED"); - } - private String getEIPString(String feature) { - return getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getString(feature, ""); - } - + private boolean canStartEIP() { - return (isAllowedAnon() || !getEIPString(EIP.CERTIFICATE).isEmpty()) && !mEipStartPending && !isEipConnected(); + boolean certificateExists = !Dashboard.preferences.getString(EIP.CERTIFICATE, "").isEmpty(); + boolean isAllowedAnon = Dashboard.preferences.getBoolean(EIP.ALLOWED_ANON, false); + return (isAllowedAnon || certificateExists) && !EIP.mIsStarting && !EIP.isConnected(); } - private void handleEipSwitch(boolean isChecked) { - if(isChecked) { - handleEipSwitchOn(); - } else { - handleEipSwitchOff(); - } + private void handleSwitch(boolean isChecked) { + if(isChecked) + handleSwitchOn(); + else + handleSwitchOff(); + saveEipStatus(); } - private void handleEipSwitchOn() { - if(canStartEIP()) { + private void handleSwitchOn() { + if(canStartEIP()) startEipFromScratch(); - } } - private void handleEipSwitchOff() { - if(mEipStartPending) { - 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)) - .setPositiveButton((R.string.eip_cancel_connect_cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - stopEIP(); - } - }) - .setNegativeButton(getResources().getString(R.string.eip_cancel_connect_cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - eipSwitch.setChecked(true); - } - }) - .show(); - } else if(isEipConnected()) { + private void handleSwitchOff() { + if(EIP.mIsStarting) { + askPendingStartCancellation(); + } else if(EIP.isConnected()) { Log.d(TAG, "Stopping EIP"); stopEIP(); } } + 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)) + .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() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d(TAG, "askPendingStartCancellation checks the switch to true"); + eipSwitch.setChecked(true); + } + }) + .show(); + } + public void startEipFromScratch() { - mEipStartPending = true; - eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - eipStatus.setText(R.string.eip_status_start_pending); + EIP.mIsStarting = true; + eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); + String status = getResources().getString(R.string.eip_status_start_pending); + setEipStatus(status); if(!eipSwitch.isChecked()) { - eipSwitch.setChecked(true); + Log.d(TAG, "startEipFromScratch checks the switch to true"); + eipSwitch.setChecked(true); saveEipStatus(); } eipCommand(EIP.ACTION_START_EIP); } private void stopEIP() { - mEipStartPending = false; + EIP.mIsStarting = false; View eipProgressBar = getActivity().findViewById(R.id.eipProgress); if(eipProgressBar != null) eipProgressBar.setVisibility(View.GONE); - if(eipStatus != null) - eipStatus.setText(R.string.eip_state_not_connected); + + String status = getResources().getString(R.string.eip_state_not_connected); + setEipStatus(status); eipCommand(EIP.ACTION_STOP_EIP); } @@ -216,45 +219,86 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe getActivity().startService(vpn_intent); } - @Override - public void updateState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { - // Note: "states" are not organized anywhere...collected state strings: - // NOPROCESS,NONETWORK,BYTECOUNT,AUTH_FAILED + some parsing thing ( WAIT(?),AUTH,GET_CONFIG,ASSIGN_IP,CONNECTED,SIGINT ) - getActivity().runOnUiThread(new Runnable() { - - @Override - public void run() { - if (eipStatus != null) { - boolean switchState = true; - String statusMessage = ""; - String prefix = getString(localizedResId); - if (level == ConnectionStatus.LEVEL_CONNECTED){ - statusMessage = getString(R.string.eip_state_connected); - getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); - mEipStartPending = 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. - } else if ( (level == ConnectionStatus.LEVEL_NONETWORK || level == ConnectionStatus.LEVEL_NOTCONNECTED || level == ConnectionStatus.LEVEL_AUTH_FAILED) && !mEipStartPending) { - Log.d(TAG, "Not connected updated state"); - statusMessage = getString(R.string.eip_state_not_connected); - if(getActivity() != null && getActivity().findViewById(R.id.eipProgress) != null) - getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); - mEipStartPending = false; //TODO See above - switchState = false; - } else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) { - if(state.equals("AUTH") || state.equals("GET_CONFIG")) - statusMessage = prefix + " " + logmessage; - } else if (level == ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) { - statusMessage = prefix + " " + logmessage; - } - - // eipAutoSwitched = true; - // eipSwitch.setChecked(switchState); - // eipAutoSwitched = false; - eipStatus.setText(statusMessage); - } - } + @Override + public void updateState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { + boolean isNewLevel = EIP.lastConnectionStatusLevel != level; + boolean justDecidedOnDisconnect = EIP.lastConnectionStatusLevel == ConnectionStatus.UNKNOWN_LEVEL; + Log.d(TAG, "update state with level " + level); + if(isNewLevel && !justDecidedOnDisconnect) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + EIP.lastConnectionStatusLevel = level; + handleNewState(state, logmessage, localizedResId, level); + } }); + } else if(justDecidedOnDisconnect && level == ConnectionStatus.LEVEL_CONNECTED) { + EIP.lastConnectionStatusLevel = ConnectionStatus.LEVEL_NOTCONNECTED; + updateState(state, logmessage, localizedResId, level); } + } + private void handleNewState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { + if (level == ConnectionStatus.LEVEL_CONNECTED) + setConnectedUI(); + else if (isDisconnectedLevel(level) && !EIP.mIsStarting) + setDisconnectedUI(); + else if (level == ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET) + setNoServerReplyUI(localizedResId, logmessage); + else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) + setServerReplyUI(state, localizedResId, logmessage); + } + + private boolean isDisconnectedLevel(final ConnectionStatus level) { + return level == ConnectionStatus.LEVEL_NONETWORK || level == ConnectionStatus.LEVEL_NOTCONNECTED || level == 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(); + } + + 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 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); + } + } + + protected void setEipStatus(String status) { + if(eipStatus == null) + eipStatus = (TextView) getActivity().findViewById(R.id.eipStatus); + eipStatus.setText(status); + } + + private void hideProgressBar() { + if(getActivity() != null && getActivity().findViewById(R.id.eipProgress) != null) + getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); + } /** * Inner class for handling messages related to EIP status and control requests @@ -289,7 +333,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe Log.d(TAG, "Action start eip = Result OK"); checked = true; eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); - mEipStartPending = false; + EIP.mIsStarting = false; break; case Activity.RESULT_CANCELED: checked = false; @@ -322,9 +366,10 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe break; case Activity.RESULT_CANCELED: Dashboard dashboard = (Dashboard) getActivity(); - + dashboard.setProgressBarVisibility(ProgressBar.VISIBLE); - dashboard.setEipStatus(R.string.updating_certificate_message); + String status = getResources().getString(R.string.updating_certificate_message); + setEipStatus(status); Intent provider_API_command = new Intent(getActivity(), ProviderAPI.class); if(dashboard.providerAPI_result_receiver == null) { @@ -338,10 +383,6 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe break; } } - - // eipAutoSwitched = true; - // eipSwitch.setChecked(checked); - // eipAutoSwitched = false; } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipStatusReceiver.java b/app/src/main/java/se/leap/bitmaskclient/EipStatusReceiver.java deleted file mode 100644 index 8793cf36..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/EipStatusReceiver.java +++ /dev/null @@ -1,17 +0,0 @@ -package se.leap.bitmaskclient; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - - -public class EipStatusReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals("de.blinkt.openvpn.VPN_STATUS")) { - context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Context.MODE_PRIVATE).edit().putString(EIP.STATUS, intent.getStringExtra("status")).commit(); - } - } -} |