diff --git a/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt b/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt index 6fb952cf1f..f6b2c8b760 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/BiometricDeviceAuthentication.kt @@ -38,11 +38,7 @@ class BiometricDeviceAuthentication( } private fun isDeviceSecure(context: Context): Boolean { - return if (Build.VERSION.SDK_INT > 23) { - ServiceUtil.getKeyguardManager(context).isDeviceSecure - } else { - ServiceUtil.getKeyguardManager(context).isKeyguardSecure - } + return ServiceUtil.getKeyguardManager(context).isDeviceSecure } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt index ff0fee0b4b..632b6c12ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt @@ -29,9 +29,11 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.BoxWithConstraintsScope import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.displayCutoutPadding import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material3.MaterialTheme @@ -125,7 +127,6 @@ import org.thoughtcrime.securesms.main.MainToolbarMode import org.thoughtcrime.securesms.main.MainToolbarState import org.thoughtcrime.securesms.main.MainToolbarViewModel import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder -import org.thoughtcrime.securesms.main.NavigationBarSpacerCompat import org.thoughtcrime.securesms.main.SnackbarState import org.thoughtcrime.securesms.main.callNavGraphBuilder import org.thoughtcrime.securesms.main.chatNavGraphBuilder @@ -514,7 +515,7 @@ class MainActivity : PassphraseRequiredActivity(), VoiceNoteMediaControllerOwner ) if (!windowSizeClass.isSplitPane()) { - NavigationBarSpacerCompat() + Spacer(Modifier.navigationBarsPadding()) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentUploadUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentUploadUtil.kt index ade12ec818..87c114dc05 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentUploadUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/AttachmentUploadUtil.kt @@ -7,7 +7,6 @@ package org.thoughtcrime.securesms.attachments import android.content.Context import android.graphics.Bitmap -import android.os.Build import org.signal.core.util.logging.Log import org.signal.core.util.mebiBytes import org.signal.protos.resumableuploads.ResumableUpload @@ -93,11 +92,6 @@ object AttachmentUploadUtil { return attachment.blurHash.hash } - if (Build.VERSION.SDK_INT < 23) { - Log.w(TAG, "Video thumbnails not supported...") - return null - } - return MediaUtil.getVideoThumbnail(context, Objects.requireNonNull(attachment.uri), 1000)?.let { bitmap -> val thumb = Bitmap.createScaledBitmap(bitmap, 100, 100, false) bitmap.recycle() diff --git a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForms.kt b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForms.kt index 3e00cfb0ec..9cf9a43d2d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForms.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/audio/AudioWaveForms.kt @@ -4,7 +4,6 @@ import android.content.Context import android.net.Uri import android.util.LruCache import androidx.annotation.AnyThread -import androidx.annotation.RequiresApi import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.subjects.SingleSubject @@ -24,7 +23,6 @@ import kotlin.concurrent.write * * Maintains an in-memory cache of recently requested wave forms. */ -@RequiresApi(23) object AudioWaveForms { private val TAG = Log.tag(AudioWaveForms::class.java) diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/fallback/FallbackAvatarDrawable.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/fallback/FallbackAvatarDrawable.kt index 8709a05282..3bf7fea285 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/fallback/FallbackAvatarDrawable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/fallback/FallbackAvatarDrawable.kt @@ -10,7 +10,6 @@ import android.content.res.ColorStateList import android.graphics.Canvas import android.graphics.Rect import android.graphics.drawable.Drawable -import android.os.Build import androidx.core.content.ContextCompat import com.airbnb.lottie.SimpleColorFilter import com.google.android.material.shape.MaterialShapeDrawable @@ -58,9 +57,7 @@ class FallbackAvatarDrawable( ) resourceIcon.bounds = iconBounds - if (Build.VERSION.SDK_INT >= 23) { - resourceIcon.setLayoutDirection(layoutDirection) - } + resourceIcon.setLayoutDirection(layoutDirection) resourceIcon } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java index f4d2382a10..f3effaf30c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.backup; import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -24,8 +23,8 @@ public final class BackupPassphrase { String passphrase = TextSecurePreferences.getBackupPassphrase(context); String encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context); - if (Build.VERSION.SDK_INT < 23 || (passphrase == null && encryptedPassphrase == null)) { - return stripSpaces(passphrase); + if (passphrase == null && encryptedPassphrase == null) { + return null; } if (encryptedPassphrase == null) { @@ -40,8 +39,8 @@ public final class BackupPassphrase { } public static void set(@NonNull Context context, @Nullable String passphrase) { - if (passphrase == null || Build.VERSION.SDK_INT < 23) { - TextSecurePreferences.setBackupPassphrase(context, passphrase); + if (passphrase == null) { + TextSecurePreferences.setBackupPassphrase(context, null); TextSecurePreferences.setEncryptedBackupPassphrase(context, null); } else { KeyStoreHelper.SealedData encryptedPassphrase = KeyStoreHelper.seal(passphrase.getBytes()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt index f4560d8ed1..f83ca946ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/banner/banners/DozeBanner.kt @@ -6,7 +6,6 @@ package org.thoughtcrime.securesms.banner.banners import android.content.Context -import android.os.Build import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource @@ -27,17 +26,13 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences class DozeBanner(private val context: Context, private val onDismissListener: () -> Unit) : Banner() { override val enabled: Boolean - get() = Build.VERSION.SDK_INT >= 23 && !SignalStore.account.fcmEnabled && !TextSecurePreferences.hasPromptedOptimizeDoze(context) && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName) + get() = !SignalStore.account.fcmEnabled && !TextSecurePreferences.hasPromptedOptimizeDoze(context) && !ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.packageName) override val dataFlow: Flow get() = flowOf(Unit) @Composable override fun DisplayBanner(model: Unit, contentPadding: PaddingValues) { - if (Build.VERSION.SDK_INT < 23) { - throw IllegalStateException("Showing a Doze banner for an OS prior to Android 6.0") - } - Banner( contentPadding = contentPadding, onDismissListener = { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/AudioView.java b/app/src/main/java/org/thoughtcrime/securesms/components/AudioView.java index 94e7528eff..8f15bb81e2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/AudioView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/AudioView.java @@ -219,28 +219,21 @@ public final class AudioView extends FrameLayout { if (seekBar instanceof WaveFormSeekBarView) { WaveFormSeekBarView waveFormView = (WaveFormSeekBarView) seekBar; waveFormView.setColors(waveFormPlayedBarsColor, waveFormUnplayedBarsColor, waveFormThumbTint); - if (android.os.Build.VERSION.SDK_INT >= 23) { - if (audioSlide == null || !Objects.equals(audioSlide.getUri(), audio.getUri())) { - disposable.dispose(); - disposable = AudioWaveForms.getWaveForm(getContext(), audio.asAttachment()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - data -> { - durationMillis = data.getDuration(TimeUnit.MILLISECONDS); - updateProgress(0, 0); - if (!forceHideDuration && duration != null) { - duration.setVisibility(VISIBLE); - } - waveFormView.setWaveData(data.getWaveForm()); - }, - t -> waveFormView.setWaveMode(false) - ); - } - } else { - waveFormView.setWaveMode(false); - if (duration != null) { - duration.setVisibility(GONE); - } + if (audioSlide == null || !Objects.equals(audioSlide.getUri(), audio.getUri())) { + disposable.dispose(); + disposable = AudioWaveForms.getWaveForm(getContext(), audio.asAttachment()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + data -> { + durationMillis = data.getDuration(TimeUnit.MILLISECONDS); + updateProgress(0, 0); + if (!forceHideDuration && duration != null) { + duration.setVisibility(VISIBLE); + } + waveFormView.setWaveData(data.getWaveForm()); + }, + t -> waveFormView.setWaveMode(false) + ); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt index c896e6f4e1..5a42298e57 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt @@ -18,7 +18,6 @@ import androidx.lifecycle.Lifecycle import org.signal.core.util.concurrent.LifecycleDisposable import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.components.DebugLogsPromptDialogFragment.Purpose.entries import org.thoughtcrime.securesms.databinding.PromptLogsBottomSheetBinding import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -159,11 +158,7 @@ class DebugLogsPromptDialogFragment : FixedRoundedCornerBottomSheetDialogFragmen } private fun batteryOptimizationsString(): String { - return if (Build.VERSION.SDK_INT < 23) { - "N/A (API < 23)" - } else { - PowerManagerCompat.isIgnoringBatteryOptimizations(requireContext()).toString() - } + return PowerManagerCompat.isIgnoringBatteryOptimizations(requireContext()).toString() } private fun backgroundRestrictedString(): String { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java index 60210d8c44..751cea3244 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java @@ -135,7 +135,7 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { protected void onAttachedToWindow() { super.onAttachedToWindow(); rotation = getDeviceRotation(); - if (Build.VERSION.SDK_INT >= 23 && getRootWindowInsets() != null) { + if (getRootWindowInsets() != null) { int bottomInset; WindowInsets windowInsets = getRootWindowInsets(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/PromptBatterySaverDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/PromptBatterySaverDialogFragment.kt index 6ee4197c41..622fe24dd2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/PromptBatterySaverDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/PromptBatterySaverDialogFragment.kt @@ -9,7 +9,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import androidx.core.os.bundleOf import androidx.fragment.app.FragmentManager @@ -23,7 +22,6 @@ import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.LocalMetrics import org.thoughtcrime.securesms.util.PowerManagerCompat -@RequiresApi(23) class PromptBatterySaverDialogFragment : FixedRoundedCornerBottomSheetDialogFragment() { companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java index 808dc4e20a..18e49668d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java @@ -604,9 +604,7 @@ public class ThumbnailView extends FrameLayout { .downsample(SignalDownsampleStrategy.CENTER_OUTSIDE_NO_UPSCALE) .transition(withCrossFade())); - boolean doNotShowMissingThumbnailImage = Build.VERSION.SDK_INT < 23; - - if (slide.isInProgress() || doNotShowMissingThumbnailImage) { + if (slide.isInProgress()) { return requestBuilder; } else { return requestBuilder.apply(RequestOptions.errorOf(R.drawable.missing_thumbnail)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java index f65fc49969..5f2d22f4f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiEditText.java @@ -116,16 +116,12 @@ public class EmojiEditText extends AppCompatEditText { ClipData clipData = ServiceUtil.getClipboardManager(getContext()).getPrimaryClip(); if (clipData != null) { - CharSequence label = clipData.getDescription().getLabel(); - CharSequence pendingPaste = getTextFromClipData(clipData); + CharSequence label = clipData.getDescription().getLabel(); if (TextUtils.equals(Util.COPY_LABEL, label) && shouldPersistSignalStylingWhenPasting()) { return super.onTextContextMenuItem(id); - } else if (Build.VERSION.SDK_INT >= 23) { + } else { return super.onTextContextMenuItem(android.R.id.pasteAsPlainText); - } else if (pendingPaste != null) { - Util.copyToClipboard(getContext(), pendingPaste.toString()); - return super.onTextContextMenuItem(id); } } } else if (id == android.R.id.copy || id == android.R.id.cut) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt index 0ef42072fa..4d0017854e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt @@ -10,7 +10,6 @@ import android.widget.Toast import androidx.activity.result.ActivityResultCallback import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContract -import androidx.annotation.RequiresApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer @@ -238,7 +237,6 @@ open class DefaultNotificationsSettingsCallbacks( viewModel.setMessageNotificationPrivacy(selection) } - @RequiresApi(23) override fun onTroubleshootNotificationsClick() { PromptBatterySaverDialogFragment.show(activity.supportFragmentManager) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationErrorNotifications.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationErrorNotifications.kt index c345b2f1d5..30af7ef1f6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationErrorNotifications.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/errors/DonationErrorNotifications.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri -import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat @@ -106,7 +105,7 @@ object DonationErrorNotifications { context, 0, actionIntent, - if (Build.VERSION.SDK_INT >= 23) PendingIntentFlags.oneShot() else PendingIntentFlags.mutable() + PendingIntentFlags.oneShot() ) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java index 2937b42453..98ee6cca18 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/AttachmentSecretProvider.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.crypto; import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; @@ -60,25 +59,17 @@ public class AttachmentSecretProvider { { AttachmentSecret attachmentSecret = AttachmentSecret.fromString(unencryptedSecret); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return attachmentSecret; - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); - TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); - TextSecurePreferences.setAttachmentUnencryptedSecret(context, null); + TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); + TextSecurePreferences.setAttachmentUnencryptedSecret(context, null); - return attachmentSecret; - } + return attachmentSecret; } private AttachmentSecret getEncryptedAttachmentSecret(@NonNull String serializedEncryptedSecret) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); - return AttachmentSecret.fromString(new String(KeyStoreHelper.unseal(encryptedSecret))); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); + return AttachmentSecret.fromString(new String(KeyStoreHelper.unseal(encryptedSecret))); } private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) { @@ -93,12 +84,7 @@ public class AttachmentSecretProvider { } private void storeAttachmentSecret(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); - TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setAttachmentUnencryptedSecret(context, attachmentSecret.serialize()); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); + TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); } - } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java index 7980764929..bd64474461 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/DatabaseSecretProvider.java @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.crypto; import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; @@ -48,28 +47,20 @@ public final class DatabaseSecretProvider { try { DatabaseSecret databaseSecret = new DatabaseSecret(unencryptedSecret); - if (Build.VERSION.SDK_INT < 23) { - return databaseSecret; - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); - TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); - TextSecurePreferences.setDatabaseUnencryptedSecret(context, null); + TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); + TextSecurePreferences.setDatabaseUnencryptedSecret(context, null); - return databaseSecret; - } + return databaseSecret; } catch (IOException e) { throw new AssertionError(e); } } private static @NonNull DatabaseSecret getEncryptedDatabaseSecret(@NonNull String serializedEncryptedSecret) { - if (Build.VERSION.SDK_INT < 23) { - throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); - } else { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); - return new DatabaseSecret(KeyStoreHelper.unseal(encryptedSecret)); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); + return new DatabaseSecret(KeyStoreHelper.unseal(encryptedSecret)); } private static @NonNull DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) { @@ -79,12 +70,8 @@ public final class DatabaseSecretProvider { DatabaseSecret databaseSecret = new DatabaseSecret(secret); - if (Build.VERSION.SDK_INT >= 23) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); - TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setDatabaseUnencryptedSecret(context, databaseSecret.asString()); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); + TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); return databaseSecret; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/KeyStoreHelper.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/KeyStoreHelper.java index 0a429a7afd..ae3bd2b03f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/KeyStoreHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/KeyStoreHelper.java @@ -51,7 +51,6 @@ public final class KeyStoreHelper { private static final String KEY_ALIAS = "SignalSecret"; private static final Executor executor = Executors.newSingleThreadExecutor(); - @RequiresApi(23) public static SealedData seal(@NonNull byte[] input) { CountDownLatch latch = new CountDownLatch(1); AtomicReference result = new AtomicReference<>(); @@ -83,7 +82,6 @@ public final class KeyStoreHelper { return result.get(); } - @RequiresApi(23) public static byte[] unseal(@NonNull SealedData sealedData) { CountDownLatch latch = new CountDownLatch(1); AtomicReference result = new AtomicReference<>(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt index a4ece1a85d..95d40ce4af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt @@ -22,7 +22,6 @@ import android.database.Cursor import android.media.MediaDataSource import android.os.Parcelable import android.text.TextUtils -import androidx.annotation.RequiresApi import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread import androidx.core.content.contentValuesOf @@ -2150,7 +2149,6 @@ class AttachmentTable( .run() } - @RequiresApi(23) fun mediaDataSourceFor(attachmentId: AttachmentId, allowReadingFromTempFile: Boolean): MediaDataSource? { val dataInfo = getDataFileInfo(attachmentId) if (dataInfo != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt index 4111692da1..1ea4713b41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt @@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.jobs -import android.os.Build import org.signal.core.util.logging.Log import org.signal.protos.resumableuploads.ResumableUpload import org.thoughtcrime.securesms.attachments.AttachmentId @@ -263,7 +262,7 @@ class ArchiveThumbnailUploadJob private constructor( return if (MediaUtil.isImageType(attachment.contentType)) { compress(uri, attachment.contentType ?: "") - } else if (Build.VERSION.SDK_INT >= 23 && MediaUtil.isVideoType(attachment.contentType)) { + } else if (MediaUtil.isVideoType(attachment.contentType)) { MediaUtil.getVideoThumbnail(context, attachment.uri)?.let { compress(uri, attachment.contentType ?: "") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt index 125deed6e7..b8b6fc7dc4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GenerateAudioWaveFormJob.kt @@ -1,7 +1,5 @@ package org.thoughtcrime.securesms.jobs -import android.os.Build -import androidx.annotation.RequiresApi import org.signal.core.util.concurrent.safeBlockingGet import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.attachments.AttachmentId @@ -28,11 +26,7 @@ class GenerateAudioWaveFormJob private constructor(private val attachmentId: Att @JvmStatic fun enqueue(attachmentId: AttachmentId) { - if (Build.VERSION.SDK_INT < 23) { - Log.i(TAG, "Unable to generate waveform on this version of Android") - } else { - AppDependencies.jobManager.add(GenerateAudioWaveFormJob(attachmentId)) - } + AppDependencies.jobManager.add(GenerateAudioWaveFormJob(attachmentId)) } } @@ -53,7 +47,6 @@ class GenerateAudioWaveFormJob private constructor(private val attachmentId: Att override fun getFactoryKey(): String = KEY - @RequiresApi(23) override fun onRun() { val attachment: DatabaseAttachment? = SignalDatabase.attachments.getAttachment(attachmentId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java b/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java index 57ac3ee714..208d3e8626 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logging/LogSecretProvider.java @@ -1,12 +1,11 @@ package org.thoughtcrime.securesms.logging; import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.crypto.KeyStoreHelper; import org.signal.core.util.Base64; +import org.thoughtcrime.securesms.crypto.KeyStoreHelper; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.io.IOException; @@ -32,12 +31,8 @@ public class LogSecretProvider { } private static byte[] parseEncryptedSecret(String secret) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(secret); - return KeyStoreHelper.unseal(encryptedSecret); - } else { - throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(secret); + return KeyStoreHelper.unseal(encryptedSecret); } private static byte[] createAndStoreSecret(@NonNull Context context) { @@ -45,12 +40,8 @@ public class LogSecretProvider { byte[] secret = new byte[32]; random.nextBytes(secret); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); - TextSecurePreferences.setLogEncryptedSecret(context, encryptedSecret.serialize()); - } else { - TextSecurePreferences.setLogUnencryptedSecret(context, Base64.encodeWithPadding(secret)); - } + KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(secret); + TextSecurePreferences.setLogEncryptedSecret(context, encryptedSecret.serialize()); return secret; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionMemory.kt b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionMemory.kt index a5d568f3de..f857e68734 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionMemory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionMemory.kt @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.logsubmit import android.content.Context -import android.os.Build import org.signal.core.util.MemoryTracker import org.signal.core.util.bytes import org.signal.core.util.kibiBytes @@ -28,20 +27,18 @@ class LogSectionMemory : LogSection { Low Memory? : ${nativeMemory.lowMemory} """.trimIndent() - if (Build.VERSION.SDK_INT >= 23) { - val detailedMemory = MemoryTracker.getDetailedMemoryStats() + val detailedMemory = MemoryTracker.getDetailedMemoryStats() - base += "\n\n" - base += """ - -- Detailed Memory (API 23+) - App JVM Heap Usage : ${detailedMemory.appJavaHeapUsageKb?.kbDisplay()} - App Native Heap Usage: ${detailedMemory.appNativeHeapUsageKb?.kbDisplay()} - Code Usage : ${detailedMemory.codeUsageKb?.kbDisplay()} - Graphics Usage : ${detailedMemory.graphicsUsageKb?.kbDisplay()} - Stack Usage : ${detailedMemory.stackUsageKb?.kbDisplay()} - Other Usage : ${detailedMemory.appOtherUsageKb?.kbDisplay()} - """.trimIndent() - } + base += "\n\n" + base += """ + -- Detailed Memory (API 23+) + App JVM Heap Usage : ${detailedMemory.appJavaHeapUsageKb?.kbDisplay()} + App Native Heap Usage: ${detailedMemory.appNativeHeapUsageKb?.kbDisplay()} + Code Usage : ${detailedMemory.codeUsageKb?.kbDisplay()} + Graphics Usage : ${detailedMemory.graphicsUsageKb?.kbDisplay()} + Stack Usage : ${detailedMemory.stackUsageKb?.kbDisplay()} + Other Usage : ${detailedMemory.appOtherUsageKb?.kbDisplay()} + """.trimIndent() return base } diff --git a/app/src/main/java/org/thoughtcrime/securesms/main/NavigationBarSpacerCompat.kt b/app/src/main/java/org/thoughtcrime/securesms/main/NavigationBarSpacerCompat.kt deleted file mode 100644 index f3fe4789f7..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/main/NavigationBarSpacerCompat.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2025 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.thoughtcrime.securesms.main - -import android.os.Build -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import org.signal.core.util.DimensionUnit -import org.thoughtcrime.securesms.util.ViewUtil - -@Composable -fun NavigationBarSpacerCompat() { - if (Build.VERSION.SDK_INT >= 23) { - Spacer(Modifier.navigationBarsPadding()) - } else { - val resources = LocalContext.current.resources - val navigationBarHeight = remember(resources) { - DimensionUnit.PIXELS.toDp(ViewUtil.getNavigationBarHeight(resources).toFloat()).dp - } - - Spacer(Modifier.height(navigationBarHeight)) - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoEditorFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoEditorFragment.kt index 558589ea1e..23fdac0af4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoEditorFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/VideoEditorFragment.kt @@ -1,14 +1,12 @@ package org.thoughtcrime.securesms.mediasend import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.annotation.RequiresApi import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import org.signal.core.util.logging.Log @@ -161,7 +159,6 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm } } - @RequiresApi(23) private fun bindVideoTimeline(data: VideoTrimData) { val autoplay = isVideoGif val slide = VideoSlide(requireContext(), uri, 0, autoplay) @@ -213,10 +210,8 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm } private fun startPositionUpdates() { - if (Build.VERSION.SDK_INT >= 23) { - stopPositionUpdates() - handler.post(updatePosition) - } + stopPositionUpdates() + handler.post(updatePosition) } private fun stopPositionUpdates() { @@ -250,7 +245,6 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm hud.showPlayButton() } - @RequiresApi(23) private fun onEditVideoDuration(data: VideoTrimData, editingComplete: Boolean) { if (editingComplete) { isInEdit = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/VideoSlide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/VideoSlide.java index afa2105eb0..da86906da5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/VideoSlide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/VideoSlide.java @@ -19,7 +19,6 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; import android.content.res.Resources.Theme; import android.net.Uri; -import android.os.Build; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; @@ -56,7 +55,7 @@ public class VideoSlide extends Slide { @Override public boolean hasPlayOverlay() { - return !(isVideoGif() && GiphyMp4PlaybackPolicy.autoplay()) || Build.VERSION.SDK_INT < 23; + return !(isVideoGif() && GiphyMp4PlaybackPolicy.autoplay()); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java index 908fdd93b5..4c32c64d64 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DoNotDisturbUtil.java @@ -9,14 +9,13 @@ import android.os.Build; import android.provider.ContactsContract; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; +import org.signal.core.util.CursorUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; -import org.signal.core.util.CursorUtil; import org.thoughtcrime.securesms.util.ServiceUtil; import java.util.concurrent.TimeUnit; @@ -31,8 +30,6 @@ public final class DoNotDisturbUtil { @WorkerThread @SuppressLint("SwitchIntDef") public static boolean shouldDisturbUserWithCall(@NonNull Context context) { - if (Build.VERSION.SDK_INT <= 23) return true; - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); switch (notificationManager.getCurrentInterruptionFilter()) { @@ -47,8 +44,6 @@ public final class DoNotDisturbUtil { @WorkerThread @SuppressLint("SwitchIntDef") public static boolean shouldDisturbUserWithCall(@NonNull Context context, @NonNull Recipient recipient) { - if (Build.VERSION.SDK_INT <= 23) return true; - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); switch (notificationManager.getCurrentInterruptionFilter()) { @@ -65,7 +60,6 @@ public final class DoNotDisturbUtil { } } - @RequiresApi(23) private static boolean handlePriority(@NonNull Context context, @NonNull NotificationManager notificationManager, @NonNull Recipient recipient) { if (Build.VERSION.SDK_INT < 28 && !notificationManager.isNotificationPolicyAccessGranted()) { Log.w(TAG, "Notification Policy is not granted"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java index 9f6b4d29ca..e2eb48646e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCancellationHelper.java @@ -14,8 +14,8 @@ import com.annimon.stream.Stream; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.AppDependencies; -import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier; import org.thoughtcrime.securesms.notifications.v2.ConversationId; +import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.BubbleUtil; import org.thoughtcrime.securesms.util.ConversationUtil; @@ -53,31 +53,27 @@ public final class NotificationCancellationHelper { * bubble notifications that do not have unread messages in them. */ public static void cancelAllMessageNotifications(@NonNull Context context, @NonNull Set stickyNotifications) { - if (Build.VERSION.SDK_INT >= 23) { - try { - NotificationManager notifications = ServiceUtil.getNotificationManager(context); - StatusBarNotification[] activeNotifications = notifications.getActiveNotifications(); - int activeCount = 0; + try { + NotificationManager notifications = ServiceUtil.getNotificationManager(context); + StatusBarNotification[] activeNotifications = notifications.getActiveNotifications(); + int activeCount = 0; - for (StatusBarNotification activeNotification : activeNotifications) { - if (isSingleThreadNotification(activeNotification)) { - activeCount++; - if (!stickyNotifications.contains(activeNotification.getId()) && cancel(context, activeNotification.getId())) { - activeCount--; - } + for (StatusBarNotification activeNotification : activeNotifications) { + if (isSingleThreadNotification(activeNotification)) { + activeCount++; + if (!stickyNotifications.contains(activeNotification.getId()) && cancel(context, activeNotification.getId())) { + activeCount--; } } - - if (activeCount == 0) { - cancelLegacy(context, NotificationIds.MESSAGE_SUMMARY); - } - } catch (Throwable e) { - // XXX Appears to be a ROM bug, see #6043 - Log.w(TAG, "Canceling all notifications.", e); - ServiceUtil.getNotificationManager(context).cancelAll(); } - } else { - cancelLegacy(context, NotificationIds.MESSAGE_SUMMARY); + + if (activeCount == 0) { + cancelLegacy(context, NotificationIds.MESSAGE_SUMMARY); + } + } catch (Throwable e) { + // XXX Appears to be a ROM bug, see #6043 + Log.w(TAG, "Canceling all notifications.", e); + ServiceUtil.getNotificationManager(context).cancelAll(); } } @@ -110,7 +106,6 @@ public final class NotificationCancellationHelper { /** * @return whether this is a non-summary notification that is a member of the NOTIFICATION_GROUP group. */ - @RequiresApi(23) private static boolean isSingleThreadNotification(@NonNull StatusBarNotification statusBarNotification) { return statusBarNotification.getId() != NotificationIds.MESSAGE_SUMMARY && Objects.equals(statusBarNotification.getNotification().getGroup(), DefaultMessageNotifier.NOTIFICATION_GROUP); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt index 68c17aef1d..cf6c917331 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt @@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.notifications -import android.os.Build import android.text.TextUtils import androidx.annotation.WorkerThread import org.signal.core.util.logging.Log @@ -76,10 +75,6 @@ object SlowNotificationHeuristics { @JvmStatic fun shouldPromptBatterySaver(): Boolean { - if (Build.VERSION.SDK_INT < 23) { - return false - } - val remoteEnabled = LocaleRemoteConfig.isBatterySaverPromptEnabled() || LocaleRemoteConfig.isDelayedNotificationPromptEnabled() if (!remoteEnabled || SignalStore.uiHints.hasDismissedBatterySaverPrompt()) { return false diff --git a/app/src/main/java/org/thoughtcrime/securesms/permissions/Permissions.java b/app/src/main/java/org/thoughtcrime/securesms/permissions/Permissions.java index 732a534542..a82fa4ad40 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/permissions/Permissions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/permissions/Permissions.java @@ -6,7 +6,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; import android.provider.Settings; import android.util.DisplayMetrics; import android.view.Display; @@ -16,7 +15,6 @@ import android.view.WindowManager; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; @@ -52,10 +50,6 @@ public class Permissions { return new PermissionsBuilder(new FragmentPermissionObject(fragment)); } - public static boolean isRuntimePermissionsRequired() { - return Build.VERSION.SDK_INT >= 23; - } - public static class PermissionsBuilder { private final PermissionObject permissionObject; @@ -277,14 +271,12 @@ public class Permissions { } public static boolean hasAny(@NonNull Context context, String... permissions) { - return !isRuntimePermissionsRequired() || - Stream.of(permissions).anyMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED); + return Stream.of(permissions).anyMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED); } public static boolean hasAll(@NonNull Context context, String... permissions) { - return !isRuntimePermissionsRequired() || - Stream.of(permissions).allMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED); + return Stream.of(permissions).allMatch(permission -> ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java index 2c1f6cc2f4..fcf183a1a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java @@ -10,7 +10,6 @@ import androidx.annotation.AnyThread; import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; @@ -155,7 +154,6 @@ public class BlobProvider { position)); } - @RequiresApi(23) public synchronized @NonNull MediaDataSource getMediaDataSource(@NonNull Context context, @NonNull Uri uri) throws IOException { waitUntilInitialized(); return getBlobRepresentation(context, diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt index 029abbdfe9..5bf6627cfb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.push import android.content.Context import android.net.ConnectivityManager -import android.os.Build import androidx.core.content.ContextCompat import com.google.i18n.phonenumbers.PhoneNumberUtil import okhttp3.CipherSuite @@ -33,7 +32,6 @@ import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url import java.io.IOException import java.util.Optional -import android.net.Proxy as AndroidProxy /** * Provides a [SignalServiceConfiguration] to be used with our service layer. @@ -142,24 +140,13 @@ class SignalServiceNetworkAccess(context: Context) { @Suppress("DEPRECATION") private fun getSystemHttpProxy(context: Context): HttpProxy? { - return if (Build.VERSION.SDK_INT >= 23) { - val connectivityManager = ContextCompat.getSystemService(context, ConnectivityManager::class.java) ?: return null + val connectivityManager = ContextCompat.getSystemService(context, ConnectivityManager::class.java) ?: return null - connectivityManager - .activeNetwork - ?.let { connectivityManager.getLinkProperties(it)?.httpProxy } - ?.takeIf { !it.exclusionList.contains(BuildConfig.SIGNAL_URL.stripProtocol()) } - ?.let { proxy -> HttpProxy(proxy.host, proxy.port) } - } else { - val host: String? = AndroidProxy.getHost(context) - val port: Int = AndroidProxy.getPort(context) - - if (host != null) { - HttpProxy(host, port) - } else { - null - } - } + return connectivityManager + .activeNetwork + ?.let { connectivityManager.getLinkProperties(it)?.httpProxy } + ?.takeIf { !it.exclusionList.contains(BuildConfig.SIGNAL_URL.stripProtocol()) } + ?.let { proxy -> HttpProxy(proxy.host, proxy.port) } } } @@ -298,9 +285,11 @@ class SignalServiceNetworkAccess(context: Context) { SettingsValues.CensorshipCircumventionEnabled.ENABLED -> { censorshipConfiguration[countryCode] ?: defaultCensoredConfiguration } + SettingsValues.CensorshipCircumventionEnabled.DISABLED -> { uncensoredConfiguration } + SettingsValues.CensorshipCircumventionEnabled.DEFAULT -> { if (defaultCensoredCountryCodes.contains(countryCode)) { censorshipConfiguration[countryCode] ?: defaultCensoredConfiguration diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/SignalStrengthPhoneStateListener.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/SignalStrengthPhoneStateListener.java index abbe6d0048..2b7f961a6d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/SignalStrengthPhoneStateListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/SignalStrengthPhoneStateListener.java @@ -55,12 +55,7 @@ public final class SignalStrengthPhoneStateListener extends PhoneStateListener } private boolean isLowLevel(@NonNull SignalStrength signalStrength) { - if (Build.VERSION.SDK_INT >= 23) { - return signalStrength.getLevel() == 0; - } else { - //noinspection deprecation: False lint warning, deprecated by 29, but this else block is for < 23 - return signalStrength.getGsmSignalStrength() == 0; - } + return signalStrength.getLevel() == 0; } public interface Callback { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/permissions/GrantPermissionsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/permissions/GrantPermissionsFragment.kt index 0ec824d583..f09092475d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/permissions/GrantPermissionsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/permissions/GrantPermissionsFragment.kt @@ -8,7 +8,6 @@ package org.thoughtcrime.securesms.registration.ui.permissions import android.content.pm.PackageManager import android.os.Build import androidx.activity.result.contract.ActivityResultContracts -import androidx.annotation.RequiresApi import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import androidx.core.content.ContextCompat @@ -28,7 +27,6 @@ import org.thoughtcrime.securesms.util.BackupUtil /** * Screen in account registration that provides rationales for the suggested runtime permissions. */ -@RequiresApi(23) class GrantPermissionsFragment : ComposeFragment() { companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/welcome/WelcomeFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/welcome/WelcomeFragment.kt index f3d496e347..d755f13eba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/welcome/WelcomeFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/welcome/WelcomeFragment.kt @@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.databinding.FragmentRegistrationWelcomeV3Binding -import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView import org.thoughtcrime.securesms.registration.fragments.WelcomePermissions import org.thoughtcrime.securesms.registration.ui.RegistrationCheckpoint @@ -75,23 +74,21 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome_v } } - if (Permissions.isRuntimePermissionsRequired()) { - parentFragmentManager.setFragmentResultListener(GrantPermissionsFragment.REQUEST_KEY, viewLifecycleOwner) { requestKey, bundle -> - if (requestKey == GrantPermissionsFragment.REQUEST_KEY) { - when (val userSelection = bundle.getSerializableCompat(GrantPermissionsFragment.REQUEST_KEY, WelcomeUserSelection::class.java)) { - WelcomeUserSelection.RESTORE_WITH_OLD_PHONE, - WelcomeUserSelection.RESTORE_WITH_NO_PHONE -> navigateToNextScreenViaRestore(userSelection) - WelcomeUserSelection.CONTINUE -> navigateToNextScreenViaContinue() - WelcomeUserSelection.LINK -> navigateToLinkDevice() - null -> Unit - } + parentFragmentManager.setFragmentResultListener(GrantPermissionsFragment.REQUEST_KEY, viewLifecycleOwner) { requestKey, bundle -> + if (requestKey == GrantPermissionsFragment.REQUEST_KEY) { + when (val userSelection = bundle.getSerializableCompat(GrantPermissionsFragment.REQUEST_KEY, WelcomeUserSelection::class.java)) { + WelcomeUserSelection.RESTORE_WITH_OLD_PHONE, + WelcomeUserSelection.RESTORE_WITH_NO_PHONE -> navigateToNextScreenViaRestore(userSelection) + WelcomeUserSelection.CONTINUE -> navigateToNextScreenViaContinue() + WelcomeUserSelection.LINK -> navigateToLinkDevice() + null -> Unit } } } } private fun onLinkDeviceClicked() { - if (Permissions.isRuntimePermissionsRequired() && !hasAllPermissions()) { + if (!hasAllPermissions()) { findNavController().safeNavigate(WelcomeFragmentDirections.actionWelcomeFragmentToGrantPermissionsFragment(WelcomeUserSelection.LINK)) } else { navigateToLinkDevice() @@ -108,7 +105,7 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome_v } private fun onContinueClicked() { - if (Permissions.isRuntimePermissionsRequired() && !hasAllPermissions()) { + if (!hasAllPermissions()) { findNavController().safeNavigate(WelcomeFragmentDirections.actionWelcomeFragmentToGrantPermissionsFragment(WelcomeUserSelection.CONTINUE)) } else { navigateToNextScreenViaContinue() @@ -129,7 +126,7 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome_v } private fun afterRestoreOrTransferClicked(userSelection: WelcomeUserSelection) { - if (Permissions.isRuntimePermissionsRequired() && !hasAllPermissions()) { + if (!hasAllPermissions()) { findNavController().safeNavigate(WelcomeFragmentDirections.actionWelcomeFragmentToGrantPermissionsFragment(userSelection)) } else { navigateToNextScreenViaRestore(userSelection) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java index 67d60dbb22..ce5dfa5dfc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java @@ -24,7 +24,6 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; -import android.os.Build; import android.os.IBinder; import android.os.SystemClock; @@ -313,11 +312,7 @@ public class KeyCachingService extends Service { } private static int getPendingIntentFlags() { - if (Build.VERSION.SDK_INT >= 23) { - return PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT; - } else { - return PendingIntent.FLAG_UPDATE_CURRENT; - } + return PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT; } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MediaMetadataRetrieverUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/MediaMetadataRetrieverUtil.java index 04be39b9f5..24dd827610 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MediaMetadataRetrieverUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MediaMetadataRetrieverUtil.java @@ -4,7 +4,6 @@ import android.media.MediaDataSource; import android.media.MediaMetadataRetriever; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import java.io.IOException; @@ -16,7 +15,6 @@ public final class MediaMetadataRetrieverUtil { * {@link MediaMetadataRetriever#setDataSource(MediaDataSource)} tends to crash in native code on * specific devices, so this just a wrapper to convert that into an {@link IOException}. */ - @RequiresApi(23) public static void setDataSource(@NonNull MediaMetadataRetriever retriever, @NonNull MediaDataSource dataSource) throws IOException diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java index b1465a9957..0fd3580ba6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java @@ -12,7 +12,6 @@ import android.media.MediaDataSource; import android.media.MediaMetadataRetriever; import android.media.ThumbnailUtils; import android.net.Uri; -import android.os.Build; import android.provider.MediaStore; import android.text.TextUtils; import android.util.Pair; @@ -20,7 +19,6 @@ import android.webkit.MimeTypeMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; import androidx.exifinterface.media.ExifInterface; @@ -431,7 +429,7 @@ public class MediaUtil { return false; } - if (BlobProvider.isAuthority(uri) && MediaUtil.isVideo(BlobProvider.getMimeType(uri)) && Build.VERSION.SDK_INT >= 23) { + if (BlobProvider.isAuthority(uri) && MediaUtil.isVideo(BlobProvider.getMimeType(uri))) { return true; } @@ -476,8 +474,7 @@ public class MediaUtil { MediaUtil.isVideo(URLConnection.guessContentTypeFromName(uri.toString()))) { return ThumbnailUtils.createVideoThumbnail(uri.toString().replace("file://", ""), MediaStore.Video.Thumbnails.MINI_KIND); - } else if (Build.VERSION.SDK_INT >= 23 && - BlobProvider.isAuthority(uri) && + } else if (BlobProvider.isAuthority(uri) && MediaUtil.isVideo(BlobProvider.getMimeType(uri))) { try { @@ -486,8 +483,7 @@ public class MediaUtil { } catch (IOException e) { Log.w(TAG, "Failed to extract frame for URI: " + uri, e); } - } else if (Build.VERSION.SDK_INT >= 23 && - PartAuthority.isAttachmentUri(uri) && + } else if (PartAuthority.isAttachmentUri(uri) && MediaUtil.isVideoType(PartAuthority.getAttachmentContentType(context, uri))) { try { @@ -502,7 +498,6 @@ public class MediaUtil { return null; } - @RequiresApi(23) private static @Nullable Bitmap extractFrame(@Nullable MediaDataSource dataSource, long timeUs) throws IOException { if (dataSource == null) { return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java index ad10b425a9..abb1a65215 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/NetworkUtil.java @@ -89,17 +89,13 @@ public final class NetworkUtil { public static @NonNull NetworkStatus getNetworkStatus(@NonNull Context context) { ConnectivityManager connectivityManager = ServiceUtil.getConnectivityManager(context); - if (Build.VERSION.SDK_INT >= 23) { - Network network = connectivityManager.getActiveNetwork(); - NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network); + Network network = connectivityManager.getActiveNetwork(); + NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network); - boolean onVpn = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); - boolean isNotMetered = capabilities == null || capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + boolean onVpn = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); + boolean isNotMetered = capabilities == null || capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - return new NetworkStatus(onVpn, !isNotMetered); - } else { - return new NetworkStatus(false, false); - } + return new NetworkStatus(onVpn, !isNotMetered); } private static boolean useLowDataCalling(@NonNull Context context, @NonNull PeerConnection.AdapterType networkAdapter) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/PowerManagerCompat.java b/app/src/main/java/org/thoughtcrime/securesms/util/PowerManagerCompat.java index 8c202e3a40..551aa7df12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/PowerManagerCompat.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/PowerManagerCompat.java @@ -3,30 +3,21 @@ package org.thoughtcrime.securesms.util; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.Build; import android.os.PowerManager; import android.provider.Settings; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; public class PowerManagerCompat { public static boolean isDeviceIdleMode(@NonNull PowerManager powerManager) { - if (Build.VERSION.SDK_INT >= 23) { - return powerManager.isDeviceIdleMode(); - } - return false; + return powerManager.isDeviceIdleMode(); } public static boolean isIgnoringBatteryOptimizations(@NonNull Context context) { - if (Build.VERSION.SDK_INT < 23) { - return true; - } return ServiceUtil.getPowerManager(context).isIgnoringBatteryOptimizations(context.getPackageName()); } - @RequiresApi(api = 23) public static void requestIgnoreBatteryOptimizations(@NonNull Context context) { Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse("package:" + context.getPackageName())); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index acadff90cd..8f5a199bbd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -659,11 +659,7 @@ public class TextSecurePreferences { @Deprecated public static boolean isCallNotificationVibrateEnabled(Context context) { - boolean defaultValue = true; - - if (Build.VERSION.SDK_INT >= 23) { - defaultValue = (Settings.System.getInt(context.getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 1) == 1); - } + boolean defaultValue = (Settings.System.getInt(context.getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 1) == 1); return getBooleanPreference(context, CALL_VIBRATE_PREF, defaultValue); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java index deefc6c567..fcbca52464 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/WindowUtil.java @@ -62,8 +62,6 @@ public final class WindowUtil { } public static void setLightStatusBarFromTheme(@NonNull Activity activity) { - if (Build.VERSION.SDK_INT < 23) return; - final boolean isLightStatusBar = ThemeUtil.getThemedBoolean(activity, android.R.attr.windowLightStatusBar); if (isLightStatusBar) setLightStatusBar(activity.getWindow()); @@ -71,14 +69,10 @@ public final class WindowUtil { } public static void clearLightStatusBar(@NonNull Window window) { - if (Build.VERSION.SDK_INT < 23) return; - clearSystemUiFlags(window, View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } public static void setLightStatusBar(@NonNull Window window) { - if (Build.VERSION.SDK_INT < 23) return; - setSystemUiFlags(window, View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/ByteArrayMediaDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/ByteArrayMediaDataSource.java index 8eed88023b..3b650386b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/ByteArrayMediaDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/ByteArrayMediaDataSource.java @@ -2,11 +2,8 @@ package org.thoughtcrime.securesms.video; import android.media.MediaDataSource; -import androidx.annotation.RequiresApi; - import java.io.IOException; -@RequiresApi(23) public class ByteArrayMediaDataSource extends MediaDataSource { private byte[] data; diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/ClassicEncryptedMediaDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/ClassicEncryptedMediaDataSource.java index f4a019978e..fa254a46cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/ClassicEncryptedMediaDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/ClassicEncryptedMediaDataSource.java @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.video; import android.media.MediaDataSource; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream; @@ -13,7 +12,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -@RequiresApi(23) final class ClassicEncryptedMediaDataSource extends MediaDataSource { private final AttachmentSecret attachmentSecret; diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/EncryptedMediaDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/EncryptedMediaDataSource.java index 6001bcaca0..0328d8511d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/EncryptedMediaDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/EncryptedMediaDataSource.java @@ -4,13 +4,11 @@ import android.media.MediaDataSource; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import java.io.File; -@RequiresApi(23) public final class EncryptedMediaDataSource { public static MediaDataSource createFor(@NonNull AttachmentSecret attachmentSecret, @NonNull File mediaFile, @Nullable byte[] random, long length) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/ModernEncryptedMediaDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/ModernEncryptedMediaDataSource.java index 74c3b3508c..59d3343225 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/ModernEncryptedMediaDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/ModernEncryptedMediaDataSource.java @@ -4,7 +4,6 @@ import android.media.MediaDataSource; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; @@ -22,7 +21,6 @@ import java.io.InputStream; * It is "modern" compared to the {@link ClassicEncryptedMediaDataSource}. And "modern" refers to * the presence of a random part of the key supplied in the constructor. */ -@RequiresApi(23) final class ModernEncryptedMediaDataSource extends InputStreamMediaDataSource { private final AttachmentSecret attachmentSecret; diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java index 6685c7dedf..87a6e77f84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java @@ -172,33 +172,26 @@ public abstract class AudioManagerCompat { audioManager.clearCommunicationDevice(); } - @RequiresApi(23) public void registerAudioDeviceCallback(@NonNull AudioDeviceCallback deviceCallback, @NonNull Handler handler) { audioManager.registerAudioDeviceCallback(deviceCallback, handler); } - @RequiresApi(23) public void unregisterAudioDeviceCallback(@NonNull AudioDeviceCallback deviceCallback) { audioManager.unregisterAudioDeviceCallback(deviceCallback); } @SuppressLint("WrongConstant") public boolean isWiredHeadsetOn() { - if (Build.VERSION.SDK_INT < 23) { - //noinspection deprecation - return audioManager.isWiredHeadsetOn(); - } else { - AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL); - for (AudioDeviceInfo device : devices) { - final int type = device.getType(); - if (type == AudioDeviceInfo.TYPE_WIRED_HEADSET) { - return true; - } else if (type == AudioDeviceInfo.TYPE_USB_DEVICE) { - return true; - } + AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL); + for (AudioDeviceInfo device : devices) { + final int type = device.getType(); + if (type == AudioDeviceInfo.TYPE_WIRED_HEADSET) { + return true; + } else if (type == AudioDeviceInfo.TYPE_USB_DEVICE) { + return true; } - return false; } + return false; } public float ringVolumeWithMinimum() { diff --git a/core-util/src/main/java/org/signal/core/util/MemoryTracker.kt b/core-util/src/main/java/org/signal/core/util/MemoryTracker.kt index 19f728f032..8e2c7b65bd 100644 --- a/core-util/src/main/java/org/signal/core/util/MemoryTracker.kt +++ b/core-util/src/main/java/org/signal/core/util/MemoryTracker.kt @@ -9,7 +9,6 @@ import android.app.ActivityManager import android.content.Context import android.os.Debug import android.os.Handler -import androidx.annotation.RequiresApi import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.logging.Log import kotlin.time.Duration.Companion.milliseconds @@ -89,7 +88,6 @@ object MemoryTracker { * This gives us details stats, but it takes an appreciable amount of time. On an emulator, it can take ~30ms. * As a result, we don't want to be calling this regularly for most users. */ - @RequiresApi(23) fun getDetailedMemoryStats(): DetailedMemoryStats { Debug.getMemoryInfo(debugMemoryInfo) diff --git a/core-util/src/main/java/org/signal/core/util/PendingIntentFlags.kt b/core-util/src/main/java/org/signal/core/util/PendingIntentFlags.kt index 507e737bee..1adfa091f4 100644 --- a/core-util/src/main/java/org/signal/core/util/PendingIntentFlags.kt +++ b/core-util/src/main/java/org/signal/core/util/PendingIntentFlags.kt @@ -42,6 +42,6 @@ object PendingIntentFlags { @JvmStatic fun immutable(): Int { - return if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0 + return PendingIntent.FLAG_IMMUTABLE } } diff --git a/device-transfer/app/src/main/java/org/signal/devicetransfer/app/MainActivity.java b/device-transfer/app/src/main/java/org/signal/devicetransfer/app/MainActivity.java index c0a967d347..8b11cbe9cd 100644 --- a/device-transfer/app/src/main/java/org/signal/devicetransfer/app/MainActivity.java +++ b/device-transfer/app/src/main/java/org/signal/devicetransfer/app/MainActivity.java @@ -86,7 +86,7 @@ public class MainActivity extends AppCompatActivity { findViewById(R.id.stop).setOnClickListener(v -> DeviceToDeviceTransferService.stop(this)); findViewById(R.id.enable_permission).setOnClickListener(v -> { - if (Build.VERSION.SDK_INT >= 23 && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 420); } }); diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/WifiDirect.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/WifiDirect.java index 8834119d12..d816be00ca 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/WifiDirect.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/WifiDirect.java @@ -92,13 +92,13 @@ public final class WifiDirect { if (Build.VERSION.SDK_INT >= 33 && context.checkSelfPermission(Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "Nearby Wifi permission required"); return AvailableStatus.REQUIRED_PERMISSION_NOT_GRANTED; - } else if (Build.VERSION.SDK_INT < 33 && Build.VERSION.SDK_INT >= 23 && context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + } else if (Build.VERSION.SDK_INT < 33 && context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "Fine location permission required"); return AvailableStatus.REQUIRED_PERMISSION_NOT_GRANTED; } - return Build.VERSION.SDK_INT <= 23 || wifiManager.isP2pSupported() ? AvailableStatus.AVAILABLE - : AvailableStatus.WIFI_DIRECT_NOT_AVAILABLE; + return wifiManager.isP2pSupported() ? AvailableStatus.AVAILABLE + : AvailableStatus.WIFI_DIRECT_NOT_AVAILABLE; } WifiDirect(@NonNull Context context) { diff --git a/qr/app/src/main/java/org/signal/qrtest/QrMainActivity.kt b/qr/app/src/main/java/org/signal/qrtest/QrMainActivity.kt index 1033325ed4..e1162c5c23 100644 --- a/qr/app/src/main/java/org/signal/qrtest/QrMainActivity.kt +++ b/qr/app/src/main/java/org/signal/qrtest/QrMainActivity.kt @@ -2,7 +2,6 @@ package org.signal.qrtest import android.annotation.SuppressLint import android.graphics.Bitmap -import android.os.Build import android.os.Bundle import android.view.View import android.widget.EditText @@ -73,9 +72,7 @@ class QrMainActivity : AppCompatActivity() { text = findViewById(R.id.log) - if (Build.VERSION.SDK_INT >= 23) { - requestPermissions(arrayOf(android.Manifest.permission.CAMERA), 1) - } + requestPermissions(arrayOf(android.Manifest.permission.CAMERA), 1) val scanner = findViewById(R.id.scanner) scanner.start(this) diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/MediaConverter.java b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/MediaConverter.java index e19cc3ac45..353d950946 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/MediaConverter.java +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/MediaConverter.java @@ -29,9 +29,9 @@ import androidx.annotation.StringDef; import androidx.annotation.WorkerThread; import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.video.videoconverter.exceptions.EncodingException; import org.thoughtcrime.securesms.video.interfaces.MediaInput; import org.thoughtcrime.securesms.video.interfaces.Muxer; +import org.thoughtcrime.securesms.video.videoconverter.exceptions.EncodingException; import org.thoughtcrime.securesms.video.videoconverter.muxer.StreamingMuxer; import java.io.File; @@ -142,7 +142,6 @@ public final class MediaConverter { * @return The total content size of the MP4 mdat box. */ @WorkerThread - @RequiresApi(23) public long convert() throws EncodingException, IOException { // Exception that may be thrown during release. Exception exception = null; diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/VideoTrackConverter.java b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/VideoTrackConverter.java index a045d0ef0e..2fb2c1a11c 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/VideoTrackConverter.java +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/VideoTrackConverter.java @@ -14,7 +14,6 @@ import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.video.interfaces.MediaInput; @@ -78,7 +77,6 @@ final class VideoTrackConverter { private Muxer mMuxer; - @RequiresApi(23) static @Nullable VideoTrackConverter create( final @NonNull MediaInput input, final long timeFrom, @@ -97,7 +95,6 @@ final class VideoTrackConverter { } - @RequiresApi(23) private VideoTrackConverter( final @NonNull MediaExtractor videoExtractor, final int videoInputTrack, diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/InputStreamMediaDataSource.kt b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/InputStreamMediaDataSource.kt index db62e28c1b..bf79727771 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/InputStreamMediaDataSource.kt +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/InputStreamMediaDataSource.kt @@ -6,14 +6,12 @@ package org.thoughtcrime.securesms.video.videoconverter.mediadatasource import android.media.MediaDataSource -import androidx.annotation.RequiresApi import java.io.IOException import java.io.InputStream /** * Extend this class in order to be able to use the system media framework with any arbitrary [InputStream] of bytes. */ -@RequiresApi(23) abstract class InputStreamMediaDataSource : MediaDataSource() { @Throws(IOException::class) override fun readAt(position: Long, bytes: ByteArray?, offset: Int, length: Int): Int { diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/MediaDataSourceMediaInput.kt b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/MediaDataSourceMediaInput.kt index 12f87c8604..40edc51ff5 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/MediaDataSourceMediaInput.kt +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/mediadatasource/MediaDataSourceMediaInput.kt @@ -7,14 +7,12 @@ package org.thoughtcrime.securesms.video.videoconverter.mediadatasource import android.media.MediaDataSource import android.media.MediaExtractor -import androidx.annotation.RequiresApi import org.thoughtcrime.securesms.video.interfaces.MediaInput import java.io.IOException /** * [MediaInput] implementation that adds support for the system framework's media data source. */ -@RequiresApi(23) class MediaDataSourceMediaInput(private val mediaDataSource: MediaDataSource) : MediaInput { @Throws(IOException::class) override fun createExtractor(): MediaExtractor { diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/MediaCodecCompat.kt b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/MediaCodecCompat.kt index 963badbeb2..ca38600c23 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/MediaCodecCompat.kt +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/MediaCodecCompat.kt @@ -10,7 +10,6 @@ import android.media.MediaCodecInfo.CodecProfileLevel import android.media.MediaCodecList import android.media.MediaFormat import android.os.Build -import androidx.annotation.RequiresApi import org.signal.core.util.logging.Log import java.io.IOException @@ -77,9 +76,7 @@ object MediaCodecCompat { // dolby vision profile 04/08: Base layer is H.265 Main10 High Profile, Rec709/HLG/HDR10 mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_HEVC) mediaFormat.setInteger(MediaFormat.KEY_PROFILE, CodecProfileLevel.HEVCProfileMain10) - if (Build.VERSION.SDK_INT >= 23) { - mediaFormat.setBaseCodecLevelFromDolbyVisionLevel() - } + mediaFormat.setBaseCodecLevelFromDolbyVisionLevel() return findDecoder(mediaFormat) } @@ -87,9 +84,7 @@ object MediaCodecCompat { // dolby vision profile 09: Base layer is H.264 High/Progressive/Constrained Profile, Rec 709 mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC) mediaFormat.setInteger(MediaFormat.KEY_PROFILE, CodecProfileLevel.AVCProfileHigh) - if (Build.VERSION.SDK_INT >= 23) { - mediaFormat.setBaseCodecLevelFromDolbyVisionLevel() - } + mediaFormat.setBaseCodecLevelFromDolbyVisionLevel() return findDecoder(mediaFormat) } @@ -100,7 +95,6 @@ object MediaCodecCompat { } } - @RequiresApi(23) private fun MediaFormat.setBaseCodecLevelFromDolbyVisionLevel(): Boolean { val mimeType = this.getString(MediaFormat.KEY_MIME) ?: return false try {