Set minSdkVersion to 23 (Android 6)

Signed-off-by: Tim Krüger <t@timkrueger.me>
This commit is contained in:
Tim Krüger 2022-10-14 11:52:17 +02:00
parent 49da463971
commit 4b46270362
No known key found for this signature in database
GPG Key ID: FECE3A7222C52A4E
17 changed files with 87 additions and 257 deletions

View File

@ -42,7 +42,7 @@ android {
namespace 'com.nextcloud.talk'
defaultConfig {
minSdkVersion 21
minSdkVersion 23
targetSdkVersion 31
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@ -22,7 +22,6 @@ package com.nextcloud.talk.activities
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
@ -76,9 +75,7 @@ open class BaseActivity : AppCompatActivity() {
}
if (appPreferences.isScreenLocked) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
SecurityUtils.createKey(appPreferences.screenLockTimeout)
}
SecurityUtils.createKey(appPreferences.screenLockTimeout)
}
}

View File

@ -732,10 +732,8 @@ public class CallActivity extends CallBaseActivity {
} else {
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CALL)) {
onPermissionsGranted();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(PERMISSIONS_CALL, 100);
} else {
onRequestPermissionsResult(100, PERMISSIONS_CALL, new int[]{1, 1});
requestPermissions(PERMISSIONS_CALL, 100);
}
}
@ -980,11 +978,7 @@ public class CallActivity extends CallBaseActivity {
R.string.nc_microphone_permission_permanently_denied,
R.string.nc_permissions_settings, (AppCompatActivity) this);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(PERMISSIONS_MICROPHONE, 100);
} else {
onRequestPermissionsResult(100, PERMISSIONS_MICROPHONE, new int[]{1});
}
requestPermissions(PERMISSIONS_MICROPHONE, 100);
}
}
@ -1017,12 +1011,7 @@ public class CallActivity extends CallBaseActivity {
R.string.nc_camera_permission_permanently_denied,
R.string.nc_permissions_settings, (AppCompatActivity) this);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(PERMISSIONS_CAMERA, 100);
} else {
onRequestPermissionsResult(100, PERMISSIONS_CAMERA, new int[]{1});
}
requestPermissions(PERMISSIONS_CAMERA, 100);
}
}

View File

@ -24,12 +24,10 @@ package com.nextcloud.talk.activities
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
import android.text.TextUtils
import android.util.Log
import androidx.annotation.RequiresApi
import autodagger.AutoInjector
import com.bluelinelabs.conductor.Conductor
import com.bluelinelabs.conductor.Router
@ -148,10 +146,7 @@ class MainActivity : BaseActivity(), ActionBarProvider {
super.onStart()
Log.d(TAG, "onStart: Activity: " + System.identityHashCode(this).toString())
logRouterBackStack(router!!)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
lockScreenIfConditionsApply()
}
lockScreenIfConditionsApply()
}
override fun onResume() {
@ -323,7 +318,6 @@ class MainActivity : BaseActivity(), ActionBarProvider {
})
}
@RequiresApi(api = Build.VERSION_CODES.M)
fun lockScreenIfConditionsApply() {
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isKeyguardSecure && appPreferences.isScreenLocked) {

View File

@ -64,7 +64,6 @@ import com.nextcloud.talk.jobs.SignalingSettingsWorker
import com.nextcloud.talk.ui.theme.ThemeModule
import com.nextcloud.talk.utils.ClosedInterfaceImpl
import com.nextcloud.talk.utils.DeviceUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.NotificationUtils
import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule
import com.nextcloud.talk.utils.database.user.UserModule
@ -163,7 +162,6 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver {
securityKeyManager.init(this, securityKeyConfig)
initializeWebRtc()
DisplayUtils.useCompatVectorIfNeeded()
buildComponent()
DavUtils.registerCustomFactories()

View File

@ -1149,14 +1149,10 @@ class ChatController(args: Bundle) :
}
private fun isRecordAudioPermissionGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return PermissionChecker.checkSelfPermission(
context,
Manifest.permission.RECORD_AUDIO
) == PermissionChecker.PERMISSION_GRANTED
} else {
true
}
return PermissionChecker.checkSelfPermission(
context,
Manifest.permission.RECORD_AUDIO
) == PermissionChecker.PERMISSION_GRANTED
}
private fun startAudioRecording(file: String) {

View File

@ -442,23 +442,19 @@ class LocationPickerController(args: Bundle) :
private fun isLocationPermissionsGranted(): Boolean {
fun isCoarseLocationGranted(): Boolean {
return PermissionChecker.checkSelfPermission(
context!!,
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PermissionChecker.PERMISSION_GRANTED
}
fun isFineLocationGranted(): Boolean {
return PermissionChecker.checkSelfPermission(
context!!,
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PermissionChecker.PERMISSION_GRANTED
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
isCoarseLocationGranted() && isFineLocationGranted()
} else {
true
}
return isCoarseLocationGranted() && isFineLocationGranted()
}
private fun requestLocationPermissions() {

View File

@ -25,12 +25,10 @@ import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.biometric.BiometricPrompt
import androidx.biometric.BiometricPrompt.PromptInfo
import androidx.core.content.res.ResourcesCompat
@ -62,15 +60,11 @@ class LockedController : BaseController(R.layout.controller_locked) {
override fun onViewBound(view: View) {
super.onViewBound(view)
sharedApplication!!.componentApplication.inject(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.unlockContainer.setOnClickListener {
unlock()
}
binding.unlockContainer.setOnClickListener {
unlock()
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
override fun onAttach(view: View) {
super.onAttach(view)
Log.d(TAG, "onAttach")
@ -92,12 +86,10 @@ class LockedController : BaseController(R.layout.controller_locked) {
Log.d(TAG, "onDetach")
}
@RequiresApi(api = Build.VERSION_CODES.M)
fun unlock() {
checkIfWeAreSecure()
}
@RequiresApi(api = Build.VERSION_CODES.M)
private fun showBiometricDialog() {
val context: Context? = activity
if (context != null) {
@ -140,11 +132,10 @@ class LockedController : BaseController(R.layout.controller_locked) {
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private fun checkIfWeAreSecure() {
val keyguardManager = activity?.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager?
if (keyguardManager?.isKeyguardSecure == true && appPreferences!!.isScreenLocked) {
if (!SecurityUtils.checkIfWeAreAuthenticated(appPreferences!!.screenLockTimeout)) {
if (keyguardManager?.isKeyguardSecure == true && appPreferences.isScreenLocked) {
if (!SecurityUtils.checkIfWeAreAuthenticated(appPreferences.screenLockTimeout)) {
Log.d(TAG, "showBiometricDialog because 'we are NOT authenticated'...")
showBiometricDialog()
} else {
@ -172,8 +163,7 @@ class LockedController : BaseController(R.layout.controller_locked) {
if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
if (resultCode == Activity.RESULT_OK) {
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
SecurityUtils.checkIfWeAreAuthenticated(appPreferences!!.screenLockTimeout)
SecurityUtils.checkIfWeAreAuthenticated(appPreferences.screenLockTimeout)
) {
Log.d(TAG, "All went well, dismiss locked controller")
router.popCurrentController()

View File

@ -157,18 +157,13 @@ class SettingsController : BaseController(R.layout.controller_settings) {
binding.settingsIncognitoKeyboard.visibility = View.GONE
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
binding.settingsScreenLock.visibility = View.GONE
binding.settingsScreenLockTimeout.visibility = View.GONE
} else {
binding.settingsScreenLock.setSummary(
String.format(
Locale.getDefault(),
resources!!.getString(R.string.nc_settings_screen_lock_desc),
resources!!.getString(R.string.nc_app_product_name)
)
binding.settingsScreenLock.setSummary(
String.format(
Locale.getDefault(),
resources!!.getString(R.string.nc_settings_screen_lock_desc),
resources!!.getString(R.string.nc_app_product_name)
)
}
)
setupPrivacyUrl()
setupSourceCodeUrl()
@ -662,10 +657,8 @@ class SettingsController : BaseController(R.layout.controller_settings) {
appPreferences.isKeyboardIncognito
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
(binding.settingsIncognitoKeyboard.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isKeyboardIncognito
}
(binding.settingsIncognitoKeyboard.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isKeyboardIncognito
if (CapabilitiesUtilNew.isReadStatusAvailable(userManager.currentUser.blockingGet())) {
(binding.settingsReadPrivacy.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
@ -679,29 +672,27 @@ class SettingsController : BaseController(R.layout.controller_settings) {
}
private fun setupScreenLockSetting() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isKeyguardSecure) {
binding.settingsScreenLock.isEnabled = true
binding.settingsScreenLockTimeout.isEnabled = true
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isScreenLocked
binding.settingsScreenLockTimeout.isEnabled = appPreferences.isScreenLocked
if (appPreferences.isScreenLocked) {
binding.settingsScreenLockTimeout.alpha = ENABLED_ALPHA
} else {
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA
}
binding.settingsScreenLock.alpha = ENABLED_ALPHA
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isKeyguardSecure) {
binding.settingsScreenLock.isEnabled = true
binding.settingsScreenLockTimeout.isEnabled = true
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isScreenLocked
binding.settingsScreenLockTimeout.isEnabled = appPreferences.isScreenLocked
if (appPreferences.isScreenLocked) {
binding.settingsScreenLockTimeout.alpha = ENABLED_ALPHA
} else {
binding.settingsScreenLock.isEnabled = false
binding.settingsScreenLockTimeout.isEnabled = false
appPreferences.removeScreenLock()
appPreferences.removeScreenLockTimeout()
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = false
binding.settingsScreenLock.alpha = DISABLED_ALPHA
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA
}
binding.settingsScreenLock.alpha = ENABLED_ALPHA
} else {
binding.settingsScreenLock.isEnabled = false
binding.settingsScreenLockTimeout.isEnabled = false
appPreferences.removeScreenLock()
appPreferences.removeScreenLockTimeout()
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = false
binding.settingsScreenLock.alpha = DISABLED_ALPHA
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA
}
}
@ -805,9 +796,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private inner class ScreenLockTimeoutListener : OnPreferenceValueChangedListener<String?> {
override fun onChanged(newValue: String?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
SecurityUtils.createKey(appPreferences.screenLockTimeout)
}
SecurityUtils.createKey(appPreferences.screenLockTimeout)
}
}

View File

@ -447,11 +447,9 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
EmojiCompat.get().process(pushMessage.text!!)
)
}
if (Build.VERSION.SDK_INT >= 23) {
// This method should exist since API 21, but some phones don't have it
// So as a safeguard, we don't use it until 23
notificationBuilder.color = context!!.resources.getColor(R.color.colorPrimary)
}
notificationBuilder.color = context!!.resources.getColor(R.color.colorPrimary)
val notificationInfoBundle = Bundle()
notificationInfoBundle.putLong(KEY_INTERNAL_USER_ID, signatureVerification.user!!.id!!)
// could be an ID or a TOKEN
@ -694,7 +692,6 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
.subscribe(object : Observer<ParticipantsOverall> {
override fun onSubscribe(d: Disposable) = Unit
@RequiresApi(Build.VERSION_CODES.M)
override fun onNext(participantsOverall: ParticipantsOverall) {
val participantList: List<Participant> = participantsOverall.ocs!!.data!!
hasParticipantsInCall = participantList.isNotEmpty()
@ -726,7 +723,6 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
Log.e(TAG, "Error in getPeersForCall", e)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onComplete() {
if (isCallNotificationVisible) {
@ -821,7 +817,6 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
return PendingIntent.getActivity(context, requestCode, intent, intentFlag)
}
@RequiresApi(Build.VERSION_CODES.M)
private fun isCallNotificationVisible(decryptedPushMessage: DecryptedPushMessage): Boolean {
var isVisible = false

View File

@ -295,7 +295,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
false
}
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
else -> {
if (PermissionChecker.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
@ -308,10 +308,6 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
false
}
}
else -> { // permission is automatically granted on sdk<23 upon installation
Log.d(TAG, "Permission is granted")
true
}
}
}
@ -325,7 +321,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
REQUEST_PERMISSION
)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
else -> {
controller.requestPermissions(
arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE
@ -333,8 +329,6 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
REQUEST_PERMISSION
)
}
else -> { // permission is automatically granted on sdk<23 upon installation
}
}
}

View File

@ -24,7 +24,6 @@
package com.nextcloud.talk.utils;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -67,9 +66,6 @@ import com.nextcloud.talk.utils.text.Spans;
import org.greenrobot.eventbus.EventBus;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.Date;
import java.util.regex.Matcher;
@ -82,7 +78,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.XmlRes;
import androidx.appcompat.widget.AppCompatDrawableManager;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.ColorUtils;
@ -155,31 +150,6 @@ public class DisplayUtils {
return px / context.getResources().getDisplayMetrics().density;
}
// Solution inspired by https://stackoverflow.com/questions/34936590/why-isnt-my-vector-drawable-scaling-as-expected
public static void useCompatVectorIfNeeded() {
if (Build.VERSION.SDK_INT < 23) {
try {
@SuppressLint("RestrictedApi") AppCompatDrawableManager drawableManager = AppCompatDrawableManager.get();
Class<?> inflateDelegateClass = Class.forName(
"android.support.v7.widget.AppCompatDrawableManager$InflateDelegate");
Class<?> vdcInflateDelegateClass = Class.forName(
"android.support.v7.widget.AppCompatDrawableManager$VdcInflateDelegate");
Constructor<?> constructor = vdcInflateDelegateClass.getDeclaredConstructor();
constructor.setAccessible(true);
Object vdcInflateDelegate = constructor.newInstance();
Class<?> args[] = {String.class, inflateDelegateClass};
Method addDelegate = AppCompatDrawableManager.class.getDeclaredMethod("addDelegate", args);
addDelegate.setAccessible(true);
addDelegate.invoke(drawableManager, "vector", vdcInflateDelegate);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
InvocationTargetException | IllegalAccessException e) {
Log.e(TAG, "Failed to use reflection to enable proper vector scaling");
}
}
}
public static Drawable getTintedDrawable(Resources res, @DrawableRes int drawableResId, @ColorRes int colorResId) {
Drawable drawable = ResourcesCompat.getDrawable(res, drawableResId, null);
@ -206,10 +176,8 @@ public class DisplayUtils {
viewThemeUtils.material.colorChipDrawable(context, chip);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Configuration config = context.getResources().getConfiguration();
chip.setLayoutDirection(config.getLayoutDirection());
}
Configuration config = context.getResources().getConfiguration();
chip.setLayoutDirection(config.getLayoutDirection());
int drawable;
@ -386,24 +354,23 @@ public class DisplayUtils {
Window window = activity.getWindow();
boolean isLightTheme = lightTheme(color);
if (window != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decor = window.getDecorView();
if (isLightTheme) {
int systemUiFlagLightStatusBar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
} else {
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
decor.setSystemUiVisibility(systemUiFlagLightStatusBar);
View decor = window.getDecorView();
if (isLightTheme) {
int systemUiFlagLightStatusBar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
} else {
decor.setSystemUiVisibility(0);
systemUiFlagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
window.setStatusBarColor(color);
} else if (isLightTheme) {
window.setStatusBarColor(Color.BLACK);
decor.setSystemUiVisibility(systemUiFlagLightStatusBar);
} else {
decor.setSystemUiVisibility(0);
}
window.setStatusBarColor(color);
} else if (isLightTheme) {
window.setStatusBarColor(Color.BLACK);
}
}

View File

@ -218,7 +218,7 @@ object NotificationUtils {
notification: Notification
) -> Unit
) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || conversationUser.id == -1L || context == null) {
if (conversationUser.id == -1L || context == null) {
return
}

View File

@ -21,7 +21,6 @@
package com.nextcloud.talk.utils;
import android.content.res.Resources;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
@ -50,7 +49,6 @@ import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import androidx.annotation.RequiresApi;
import androidx.biometric.BiometricPrompt;
public class SecurityUtils {
@ -60,7 +58,6 @@ public class SecurityUtils {
private static BiometricPrompt.CryptoObject cryptoObject;
@RequiresApi(api = Build.VERSION_CODES.M)
public static boolean checkIfWeAreAuthenticated(String screenLockTimeout) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
@ -95,12 +92,10 @@ public class SecurityUtils {
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static BiometricPrompt.CryptoObject getCryptoObject() {
return cryptoObject;
}
@RequiresApi(api = Build.VERSION_CODES.M)
public static void createKey(String validity) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

View File

@ -23,7 +23,6 @@ package com.nextcloud.talk.utils.permissions
import android.Manifest
import android.content.Context
import android.os.Build
import androidx.core.content.PermissionChecker
import com.nextcloud.talk.BuildConfig
@ -32,13 +31,9 @@ class PlatformPermissionUtilImpl(private val context: Context) : PlatformPermiss
"${BuildConfig.APPLICATION_ID}.${BuildConfig.PERMISSION_LOCAL_BROADCAST}"
override fun isCameraPermissionGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return PermissionChecker.checkSelfPermission(
context,
Manifest.permission.CAMERA
) == PermissionChecker.PERMISSION_GRANTED
} else {
true
}
return PermissionChecker.checkSelfPermission(
context,
Manifest.permission.CAMERA
) == PermissionChecker.PERMISSION_GRANTED
}
}

View File

@ -8,12 +8,9 @@
package com.nextcloud.talk.utils.ssl
import android.os.Build
import java.io.IOException
import java.net.InetAddress
import java.net.Socket
import java.security.GeneralSecurityException
import java.util.LinkedList
import javax.net.ssl.KeyManager
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocket
@ -35,69 +32,12 @@ class SSLSocketFactoryCompat(
var cipherSuites: Array<String>? = null
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Since Android 6.0 (API level 23),
// - TLSv1.1 and TLSv1.2 is enabled by default
// - SSLv3 is disabled by default
// - all modern ciphers are activated by default
protocols = null
cipherSuites = null
} else {
val socket = SSLSocketFactory.getDefault().createSocket() as SSLSocket?
try {
socket?.let {
/* set reasonable protocol versions */
// - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0)
// - remove all SSL versions (especially SSLv3) because they're insecure now
val _protocols = LinkedList<String>()
for (protocol in socket.supportedProtocols.filterNot { it.contains("SSL", true) })
_protocols += protocol
protocols = _protocols.toTypedArray()
/* set up reasonable cipher suites */
val knownCiphers = arrayOf<String>(
// TLS 1.2
"TLS_RSA_WITH_AES_256_GCM_SHA384",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
// maximum interoperability
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
// additionally
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
)
val availableCiphers = socket.supportedCipherSuites
/* For maximum security, preferredCiphers should *replace* enabled ciphers (thus
* disabling ciphers which are enabled by default, but have become unsecure), but for
* the security level of DAVdroid and maximum compatibility, disabling of insecure
* ciphers should be a server-side task */
// for the final set of enabled ciphers, take the ciphers enabled by default, ...
val _cipherSuites = LinkedList<String>()
_cipherSuites.addAll(socket.enabledCipherSuites)
// ... add explicitly allowed ciphers ...
_cipherSuites.addAll(knownCiphers)
// ... and keep only those which are actually available
_cipherSuites.retainAll(availableCiphers)
cipherSuites = _cipherSuites.toTypedArray()
}
} catch (e: IOException) {
// Exception is to be ignored
} finally {
socket?.close() // doesn't implement Closeable on all supported Android versions
}
}
// Since Android 6.0 (API level 23),
// - TLSv1.1 and TLSv1.2 is enabled by default
// - SSLv3 is disabled by default
// - all modern ciphers are activated by default
protocols = null
cipherSuites = null
}
}

View File

@ -41,7 +41,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Build;
import android.util.Log;
import com.nextcloud.talk.events.PeerConnectionEvent;
@ -388,22 +387,18 @@ public class WebRtcAudioManager {
*/
@Deprecated
private boolean hasWiredHeadset() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return audioManager.isWiredHeadsetOn();
} else {
@SuppressLint("WrongConstant") final AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
for (AudioDeviceInfo device : devices) {
final int type = device.getType();
if (type == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
Log.d(TAG, "hasWiredHeadset: found wired headset");
return true;
} else if (type == AudioDeviceInfo.TYPE_USB_DEVICE) {
Log.d(TAG, "hasWiredHeadset: found USB audio device");
return true;
}
@SuppressLint("WrongConstant") final AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
for (AudioDeviceInfo device : devices) {
final int type = device.getType();
if (type == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
Log.d(TAG, "hasWiredHeadset: found wired headset");
return true;
} else if (type == AudioDeviceInfo.TYPE_USB_DEVICE) {
Log.d(TAG, "hasWiredHeadset: found USB audio device");
return true;
}
return false;
}
return false;
}
public void updateAudioDeviceState() {