From: Tobias Brunner Date: Tue, 29 Aug 2023 15:45:32 +0000 (+0200) Subject: android: Request permission to display notifications on Android 13 X-Git-Tag: android-2.4.2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddf84c165d94811a025f128fb6016f5911d6b179;p=thirdparty%2Fstrongswan.git android: Request permission to display notifications on Android 13 Note that displaying the notification for the background service is apparently not strictly necessary. So it's fine if the user wants to hide it. That the service is running can still be seen in the task manager (pull down the status drawer twice, there is a bullet with a number at the bottom if the service is running). Simply use the system dialog. If the user denies it twice, it won't show up again. The explanation dialog would not show up the first time (i.e. shouldShowRequestPermissionRationale() returns false), only once the user denied the permission once. Currently seems like a bit much work as we don't need the user to allow notifications. --- diff --git a/src/frontends/android/app/src/main/AndroidManifest.xml b/src/frontends/android/app/src/main/AndroidManifest.xml index e6ed1df5e1..89e3fb110e 100644 --- a/src/frontends/android/app/src/main/AndroidManifest.xml +++ b/src/frontends/android/app/src/main/AndroidManifest.xml @@ -22,6 +22,7 @@ + diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java index 06821c6a60..1913bbb5f3 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java @@ -16,6 +16,7 @@ package org.strongswan.android.ui; +import android.Manifest; import android.app.Dialog; import android.app.Service; import android.content.ActivityNotFoundException; @@ -25,6 +26,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.net.Uri; import android.net.VpnService; import android.os.Build; @@ -45,12 +47,14 @@ import org.strongswan.android.logic.VpnStateService; import org.strongswan.android.logic.VpnStateService.State; import org.strongswan.android.utils.Constants; +import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; @@ -107,11 +111,18 @@ public class VpnProfileControlActivity extends AppCompatActivity new ActivityResultContracts.StartActivityForResult(), result -> { mWaitingForResult = false; - if (mProfileInfo != null && mService != null) + if (checkNotificationPermission()) { - mService.connect(mProfileInfo, true); + performConnect(); } - finish(); + } + ); + + private final ActivityResultLauncher mRequestPermission = registerForActivityResult( + new ActivityResultContracts.RequestPermission(), + result -> { + mWaitingForResult = false; + performConnect(); } ); @@ -219,22 +230,47 @@ public class VpnProfileControlActivity extends AppCompatActivity } } + /** + * Called to actually perform the connection and terminating the activity. + */ + protected void performConnect() + { + if (mProfileInfo != null && mService != null) + { + mService.connect(mProfileInfo, true); + } + finish(); + } + /** * Called once the VpnService has been prepared and permission has been granted * by the user. */ protected void onVpnServicePrepared() { - if (checkPowerWhitelist()) + if (checkPowerWhitelist() && checkNotificationPermission()) { - if (mService != null) - { - mService.connect(mProfileInfo, true); - } - finish(); + performConnect(); } } + /** + * Check if we have permission to display notifications to the user, if necessary, + * ask the user to allow this. + * @return true if profile can be initiated immediately + */ + private boolean checkNotificationPermission() + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && + ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) + { + mWaitingForResult = true; + mRequestPermission.launch(Manifest.permission.POST_NOTIFICATIONS); + return false; + } + return true; + } + /** * Check if we are on the system's power whitelist, if necessary, or ask the user * to add us.