mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-05 01:10:48 +00:00
Clear out checks for SDK < 23 as they're no longer relevant.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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<Unit>() {
|
||||
|
||||
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<Unit>
|
||||
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 = {
|
||||
|
||||
@@ -219,7 +219,6 @@ 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())
|
||||
@@ -236,12 +235,6 @@ public final class AudioView extends FrameLayout {
|
||||
t -> waveFormView.setWaveMode(false)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
waveFormView.setWaveMode(false);
|
||||
if (duration != null) {
|
||||
duration.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (forceHideDuration && duration != null) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -117,15 +117,11 @@ public class EmojiEditText extends AppCompatEditText {
|
||||
|
||||
if (clipData != null) {
|
||||
CharSequence label = clipData.getDescription().getLabel();
|
||||
CharSequence pendingPaste = getTextFromClipData(clipData);
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.crypto;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -60,9 +59,6 @@ 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());
|
||||
|
||||
TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize());
|
||||
@@ -70,16 +66,11 @@ public class AttachmentSecretProvider {
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.crypto;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -48,29 +47,21 @@ 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());
|
||||
|
||||
TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize());
|
||||
TextSecurePreferences.setDatabaseUnencryptedSecret(context, null);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
private static @NonNull DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
return databaseSecret;
|
||||
}
|
||||
|
||||
@@ -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<SealedData> 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<byte[]> result = new AtomicReference<>();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ?: "")
|
||||
}
|
||||
|
||||
@@ -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,13 +26,9 @@ 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private constructor(attachmentId: AttachmentId) : this(
|
||||
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)
|
||||
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
@@ -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,7 +27,6 @@ class LogSectionMemory : LogSection {
|
||||
Low Memory? : ${nativeMemory.lowMemory}
|
||||
""".trimIndent()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
val detailedMemory = MemoryTracker.getDetailedMemoryStats()
|
||||
|
||||
base += "\n\n"
|
||||
@@ -41,7 +39,6 @@ class LogSectionMemory : LogSection {
|
||||
Stack Usage : ${detailedMemory.stackUsageKb?.kbDisplay()}
|
||||
Other Usage : ${detailedMemory.appOtherUsageKb?.kbDisplay()}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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,11 +210,9 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm
|
||||
}
|
||||
|
||||
private fun startPositionUpdates() {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
stopPositionUpdates()
|
||||
handler.post(updatePosition)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopPositionUpdates() {
|
||||
handler.removeCallbacks(updatePosition)
|
||||
@@ -250,7 +245,6 @@ class VideoEditorFragment : Fragment(), PositionDragListener, MediaSendPageFragm
|
||||
hud.showPlayButton()
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
private fun onEditVideoDuration(data: VideoTrimData, editingComplete: Boolean) {
|
||||
if (editingComplete) {
|
||||
isInEdit = false
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,7 +53,6 @@ public final class NotificationCancellationHelper {
|
||||
* bubble notifications that do not have unread messages in them.
|
||||
*/
|
||||
public static void cancelAllMessageNotifications(@NonNull Context context, @NonNull Set<Integer> stickyNotifications) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
try {
|
||||
NotificationManager notifications = ServiceUtil.getNotificationManager(context);
|
||||
StatusBarNotification[] activeNotifications = notifications.getActiveNotifications();
|
||||
@@ -76,9 +75,6 @@ public final class NotificationCancellationHelper {
|
||||
Log.w(TAG, "Canceling all notifications.", e);
|
||||
ServiceUtil.getNotificationManager(context).cancelAll();
|
||||
}
|
||||
} else {
|
||||
cancelLegacy(context, NotificationIds.MESSAGE_SUMMARY);
|
||||
}
|
||||
}
|
||||
|
||||
public static void cancelMessageSummaryIfSoleNotification(@NonNull Context context) {
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
connectivityManager
|
||||
return 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,7 +74,6 @@ 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)) {
|
||||
@@ -88,10 +86,9 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome_v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -89,7 +89,6 @@ 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);
|
||||
|
||||
@@ -97,9 +96,6 @@ public final class NetworkUtil {
|
||||
boolean isNotMetered = capabilities == null || capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
|
||||
|
||||
return new NetworkStatus(onVpn, !isNotMetered);
|
||||
} else {
|
||||
return new NetworkStatus(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean useLowDataCalling(@NonNull Context context, @NonNull PeerConnection.AdapterType networkAdapter) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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()));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -172,22 +172,16 @@ 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();
|
||||
@@ -199,7 +193,6 @@ public abstract class AudioManagerCompat {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public float ringVolumeWithMinimum() {
|
||||
int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -92,12 +92,12 @@ 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
|
||||
return wifiManager.isP2pSupported() ? AvailableStatus.AVAILABLE
|
||||
: AvailableStatus.WIFI_DIRECT_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
val scanner = findViewById<QrScannerView>(R.id.scanner)
|
||||
scanner.start(this)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
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()
|
||||
}
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user