From 418d6b09a0eda97cf05646c56032a5e9691cdb1b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 17 Oct 2023 08:19:31 +0200 Subject: [PATCH] explicitly declare foreground service type --- src/main/AndroidManifest.xml | 40 ++++++++--- .../services/XmppConnectionService.java | 67 ++++++++++++++++--- 2 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index d7da25ccc..56b7865c9 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -3,8 +3,13 @@ xmlns:tools="http://schemas.android.com/tools"> - - + + + + + + + + + @@ -77,32 +92,40 @@ - + + + - @@ -150,7 +173,6 @@ + android:exported="true"> @@ -265,7 +286,6 @@ diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 5a072e9c6..6c87fd94a 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -19,6 +19,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; import android.database.ContentObserver; import android.graphics.Bitmap; import android.media.AudioManager; @@ -487,6 +488,7 @@ public class XmppConnectionService extends Service { private WakeLock wakeLock; private LruCache mBitmapCache; private final BroadcastReceiver mInternalEventReceiver = new InternalEventReceiver(); + private final BroadcastReceiver mInternalRestrictedEventReceiver = new RestrictedEventReceiver(Arrays.asList(TorServiceUtils.ACTION_STATUS)); private final BroadcastReceiver mInternalScreenEventReceiver = new InternalEventReceiver(); private static String generateFetchKey(Account account, final Avatar avatar) { @@ -1236,16 +1238,26 @@ public class XmppConnectionService extends Service { toggleForegroundService(); updateUnreadCountBadge(); toggleScreenEventReceiver(); - final IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(TorServiceUtils.ACTION_STATUS); + final IntentFilter systemBroadcastFilter = new IntentFilter(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { scheduleNextIdlePing(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + systemBroadcastFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); } - intentFilter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED); + systemBroadcastFilter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED); } - registerReceiver(this.mInternalEventReceiver, intentFilter); + ContextCompat.registerReceiver( + this, + this.mInternalEventReceiver, + systemBroadcastFilter, + ContextCompat.RECEIVER_NOT_EXPORTED); + final IntentFilter exportedBroadcastFilter = new IntentFilter(); + exportedBroadcastFilter.addAction(TorServiceUtils.ACTION_STATUS); + ContextCompat.registerReceiver( + this, + this.mInternalRestrictedEventReceiver, + exportedBroadcastFilter, + ContextCompat.RECEIVER_EXPORTED); mForceDuringOnCreate.set(false); toggleForegroundService(); setupPhoneStateListener(); @@ -1315,6 +1327,7 @@ public class XmppConnectionService extends Service { public void onDestroy() { try { unregisterReceiver(this.mInternalEventReceiver); + unregisterReceiver(this.mInternalRestrictedEventReceiver); unregisterReceiver(this.mInternalScreenEventReceiver); } catch (final IllegalArgumentException e) { //ignored @@ -1396,9 +1409,26 @@ public class XmppConnectionService extends Service { private void startForegroundOrCatch(final int id, final Notification notification) { try { - startForeground(id, notification); - } catch (final IllegalStateException e) { - Log.e(Config.LOGTAG,"Could not start foreground service", e); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + final int foregroundServiceType; + if (getSystemService(PowerManager.class) + .isIgnoringBatteryOptimizations(getPackageName())) { + foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED; + } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) + == PackageManager.PERMISSION_GRANTED) { + foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; + } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) + == PackageManager.PERMISSION_GRANTED) { + foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; + } else { + foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE; + } + startForeground(id, notification, foregroundServiceType); + } else { + startForeground(id, notification); + } + } catch (final IllegalStateException | SecurityException e) { + Log.e(Config.LOGTAG, "Could not start foreground service", e); } } @@ -5027,11 +5057,30 @@ public class XmppConnectionService extends Service { private class InternalEventReceiver extends BroadcastReceiver { @Override - public void onReceive(Context context, Intent intent) { + public void onReceive(final Context context, final Intent intent) { onStartCommand(intent, 0, 0); } } + private class RestrictedEventReceiver extends BroadcastReceiver { + + private final Collection allowedActions; + + private RestrictedEventReceiver(final Collection allowedActions) { + this.allowedActions = allowedActions; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent == null ? null : intent.getAction(); + if (allowedActions.contains(action)) { + onStartCommand(intent,0,0); + } else { + Log.e(Config.LOGTAG,"restricting broadcast of event "+action); + } + } + } + public static class OngoingCall { public final AbstractJingleConnection.Id id; public final Set media;