diff --git a/core/src/main/java/net/ivpn/core/v2/viewmodel/SplitTunnelingViewModel.java b/core/src/main/java/net/ivpn/core/v2/viewmodel/SplitTunnelingViewModel.java
index 661ebf830..a61d85302 100644
--- a/core/src/main/java/net/ivpn/core/v2/viewmodel/SplitTunnelingViewModel.java
+++ b/core/src/main/java/net/ivpn/core/v2/viewmodel/SplitTunnelingViewModel.java
@@ -22,9 +22,11 @@
along with the IVPN Android app. If not, see .
*/
+import android.Manifest;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
+import android.widget.CompoundButton;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableBoolean;
@@ -45,10 +47,13 @@
public class SplitTunnelingViewModel {
public final ObservableBoolean dataLoading = new ObservableBoolean();
+ public final ObservableBoolean showSystemApps = new ObservableBoolean();
public final ObservableBoolean isAllItemsAllowed = new ObservableBoolean();
public final ObservableArrayList apps = new ObservableArrayList<>();
+ public final ObservableArrayList systemApps = new ObservableArrayList<>();
public final ObservableArrayList disallowedApps = new ObservableArrayList();
public final ObservableField adapter = new ObservableField<>();
+ public CompoundButton.OnCheckedChangeListener toggleSystemApps = (compoundButton, value) -> toggleSystemApps(value);
public final OnApplicationItemSelectionChangedListener selectionChangedListener = new OnApplicationItemSelectionChangedListener() {
@Override
public void onApplicationItemSelectionChanged(ApplicationItem applicationItem, boolean isSelected) {
@@ -73,10 +78,7 @@ public void onItemsSelectionStateChanged(boolean isAllItemSelected) {
this.adapter.set(adapter);
this.menuHandler = adapter.getMenuHandler();
this.preference = preference;
-
- disallowedApps.clear();
- disallowedApps.addAll(getDisallowedPackages());
-
+ reloadDisallowedApps();
isAllItemsAllowed.set(disallowedApps.size() == 0);
}
@@ -87,11 +89,25 @@ public void getApplicationsList(PackageManager packageManager) {
public void selectAll() {
allowAllPackages();
menuHandler.selectAll();
+ reloadDisallowedApps();
}
public void deselectAll() {
- disallowAllApps(new HashSet<>(apps));
+ ObservableArrayList allApps = new ObservableArrayList<>();
+ allApps.addAll(apps);
+ allApps.addAll(systemApps);
+ disallowAllApps(new HashSet<>(allApps));
menuHandler.deselectAll();
+ reloadDisallowedApps();
+ }
+
+ private void reloadDisallowedApps() {
+ disallowedApps.clear();
+ disallowedApps.addAll(getDisallowedPackages());
+ }
+
+ private void toggleSystemApps(Boolean value) {
+ showSystemApps.set(value);
}
private void disallowAllApps(Set applicationItems) {
@@ -145,15 +161,24 @@ protected void onPreExecute() {
@Override
protected List doInBackground(Void... voids) {
List items = new LinkedList<>();
+ List systemItems = new LinkedList<>();
Set packageNames = new HashSet<>();
+ Set systemPackageNames = new HashSet<>();
for (ApplicationInfo info : applicationInfoList) {
try {
- if (null != packageManager.getLaunchIntentForPackage(info.packageName) ||
- null != packageManager.getLeanbackLaunchIntentForPackage(info.packageName) ||
- null != packageManager.getInstallerPackageName(info.packageName)
- ) {
- if (packageNames.add(info.loadLabel(packageManager).toString())) {
- items.add(new ApplicationItem(info.loadLabel(packageManager).toString(), info.packageName,
+ if (PackageManager.PERMISSION_GRANTED == packageManager.checkPermission(Manifest.permission.INTERNET, info.packageName)) {
+ if ((null != packageManager.getLaunchIntentForPackage(info.packageName) ||
+ null != packageManager.getLeanbackLaunchIntentForPackage(info.packageName) ||
+ null != packageManager.getInstallerPackageName(info.packageName) &&
+ (info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
+ ) {
+ if (packageNames.add(info.loadLabel(packageManager).toString())) {
+ items.add(new ApplicationItem(info.loadLabel(packageManager).toString(), info.packageName,
+ info.loadIcon(packageManager)));
+ }
+ }
+ if (systemPackageNames.add(info.loadLabel(packageManager).toString())) {
+ systemItems.add(new ApplicationItem(info.loadLabel(packageManager).toString(), info.packageName,
info.loadIcon(packageManager)));
}
}
@@ -161,13 +186,15 @@ protected List doInBackground(Void... voids) {
e.printStackTrace();
}
}
+ apps.clear();
+ apps.addAll(items);
+ systemApps.clear();
+ systemApps.addAll(systemItems);
return items;
}
@Override
protected void onPostExecute(List applicationItems) {
- apps.clear();
- apps.addAll(applicationItems);
dataLoading.set(false);
}
}
diff --git a/core/src/main/res/layout/content_split_tunneling.xml b/core/src/main/res/layout/content_split_tunneling.xml
index ab3637cfd..40e6a235e 100644
--- a/core/src/main/res/layout/content_split_tunneling.xml
+++ b/core/src/main/res/layout/content_split_tunneling.xml
@@ -48,19 +48,55 @@
android:textSize="14sp"
android:textStyle="normal" />
-
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_marginBottom="16dp"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index a5f1a4074..faab9c78a 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -189,6 +189,7 @@
Split tunnelling allows you to control which apps use the VPN tunnel. New apps that you install will automatically use the VPN tunnel.
TURN ON ALL
TURN OFF ALL
+ Show system apps
Mobile data