From d41561376321d04ce585ac1f45221cb93446e55f Mon Sep 17 00:00:00 2001 From: cyberta Date: Thu, 27 Feb 2020 22:44:50 -0600 Subject: disable battery save mode while tethering is enabled --- app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java | 5 +++-- .../main/java/se/leap/bitmaskclient/tethering/TetheringState.java | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index eeed29bc..02184f03 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -17,6 +17,7 @@ import android.preference.PreferenceManager; import se.leap.bitmaskclient.R; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; +import se.leap.bitmaskclient.tethering.TetheringObservable; import java.util.LinkedList; import java.util.Objects; @@ -143,8 +144,8 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL networkStateChange(context); } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { boolean screenOffPause = prefs.getBoolean("screenoff", false); - - if (screenOffPause) { + boolean isTethering = TetheringObservable.getInstance().getTetheringState().isVpnTetheringRunning(); + if (screenOffPause && !isTethering) { if (VpnStatus.getLastConnectedVpnProfile() != null && !VpnStatus.getLastConnectedVpnProfile().mPersistTun) VpnStatus.logError(R.string.screen_nopersistenttun); diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java index 8ef237c6..103462cc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java @@ -41,5 +41,9 @@ public class TetheringState implements Cloneable { return isVpnWifiTetheringAllowed || isVpnUsbTetheringAllowed || isVpnBluetoothTetheringAllowed; } + public boolean isVpnTetheringRunning() { + return tetherWifiVpn() || tetherUsbVpn() || tetherBluetoothVpn(); + } + } -- cgit v1.2.3 From 2b22e4ad47ae7df24b15ea28b08e60a4999a96cf Mon Sep 17 00:00:00 2001 From: cyberta Date: Thu, 27 Feb 2020 22:53:25 -0600 Subject: enable/disable save battery switch in navigation drawer depending on tethering state --- .../drawer/NavigationDrawerFragment.java | 27 +++++++++++++++++++++- .../leap/bitmaskclient/views/IconSwitchEntry.java | 4 ++++ app/src/main/res/layout/f_drawer_main.xml | 1 + app/src/main/res/values/strings.xml | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) (limited to 'app/src') 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 104f1edc..1097addb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -45,6 +45,8 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import java.util.Observable; +import java.util.Observer; import java.util.Set; import de.blinkt.openvpn.core.VpnStatus; @@ -63,6 +65,7 @@ import se.leap.bitmaskclient.fragments.AlwaysOnDialog; import se.leap.bitmaskclient.fragments.ExcludeAppsFragment; import se.leap.bitmaskclient.fragments.LogFragment; import se.leap.bitmaskclient.fragments.TetheringDialog; +import se.leap.bitmaskclient.tethering.TetheringObservable; import se.leap.bitmaskclient.utils.PreferenceHelper; import se.leap.bitmaskclient.views.IconSwitchEntry; import se.leap.bitmaskclient.views.IconTextEntry; @@ -92,7 +95,7 @@ import static se.leap.bitmaskclient.utils.PreferenceHelper.usePluggableTransport * See the * design guidelines for a complete explanation of the behaviors implemented here. */ -public class NavigationDrawerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener { +public class NavigationDrawerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener, Observer { /** * Per the design guidelines, you should show the drawer on launch until the user manually @@ -149,9 +152,16 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen Bundle savedInstanceState) { drawerView = inflater.inflate(R.layout.f_drawer_main, container, false); restoreFromSavedInstance(savedInstanceState); + TetheringObservable.getInstance().addObserver(this); return drawerView; } + @Override + public void onDestroyView() { + super.onDestroyView(); + TetheringObservable.getInstance().deleteObserver(this); + } + public boolean isDrawerOpen() { return drawerLayout != null && drawerLayout.isDrawerOpen(fragmentContainerView); } @@ -313,6 +323,13 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen saveBattery(getContext(), false); } })); + boolean enableEntry = !TetheringObservable.getInstance().getTetheringState().isVpnTetheringRunning(); + enableSaveBatteryEntry(enableEntry); + } + + private void enableSaveBatteryEntry(boolean enabled) { + saveBattery.setEnabled(enabled); + saveBattery.showSubtitle(!enabled); } private void initAlwaysOnVpnEntry() { @@ -630,4 +647,12 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen initUseBridgesEntry(); } } + + @Override + public void update(Observable o, Object arg) { + if (o instanceof TetheringObservable) { + TetheringObservable observable = (TetheringObservable) o; + enableSaveBatteryEntry(!observable.getTetheringState().isVpnTetheringRunning()); + } + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java b/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java index 02347b05..8bb809fd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java +++ b/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java @@ -88,6 +88,10 @@ public class IconSwitchEntry extends LinearLayout { textView.setText(id); } + public void showSubtitle(boolean show) { + subtitleView.setVisibility(show ? VISIBLE : GONE); + } + public void setIcon(@DrawableRes int id) { iconView.setImageResource(id); } diff --git a/app/src/main/res/layout/f_drawer_main.xml b/app/src/main/res/layout/f_drawer_main.xml index 191d547f..7e6291b7 100644 --- a/app/src/main/res/layout/f_drawer_main.xml +++ b/app/src/main/res/layout/f_drawer_main.xml @@ -65,6 +65,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:text="@string/save_battery" + app:subtitle="@string/subtitle_save_battery" app:icon="@drawable/ic_battery_36" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b5fc2fa2..61cedffb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -102,6 +102,7 @@ VPN certificate is invalid. Try to download a new one. The VPN certificate is invalid. Please log in to download a new one. Save battery + Disabled while VPN Hotspot on Background data connections will hibernate when your phone is inactive. Always-on VPN Open Android System Settings -- cgit v1.2.3 From b370e063453edb5caeaf11cdb85d1ca1c1ac15e9 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 1 Mar 2020 23:50:06 +0100 Subject: improve visual disabled state for switch entries in navigation drawer --- .../java/se/leap/bitmaskclient/views/IconSwitchEntry.java | 11 ++++++++++- app/src/main/res/layout-xlarge/v_switch_list_item.xml | 2 +- app/src/main/res/layout/v_switch_list_item.xml | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java b/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java index 8bb809fd..b41f3a50 100644 --- a/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java +++ b/app/src/main/java/se/leap/bitmaskclient/views/IconSwitchEntry.java @@ -7,6 +7,7 @@ import android.graphics.drawable.Drawable; import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.support.annotation.StringRes; +import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.SwitchCompat; import android.util.AttributeSet; import android.view.LayoutInflater; @@ -22,7 +23,7 @@ public class IconSwitchEntry extends LinearLayout { private TextView textView; private TextView subtitleView; - private ImageView iconView; + private AppCompatImageView iconView; private SwitchCompat switchView; private CompoundButton.OnCheckedChangeListener checkedChangeListener; @@ -105,4 +106,12 @@ public class IconSwitchEntry extends LinearLayout { switchView.setChecked(isChecked); switchView.setOnCheckedChangeListener(checkedChangeListener); } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + switchView.setVisibility(enabled ? VISIBLE : GONE); + textView.setTextColor(getResources().getColor(enabled ? android.R.color.black : R.color.colorDisabled)); + iconView.setImageAlpha(enabled ? 255 : 128); + } } diff --git a/app/src/main/res/layout-xlarge/v_switch_list_item.xml b/app/src/main/res/layout-xlarge/v_switch_list_item.xml index c393a0f8..8ad83650 100644 --- a/app/src/main/res/layout-xlarge/v_switch_list_item.xml +++ b/app/src/main/res/layout-xlarge/v_switch_list_item.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" > - - Date: Mon, 2 Mar 2020 02:15:30 +0100 Subject: use only rndis as valid interface name for usb tethering --- .../java/se/leap/bitmaskclient/tethering/TetheringStateManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java index d3c934f6..dac31e53 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java @@ -111,7 +111,7 @@ public class TetheringStateManager { } private static NetworkInterface getUsbInterface() { - return getNetworkInterface(new String[]{"rndis", "usb"}); + return getNetworkInterface(new String[]{"rndis"}); } private static boolean isBluetoothTetheringEnabled() { -- cgit v1.2.3 From f9e1a1449ee7b8f1aa796416be5fe6de106b8f86 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 2 Mar 2020 02:27:52 +0100 Subject: open android tethering settings activity on click on TetheringDialog's link --- .../main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java index c53d2a6c..d1e43a38 100644 --- a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java @@ -1,6 +1,7 @@ package se.leap.bitmaskclient.fragments; import android.app.Dialog; +import android.content.ComponentName; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -199,7 +200,11 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer spannable.setSpan(new ClickableSpan() { @Override public void onClick(@NonNull View widget) { - Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); + final Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.TetherSettings"); + intent.setComponent(cn); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); -- cgit v1.2.3 From f1c88d01dbbcc2ccd1fd7f82c822e5f280ed75f7 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 2 Mar 2020 03:19:14 +0100 Subject: fallback to genereal wifi settings if tethering settings activity cannot not be found --- .../leap/bitmaskclient/fragments/TetheringDialog.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java index d1e43a38..1bc90605 100644 --- a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java @@ -1,6 +1,7 @@ package se.leap.bitmaskclient.fragments; import android.app.Dialog; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -200,12 +201,18 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer spannable.setSpan(new ClickableSpan() { @Override public void onClick(@NonNull View widget) { - final Intent intent = new Intent(Intent.ACTION_MAIN, null); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.TetherSettings"); - intent.setComponent(cn); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); + try { + final Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.TetherSettings"); + intent.setComponent(cn); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } catch (ActivityNotFoundException e) { + Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); + startActivity(intent); + } + } }, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); -- cgit v1.2.3 From 2fcae35a5592aae3ac932e595717ea8d185ab606 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 2 Mar 2020 04:17:23 +0100 Subject: finish bluetooth tethering implementation --- .../leap/bitmaskclient/firewall/SetupTetheringTask.java | 17 ++++++++++------- .../leap/bitmaskclient/fragments/TetheringDialog.java | 12 ++++++------ .../bitmaskclient/tethering/TetheringStateManager.java | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java b/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java index 7abd01a8..6ce8ee61 100644 --- a/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java +++ b/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java @@ -130,7 +130,7 @@ public class SetupTetheringTask extends AsyncTask { } private boolean removeWifiTetheringRules(TetheringState state, StringBuilder log) throws Exception { - Log.d(TAG, "add Wifi tethering Rules"); + Log.d(TAG, "remove Wifi tethering Rules"); String[] removeRules = getDeletionRules(state, state.lastSeenWifiAddress, state.lastSeenWifiInterface); return runBlockingCmd(removeRules, log) == 0; } @@ -142,18 +142,21 @@ public class SetupTetheringTask extends AsyncTask { } private boolean removeUsbTetheringRules(TetheringState state, StringBuilder log) throws Exception { - Log.d(TAG, "add usb tethering rules"); + Log.d(TAG, "remove usb tethering rules"); String[] addRules = getDeletionRules(state, state.lastSeenUsbAddress, state.lastSeenUsbInterface); return runBlockingCmd(addRules, log) == 0; } - //TODO: implement the follwing methods -v - private boolean removeBluetoothTetheringRules(TetheringState state, StringBuilder log) { - return true; + private boolean removeBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { + Log.d(TAG, "add bluetooth tethering rules"); + String[] addRules = getAdditionRules(state.bluetoothAddress, state.bluetoothInterface); + return runBlockingCmd(addRules, log) == 0; } - private boolean addBluetoothTetheringRules(TetheringState state, StringBuilder log) { - return true; + private boolean addBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { + Log.d(TAG, "remove bluetooth tethering rules"); + String[] addRules = getDeletionRules(state, state.lastSeenBluetoothAddress, state.lastSeenBluetoothInterface); + return runBlockingCmd(addRules, log) == 0; } private String[] getAdditionRules(String addressRange, String interfaceName) { diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java index 1bc90605..900d1885 100644 --- a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java @@ -152,10 +152,10 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer .setPositiveButton(android.R.string.ok, (dialog, id) -> { PreferenceHelper.allowWifiTethering(getContext(), dataset[0].checked); PreferenceHelper.allowUsbTethering(getContext(), dataset[1].checked); -// PreferenceHelper.allowBluetoothTethering(getContext(), dataset[2].checked); + PreferenceHelper.allowBluetoothTethering(getContext(), dataset[2].checked); TetheringObservable.allowVpnWifiTethering(dataset[0].checked); TetheringObservable.allowVpnUsbTethering(dataset[1].checked); -// TetheringObservable.allowVpnBluetoothTethering(dataset[2].checked); + TetheringObservable.allowVpnBluetoothTethering(dataset[2].checked); FirewallManager firewallManager = new FirewallManager(getContext().getApplicationContext(), false); if (VpnStatus.isVPNActive()) { if (TetheringObservable.getInstance().getTetheringState().hasAnyDeviceTetheringEnabled() && @@ -174,7 +174,7 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer super.onResume(); dataset[0].enabled = TetheringObservable.getInstance().isWifiTetheringEnabled(); dataset[1].enabled = TetheringObservable.getInstance().isUsbTetheringEnabled(); -// dataset[2].enabled = TetheringObservable.getInstance().isBluetoothTetheringEnabled(); + dataset[2].enabled = TetheringObservable.getInstance().isBluetoothTetheringEnabled(); adapter.notifyDataSetChanged(); TetheringObservable.getInstance().addObserver(this); } @@ -229,10 +229,10 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer getContext().getString(R.string.tethering_usb), PreferenceHelper.isUsbTetheringAllowed(getContext()), TetheringObservable.getInstance().isUsbTetheringEnabled()), -/* new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_bluetooth), + new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_bluetooth), getContext().getString(R.string.tethering_bluetooth), PreferenceHelper.isBluetoothTetheringAllowed(getContext()), - TetheringObservable.getInstance().isUsbTetheringEnabled())*/ + TetheringObservable.getInstance().isUsbTetheringEnabled()) }; } @@ -243,7 +243,7 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer Log.d(TAG, "TetheringObservable is updated"); dataset[0].enabled = observable.isWifiTetheringEnabled(); dataset[1].enabled = observable.isUsbTetheringEnabled(); -// dataset[2].enabled = observable.isBluetoothTetheringEnabled(); + dataset[2].enabled = observable.isBluetoothTetheringEnabled(); adapter.notifyDataSetChanged(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java index dac31e53..1a11945b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java @@ -85,7 +85,7 @@ public class TetheringStateManager { } static void updateBluetoothTetheringState() { - //TetheringObservable.setBluetoothTethering(isBluetoothTetheringEnabled()); + TetheringObservable.setBluetoothTethering(isBluetoothTetheringEnabled()); } private static String getWifiAddressRange() { -- cgit v1.2.3 From 2a8d82d85f4cfd34143d87174ee022966e364f69 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Tue, 3 Mar 2020 02:02:16 +0100 Subject: take vpn state into account in isVpnTetheringRunning() --- app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java index 103462cc..7ee7bec7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java @@ -1,5 +1,7 @@ package se.leap.bitmaskclient.tethering; +import de.blinkt.openvpn.core.VpnStatus; + public class TetheringState implements Cloneable { public boolean isWifiTetheringEnabled; public boolean isUsbTetheringEnabled; @@ -42,7 +44,7 @@ public class TetheringState implements Cloneable { } public boolean isVpnTetheringRunning() { - return tetherWifiVpn() || tetherUsbVpn() || tetherBluetoothVpn(); + return (tetherWifiVpn() || tetherUsbVpn() || tetherBluetoothVpn()) && VpnStatus.isVPNActive(); } -- cgit v1.2.3 From 649635bc8f8178aba36f07b59ada813f55dc34a0 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 7 Mar 2020 01:04:19 +0100 Subject: fix bluetooth tethering --- .../leap/bitmaskclient/firewall/SetupTetheringTask.java | 5 +++-- .../leap/bitmaskclient/tethering/TetheringObservable.java | 13 ++++++++++--- .../bitmaskclient/tethering/TetheringStateManager.java | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 6 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java b/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java index 6ce8ee61..edf79add 100644 --- a/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java +++ b/app/src/main/java/se/leap/bitmaskclient/firewall/SetupTetheringTask.java @@ -147,18 +147,19 @@ public class SetupTetheringTask extends AsyncTask { return runBlockingCmd(addRules, log) == 0; } - private boolean removeBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { + private boolean addBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { Log.d(TAG, "add bluetooth tethering rules"); String[] addRules = getAdditionRules(state.bluetoothAddress, state.bluetoothInterface); return runBlockingCmd(addRules, log) == 0; } - private boolean addBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { + private boolean removeBluetoothTetheringRules(TetheringState state, StringBuilder log) throws Exception { Log.d(TAG, "remove bluetooth tethering rules"); String[] addRules = getDeletionRules(state, state.lastSeenBluetoothAddress, state.lastSeenBluetoothInterface); return runBlockingCmd(addRules, log) == 0; } + private String[] getAdditionRules(String addressRange, String interfaceName) { return new String[] { "su", diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringObservable.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringObservable.java index 75d29417..9bca25e9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringObservable.java @@ -91,9 +91,16 @@ public class TetheringObservable extends Observable { } } - static void setBluetoothTethering(boolean enabled) { - if (getInstance().tetheringState.isBluetoothTetheringEnabled != enabled) { - getInstance().tetheringState.isBluetoothTetheringEnabled = enabled; + static void setBluetoothTethering(boolean enabled, @NonNull String address, @NonNull String interfaceName) { + if (getInstance().tetheringState.isBluetoothTetheringEnabled != enabled || + !getInstance().tetheringState.bluetoothAddress.equals(address) || + !getInstance().tetheringState.bluetoothInterface.equals(interfaceName)) { + TetheringState state = getInstance().tetheringState; + state.isBluetoothTetheringEnabled = enabled; + state.bluetoothAddress = address; + state.bluetoothInterface = interfaceName; + state.lastSeenBluetoothAddress = address.isEmpty() ? state.lastSeenBluetoothAddress : address; + state.lastSeenBluetoothInterface = interfaceName.isEmpty() ? state.lastSeenBluetoothInterface : interfaceName; getInstance().setChanged(); getInstance().notifyObservers(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java index 1a11945b..0af4c357 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java @@ -85,7 +85,7 @@ public class TetheringStateManager { } static void updateBluetoothTetheringState() { - TetheringObservable.setBluetoothTethering(isBluetoothTetheringEnabled()); + TetheringObservable.setBluetoothTethering(isBluetoothTetheringEnabled(), getBluetoothAddressRange(), getBluetoothInterfaceName()); } private static String getWifiAddressRange() { @@ -98,6 +98,11 @@ public class TetheringStateManager { return getAddressRange(interfaceAddress); } + private static String getBluetoothAddressRange() { + String interfaceAddress = getInterfaceAddress(getBluetoothInterface()); + return getAddressRange(interfaceAddress); + } + private static String getWlanInterfaceName() { return getInterfaceName(getWlanInterface()); } @@ -106,6 +111,10 @@ public class TetheringStateManager { return getInterfaceName(getUsbInterface()); } + private static String getBluetoothInterfaceName() { + return getInterfaceName(getBluetoothInterface()); + } + private static NetworkInterface getWlanInterface() { return getNetworkInterface(new String[]{"wlan", "eth"}); } @@ -114,6 +123,10 @@ public class TetheringStateManager { return getNetworkInterface(new String[]{"rndis"}); } + private static NetworkInterface getBluetoothInterface() { + return getNetworkInterface(new String[]{"bt-pan"}); + } + private static boolean isBluetoothTetheringEnabled() { StringBuilder log = new StringBuilder(); boolean hasBtPan = false; -- cgit v1.2.3 From 394d4eadf0c28653c6b0fef55551c12571c9740d Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 7 Mar 2020 01:18:58 +0100 Subject: disable battery save mode only if actually VPN is running and at least one tethering interface is up --- .../bitmaskclient/drawer/NavigationDrawerFragment.java | 17 ++++++++++++++--- .../se/leap/bitmaskclient/tethering/TetheringState.java | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'app/src') 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 1097addb..bbeb83e5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -59,6 +59,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.eip.EipStatus; import se.leap.bitmaskclient.firewall.FirewallManager; import se.leap.bitmaskclient.fragments.AboutFragment; import se.leap.bitmaskclient.fragments.AlwaysOnDialog; @@ -153,6 +154,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen drawerView = inflater.inflate(R.layout.f_drawer_main, container, false); restoreFromSavedInstance(savedInstanceState); TetheringObservable.getInstance().addObserver(this); + EipStatus.getInstance().addObserver(this); return drawerView; } @@ -160,6 +162,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen public void onDestroyView() { super.onDestroyView(); TetheringObservable.getInstance().deleteObserver(this); + EipStatus.getInstance().deleteObserver(this); } public boolean isDrawerOpen() { @@ -312,6 +315,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen private void initSaveBatteryEntry() { saveBattery = drawerView.findViewById(R.id.battery_switch); + saveBattery.showSubtitle(false); saveBattery.setChecked(getSaveBattery(getContext())); saveBattery.setOnCheckedChangeListener(((buttonView, isChecked) -> { if (!buttonView.isPressed()) { @@ -328,6 +332,9 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen } private void enableSaveBatteryEntry(boolean enabled) { + if (saveBattery.isEnabled() == enabled) { + return; + } saveBattery.setEnabled(enabled); saveBattery.showSubtitle(!enabled); } @@ -650,9 +657,13 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen @Override public void update(Observable o, Object arg) { - if (o instanceof TetheringObservable) { - TetheringObservable observable = (TetheringObservable) o; - enableSaveBatteryEntry(!observable.getTetheringState().isVpnTetheringRunning()); + if (o instanceof TetheringObservable || o instanceof EipStatus) { + try { + getActivity().runOnUiThread(() -> + enableSaveBatteryEntry(!TetheringObservable.getInstance().getTetheringState().isVpnTetheringRunning())); + } catch (NullPointerException npe) { + // eat me + } } } } diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java index 7ee7bec7..21c378ee 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringState.java @@ -1,6 +1,7 @@ package se.leap.bitmaskclient.tethering; import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.eip.EipStatus; public class TetheringState implements Cloneable { public boolean isWifiTetheringEnabled; @@ -44,7 +45,7 @@ public class TetheringState implements Cloneable { } public boolean isVpnTetheringRunning() { - return (tetherWifiVpn() || tetherUsbVpn() || tetherBluetoothVpn()) && VpnStatus.isVPNActive(); + return (tetherWifiVpn() || tetherUsbVpn() || tetherBluetoothVpn()) && (EipStatus.getInstance().isConnecting() || EipStatus.getInstance().isConnected() || EipStatus.getInstance().isBlocking()); } -- cgit v1.2.3 From 432a9885451dafb47e0feafb6070b415d93aac03 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 8 Mar 2020 12:39:45 +0100 Subject: Show error toast and reset root feature settings if app could not obtain root permissions --- app/src/main/java/se/leap/bitmaskclient/Constants.java | 1 - .../bitmaskclient/drawer/NavigationDrawerFragment.java | 13 +++++++++---- .../se/leap/bitmaskclient/firewall/FirewallManager.java | 15 ++++++++++++++- .../se/leap/bitmaskclient/utils/PreferenceHelper.java | 9 --------- app/src/main/res/values/strings.xml | 1 + 5 files changed, 24 insertions(+), 15 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java index 60edc941..6ec3076c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -15,7 +15,6 @@ public interface Constants { String LAST_USED_PROFILE = "last_used_profile"; String EXCLUDED_APPS = "excluded_apps"; String USE_PLUGGABLE_TRANSPORTS = "usePluggableTransports"; - String SU_PERMISSION = "su_permission"; String ALLOW_TETHERING_BLUETOOTH = "tethering_bluetooth"; String ALLOW_TETHERING_WIFI = "tethering_wifi"; String ALLOW_TETHERING_USB = "tethering_usb"; 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 bbeb83e5..715d278d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -50,7 +50,6 @@ import java.util.Observer; import java.util.Set; import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.Constants; import se.leap.bitmaskclient.EipFragment; import se.leap.bitmaskclient.FragmentManagerEnhanced; import se.leap.bitmaskclient.MainActivity; @@ -80,6 +79,8 @@ import static se.leap.bitmaskclient.Constants.ENABLE_DONATION; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.Constants.USE_IPv6_FIREWALL; +import static se.leap.bitmaskclient.Constants.USE_PLUGGABLE_TRANSPORTS; import static se.leap.bitmaskclient.R.string.about_fragment_title; import static se.leap.bitmaskclient.R.string.exclude_apps_fragment_title; import static se.leap.bitmaskclient.R.string.log_fragment_title; @@ -130,6 +131,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen private final static String KEY_SHOW_SAVE_BATTERY_ALERT = "KEY_SHOW_SAVE_BATTERY_ALERT"; private volatile boolean showSaveBattery = false; AlertDialog alertDialog; + private FirewallManager firewallManager; @Override public void onCreate(Bundle savedInstanceState) { @@ -139,6 +141,8 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); userLearnedDrawer = preferences.getBoolean(PREF_USER_LEARNED_DRAWER, false); preferences.registerOnSharedPreferenceChangeListener(this); + firewallManager = new FirewallManager(getContext().getApplicationContext(), false); + } @Override @@ -398,13 +402,12 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen firewall = drawerView.findViewById(R.id.enableIPv6Firewall); boolean show = showExperimentalFeatures(getContext()); firewall.setVisibility(show ? VISIBLE : GONE); - firewall.setChecked(PreferenceHelper.useIpv6Firewall(this.getContext())); + firewall.setChecked(PreferenceHelper.useIpv6Firewall(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(); @@ -650,8 +653,10 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (key.equals(Constants.USE_PLUGGABLE_TRANSPORTS)) { + if (key.equals(USE_PLUGGABLE_TRANSPORTS)) { initUseBridgesEntry(); + } else if (key.equals(USE_IPv6_FIREWALL)) { + initFirewallEntry(); } } 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 c148497b..ace8a298 100644 --- a/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java @@ -17,11 +17,15 @@ package se.leap.bitmaskclient.firewall; */ import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; import java.util.Observable; import java.util.Observer; import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.tethering.TetheringObservable; import se.leap.bitmaskclient.tethering.TetheringState; import se.leap.bitmaskclient.utils.PreferenceHelper; @@ -80,9 +84,18 @@ public class FirewallManager implements FirewallCallback, Observer { @Override public void onSuRequested(boolean success) { - PreferenceHelper.setSuPermission(context, success); if (!success) { VpnStatus.logError("[FIREWALL] Root permission needed to execute custom firewall rules."); + new Handler(Looper.getMainLooper()).post(() -> { + Toast.makeText(context.getApplicationContext(), context.getString(R.string.root_permission_error, context.getString(R.string.app_name)), Toast.LENGTH_LONG).show(); + }); + TetheringObservable.allowVpnWifiTethering(false); + TetheringObservable.allowVpnUsbTethering(false); + TetheringObservable.allowVpnBluetoothTethering(false); + PreferenceHelper.allowWifiTethering(context, false); + PreferenceHelper.allowUsbTethering(context, false); + PreferenceHelper.allowBluetoothTethering(context, false); + PreferenceHelper.setUseIPv6Firewall(context, false); } } 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 6f9744bc..238b00a1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java @@ -29,7 +29,6 @@ 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.USE_IPv6_FIREWALL; import static se.leap.bitmaskclient.Constants.USE_PLUGGABLE_TRANSPORTS; @@ -121,14 +120,6 @@ public class PreferenceHelper { apply(); } - public static boolean hasSuPermission(Context context) { - return getBoolean(context, SU_PERMISSION, false); - } - - public static void setSuPermission(Context context, boolean allowed) { - putBoolean(context, SU_PERMISSION, allowed); - } - public static boolean getUsePluggableTransports(Context context) { return getBoolean(context, USE_PLUGGABLE_TRANSPORTS, false); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 61cedffb..abab24df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -140,4 +140,5 @@ Try obfuscated connection Try standard connection Android failed to establish the VPN service. + %s cannot execute features like VPN Hotspot or IPv6 firewall without root permissions. -- cgit v1.2.3