summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Dashboard.java275
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipFragment.java37
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Provider.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/User.java41
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java70
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java3
7 files changed, 279 insertions, 158 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
index 04385ddd..face6ced 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
@@ -28,6 +28,7 @@ import android.widget.*;
import org.jetbrains.annotations.NotNull;
import org.json.*;
import java.net.*;
+import java.util.*;
import butterknife.*;
import de.blinkt.openvpn.activities.*;
@@ -40,7 +41,7 @@ import se.leap.bitmaskclient.eip.*;
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author parmegv
*/
-public class Dashboard extends Activity implements SessionDialog.SessionDialogInterface, ProviderAPIResultReceiver.Receiver {
+public class Dashboard extends Activity implements SessionDialog.SessionDialogInterface, ProviderAPIResultReceiver.Receiver, Observer {
protected static final int CONFIGURE_LEAP = 0;
protected static final int SWITCH_PROVIDER = 1;
@@ -60,46 +61,65 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
@InjectView(R.id.providerName)
TextView provider_name;
+ @InjectView(R.id.user_session_status)
+ TextView user_session_status_text_view;
+ @InjectView(R.id.user_session_status_progress)
+ ProgressBar user_session_status_progress_bar;
EipFragment eip_fragment;
private Provider provider;
+ private UserSessionStatus user_session_status;
public ProviderAPIResultReceiver providerAPI_result_receiver;
private boolean switching_provider;
@Override
protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- app = this;
+ super.onCreate(savedInstanceState);
- PRNGFixes.apply();
+ app = this;
+ user_session_status = UserSessionStatus.getInstance();
+ user_session_status.addObserver(this);
- preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
- fragment_manager = new FragmentManagerEnhanced(getFragmentManager());
- handleVersion();
+ PRNGFixes.apply();
- provider = getSavedProvider(savedInstanceState);
+ preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ fragment_manager = new FragmentManagerEnhanced(getFragmentManager());
+ handleVersion();
+
+ restoreProvider(savedInstanceState);
if (provider == null || provider.getName().isEmpty())
- startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP);
- else
- buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false));
+ startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP);
+ else {
+ buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false));
+ restoreSessionStatus(savedInstanceState);
+ }
+ }
+
+ private void restoreProvider(Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ if(savedInstanceState.containsKey(Provider.KEY))
+ provider = savedInstanceState.getParcelable(Provider.KEY);
+ }
+ if(provider == null && preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false))
+ provider = getSavedProviderFromSharedPreferences();
+ }
+
+ private void restoreSessionStatus(Bundle savedInstanceState) {
+ if (savedInstanceState != null)
+ if(savedInstanceState.containsKey(UserSessionStatus.TAG)) {
+ UserSessionStatus.SessionStatus status = (UserSessionStatus.SessionStatus) savedInstanceState.getSerializable(UserSessionStatus.TAG);
+ user_session_status.updateStatus(status);
+ }
}
@Override
protected void onSaveInstanceState(@NotNull Bundle outState) {
if(provider != null)
outState.putParcelable(Provider.KEY, provider);
- super.onSaveInstanceState(outState);
- }
-
- 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();
+ if(user_session_status_text_view != null && user_session_status_text_view.getVisibility() == TextView.VISIBLE)
+ outState.putSerializable(UserSessionStatus.TAG, user_session_status.sessionStatus());
- return provider;
+ super.onSaveInstanceState(outState);
}
private Provider getSavedProviderFromSharedPreferences() {
@@ -107,9 +127,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
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) {
+ } catch (MalformedURLException | JSONException e) {
e.printStackTrace();
}
@@ -136,8 +154,8 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
- if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) {
- if ( resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) {
+ if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) {
+ if ( resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) {
provider = data.getParcelableExtra(Provider.KEY);
providerToPreferences(provider);
@@ -147,13 +165,13 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
sessionDialog(Bundle.EMPTY);
}
- } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) {
+ } else if (resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) {
finish();
- } else
- configErrorDialog();
- } else if(requestCode == EIP.DISCONNECT) {
- EipStatus.getInstance().setConnectedOrDisconnected();
- }
+ } else
+ configErrorDialog();
+ } else if(requestCode == EIP.DISCONNECT) {
+ EipStatus.getInstance().setConnectedOrDisconnected();
+ }
}
@SuppressLint("CommitPrefEdits")
@@ -164,7 +182,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
}
private void configErrorDialog() {
- AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getAppContext());
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getContext());
alertBuilder.setTitle(getResources().getString(R.string.setup_error_title));
alertBuilder
.setMessage(getResources().getString(R.string.setup_error_text))
@@ -172,7 +190,7 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
.setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- startActivityForResult(new Intent(getAppContext(),ConfigurationWizard.class),CONFIGURE_LEAP);
+ startActivityForResult(new Intent(getContext(),ConfigurationWizard.class),CONFIGURE_LEAP);
}
})
.setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() {
@@ -190,55 +208,39 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
* service dependent UI elements to include.
*/
private void buildDashboard(boolean hide_and_turn_on_eip) {
- setContentView(R.layout.dashboard);
+ setContentView(R.layout.dashboard);
ButterKnife.inject(this);
- provider_name.setText(provider.getDomain());
- if ( provider.hasEIP()){
+ provider_name.setText(provider.getDomain());
+ if ( provider.hasEIP()){
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(EipFragment.START_ON_BOOT, true);
+ if (hide_and_turn_on_eip) {
+ preferences.edit().remove(Dashboard.START_ON_BOOT).apply();
+ Bundle arguments = new Bundle();
+ arguments.putBoolean(EipFragment.START_ON_BOOT, true);
if(eip_fragment != null) eip_fragment.setArguments(arguments);
- }
+ }
fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG);
- if (hide_and_turn_on_eip) {
- onBackPressed();
- }
- }
+ if (hide_and_turn_on_eip) {
+ onBackPressed();
+ }
+ }
+ handleNewUserSessionStatus(user_session_status);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- JSONObject provider_json;
- try {
- String provider_json_string = preferences.getString(Provider.KEY, "");
- if(!provider_json_string.isEmpty()) {
- provider_json = new JSONObject(provider_json_string);
- JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
- boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION);
- preferences.edit().putBoolean(Constants.ALLOWED_REGISTERED, allow_registered_eip).apply();
-
- if(allow_registered_eip) {
- if(LeapSRPSession.loggedIn()) {
- menu.findItem(R.id.login_button).setVisible(false);
- menu.findItem(R.id.logout_button).setVisible(true);
- } else {
- menu.findItem(R.id.login_button).setVisible(true);
- menu.findItem(R.id.logout_button).setVisible(false);
- }
- menu.findItem(R.id.signup_button).setVisible(true);
- }
- }
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return true;
+ if(provider.allowsRegistration()) {
+ menu.findItem(R.id.signup_button).setVisible(true);
+
+ boolean logged_in = User.loggedIn();
+ menu.findItem(R.id.login_button).setVisible(!logged_in);
+ menu.findItem(R.id.logout_button).setVisible(logged_in);
+ }
+ return true;
}
@Override
@@ -281,26 +283,74 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
}
public void showLog() {
- Intent startLW = new Intent(getAppContext(), LogWindow.class);
- //startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ Intent startLW = new Intent(getContext(), LogWindow.class);
startActivity(startLW);
}
@Override
public void signUp(String username, String password) {
- Bundle parameters = bundleParameters(username, password);
- providerApiCommand(parameters, R.string.signingup_message, ProviderAPI.SRP_REGISTER);
+ User.setUserName(username);
+ Bundle parameters = bundlePassword(password);
+ providerApiCommand(parameters, R.string.signingup_message, ProviderAPI.SIGN_UP);
}
@Override
public void logIn(String username, String password) {
- Bundle parameters = bundleParameters(username, password);
- providerApiCommand(parameters, R.string.authenticating_message, ProviderAPI.SRP_AUTH);
+ User.setUserName(username);
+ Bundle parameters = bundlePassword(password);
+ providerApiCommand(parameters, R.string.authenticating_message, ProviderAPI.LOG_IN);
}
public void logOut() {
providerApiCommand(Bundle.EMPTY, R.string.logout_message, ProviderAPI.LOG_OUT);
}
+
+ @Override
+ public void update (Observable observable, Object data) {
+ if(observable instanceof UserSessionStatus) {
+ UserSessionStatus status = (UserSessionStatus) observable;
+ handleNewUserSessionStatus(status);
+ }
+ }
+
+ private void handleNewUserSessionStatus(UserSessionStatus status) {
+ user_session_status = status;
+ if(provider.allowsRegistration()) {
+ if(user_session_status.inProgress())
+ showUserSessionProgressBar();
+ else
+ hideUserSessionProgressBar();
+ changeSessionStatusMessage(user_session_status.toString());
+ invalidateOptionsMenu();
+ }
+ }
+
+ private void changeSessionStatusMessage(final String message) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ user_session_status_text_view.setText(message);
+ }
+ });
+ }
+
+ private void showUserSessionProgressBar() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ user_session_status_progress_bar.setVisibility(ProgressBar.VISIBLE);
+ }
+ });
+ }
+
+ private void hideUserSessionProgressBar() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ user_session_status_progress_bar.setVisibility(ProgressBar.GONE);
+ }
+ });
+ }
protected void downloadVpnCertificate() {
boolean is_authenticated = LeapSRPSession.loggedIn();
@@ -312,10 +362,8 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
}
- private Bundle bundleParameters(String username, String password) {
+ private Bundle bundlePassword(String password) {
Bundle parameters = new Bundle();
- if(!username.isEmpty())
- parameters.putString(SessionDialog.USERNAME, username);
if(!password.isEmpty())
parameters.putString(SessionDialog.PASSWORD, password);
return parameters;
@@ -374,26 +422,20 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
String password = resultData.getString(SessionDialog.PASSWORD);
logIn(username, password);
} else if(resultCode == ProviderAPI.FAILED_SIGNUP) {
- updateViewHidingProgressBar(resultCode);
sessionDialog(resultData);
} else if(resultCode == ProviderAPI.SUCCESSFUL_LOGIN) {
- updateViewHidingProgressBar(resultCode);
downloadVpnCertificate();
} else if(resultCode == ProviderAPI.FAILED_LOGIN) {
- updateViewHidingProgressBar(resultCode);
sessionDialog(resultData);
} else if(resultCode == ProviderAPI.SUCCESSFUL_LOGOUT) {
- updateViewHidingProgressBar(resultCode);
if(switching_provider) switchProvider();
} else if(resultCode == ProviderAPI.LOGOUT_FAILED) {
- updateViewHidingProgressBar(resultCode);
setResult(RESULT_CANCELED);
} else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
- updateViewHidingProgressBar(resultCode);
eip_fragment.updateEipService();
+ eip_fragment.handleNewVpnCertificate();
setResult(RESULT_OK);
} else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
- updateViewHidingProgressBar(resultCode);
setResult(RESULT_CANCELED);
}
else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) {
@@ -404,67 +446,12 @@ public class Dashboard extends Activity implements SessionDialog.SessionDialogIn
}
}
- private void updateViewHidingProgressBar(int resultCode) {
- changeStatusMessage(resultCode);
- hideProgressBar();
- invalidateOptionsMenu();
- }
-
- private void changeStatusMessage(final int previous_result_code) {
- ResultReceiver status_receiver = new ResultReceiver(new Handler()){
- protected void onReceiveResult(int resultCode, Bundle resultData){
- super.onReceiveResult(resultCode, resultData);
- String request = resultData.getString(Constants.REQUEST_TAG);
- if (request.equalsIgnoreCase(Constants.ACTION_IS_EIP_RUNNING)){
- if (resultCode == Activity.RESULT_OK){
- switch(previous_result_code){
- case ProviderAPI.SUCCESSFUL_LOGIN: setStatusMessage(R.string.succesful_authentication_message); break;
- case ProviderAPI.FAILED_LOGIN: setStatusMessage(R.string.authentication_failed_message); break;
- case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: setStatusMessage(R.string.incorrectly_downloaded_certificate_message); break;
- case ProviderAPI.SUCCESSFUL_LOGOUT: setStatusMessage(R.string.logged_out_message); break;
- case ProviderAPI.LOGOUT_FAILED: setStatusMessage(R.string.log_out_failed_message); break;
-
- }
- }
- else if(resultCode == Activity.RESULT_CANCELED){
- switch(previous_result_code){
- case ProviderAPI.SUCCESSFUL_LOGIN: setStatusMessage(R.string.succesful_authentication_message); break;
- case ProviderAPI.FAILED_LOGIN: setStatusMessage(R.string.authentication_failed_message); break;
- case ProviderAPI.FAILED_SIGNUP: setStatusMessage(R.string.registration_failed_message); break;
- case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break;
- case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: setStatusMessage(R.string.incorrectly_downloaded_certificate_message); break;
- case ProviderAPI.SUCCESSFUL_LOGOUT: setStatusMessage(R.string.logged_out_message); break;
- case ProviderAPI.LOGOUT_FAILED: setStatusMessage(R.string.log_out_failed_message); break;
- }
- }
- }
-
- }
- };
- eipIsRunning(status_receiver);
- }
-
private void setStatusMessage(int string_resId) {
if(eip_fragment != null && eip_fragment.status_message != null)
eip_fragment.status_message.setText(string_resId);
}
- 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 intent = new Intent(this, EIP.class);
- intent.setAction(Constants.ACTION_IS_EIP_RUNNING);
- intent.putExtra(Constants.RECEIVER_TAG, eip_receiver);
- startService(intent);
- }
-
- private void hideProgressBar() {
- if(eip_fragment != null) {
- eip_fragment.progress_bar.setProgress(0);
- eip_fragment.progress_bar.setVisibility(ProgressBar.GONE);
- }
- }
-
- public static Context getAppContext() {
+ public static Context getContext() {
return app;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
index 680f21e1..2057a80b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
@@ -23,6 +23,8 @@ import android.util.*;
import android.view.*;
import android.widget.*;
+import org.jetbrains.annotations.NotNull;
+
import java.util.*;
import butterknife.*;
@@ -80,18 +82,20 @@ public class EipFragment extends Fragment implements Observer {
Bundle arguments = getArguments();
if(arguments != null && arguments.containsKey(START_ON_BOOT) && arguments.getBoolean(START_ON_BOOT))
startEipFromScratch();
+ if(savedInstanceState != null) restoreState(savedInstanceState);
- 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;
}
+ private void restoreState(@NotNull Bundle savedInstanceState) {
+ if(savedInstanceState.getBoolean(IS_PENDING))
+ eip_status.setConnecting();
+ else if(savedInstanceState.getBoolean(IS_CONNECTED))
+ eip_status.setConnectedOrDisconnected();
+ else
+ status_message.setText(savedInstanceState.getString(STATUS_MESSAGE));
+ }
+
@Override
public void onResume() {
super.onResume();
@@ -103,17 +107,19 @@ public class EipFragment extends Fragment implements Observer {
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 saveStatus() {
boolean is_on = eip_switch.isChecked();
- Log.d(TAG, "saveStatus: is_on = " + is_on);
Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, is_on).commit();
}
+ void handleNewVpnCertificate() {
+ handleSwitch(!eip_switch.isEnabled());
+ }
+
@OnCheckedChanged(R.id.eipSwitch)
void handleSwitch(boolean isChecked) {
if(isChecked)
@@ -154,7 +160,8 @@ public class EipFragment extends Fragment implements Observer {
askPendingStartCancellation();
} else if(eip_status.isConnected()) {
askToStopEIP();
- }
+ } else
+ setDisconnectedUI();
}
private void askPendingStartCancellation() {
@@ -294,16 +301,22 @@ public class EipFragment extends Fragment implements Observer {
String logmessage = eip_status.getLogMessage();
String prefix = dashboard.getString(localizedResId);
+ showProgressBar();
status_message.setText(prefix + " " + logmessage);
is_starting_to_connect = false;
adjustSwitch();
}
private void updatingCertificateUI() {
- progress_bar.setVisibility(View.VISIBLE);
+ showProgressBar();
status_message.setText(getString(R.string.updating_certificate_message));
}
+ private void showProgressBar() {
+ if(progress_bar != null)
+ progress_bar.setVisibility(View.VISIBLE);
+ }
+
private void hideProgressBar() {
if(progress_bar != null)
progress_bar.setVisibility(View.GONE);
diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
index 09855baf..49c115ae 100644
--- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
+++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
@@ -44,7 +44,8 @@ public class LeapSRPSession {
final public static String TOKEN = "token";
final public static String AUTHORIZATION_HEADER= "Authorization";
final public static String TAG= "Leap SRP session class tag";
-
+
+ private User user;
private SRPParameters params;
private String username;
private String password;
diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java
index d7ff6633..ef25c5d2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java
@@ -172,6 +172,14 @@ public final class Provider implements Parcelable {
return false;
}
+ public boolean allowsRegistration() {
+ try {
+ return definition.getJSONObject(Provider.SERVICE).getBoolean(Provider.ALLOW_REGISTRATION);
+ } catch (JSONException e) {
+ return false;
+ }
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/app/src/main/java/se/leap/bitmaskclient/User.java b/app/src/main/java/se/leap/bitmaskclient/User.java
new file mode 100644
index 00000000..6e20c165
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/User.java
@@ -0,0 +1,41 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package se.leap.bitmaskclient;
+
+public class User {
+ private static String user_name = "You";
+ private static User user;
+
+ public static User getInstance() {
+ if(user == null) {
+ user = new User();
+ }
+ return user;
+ }
+
+ public static void setUserName(String user_name) {
+ User.user_name = user_name;
+ }
+
+ private User() { }
+
+ public static String userName() { return user_name; }
+
+ public static boolean loggedIn() {
+ return LeapSRPSession.loggedIn();
+ }
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java b/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java
new file mode 100644
index 00000000..f533819b
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/UserSessionStatus.java
@@ -0,0 +1,70 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package se.leap.bitmaskclient;
+
+import android.os.*;
+
+import java.util.*;
+
+public class UserSessionStatus extends Observable {
+ public static String TAG = UserSessionStatus.class.getSimpleName();
+ private static UserSessionStatus current_status;
+
+ public enum SessionStatus {
+ LOGGED_IN,
+ LOGGED_OUT,
+ NOT_LOGGED_IN,
+ DIDNT_LOG_OUT,
+ LOGGING_IN,
+ LOGGING_OUT
+ }
+
+ private static SessionStatus session_status = SessionStatus.NOT_LOGGED_IN;
+
+ public static UserSessionStatus getInstance() {
+ if(current_status == null) {
+ current_status = new UserSessionStatus();
+ }
+ return current_status;
+ }
+
+ private UserSessionStatus() { }
+
+ private void sessionStatus(SessionStatus session_status) {
+ this.session_status = session_status;
+ }
+
+ public SessionStatus sessionStatus() { return session_status; }
+
+ public boolean inProgress() {
+ return session_status == SessionStatus.LOGGING_IN
+ || session_status == SessionStatus.LOGGING_OUT;
+ }
+
+ public static void updateStatus(SessionStatus session_status) {
+ current_status = getInstance();
+ current_status.sessionStatus(session_status);
+ current_status.setChanged();
+ current_status.notifyObservers();
+ }
+
+ @Override
+ public String toString() {
+ return User.userName() + " is "
+ + session_status.toString().toLowerCase().replaceAll("_", " ");
+ }
+}
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 0c773208..0a707ab1 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
@@ -42,7 +42,8 @@ public class VoidVpnService extends VpnService {
public static boolean stop() {
try {
- fd.close();
+ if(fd != null)
+ fd.close();
return true;
} catch (IOException | NullPointerException e) {
android.util.Log.d(TAG, "VoidVpnService didn't stop");