bump targetSdk to 32

Daniel Gultsch created

Change summary

build.gradle                                                             |  4 
src/conversations/AndroidManifest.xml                                    |  3 
src/main/AndroidManifest.xml                                             | 16 
src/main/java/eu/siacs/conversations/services/NotificationService.java   | 96 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 17 
src/main/java/eu/siacs/conversations/utils/Compatibility.java            | 68 
6 files changed, 142 insertions(+), 62 deletions(-)

Detailed changes

build.gradle 🔗

@@ -86,11 +86,11 @@ ext {
 
 android {
     namespace 'eu.siacs.conversations'
-    compileSdkVersion 31
+    compileSdkVersion 32
 
     defaultConfig {
         minSdkVersion 21
-        targetSdkVersion 30
+        targetSdkVersion 32
         versionCode 42034
         versionName "2.10.8"
         archivesBaseName += "-$versionName"

src/conversations/AndroidManifest.xml 🔗

@@ -26,7 +26,8 @@
         <activity
             android:name=".ui.ImportBackupActivity"
             android:label="@string/restore_backup"
-            android:launchMode="singleTask">
+            android:launchMode="singleTask"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />

src/main/AndroidManifest.xml 🔗

@@ -83,7 +83,9 @@
 
         <service android:name=".services.XmppConnectionService" />
 
-        <receiver android:name=".services.EventReceiver">
+        <receiver
+            android:name=".services.EventReceiver"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
@@ -107,6 +109,7 @@
             android:label="@string/title_activity_show_location" />
         <activity
             android:name=".ui.ConversationActivity"
+            android:exported="true"
             android:theme="@style/SplashTheme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -127,6 +130,7 @@
             android:windowSoftInputMode="stateAlwaysHidden" />
         <activity
             android:name=".ui.UriHandlerActivity"
+            android:exported="true"
             android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
@@ -166,6 +170,7 @@
         </activity>
         <activity
             android:name=".ui.StartConversationActivity"
+            android:exported="true"
             android:label="@string/title_activity_start_conversation"
             android:launchMode="singleTop">
             <intent-filter>
@@ -174,6 +179,7 @@
         </activity>
         <activity
             android:name=".ui.SettingsActivity"
+            android:exported="true"
             android:label="@string/title_activity_settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -192,6 +198,7 @@
         <activity
             android:name=".ui.ChooseAccountForProfilePictureActivity"
             android:enabled="false"
+            android:exported="true"
             android:label="@string/choose_account">
             <intent-filter android:label="@string/set_profile_picture">
                 <action android:name="android.intent.action.ATTACH_DATA" />
@@ -225,6 +232,7 @@
             android:label="@string/group_chat_avatar" />
         <activity
             android:name=".ui.ShareWithActivity"
+            android:exported="true"
             android:label="@string/app_name"
             android:launchMode="singleTop">
 
@@ -261,10 +269,6 @@
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value="eu.siacs.conversations.ui.SettingsActivity" />
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.PREFERENCE" />
-            </intent-filter>
         </activity>
         <activity
             android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
@@ -279,6 +283,7 @@
         <service android:name=".services.ImportBackupService" />
         <service
             android:name=".services.ContactChooserTargetService"
+            android:exported="true"
             android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
             <intent-filter>
                 <action android:name="android.service.chooser.ChooserTargetService" />
@@ -302,6 +307,7 @@
 
         <activity
             android:name=".ui.ShortcutActivity"
+            android:exported="true"
             android:label="@string/contact">
             <intent-filter>
                 <action android:name="android.intent.action.CREATE_SHORTCUT" />

src/main/java/eu/siacs/conversations/services/NotificationService.java 🔗

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.services;
 
+import static eu.siacs.conversations.utils.Compatibility.s;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
@@ -625,7 +627,9 @@ public class NotificationService {
                 mXmppConnectionService,
                 requestCode,
                 fullScreenIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                s()
+                        ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     public void cancelIncomingCallNotification() {
@@ -759,7 +763,7 @@ public class NotificationService {
                         && conversations != null
                         && conversations.size()
                                 == 1; // if this check is changed to > 0 catchup messages will
-                                      // create one notification per conversation
+        // create one notification per conversation
 
         if (notifications.size() == 0) {
             cancel(NOTIFICATION_ID);
@@ -835,9 +839,7 @@ public class NotificationService {
         } else {
             mBuilder.setLocalOnly(true);
         }
-        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            mBuilder.setCategory(Notification.CATEGORY_MESSAGE);
-        }
+        mBuilder.setCategory(Notification.CATEGORY_MESSAGE);
         mBuilder.setPriority(
                 notify
                         ? (headsup
@@ -1280,7 +1282,9 @@ public class NotificationService {
                         mXmppConnectionService,
                         generateRequestCode(message.getConversation(), 18),
                         intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT);
+                        s()
+                                ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                                : PendingIntent.FLAG_UPDATE_CURRENT);
             }
         }
         return null;
@@ -1299,13 +1303,17 @@ public class NotificationService {
                     mXmppConnectionService,
                     generateRequestCode(conversationUuid, 8),
                     viewConversationIntent,
-                    PendingIntent.FLAG_UPDATE_CURRENT);
+                    s()
+                            ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                            : PendingIntent.FLAG_UPDATE_CURRENT);
         } else {
             return PendingIntent.getActivity(
                     mXmppConnectionService,
                     generateRequestCode(conversationUuid, 10),
                     viewConversationIntent,
-                    PendingIntent.FLAG_UPDATE_CURRENT);
+                    s()
+                            ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                            : PendingIntent.FLAG_UPDATE_CURRENT);
         }
     }
 
@@ -1332,9 +1340,20 @@ public class NotificationService {
         if (conversation != null) {
             intent.putExtra("uuid", conversation.getUuid());
             return PendingIntent.getService(
-                    mXmppConnectionService, generateRequestCode(conversation, 20), intent, 0);
+                    mXmppConnectionService,
+                    generateRequestCode(conversation, 20),
+                    intent,
+                    s()
+                            ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                            : PendingIntent.FLAG_UPDATE_CURRENT);
         }
-        return PendingIntent.getService(mXmppConnectionService, 0, intent, 0);
+        return PendingIntent.getService(
+                mXmppConnectionService,
+                0,
+                intent,
+                s()
+                        ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createReplyIntent(
@@ -1348,7 +1367,12 @@ public class NotificationService {
         intent.putExtra("last_message_uuid", lastMessageUuid);
         final int id = generateRequestCode(conversation, dismissAfterReply ? 12 : 14);
         return PendingIntent.getService(
-                mXmppConnectionService, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+                mXmppConnectionService,
+                id,
+                intent,
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createReadPendingIntent(Conversation conversation) {
@@ -1360,7 +1384,9 @@ public class NotificationService {
                 mXmppConnectionService,
                 generateRequestCode(conversation, 16),
                 intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createCallAction(String sessionId, final String action, int requestCode) {
@@ -1369,7 +1395,12 @@ public class NotificationService {
         intent.setPackage(mXmppConnectionService.getPackageName());
         intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId);
         return PendingIntent.getService(
-                mXmppConnectionService, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+                mXmppConnectionService,
+                requestCode,
+                intent,
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createSnoozeIntent(Conversation conversation) {
@@ -1381,19 +1412,33 @@ public class NotificationService {
                 mXmppConnectionService,
                 generateRequestCode(conversation, 22),
                 intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createTryAgainIntent() {
         final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
         intent.setAction(XmppConnectionService.ACTION_TRY_AGAIN);
-        return PendingIntent.getService(mXmppConnectionService, 45, intent, 0);
+        return PendingIntent.getService(
+                mXmppConnectionService,
+                45,
+                intent,
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createDismissErrorIntent() {
         final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
         intent.setAction(XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS);
-        return PendingIntent.getService(mXmppConnectionService, 69, intent, 0);
+        return PendingIntent.getService(
+                mXmppConnectionService,
+                69,
+                intent,
+                s()
+                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                        : PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private boolean wasHighlightedOrPrivate(final Message message) {
@@ -1538,15 +1583,9 @@ public class NotificationService {
             }
         }
         mBuilder.setDeleteIntent(createDismissErrorIntent());
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
-            mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
-        } else {
-            mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning);
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
-            mBuilder.setLocalOnly(true);
-        }
+        mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
+        mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
+        mBuilder.setLocalOnly(true);
         mBuilder.setPriority(Notification.PRIORITY_LOW);
         final Intent intent;
         if (AccountUtils.MANAGE_ACCOUNT_ACTIVITY != null) {
@@ -1558,7 +1597,12 @@ public class NotificationService {
         }
         mBuilder.setContentIntent(
                 PendingIntent.getActivity(
-                        mXmppConnectionService, 145, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                        mXmppConnectionService,
+                        145,
+                        intent,
+                        s()
+                                ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
+                                : PendingIntent.FLAG_UPDATE_CURRENT));
         if (Compatibility.runsTwentySix()) {
             mBuilder.setChannelId("error");
         }

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -36,6 +36,7 @@ import android.preference.PreferenceManager;
 import android.provider.ContactsContract;
 import android.security.KeyChain;
 import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
@@ -1203,9 +1204,10 @@ public class XmppConnectionService extends Service {
 
     private void setupPhoneStateListener() {
         final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-        if (telephonyManager != null) {
-            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+        if (telephonyManager == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            return;
         }
+        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
     }
 
     public boolean isPhoneInCall() {
@@ -1402,7 +1404,16 @@ public class XmppConnectionService extends Service {
         final Intent intent = new Intent(this, EventReceiver.class);
         intent.setAction("ping");
         try {
-            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
+            final PendingIntent pendingIntent;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                pendingIntent =
+                        PendingIntent.getBroadcast(
+                                this, requestCode, intent, PendingIntent.FLAG_IMMUTABLE);
+            } else {
+                pendingIntent =
+                        PendingIntent.getBroadcast(
+                                this, requestCode, intent, 0);
+            }
             alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingIntent);
         } catch (RuntimeException e) {
             Log.e(Config.LOGTAG, "unable to schedule alarm for ping", e);

src/main/java/eu/siacs/conversations/utils/Compatibility.java 🔗

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.utils;
 
+import static eu.siacs.conversations.services.EventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE;
+
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Intent;
@@ -24,23 +26,26 @@ import eu.siacs.conversations.R;
 import eu.siacs.conversations.ui.SettingsActivity;
 import eu.siacs.conversations.ui.SettingsFragment;
 
-import static eu.siacs.conversations.services.EventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE;
-
 public class Compatibility {
 
-    private static final List<String> UNUSED_SETTINGS_POST_TWENTYSIX = Arrays.asList(
-            "led",
-            "notification_ringtone",
-            "notification_headsup",
-            "vibrate_on_notification"
-    );
-    private static final List<String> UNUESD_SETTINGS_PRE_TWENTYSIX = Collections.singletonList(
-            "message_notification_settings"
-    );
-
+    private static final List<String> UNUSED_SETTINGS_POST_TWENTYSIX =
+            Arrays.asList(
+                    "led",
+                    "notification_ringtone",
+                    "notification_headsup",
+                    "vibrate_on_notification");
+    private static final List<String> UNUESD_SETTINGS_PRE_TWENTYSIX =
+            Collections.singletonList("message_notification_settings");
 
     public static boolean hasStoragePermission(Context context) {
-        return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
+        return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+                || ContextCompat.checkSelfPermission(
+                                context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
+                        == PackageManager.PERMISSION_GRANTED;
+    }
+
+    public static boolean s() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
     }
 
     private static boolean runsTwentyFour() {
@@ -66,20 +71,22 @@ public class Compatibility {
     private static boolean targetsTwentySix(Context context) {
         try {
             final PackageManager packageManager = context.getPackageManager();
-            final ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
+            final ApplicationInfo applicationInfo =
+                    packageManager.getApplicationInfo(context.getPackageName(), 0);
             return applicationInfo == null || applicationInfo.targetSdkVersion >= 26;
         } catch (PackageManager.NameNotFoundException | RuntimeException e) {
-            return true; //when in doubt…
+            return true; // when in doubt…
         }
     }
 
     private static boolean targetsTwentyFour(Context context) {
         try {
             final PackageManager packageManager = context.getPackageManager();
-            final ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
+            final ApplicationInfo applicationInfo =
+                    packageManager.getApplicationInfo(context.getPackageName(), 0);
             return applicationInfo == null || applicationInfo.targetSdkVersion >= 24;
         } catch (PackageManager.NameNotFoundException | RuntimeException e) {
-            return true; //when in doubt…
+            return true; // when in doubt…
         }
     }
 
@@ -92,14 +99,23 @@ public class Compatibility {
     }
 
     public static boolean keepForegroundService(Context context) {
-        return runsAndTargetsTwentySix(context) || getBooleanPreference(context, SettingsActivity.KEEP_FOREGROUND_SERVICE, R.bool.enable_foreground_service);
+        return runsAndTargetsTwentySix(context)
+                || getBooleanPreference(
+                        context,
+                        SettingsActivity.KEEP_FOREGROUND_SERVICE,
+                        R.bool.enable_foreground_service);
     }
 
     public static void removeUnusedPreferences(SettingsFragment settingsFragment) {
-        List<PreferenceCategory> categories = Arrays.asList(
-                (PreferenceCategory) settingsFragment.findPreference("notification_category"),
-                (PreferenceCategory) settingsFragment.findPreference("advanced"));
-        for (String key : (runsTwentySix() ? UNUSED_SETTINGS_POST_TWENTYSIX : UNUESD_SETTINGS_PRE_TWENTYSIX)) {
+        List<PreferenceCategory> categories =
+                Arrays.asList(
+                        (PreferenceCategory)
+                                settingsFragment.findPreference("notification_category"),
+                        (PreferenceCategory) settingsFragment.findPreference("advanced"));
+        for (String key :
+                (runsTwentySix()
+                        ? UNUSED_SETTINGS_POST_TWENTYSIX
+                        : UNUESD_SETTINGS_PRE_TWENTYSIX)) {
             Preference preference = settingsFragment.findPreference(key);
             if (preference != null) {
                 for (PreferenceCategory category : categories) {
@@ -111,7 +127,8 @@ public class Compatibility {
         }
         if (Compatibility.runsTwentySix()) {
             if (targetsTwentySix(settingsFragment.getContext())) {
-                Preference preference = settingsFragment.findPreference(SettingsActivity.KEEP_FOREGROUND_SERVICE);
+                Preference preference =
+                        settingsFragment.findPreference(SettingsActivity.KEEP_FOREGROUND_SERVICE);
                 if (preference != null) {
                     for (PreferenceCategory category : categories) {
                         if (category != null) {
@@ -132,11 +149,12 @@ public class Compatibility {
                 context.startService(intent);
             }
         } catch (RuntimeException e) {
-            Log.d(Config.LOGTAG, context.getClass().getSimpleName() + " was unable to start service");
+            Log.d(
+                    Config.LOGTAG,
+                    context.getClass().getSimpleName() + " was unable to start service");
         }
     }
 
-
     @SuppressLint("UnsupportedChromeOsCameraSystemFeature")
     public static boolean hasFeatureCamera(final Context context) {
         final PackageManager packageManager = context.getPackageManager();