From 32e00cb1dc377672b31c8eb8b0d78ff38aec4023 Mon Sep 17 00:00:00 2001 From: "martin.byrenheid" <martin.byrenheid@5a230232-f31e-4839-b85c-661838634aa0> Date: Mon, 16 Apr 2018 17:29:52 +0000 Subject: [PATCH] Integrated connectivity management of vpn lib --- app/src/main/AndroidManifest.xml | 3 +- .../anon_next/android/AndroidVpnService.java | 4 +- .../service/foreground/ForegroundService.java | 66 ++++--- .../service/gui/AndroidGUIInterface.java | 168 ++++++++---------- .../AndroidConnectivityMonitor.java | 63 +++++++ .../AndroidConnectivityMonitorFactory.java | 35 ++++ .../android/ui/VPNConnectedActivity.java | 3 +- .../android/ui/main/AnonFragment.java | 101 ++++++----- .../android/ui/main/MainActivity.java | 83 +++------ app/src/main/res/values/colors.xml | 3 +- app/src/main/res/values/strings.xml | 6 +- 11 files changed, 315 insertions(+), 220 deletions(-) create mode 100644 app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitor.java create mode 100644 app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitorFactory.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bf393ef..7910f02 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,8 +20,7 @@ tools:node="remove"/> <uses-permission - android:name="android.permission.ACCESS_NETWORK_STATE" - tools:node="remove"/> + android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" tools:node="remove"/> diff --git a/app/src/main/java/anonvpn/anon_next/android/AndroidVpnService.java b/app/src/main/java/anonvpn/anon_next/android/AndroidVpnService.java index 866ce15..7d03f19 100644 --- a/app/src/main/java/anonvpn/anon_next/android/AndroidVpnService.java +++ b/app/src/main/java/anonvpn/anon_next/android/AndroidVpnService.java @@ -17,6 +17,7 @@ import java.io.IOException; import anonvpn.anon_next.android.service.gui.AndroidGUIFactory; import anonvpn.anon_next.android.service.gui.AndroidGUIInterface; +import anonvpn.anon_next.android.service.networking.AndroidConnectivityMonitorFactory; import anonvpn.anon_next.android.service.networking.AndroidNetworkFactory; import anonvpn.anon_next.android.service.networking.AndroidProtectedSocketFactory; import anonvpn.anon_next.android.service.persistence.AndroidPersistenceFactory; @@ -80,10 +81,11 @@ public class AndroidVpnService extends VpnService AndroidProtectedSocketFactory mixSocketFactory = new AndroidProtectedSocketFactory(this); AndroidGUIFactory guiFactory = new AndroidGUIFactory(this); + AndroidConnectivityMonitorFactory connMonFactory = new AndroidConnectivityMonitorFactory(getApplicationContext()); Log.e("AndroidVPNService", "Starting core service!"); AndroidResourceLoaderHelper resourecLoaderHelper = new AndroidResourceLoaderHelper(getAssets()); AndroidLog logger = new AndroidLog(); - anonvpnService = new ANONVPNService(mNetworkFactory, persistenceFactory, guiFactory, mixSocketFactory, resourecLoaderHelper, logger); + anonvpnService = new ANONVPNService(mNetworkFactory, persistenceFactory, guiFactory, connMonFactory, mixSocketFactory, resourecLoaderHelper, logger); } // service running until it is explicitly stopped,return sticky. diff --git a/app/src/main/java/anonvpn/anon_next/android/service/foreground/ForegroundService.java b/app/src/main/java/anonvpn/anon_next/android/service/foreground/ForegroundService.java index eb3d3fd..ef410d9 100644 --- a/app/src/main/java/anonvpn/anon_next/android/service/foreground/ForegroundService.java +++ b/app/src/main/java/anonvpn/anon_next/android/service/foreground/ForegroundService.java @@ -18,6 +18,7 @@ import anonvpn.anon_next.android.R; import anonvpn.anon_next.android.service.gui.AndroidGUIInterface; import anonvpn.anon_next.android.ui.main.MainActivity; import anonvpn.anon_next.core.gui.IVPNInterface; +import anonvpn.anon_next.core.gui.VPNState; public class ForegroundService extends Service @@ -28,7 +29,7 @@ public class ForegroundService extends Service String cascade_location = ""; String cascade_name = ""; IVPNInterface.RxTx m_RxTx= IVPNInterface.RxTx.ALL_ZERO; - int conn_state = 0; + VPNState conn_state = VPNState.DISABLED; private final int TRAFFIC_STATS_DELAY = 3000; private final Handler mTrafficStatisticsHandler = new Handler(); @@ -97,7 +98,7 @@ public class ForegroundService extends Service cascade_ip = intent.getStringExtra("ip"); cascade_location = intent.getStringExtra("location"); cascade_name = intent.getStringExtra("name"); - conn_state = intent.getIntExtra("conn_state", 0); + conn_state = VPNState.valueOf(intent.getStringExtra("conn_state")); } showNotification(); return START_STICKY; @@ -125,39 +126,52 @@ public class ForegroundService extends Service { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setContentTitle(getString(R.string.foregroundservice_title)); - if (conn_state == 0) // Not connected to VPN - { + switch (conn_state) { + + case DISABLED: mBuilder.setSmallIcon(getIconError()).setContentText(getString(R.string.foregroundservice_desc_vpn_disabled)); if (mVPNConnection != null) - { - disconnectVPNService(); - } - } - else if (conn_state == 1) // Not connected to cascade - { + { + disconnectVPNService(); + } + break; + + case WAITING: + mBuilder.setSmallIcon(getIconWarning()).setContentText(getString(R.string.foregroundservice_desc_cascade_error)); - } - else if (conn_state == 2) // Connection successfully established - { + break; + + case CONNECTED: String message = getString(R.string.foregroundservice_desc_active_name) + - cascade_name + getString(R.string.foregroundservice_desc_active_location) + - cascade_location + getString(R.string.foregroundservice_desc_active_ip) + - cascade_ip + getString(R.string.foregroundservice_desc_active_Rx) + - Util.formatBytesValueWithUnit(m_RxTx.m_RxTotal)+"\n" + - getString(R.string.foregroundservice_desc_active_Tx) + Util.formatBytesValueWithUnit(m_RxTx.m_TxTotal) ; + cascade_name + getString(R.string.foregroundservice_desc_active_location) + + cascade_location + getString(R.string.foregroundservice_desc_active_ip) + + cascade_ip + getString(R.string.foregroundservice_desc_active_Rx) + + Util.formatBytesValueWithUnit(m_RxTx.m_RxTotal)+"\n" + + getString(R.string.foregroundservice_desc_active_Tx) + Util.formatBytesValueWithUnit(m_RxTx.m_TxTotal) ; mBuilder.setSmallIcon(getIconOK()).setStyle(new NotificationCompat.BigTextStyle().bigText(message)).setContentText(message); if (mVPNConnection == null) - { - connectToVPNService(); - } - } - else - { - throw new RuntimeException("Unexpected conn_state: " + conn_state); - } + { + connectToVPNService(); + } + break; + + case CONNECTING: + + mBuilder.setSmallIcon(getIconWarning()).setContentText(getString(R.string.foregroundservice_desc_connecting)); + + break; + + case DISCONNECTED: + + mBuilder.setSmallIcon(getIconWarning()).setContentText(getString(R.string.foregroundservice_desc_network)); + + break; + + } + // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(this, MainActivity.class); diff --git a/app/src/main/java/anonvpn/anon_next/android/service/gui/AndroidGUIInterface.java b/app/src/main/java/anonvpn/anon_next/android/service/gui/AndroidGUIInterface.java index e71aa19..4007945 100644 --- a/app/src/main/java/anonvpn/anon_next/android/service/gui/AndroidGUIInterface.java +++ b/app/src/main/java/anonvpn/anon_next/android/service/gui/AndroidGUIInterface.java @@ -6,13 +6,16 @@ import android.util.Log; import java.util.Hashtable; +import anon.crypto.SignatureVerifier; import anon.infoservice.MixCascade; +import anon.infoservice.MixInfo; import anon.util.CountryMapper; import anonvpn.anon_next.android.AndroidVpnService; import anonvpn.anon_next.android.service.foreground.ForegroundService; import anonvpn.anon_next.android.ui.main.MainActivity; import anonvpn.anon_next.core.InfoService; import anonvpn.anon_next.core.gui.IVPNInterface; +import anonvpn.anon_next.core.gui.VPNState; import anonvpn.anon_next.core.notification.Event; import anonvpn.anon_next.core.notification.NotificationDispatcher; import anonvpn.anon_next.core.notification.Observer; @@ -28,16 +31,13 @@ public class AndroidGUIInterface extends Binder implements IVPNInterface, Observ private final InfoService mInfoService; private static final String LOGTAG = "AndroidGUIInterface"; + private VPNState mVPNState = VPNState.DISABLED; + private long m_lastSentBytes = 0; private long m_lastReceivedBytes = 0; private long m_lastRxTxUpdate = 0; - private MixCascade mChosenCascade = null; - private boolean mConnected = false; - //private final RxTx m_RxTx = new RxTx(); - - public AndroidGUIInterface(AndroidVpnService vpnService, NotificationDispatcher dispatcher, IConfig config, InfoService infoService) { this.mVpnService = vpnService; @@ -45,10 +45,14 @@ public class AndroidGUIInterface extends Binder implements IVPNInterface, Observ this.mConfig = config; this.mInfoService = infoService; + mDispatcher.subscribe(Event.CASCADE_CONNECTING, this); mDispatcher.subscribe(Event.CASCADE_CONNECTED, this); mDispatcher.subscribe(Event.CASCADE_DISCONNECTED, this); + mDispatcher.subscribe(Event.CASCADE_LOST, this); + + // Simplifies notification of foreground service and main activity + // after the VPN has been disabled mDispatcher.subscribe(Event.VPN_DISABLED, this); - mDispatcher.subscribe(Event.VPN_ENABLED, this); updateFGService(); } @@ -73,14 +77,6 @@ public class AndroidGUIInterface extends Binder implements IVPNInterface, Observ return rxtx; } - - @Override - public boolean isConnectedToCascade() - { - // TODO: Replace with actual communication with service - return mConnected; - } - public boolean hasChosenCascade() { return mConfig.getChosenMixCascade() != null; @@ -137,115 +133,109 @@ public class AndroidGUIInterface extends Binder implements IVPNInterface, Observ public void enableTunneling() { mVpnService.startTunnelingDevice(); - mDispatcher.notify(Event.VPN_ENABLED); + mDispatcher.notifyAsync(Event.VPN_ENABLED); } @Override public void disableTunneling() { mVpnService.stopTunnelingDevice(); - mDispatcher.notify(Event.VPN_DISABLED); + mDispatcher.notifyAsync(Event.VPN_DISABLED); } @Override - public boolean tunnelingEnabled() - { - return mVpnService.tunnelingEnabled(); - } + public anonvpn.anon_next.core.gui.VPNState getServiceState() { + return mVPNState; + } + + private void notifyMainActivity() { + Intent notificationIntent = null; + notificationIntent = new Intent(mVpnService.getApplicationContext(), MainActivity.class); + notificationIntent.putExtra("type", "notification"); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mVpnService.startActivity(notificationIntent); + } @Override public void notify(Event event) { - // TODO: SEND INTENTS TO MAINACTIVITY HERE - if (event == Event.CASCADE_CONNECTED) - { + switch(event) { + + case VPN_DISABLED: + mVPNState = VPNState.DISABLED; + break; + + case CASCADE_CONNECTING: + mVPNState = VPNState.CONNECTING; + break; + + case CASCADE_CONNECTED: Log.i(LOGTAG, "Event received: Cascade connected."); - mConnected = true; - Intent startIntent = new Intent(mVpnService.getApplicationContext(), MainActivity.class); - startIntent.putExtra("FragmentID", MainActivity.FRAGMENTID_ANONYMITY); - startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mVpnService.startActivity(startIntent); + mVPNState = VPNState.CONNECTED; + break; - } - else if (event == Event.CASCADE_DISCONNECTED) - { + case CASCADE_DISCONNECTED: Log.i(LOGTAG, "Event received: Cascade disconnected."); - mConnected = false; + mVPNState = VPNState.DISCONNECTED; + break; - Intent startIntent = new Intent(mVpnService.getApplicationContext(), MainActivity.class); - startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mVpnService.startActivity(startIntent); + case CASCADE_LOST: + mVPNState = VPNState.WAITING; + break; - } - else if (event == Event.VPN_ENABLED) - { - Log.i(LOGTAG, "Event received: VPN enabled."); + default: - } - else if (event == Event.VPN_DISABLED) - { - Log.i(LOGTAG, "Event received: VPN disabled."); - - } - else - { Log.e(LOGTAG, "Unexpected event!"); throw new RuntimeException(); - } + } + + notifyMainActivity(); updateFGService(); - //todo: intent --> MainActivity->AnonFragment->updateStatus() } private void updateFGService() { Log.e("AndroidVPNMainActivity", "Preparing ForegroundService!"); -// mSharedPreferences.edit().putBoolean("FGServiceStarted", true).apply(); Intent startIntent = new Intent(mVpnService.getApplicationContext(), ForegroundService.class); try { - int conn_state; - if (!mVpnService.tunnelingEnabled()) - { - conn_state = 0; - } - else if (!mConnected) - { - conn_state = 1; - } - else + + MixCascade cascade = getChosenCascade(); + String ip = ""; + String location = ""; + String name = ""; + if (cascade != null) { - conn_state = 2; - MixCascade cascade = getChosenCascade(); - String ip = ""; - String location = ""; - String name = ""; - if (cascade != null) + try { - try - { - int nrOfMixes = cascade.getNumberOfMixes(); - ip = cascade.getMixInfo(nrOfMixes - 1).getFirstHostName(); - String countryCode = cascade.getMixInfo(nrOfMixes - 1).getServiceLocation().getCountryCode(); - CountryMapper c = new CountryMapper(countryCode); - location = c.toString(); - name = getChosenCascade().getName(); - } - catch (Exception e) - { - e.printStackTrace(); - } + int nrOfMixes = cascade.getNumberOfMixes(); + MixInfo cascadeInfo = cascade.getMixInfo(nrOfMixes - 1); + + String countryCode = "DE"; + ip = "Unknown"; + if (cascadeInfo != null) { + ip = cascadeInfo.getFirstHostName(); + countryCode = cascadeInfo.getServiceLocation().getCountryCode(); + } + CountryMapper c = new CountryMapper(countryCode); + location = c.toString(); + name = getChosenCascade().getName(); + } + catch (Exception e) + { + e.printStackTrace(); } - startIntent.putExtra("ip", ip); - startIntent.putExtra("location", location); - startIntent.putExtra("name", name); - - startIntent.putExtra("conn_state", conn_state); } - } - catch (Exception e) - { - e.printStackTrace(); - } + startIntent.putExtra("ip", ip); + startIntent.putExtra("location", location); + startIntent.putExtra("name", name); + + startIntent.putExtra("conn_state", mVPNState.toString()); + } + catch (Exception e) + { + e.printStackTrace(); + } mVpnService.startService(startIntent); } diff --git a/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitor.java b/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitor.java new file mode 100644 index 0000000..818fa9c --- /dev/null +++ b/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitor.java @@ -0,0 +1,63 @@ +package anonvpn.anon_next.android.service.networking; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import anonvpn.anon_next.core.networking.IConnectivityMonitor; +import anonvpn.anon_next.core.notification.Event; +import anonvpn.anon_next.core.notification.NotificationDispatcher; + +/** + * Created by martin on 03.04.18. + */ + +public class AndroidConnectivityMonitor extends BroadcastReceiver implements IConnectivityMonitor { + + private final NotificationDispatcher mNotification; + private final ConnectivityManager mConnectivityManager; + private boolean mConnected = false; + + public AndroidConnectivityMonitor(NotificationDispatcher dispatcher, ConnectivityManager connManager) { + + mNotification = dispatcher; + + mConnectivityManager = connManager; + + NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo(); + mConnected = activeNetwork != null && + activeNetwork.isConnectedOrConnecting(); + + + } + + @Override + public void onReceive(Context context, Intent intent) { + + NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo(); + + boolean connected = activeNetwork != null && + activeNetwork.isConnectedOrConnecting(); + + if (! mConnected && connected) { + mConnected = connected; + System.out.println("Network connected!"); + mNotification.notify(Event.NETWORK_CONNECTED); + + } + + if (mConnected && ! connected) { + mConnected = connected; + System.out.println("Network disconnected!"); + mNotification.notify(Event.NETWORK_DISCONNECTED); + + } + } + + @Override + public boolean deviceIsConnected() { + return mConnected; + } +} diff --git a/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitorFactory.java b/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitorFactory.java new file mode 100644 index 0000000..3666786 --- /dev/null +++ b/app/src/main/java/anonvpn/anon_next/android/service/networking/AndroidConnectivityMonitorFactory.java @@ -0,0 +1,35 @@ +package anonvpn.anon_next.android.service.networking; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; + +import anonvpn.anon_next.core.networking.IConnectivityMonitor; +import anonvpn.anon_next.core.networking.IConnectivityMonitorFactory; +import anonvpn.anon_next.core.notification.NotificationDispatcher; + +/** + * Created by martin on 06.04.18. + */ + +public class AndroidConnectivityMonitorFactory implements IConnectivityMonitorFactory { + + private final ConnectivityManager mConnectivityManager; + private final Context mAppContext; + + public AndroidConnectivityMonitorFactory(Context context) { + mAppContext = context; + ConnectivityManager cm = + (ConnectivityManager)mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mConnectivityManager = cm; + } + + @Override + public IConnectivityMonitor getConnectivityMonitor(NotificationDispatcher notificationDispatcher) { + AndroidConnectivityMonitor result = new AndroidConnectivityMonitor(notificationDispatcher, mConnectivityManager); + IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); + mAppContext.registerReceiver(result, filter); + return result; + } +} diff --git a/app/src/main/java/anonvpn/anon_next/android/ui/VPNConnectedActivity.java b/app/src/main/java/anonvpn/anon_next/android/ui/VPNConnectedActivity.java index 4399041..13b0c7d 100644 --- a/app/src/main/java/anonvpn/anon_next/android/ui/VPNConnectedActivity.java +++ b/app/src/main/java/anonvpn/anon_next/android/ui/VPNConnectedActivity.java @@ -10,6 +10,7 @@ import android.util.Log; import anonvpn.anon_next.android.AndroidVpnService; import anonvpn.anon_next.android.service.gui.AndroidGUIInterface; +import anonvpn.anon_next.core.gui.VPNState; /** * Created by martin on 8/9/17. @@ -93,7 +94,7 @@ abstract public class VPNConnectedActivity extends AppCompatActivity public boolean isTunnelingEnabled() { - return (isVPNConnected() && getServiceInterface().tunnelingEnabled()); + return (isVPNConnected() && getServiceInterface().getServiceState() != VPNState.DISABLED); } public AndroidGUIInterface getServiceInterface() diff --git a/app/src/main/java/anonvpn/anon_next/android/ui/main/AnonFragment.java b/app/src/main/java/anonvpn/anon_next/android/ui/main/AnonFragment.java index ca49c47..aecd279 100644 --- a/app/src/main/java/anonvpn/anon_next/android/ui/main/AnonFragment.java +++ b/app/src/main/java/anonvpn/anon_next/android/ui/main/AnonFragment.java @@ -22,6 +22,8 @@ import android.widget.ProgressBar; import android.widget.TextView; import anon.infoservice.MixCascade; +import anon.infoservice.MixInfo; +import anon.infoservice.ServiceLocation; import anon.util.CountryMapper; import anon.util.Util; import anonvpn.anon_next.android.R; @@ -109,9 +111,7 @@ final public class AnonFragment extends Fragment } else { - startVPNTunneling(); - updateStatus(); } } @@ -156,7 +156,6 @@ final public class AnonFragment extends Fragment { ((MainActivity) getActivity()).enableVPNTunneling(); - } private void stopVPNTunneling() @@ -263,59 +262,73 @@ final public class AnonFragment extends Fragment public void updateStatus() { - MainActivity a=(MainActivity) getActivity(); - if(a==null) - return; - if (a.isTunnelingEnabled()) - { - Log.e("ANONFragment", "VPN is running!"); - sw.setChecked(true); + MainActivity main = (MainActivity) getActivity(); - // Check if the user already selected a cascade - if (a.getServiceInterface().isConnectedToCascade()) - { - IVPNInterface.RxTx rxtx = a.getServiceInterface().getRxTx(); + if (main != null) { + AndroidGUIInterface service = main.getServiceInterface(); + + if (service != null) { + + switch (service.getServiceState()) { + + case CONNECTING: + if (!sw.isChecked()) { + sw.setChecked(true); + } + m_tvStatus.setText(getContext().getString(R.string.start_state_establish)); + m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_problem)); + break; + + case CONNECTED: + IVPNInterface.RxTx rxtx = service.getRxTx(); updateTrafficStatistics(rxtx); - if (!m_TrafficStatisticsTask.isScheduled ) - { - m_TrafficStatisticsHandler.postDelayed(m_TrafficStatisticsTask, TRAFFIC_STATS_DELAY); - m_TrafficStatisticsTask.isScheduled = true; - } + if (!m_TrafficStatisticsTask.isScheduled) { + m_TrafficStatisticsHandler.postDelayed(m_TrafficStatisticsTask, TRAFFIC_STATS_DELAY); + m_TrafficStatisticsTask.isScheduled = true; + } m_tvStatus.setText(getContext().getString(R.string.start_state_active)); m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_ok)); ((TextView) m_viewContent.findViewById(R.id.anon_tv_tip)).setText(""); - MixCascade cascade=a.getServiceInterface().getChosenCascade(); - String countryCode = cascade.getMixInfo(cascade.getNumberOfMixes() - 1).getServiceLocation().getCountryCode(); + MixCascade cascade = service.getChosenCascade(); + + MixInfo cascadeInfo = cascade.getMixInfo(cascade.getNumberOfMixes() - 1); + String countryCode = "DE"; + if (cascadeInfo != null) { + countryCode = cascadeInfo.getServiceLocation().getCountryCode(); + } CountryMapper c = new CountryMapper(countryCode); String location = c.toString(); m_tvLocation.setText(location); - - } - else - { + break; - m_tvStatus.setText(getContext().getString(R.string.start_label_noconnect)); - m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_problem)); - ((TextView) m_viewContent.findViewById(R.id.anon_tv_tip)).setText(R.string.start_tip_choosenet); + case WAITING: + m_tvStatus.setText(getContext().getString(R.string.start_state_noservice)); + m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_fatal)); + break; + + case DISCONNECTED: + m_tvStatus.setText(getContext().getString(R.string.start_state_nocon)); + m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_fatal)); + break; + + case DISABLED: + Log.e("ANONFragment", "VPN is not running!"); + sw.setChecked(false); + + m_TrafficStatisticsHandler.removeCallbacks(m_TrafficStatisticsTask); + m_TrafficStatisticsTask.isScheduled = false; + updateTrafficStatistics(IVPNInterface.RxTx.ALL_ZERO); + + m_tvStatus.setText(getContext().getString(R.string.start_state_deactive)); + m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_off)); + ((TextView) m_viewContent.findViewById(R.id.anon_tv_tip)).setText(""); ((ProgressBar) m_viewContent.findViewById(R.id.anon_iv_statusbar)).setProgress(0); - } + m_tvLocation.setText(getContext().getString(R.string.start_loc_unknown)); + break; + } } - else - { - Log.e("ANONFragment", "VPN is not running!"); - sw.setChecked(false); - - m_TrafficStatisticsHandler.removeCallbacks(m_TrafficStatisticsTask); - m_TrafficStatisticsTask.isScheduled = false; - updateTrafficStatistics(IVPNInterface.RxTx.ALL_ZERO); - - m_tvStatus.setText(getContext().getString(R.string.start_state_deactive)); - m_tvStatus.setTextColor(getResources().getColor(R.color.connectivity_off)); - ((TextView) m_viewContent.findViewById(R.id.anon_tv_tip)).setText(""); - ((ProgressBar) m_viewContent.findViewById(R.id.anon_iv_statusbar)).setProgress(0); - m_tvLocation.setText(getContext().getString(R.string.start_loc_unknown)); - } + } } } diff --git a/app/src/main/java/anonvpn/anon_next/android/ui/main/MainActivity.java b/app/src/main/java/anonvpn/anon_next/android/ui/main/MainActivity.java index 1015ade..d904ae0 100644 --- a/app/src/main/java/anonvpn/anon_next/android/ui/main/MainActivity.java +++ b/app/src/main/java/anonvpn/anon_next/android/ui/main/MainActivity.java @@ -31,6 +31,8 @@ import anonvpn.anon_next.android.ui.SettingsActivity; import anonvpn.anon_next.android.ui.VPNConnectedActivity; import anonvpn.anon_next.android.ui.tutorial.TutorialActivity; import anonvpn.anon_next.core.CascadeConnectionManager; +import anonvpn.anon_next.core.gui.VPNState; +import anonvpn.anon_next.core.notification.Event; //Main Activity of ANONmobile public class MainActivity extends VPNConnectedActivity implements NavigationView.OnNavigationItemSelectedListener @@ -41,10 +43,15 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView public static final int FRAGMENTID_CONNECTION = 1; public static final int FRAGMENTID_APPS = 2; public static final int FRAGMENTID_NETWORKS = 3; - private int mActiveFragment = -1; + private int mActiveFragment = FRAGMENTID_ANONYMITY; private final int ALLOW_VPN_REQUEST = 0; private final int CHOOSE_CONNECTION_REQUEST = 1; + private final AnonFragment mAnonFragment = new AnonFragment(); + private final ConnectFragment mConnectFragment = new ConnectFragment(); + private final NetFragment mNetFragment = new NetFragment(); + private final AppFragment mAppFragment = new AppFragment(); + private FragmentManager mFragmentManager = null; private SharedPreferences mSharedPreferences = null; @@ -98,6 +105,8 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView mSharedPreferences = getSharedPreferences(this.getString(R.string.sp_global), Context.MODE_PRIVATE); + launchMainView(); + if (mSharedPreferences.getBoolean("TutorialPassed", false) == false) { Intent intent = new Intent(this, TutorialActivity.class); @@ -110,29 +119,12 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView { String LOGTAG = "MainActivity"; Log.i(LOGTAG, "Received new intent"); - int target_fragment = intent.getIntExtra("FragmentID", -1); - if (target_fragment != -1) - { - // On redirect from connection overview to anon fragment also check WAITING_FOR_CASCADE_CONNECTED - // TODO: Else display an error message after a timeout - if (mActiveFragment == FRAGMENTID_CONNECTION && target_fragment == FRAGMENTID_ANONYMITY) - { - ConnectFragment current_fragment = (ConnectFragment) mFragmentManager.findFragmentById(R.id.fl_fragmentcontainer); - if (current_fragment != null && current_fragment.WAITING_FOR_CASCADE_CONNECTED) - { - current_fragment.WAITING_FOR_CASCADE_CONNECTED = false; - setFragment(target_fragment); - } - } - else - { - setFragment(target_fragment); - } - } - else - { -// launchMainView(); - } + System.out.println("Got Notification"); + if (intent.hasExtra("type") && intent.getStringExtra("type").equals("notification")) { + System.out.println("Updating anon fragment!"); + mAnonFragment.updateStatus(); + + } } @@ -163,24 +155,7 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); - setFragment(FRAGMENTID_ANONYMITY); - - if (mSharedPreferences.getBoolean("VPNStarted", false) && !getServiceInterface().tunnelingEnabled()) - { - enableVPNTunneling(); - } - else - { - Fragment fragment = mFragmentManager.findFragmentById(R.id.fl_fragmentcontainer); - if (fragment != null) - { - - if (fragment instanceof AnonFragment) - { - ((AnonFragment) fragment).updateStatus(); - } - } - } + setFragment(mActiveFragment); } public void enableVPNTunneling() @@ -210,12 +185,6 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView { Log.e("AndroidVPNMainActivity", "Enable tunneling device!"); getServiceInterface().enableTunneling(); - - Fragment fragment = mFragmentManager.findFragmentById(R.id.fl_fragmentcontainer); - if (fragment instanceof AnonFragment && fragment != null) - { - ((AnonFragment) fragment).updateStatus(); - } } public void disableVPNTunneling() @@ -244,8 +213,10 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView protected void onVPNServiceConnected() { - launchMainView(); - + if (mSharedPreferences.getBoolean("VPNStarted", false) && getServiceInterface().getServiceState() != VPNState.DISABLED) + { + enableVPNTunneling(); + } } protected void onVPNServiceDisconnected() @@ -393,22 +364,26 @@ public class MainActivity extends VPNConnectedActivity implements NavigationView switch (id) { case FRAGMENTID_ANONYMITY: - mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, new AnonFragment()).commit(); + //mAnonFragment = new AnonFragment(); + mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, mAnonFragment).commit(); setTheme(R.style.AppTheme_SwitchBig); setTitle(R.string.start_title); break; case FRAGMENTID_CONNECTION: - mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, new ConnectFragment()).commit(); + //mConnectFragment = new ConnectFragment(); + mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, mConnectFragment).commit(); setTheme(R.style.AppTheme); setTitle(R.string.connect_title); break; case FRAGMENTID_APPS: - mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, new AppFragment()).commit(); + //mAppFragment = new AppFragment(); + mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, mAppFragment).commit(); setTheme(R.style.AppTheme); setTitle(R.string.app_title); break; case FRAGMENTID_NETWORKS: - mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, new NetFragment()).commit(); + //mNetFragment = new NetFragment(); + mFragmentManager.beginTransaction().replace(R.id.fl_fragmentcontainer, mNetFragment).commit(); setTheme(R.style.AppTheme); setTitle(R.string.net_title); break; diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0d61f54..ddbb0af 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,7 +10,8 @@ <!-- Connectivity status --> <color name="connectivity_off">#E53935</color> - <color name="connectivity_problem">#FFDD00</color> + <color name="connectivity_fatal">#ff0d00</color> + <color name="connectivity_problem">#ff8400</color> <color name="connectivity_ok">#43A047</color> <!-- Buttons --> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5b5e726..b0319e5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,14 +64,14 @@ <string name="start_label_loc">Deutschland</string> <string name="start_label_observer">(für Beobachter)</string> <string name="start_label_unit"> kB/s</string> - <string name="start_state_nocon">Es besteht keine Verbindung zu einem Netz</string> + <string name="start_state_nocon">Es besteht keine Verbindung zu einem Netz.</string> <string name="start_loc_unknown">Unbekannt</string> <string name="start_tip_choosenet">Wähle dich in ein Netz ein, um die Anonymisierung zu beginnen.</string> <string name="start_state_nonet">"Das aktuelle Netz ist nicht anonym!"</string> <string name="start_state_active">Sie sind anonym!</string> <string name="start_state_deactive">Sie sind nicht anonym!</string> <string name="start_label_noconnect">Verbindungsproblem!</string> - <string name="start_tip_nocon">Der Anonymisierungsdienst scheint nicht erreichbar zu sein. Wählen Sie bitte einen anderen Anonymisierungsdienst und überprüfen Sie ihre Internetverbindung.</string> + <string name="start_state_noservice">Es konnte keine Verbindung zum Anonymisierungsdienst aufgebaut werden.</string> <string name="start_tip_net">Sie müssen mit einem Netz verbunden sein, um den Dienst zu aktivieren.</string> <string name="start_state_establish">Verbindung wird aufgebaut</string> <string name="start_meter_mixamount">Tipp: Wähle eine Verbindung mit mehr Verbindungspunkten, um deine Anonymität zu verstärken</string> @@ -322,6 +322,8 @@ Deshalb sollten vor allem Webanwendungen die JavaScript, Java oder Flash verwend <string name="vpn_tunneling_shutdown_progress_notification">Beende Anonymisierung...</string> + <string name="foregroundservice_desc_connecting">Verbinde zum Anonymisierungsdienst...</string> + <string name="foregroundservice_desc_network">Warte auf Verbindung zum Internet</string> </resources> -- GitLab