From 47f463122392963d81c3e12c7ffbb0443bead6ce Mon Sep 17 00:00:00 2001 From: cyberta Date: Fri, 31 Jan 2020 17:59:46 -0600 Subject: add UI in navigation drawer to enable/disable ipv6 firewall and to show/hide experimental features --- .../main/java/se/leap/bitmaskclient/Constants.java | 2 + .../drawer/NavigationDrawerFragment.java | 80 ++++++++++++++++++---- .../bitmaskclient/firewall/FirewallManager.java | 17 +++-- .../leap/bitmaskclient/utils/PreferenceHelper.java | 24 ++++++- app/src/main/res/layout/f_drawer_main.xml | 41 +++++++++-- app/src/main/res/values/strings.xml | 7 +- 6 files changed, 140 insertions(+), 31 deletions(-) (limited to 'app') diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java index 6a065d84..60edc941 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -19,6 +19,8 @@ public interface Constants { String ALLOW_TETHERING_BLUETOOTH = "tethering_bluetooth"; String ALLOW_TETHERING_WIFI = "tethering_wifi"; String ALLOW_TETHERING_USB = "tethering_usb"; + String SHOW_EXPERIMENTAL = "show_experimental"; + String USE_IPv6_FIREWALL = "use_ipv6_firewall"; ////////////////////////////////////////////// diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index de24802a..104f1edc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -43,6 +43,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import java.util.Set; @@ -56,6 +57,7 @@ import se.leap.bitmaskclient.ProviderListActivity; import se.leap.bitmaskclient.ProviderObservable; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.eip.EipCommand; +import se.leap.bitmaskclient.firewall.FirewallManager; import se.leap.bitmaskclient.fragments.AboutFragment; import se.leap.bitmaskclient.fragments.AlwaysOnDialog; import se.leap.bitmaskclient.fragments.ExcludeAppsFragment; @@ -82,6 +84,7 @@ import static se.leap.bitmaskclient.utils.PreferenceHelper.getSaveBattery; import static se.leap.bitmaskclient.utils.PreferenceHelper.getShowAlwaysOnDialog; import static se.leap.bitmaskclient.utils.PreferenceHelper.getUsePluggableTransports; import static se.leap.bitmaskclient.utils.PreferenceHelper.saveBattery; +import static se.leap.bitmaskclient.utils.PreferenceHelper.showExperimentalFeatures; import static se.leap.bitmaskclient.utils.PreferenceHelper.usePluggableTransports; /** @@ -110,6 +113,9 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen private Toolbar toolbar; private IconTextEntry account; private IconSwitchEntry saveBattery; + private IconTextEntry tethering; + private IconSwitchEntry firewall; + private View experimentalFeatureFooter; private boolean userLearnedDrawer; private volatile boolean wasPaused; @@ -237,8 +243,11 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen initUseBridgesEntry(); initSaveBatteryEntry(); initAlwaysOnVpnEntry(); - initTetheringEntry(); initExcludeAppsEntry(); + initShowExperimentalHint(); + initTetheringEntry(); + initFirewallEntry(); + initExperimentalFeatureFooter(); initDonateEntry(); initLogEntry(); initAboutEntry(); @@ -323,19 +332,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen } } - private void initTetheringEntry() { - IconTextEntry tethering = drawerView.findViewById(R.id.tethering); - if (PreferenceHelper.hasSuPermission(getContext())) { - tethering.setVisibility(VISIBLE); - tethering.setOnClickListener((buttonView) -> { - showTetheringAlert(); - }); - } else { - tethering.setVisibility(GONE); - } - - } - private void initExcludeAppsEntry() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { IconTextEntry excludeApps = drawerView.findViewById(R.id.exclude_apps); @@ -354,6 +350,62 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen } } + private void initShowExperimentalHint() { + TextView textView = drawerLayout.findViewById(R.id.show_experimental_features); + textView.setText(showExperimentalFeatures(getContext()) ? R.string.hide_experimental : R.string.show_experimental); + textView.setOnClickListener(v -> { + boolean shown = showExperimentalFeatures(getContext()); + if (shown) { + tethering.setVisibility(GONE); + firewall.setVisibility(GONE); + experimentalFeatureFooter.setVisibility(GONE); + ((TextView) v).setText(R.string.show_experimental); + } else { + tethering.setVisibility(VISIBLE); + firewall.setVisibility(VISIBLE); + experimentalFeatureFooter.setVisibility(VISIBLE); + ((TextView) v).setText(R.string.hide_experimental); + } + PreferenceHelper.setShowExperimentalFeatures(getContext(), !shown); + }); + } + + private void initFirewallEntry() { + firewall = drawerView.findViewById(R.id.enableIPv6Firewall); + boolean show = showExperimentalFeatures(getContext()); + firewall.setVisibility(show ? VISIBLE : GONE); + firewall.setChecked(PreferenceHelper.useIpv6Firewall(this.getContext())); + firewall.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (!buttonView.isPressed()) { + return; + } + PreferenceHelper.setUseIPv6Firewall(getContext(), isChecked); + FirewallManager firewallManager = new FirewallManager(getContext().getApplicationContext(), false); + if (VpnStatus.isVPNActive()) { + if (isChecked) { + firewallManager.startIPv6Firewall(); + } else { + firewallManager.stopIPv6Firewall(); + } + } + }); + } + + private void initTetheringEntry() { + tethering = drawerView.findViewById(R.id.tethering); + boolean show = showExperimentalFeatures(getContext()); + tethering.setVisibility(show ? VISIBLE : GONE); + tethering.setOnClickListener((buttonView) -> { + showTetheringAlert(); + }); + } + + private void initExperimentalFeatureFooter() { + experimentalFeatureFooter = drawerView.findViewById(R.id.experimental_features_footer); + boolean show = showExperimentalFeatures(getContext()); + experimentalFeatureFooter.setVisibility(show ? VISIBLE : GONE); + } + private void initDonateEntry() { if (ENABLE_DONATION) { IconTextEntry donate = drawerView.findViewById(R.id.donate); diff --git a/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java b/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java index 30ecebea..c148497b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java @@ -94,7 +94,9 @@ public class FirewallManager implements FirewallCallback, Observer { public void start() { if (!isRunning) { isRunning = true; - startIPv6Firewall(); + if (PreferenceHelper.useIpv6Firewall(context)) { + startIPv6Firewall(); + } TetheringState tetheringState = TetheringObservable.getInstance().getTetheringState(); if (tetheringState.hasAnyDeviceTetheringEnabled() && tetheringState.hasAnyVpnTetheringAllowed()) { startTethering(); @@ -105,8 +107,13 @@ public class FirewallManager implements FirewallCallback, Observer { public void stop() { isRunning = false; - stopIPv6Firewall(); - stopTethering(); + if (PreferenceHelper.useIpv6Firewall(context)) { + stopIPv6Firewall(); + } + TetheringState tetheringState = TetheringObservable.getInstance().getTetheringState(); + if (tetheringState.hasAnyDeviceTetheringEnabled() && tetheringState.hasAnyVpnTetheringAllowed()) { + stopTethering(); + } } public void startTethering() { @@ -119,12 +126,12 @@ public class FirewallManager implements FirewallCallback, Observer { task.execute(); } - private void startIPv6Firewall() { + public void startIPv6Firewall() { StartIPv6FirewallTask task = new StartIPv6FirewallTask(this); task.execute(); } - private void stopIPv6Firewall() { + public void stopIPv6Firewall() { ShutdownIPv6FirewallTask task = new ShutdownIPv6FirewallTask(this); task.execute(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java index 073e338c..6f9744bc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java @@ -16,6 +16,9 @@ import de.blinkt.openvpn.VpnProfile; import se.leap.bitmaskclient.Provider; import static android.content.Context.MODE_PRIVATE; +import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_BLUETOOTH; +import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_USB; +import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_WIFI; import static se.leap.bitmaskclient.Constants.ALWAYS_ON_SHOW_DIALOG; import static se.leap.bitmaskclient.Constants.DEFAULT_SHARED_PREFS_BATTERY_SAVER; import static se.leap.bitmaskclient.Constants.EXCLUDED_APPS; @@ -25,10 +28,9 @@ import static se.leap.bitmaskclient.Constants.PROVIDER_EIP_DEFINITION; import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.Constants.SHOW_EXPERIMENTAL; import static se.leap.bitmaskclient.Constants.SU_PERMISSION; -import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_BLUETOOTH; -import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_USB; -import static se.leap.bitmaskclient.Constants.ALLOW_TETHERING_WIFI; +import static se.leap.bitmaskclient.Constants.USE_IPv6_FIREWALL; import static se.leap.bitmaskclient.Constants.USE_PLUGGABLE_TRANSPORTS; /** @@ -167,6 +169,22 @@ public class PreferenceHelper { return getBoolean(context, ALLOW_TETHERING_BLUETOOTH, false); } + public static void setShowExperimentalFeatures(Context context, boolean show) { + putBoolean(context, SHOW_EXPERIMENTAL, show); + } + + public static boolean showExperimentalFeatures(Context context) { + return getBoolean(context, SHOW_EXPERIMENTAL, false); + } + + public static void setUseIPv6Firewall(Context context, boolean useFirewall) { + putBoolean(context, USE_IPv6_FIREWALL, useFirewall); + } + + public static boolean useIpv6Firewall(Context context) { + return getBoolean(context, USE_IPv6_FIREWALL, false); + } + public static void saveShowAlwaysOnDialog(Context context, boolean showAlwaysOnDialog) { putBoolean(context, ALWAYS_ON_SHOW_DIALOG, showAlwaysOnDialog); } diff --git a/app/src/main/res/layout/f_drawer_main.xml b/app/src/main/res/layout/f_drawer_main.xml index 505bd714..191d547f 100644 --- a/app/src/main/res/layout/f_drawer_main.xml +++ b/app/src/main/res/layout/f_drawer_main.xml @@ -88,29 +88,56 @@ android:visibility="gone" /> - + + + + Always-on VPN Open Android System Settings VPN Hotspot - Share your VPN - Please make sure that you have enabled tethering in the %s first! + Firewall + Requires root permissions + Show experimental options + Hide experimental options + Please make sure to enable tethering in the %s first! system settings Share your VPN with other devices via: Wifi hotspot -- cgit v1.2.3