diff --git a/app/src/main/java/eu/faircode/netguard/ActivityMain.java b/app/src/main/java/eu/faircode/netguard/ActivityMain.java index 28ae23d3..948e5cdb 100644 --- a/app/src/main/java/eu/faircode/netguard/ActivityMain.java +++ b/app/src/main/java/eu/faircode/netguard/ActivityMain.java @@ -193,24 +193,29 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences prefs.edit().putBoolean("enabled", isChecked).apply(); if (isChecked) { - String alwaysOn = Settings.Secure.getString(getContentResolver(), "always_on_vpn_app"); - Log.i(TAG, "Always-on=" + alwaysOn); - if (!TextUtils.isEmpty(alwaysOn)) - if (getPackageName().equals(alwaysOn)) { - if (prefs.getBoolean("filter", false)) { - int lockdown = Settings.Secure.getInt(getContentResolver(), "always_on_vpn_lockdown", 0); - Log.i(TAG, "Lockdown=" + lockdown); - if (lockdown != 0) { - swEnabled.setChecked(false); - Toast.makeText(ActivityMain.this, R.string.msg_always_on_lockdown, Toast.LENGTH_LONG).show(); - return; + try { + String alwaysOn = Settings.Secure.getString(getContentResolver(), "always_on_vpn_app"); + Log.i(TAG, "Always-on=" + alwaysOn); + if (!TextUtils.isEmpty(alwaysOn)) + if (getPackageName().equals(alwaysOn)) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && + prefs.getBoolean("filter", false)) { + int lockdown = Settings.Secure.getInt(getContentResolver(), "always_on_vpn_lockdown", 0); + Log.i(TAG, "Lockdown=" + lockdown); + if (lockdown != 0) { + swEnabled.setChecked(false); + Toast.makeText(ActivityMain.this, R.string.msg_always_on_lockdown, Toast.LENGTH_LONG).show(); + return; + } } + } else { + swEnabled.setChecked(false); + Toast.makeText(ActivityMain.this, R.string.msg_always_on, Toast.LENGTH_LONG).show(); + return; } - } else { - swEnabled.setChecked(false); - Toast.makeText(ActivityMain.this, R.string.msg_always_on, Toast.LENGTH_LONG).show(); - return; - } + } catch (Throwable ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } boolean filter = prefs.getBoolean("filter", false); if (filter && Util.isPrivateDns(ActivityMain.this)) diff --git a/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java b/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java index 4ff9f18c..4c3c08cd 100644 --- a/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java +++ b/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java @@ -57,6 +57,7 @@ import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.Process; import android.os.SystemClock; +import android.provider.Settings; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.Spannable; @@ -160,12 +161,13 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS private static final int NOTIFY_ENFORCING = 1; private static final int NOTIFY_WAITING = 2; private static final int NOTIFY_DISABLED = 3; - private static final int NOTIFY_AUTOSTART = 4; - private static final int NOTIFY_ERROR = 5; - private static final int NOTIFY_TRAFFIC = 6; - private static final int NOTIFY_UPDATE = 7; - public static final int NOTIFY_EXTERNAL = 8; - public static final int NOTIFY_DOWNLOAD = 9; + private static final int NOTIFY_LOCKDOWN = 4; + private static final int NOTIFY_AUTOSTART = 5; + private static final int NOTIFY_ERROR = 6; + private static final int NOTIFY_TRAFFIC = 7; + private static final int NOTIFY_UPDATE = 8; + public static final int NOTIFY_EXTERNAL = 9; + public static final int NOTIFY_DOWNLOAD = 10; public static final String EXTRA_COMMAND = "Command"; private static final String EXTRA_REASON = "Reason"; @@ -439,6 +441,16 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS Log.e(TAG, "Unknown command=" + cmd); } + if (cmd == Command.start || cmd == Command.reload) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + boolean filter = prefs.getBoolean("filter", false); + if (filter && isLockdownEnabled()) + showLockdownNotification(); + else + removeLockdownNotification(); + } + } + if (cmd == Command.start || cmd == Command.reload || cmd == Command.stop) { // Update main view Intent ruleset = new Intent(ActivityMain.ACTION_RULES_CHANGED); @@ -2898,6 +2910,36 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS NotificationManagerCompat.from(this).notify(NOTIFY_DISABLED, notification.build()); } + private void showLockdownNotification() { + Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS); + PendingIntent pi = PendingIntent.getActivity(this, NOTIFY_LOCKDOWN, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + TypedValue tv = new TypedValue(); + getTheme().resolveAttribute(R.attr.colorOff, tv, true); + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify"); + builder.setSmallIcon(R.drawable.ic_error_white_24dp) + .setContentTitle(getString(R.string.app_name)) + .setContentText(getString(R.string.msg_always_on_lockdown)) + .setContentIntent(pi) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setColor(tv.data) + .setOngoing(false) + .setAutoCancel(true); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + builder.setCategory(NotificationCompat.CATEGORY_STATUS) + .setVisibility(NotificationCompat.VISIBILITY_SECRET); + + NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder); + notification.bigText(getString(R.string.msg_always_on_lockdown)); + + NotificationManagerCompat.from(this).notify(NOTIFY_LOCKDOWN, notification.build()); + } + + private void removeLockdownNotification() { + NotificationManagerCompat.from(this).cancel(NOTIFY_LOCKDOWN); + } + private void showAutoStartNotification() { Intent main = new Intent(this, ActivityMain.class); main.putExtra(ActivityMain.EXTRA_APPROVE, true);