mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-11 18:10:44 +00:00
Set minSdkVersion to 23 (Android 6)
Signed-off-by: Tim Krüger <t@timkrueger.me>
This commit is contained in:
parent
49da463971
commit
4b46270362
@ -42,7 +42,7 @@ android {
|
||||
namespace 'com.nextcloud.talk'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 31
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user