summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/VpnFragment.java')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/VpnFragment.java178
1 files changed, 104 insertions, 74 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java
index f787a955..f1a15efd 100644
--- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java
@@ -16,26 +16,53 @@
*/
package se.leap.bitmaskclient;
-import android.app.*;
-import android.content.*;
-import android.os.*;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.util.Log;
-import android.view.*;
-import android.widget.*;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
-import org.jetbrains.annotations.*;
+import java.util.Observable;
+import java.util.Observer;
-import java.util.*;
-
-import butterknife.*;
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+import butterknife.OnClick;
import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus;
+import mbanje.kurt.fabbutton.FabButton;
import se.leap.bitmaskclient.eip.EIP;
import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.eip.VoidVpnService;
-import se.leap.bitmaskclient.userstatus.FabButton;
+
+import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE;
+import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION;
+import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
+import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
+import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
+import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
+import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
+import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
public class VpnFragment extends Fragment implements Observer {
@@ -43,14 +70,14 @@ public class VpnFragment extends Fragment implements Observer {
public static final String IS_PENDING = TAG + ".is_pending";
protected static final String IS_CONNECTED = TAG + ".is_connected";
- public static final String START_ON_BOOT = "start on boot";
+ public static final String START_EIP_ON_BOOT = "start on boot";
@InjectView(R.id.vpn_status_image)
FabButton vpn_status_image;
@InjectView(R.id.vpn_main_button)
Button main_button;
- private static Dashboard dashboard;
+ private Dashboard dashboard;
private static EIPReceiver eip_receiver;
private static EipStatus eip_status;
private boolean wants_to_connect;
@@ -96,26 +123,19 @@ public class VpnFragment extends Fragment implements Observer {
ButterKnife.inject(this, view);
Bundle arguments = getArguments();
- if (arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT))
+ if (arguments != null && arguments.containsKey(START_EIP_ON_BOOT) && arguments.getBoolean(START_EIP_ON_BOOT)) {
startEipFromScratch();
- if (savedInstanceState != null) restoreState(savedInstanceState);
+ }
return view;
}
- private void restoreState(@NotNull Bundle savedInstanceState) {
- if (savedInstanceState.getBoolean(IS_PENDING))
- eip_status.setConnecting();
- else if (savedInstanceState.getBoolean(IS_CONNECTED))
- eip_status.setConnectedOrDisconnected();
- }
-
@Override
public void onResume() {
super.onResume();
//FIXME: avoid race conditions while checking certificate an logging in at about the same time
//eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY);
- handleNewState(eip_status);
+ handleNewState();
bindOpenVpnService();
}
@@ -127,14 +147,12 @@ public class VpnFragment extends Fragment implements Observer {
@Override
public void onSaveInstanceState(Bundle outState) {
- outState.putBoolean(IS_PENDING, eip_status.isConnecting());
outState.putBoolean(IS_CONNECTED, eip_status.isConnected());
super.onSaveInstanceState(outState);
}
- private void saveStatus() {
- boolean is_on = eip_status.isConnected() || eip_status.isConnecting();
- Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, is_on).commit();
+ private void saveStatus(boolean restartOnBoot) {
+ Dashboard.preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, restartOnBoot).apply();
}
@OnClick(R.id.vpn_main_button)
@@ -143,8 +161,6 @@ public class VpnFragment extends Fragment implements Observer {
handleSwitchOff();
else
handleSwitchOn();
-
- saveStatus();
}
private void handleSwitchOn() {
@@ -153,7 +169,6 @@ public class VpnFragment extends Fragment implements Observer {
else if (canLogInToStartEIP()) {
wants_to_connect = true;
Bundle bundle = new Bundle();
- bundle.putBoolean(IS_PENDING, true);
dashboard.sessionDialog(bundle);
} else {
Log.d(TAG, "WHAT IS GOING ON HERE?!");
@@ -163,13 +178,13 @@ public class VpnFragment extends Fragment implements Observer {
}
private boolean canStartEIP() {
- boolean certificateExists = !Dashboard.preferences.getString(Constants.PROVIDER_VPN_CERTIFICATE, "").isEmpty();
- boolean isAllowedAnon = Dashboard.preferences.getBoolean(Constants.PROVIDER_ALLOW_ANONYMOUS, false);
+ boolean certificateExists = !Dashboard.preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty();
+ boolean isAllowedAnon = Dashboard.preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false);
return (isAllowedAnon || certificateExists) && !eip_status.isConnected() && !eip_status.isConnecting();
}
private boolean canLogInToStartEIP() {
- boolean isAllowedRegistered = Dashboard.preferences.getBoolean(Constants.PROVIDER_ALLOWED_REGISTERED, false);
+ boolean isAllowedRegistered = Dashboard.preferences.getBoolean(PROVIDER_ALLOWED_REGISTERED, false);
boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty();
return isAllowedRegistered && !isLoggedIn && !eip_status.isConnecting() && !eip_status.isConnected();
}
@@ -179,8 +194,9 @@ public class VpnFragment extends Fragment implements Observer {
askPendingStartCancellation();
} else if (eip_status.isConnected()) {
askToStopEIP();
- } else
+ } else {
updateIcon();
+ }
}
private void askPendingStartCancellation() {
@@ -203,25 +219,30 @@ public class VpnFragment extends Fragment implements Observer {
public void startEipFromScratch() {
wants_to_connect = false;
- eip_status.setConnecting();
-
- saveStatus();
- eipCommand(Constants.EIP_ACTION_START);
+ saveStatus(true);
+ eipCommand(EIP_ACTION_START);
}
private void stop() {
- if (eip_status.isConnecting())
- VoidVpnService.stop();
+ saveStatus(false);
+ if (eip_status.isBlockingVpnEstablished()) {
+ stopBlockingVpn();
+ }
disconnect();
}
+ private void stopBlockingVpn() {
+ Log.d(TAG, "stop VoidVpn!");
+ Intent stopVoidVpnIntent = new Intent(dashboard, VoidVpnService.class);
+ stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN);
+ dashboard.startService(stopVoidVpnIntent);
+ }
+
private void disconnect() {
- eip_status.setDisconnecting();
ProfileManager.setConntectedVpnProfileDisconnected(dashboard);
if (mService != null) {
try {
mService.stopVPN(false);
- eip_status.setConnectedOrDisconnected();
} catch (RemoteException e) {
VpnStatus.logException(e);
}
@@ -229,7 +250,8 @@ public class VpnFragment extends Fragment implements Observer {
}
protected void stopEipIfPossible() {
- eipCommand(Constants.EIP_ACTION_STOP);
+ //FIXME: no need to start a service here!
+ eipCommand(EIP_ACTION_STOP);
}
private void downloadEIPServiceConfig() {
@@ -257,7 +279,7 @@ public class VpnFragment extends Fragment implements Observer {
}
protected void updateEipService() {
- eipCommand(Constants.EIP_ACTION_UPDATE);
+ eipCommand(EIP_ACTION_UPDATE);
}
/**
@@ -270,7 +292,7 @@ public class VpnFragment extends Fragment implements Observer {
// TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
Intent vpn_intent = new Intent(dashboard.getApplicationContext(), EIP.class);
vpn_intent.setAction(action);
- vpn_intent.putExtra(Constants.EIP_RECEIVER, eip_receiver);
+ vpn_intent.putExtra(EIP_RECEIVER, eip_receiver);
dashboard.startService(vpn_intent);
}
@@ -278,36 +300,33 @@ public class VpnFragment extends Fragment implements Observer {
public void update(Observable observable, Object data) {
if (observable instanceof EipStatus) {
eip_status = (EipStatus) observable;
- final EipStatus eip_status = (EipStatus) observable;
dashboard.runOnUiThread(new Runnable() {
@Override
public void run() {
- handleNewState(eip_status);
+ handleNewState();
}
});
}
}
- private void handleNewState(EipStatus eip_status) {
- Context context = dashboard.getApplicationContext();
- String error = eip_status.lastError(5, context);
-
- if (!error.isEmpty()) VoidVpnService.stop();
+ private void handleNewState() {
updateIcon();
updateButton();
}
private void updateIcon() {
- if (eip_status.isConnected() || eip_status.isConnecting()) {
- if(eip_status.isConnecting()) {
- vpn_status_image.showProgress(true);
- vpn_status_image.setIcon(R.drawable.ic_stat_vpn_empty_halo, R.drawable.ic_stat_vpn_empty_halo);
- vpn_status_image.setTag(R.drawable.ic_stat_vpn_empty_halo);
- } else {
- vpn_status_image.showProgress(false);
- vpn_status_image.setIcon(R.drawable.ic_stat_vpn, R.drawable.ic_stat_vpn);
- vpn_status_image.setTag(R.drawable.ic_stat_vpn);
- }
+ if (eip_status.isBlocking()) {
+ vpn_status_image.showProgress(false);
+ vpn_status_image.setIcon(R.drawable.ic_stat_vpn_blocking, R.drawable.ic_stat_vpn_blocking);
+ vpn_status_image.setTag(R.drawable.ic_stat_vpn_blocking);
+ } else if (eip_status.isConnecting()) {
+ vpn_status_image.showProgress(true);
+ vpn_status_image.setIcon(R.drawable.ic_stat_vpn_empty_halo, R.drawable.ic_stat_vpn_empty_halo);
+ vpn_status_image.setTag(R.drawable.ic_stat_vpn_empty_halo);
+ } else if (eip_status.isConnected()){
+ vpn_status_image.showProgress(false);
+ vpn_status_image.setIcon(R.drawable.ic_stat_vpn, R.drawable.ic_stat_vpn);
+ vpn_status_image.setTag(R.drawable.ic_stat_vpn);
} else {
vpn_status_image.setIcon(R.drawable.ic_stat_vpn_offline, R.drawable.ic_stat_vpn_offline);
vpn_status_image.setTag(R.drawable.ic_stat_vpn_offline);
@@ -316,17 +335,28 @@ public class VpnFragment extends Fragment implements Observer {
}
private void updateButton() {
- if (eip_status.isConnected() || eip_status.isConnecting()) {
- if(eip_status.isConnecting()) {
- main_button.setText(dashboard.getString(android.R.string.cancel));
- } else {
- main_button.setText(dashboard.getString(R.string.vpn_button_turn_off));
- }
+ if (eip_status.isConnecting()) {
+ main_button.setText(dashboard.getString(android.R.string.cancel));
+ } else if (eip_status.isConnected() || isOpenVpnRunningWithoutNetwork()) {
+ main_button.setText(dashboard.getString(R.string.vpn_button_turn_off));
} else {
main_button.setText(dashboard.getString(R.string.vpn_button_turn_on));
}
}
+ private boolean isOpenVpnRunningWithoutNetwork() {
+ boolean isRunning = false;
+ try {
+ isRunning = eip_status.getLevel() == LEVEL_NONETWORK &&
+ mService.isVpnRunning();
+ } catch (Exception e) {
+ //eat me
+ e.printStackTrace();
+ }
+
+ return isRunning;
+ }
+
private void bindOpenVpnService() {
Intent intent = new Intent(dashboard, OpenVPNService.class);
intent.setAction(OpenVPNService.START_SERVICE);
@@ -343,9 +373,9 @@ public class VpnFragment extends Fragment implements Observer {
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
- String request = resultData.getString(Constants.EIP_REQUEST);
+ String request = resultData.getString(EIP_REQUEST);
- if (request.equals(Constants.EIP_ACTION_START)) {
+ if (request.equals(EIP_ACTION_START)) {
switch (resultCode) {
case Activity.RESULT_OK:
break;
@@ -353,7 +383,7 @@ public class VpnFragment extends Fragment implements Observer {
break;
}
- } else if (request.equals(Constants.EIP_ACTION_STOP)) {
+ } else if (request.equals(EIP_ACTION_STOP)) {
switch (resultCode) {
case Activity.RESULT_OK:
stop();
@@ -361,14 +391,14 @@ public class VpnFragment extends Fragment implements Observer {
case Activity.RESULT_CANCELED:
break;
}
- } else if (request.equals(Constants.EIP_NOTIFICATION)) {
+ } else if (request.equals(EIP_NOTIFICATION)) {
switch (resultCode) {
case Activity.RESULT_OK:
break;
case Activity.RESULT_CANCELED:
break;
}
- } else if (request.equals(Constants.EIP_ACTION_CHECK_CERT_VALIDITY)) {
+ } else if (request.equals(EIP_ACTION_CHECK_CERT_VALIDITY)) {
switch (resultCode) {
case Activity.RESULT_OK:
break;
@@ -376,14 +406,14 @@ public class VpnFragment extends Fragment implements Observer {
dashboard.downloadVpnCertificate();
break;
}
- } else if (request.equals(Constants.EIP_ACTION_UPDATE)) {
+ } else if (request.equals(EIP_ACTION_UPDATE)) {
switch (resultCode) {
case Activity.RESULT_OK:
if (wants_to_connect)
startEipFromScratch();
break;
case Activity.RESULT_CANCELED:
- handleNewState(eip_status);
+ handleNewState();
break;
}
}