Upgrade to Kotlin 1.5 (#1397)

* build: upgrade Kotlin to 1.5.0 and Hilt to 2.35.1

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* all: address kotlin.time.seconds deprecation

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* autofill-parser/openpgp-ktx: require Kotlin 1.5

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* all: address string method deprecations

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* build: disable NewApi lint

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2021-04-28 10:27:14 +05:30 committed by GitHub
parent d3bc28c1c3
commit 4880e1db27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 43 additions and 38 deletions

View file

@ -35,6 +35,11 @@ android {
isAbortOnError = true
isCheckReleaseBuilds = false
disable("MissingTranslation", "PluralsCandidate", "ImpliedQuantity")
// Kotlin 1.5 + AGP 4.1.3 trip up NewApi for Kotlin intrinsics like forEach
// This can be fixed by either switching to AGP 4.2.0-rc1, or disabling it
// outright.
// https://issuetracker.google.com/issues/185418482
disable("NewApi")
}
flavorDimensions("free")

View file

@ -27,8 +27,8 @@ import dev.msfjarvis.aps.util.settings.PreferenceKeys
import java.io.ByteArrayOutputStream
import java.io.File
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlin.time.seconds
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
@ -121,7 +121,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
@OptIn(ExperimentalTime::class)
private fun startAutoDismissTimer() {
lifecycleScope.launch {
delay(60.seconds)
delay(Duration.seconds(60))
finish()
}
}

View file

@ -60,8 +60,8 @@ object RandomPhonemesGenerator {
private class Element(str: String, val flags: Int) {
val upperCase = str.toUpperCase(Locale.ROOT)
val lowerCase = str.toLowerCase(Locale.ROOT)
val upperCase = str.uppercase(Locale.ROOT)
val lowerCase = str.lowercase(Locale.ROOT)
val length = str.length
val isAmbiguous = str.any { it in PasswordGenerator.AMBIGUOUS_STR }
}

View file

@ -101,10 +101,16 @@ class PasswordBuilder(ctx: Context) {
val candidate = wordBank.secureRandomElement()
val s =
when (capsType) {
CapsType.UPPERCASE -> candidate.toUpperCase(Locale.getDefault())
CapsType.Sentence -> if (i == 0) candidate.capitalize(Locale.getDefault()) else candidate
CapsType.TitleCase -> candidate.capitalize(Locale.getDefault())
CapsType.lowercase -> candidate.toLowerCase(Locale.getDefault())
CapsType.UPPERCASE -> candidate.uppercase(Locale.getDefault())
CapsType.Sentence ->
if (i == 0)
candidate.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
}
else candidate
CapsType.TitleCase ->
candidate.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
CapsType.lowercase -> candidate.lowercase(Locale.getDefault())
CapsType.As_iS -> candidate
}
password.append(s)

View file

@ -442,8 +442,7 @@ open class SearchableRepositoryAdapter<T : RecyclerView.ViewHolder>(
}
}
}
final override fun getPopupText(position: Int): String {
return getItem(position).name[0].toString().toUpperCase(Locale.getDefault())
return getItem(position).name[0].toString().uppercase(Locale.getDefault())
}
}

View file

@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file.
- Updated `androidx.annotation` to 1.1.0 and `androidx.autofill` to `1.2.0-alpha01`.
- The library now requires Kotlin 1.5.0 configured with `kotlinOptions.languageVersion = "1.5"`.
### Fixed
- Fix build warning from undeclared unsigned type use.

View file

@ -39,19 +39,16 @@ internal class FormField(
HintConstants.AUTOFILL_HINT_USERNAME,
HintConstants.AUTOFILL_HINT_NEW_USERNAME,
)
private val HINTS_NEW_PASSWORD =
listOf(
HintConstants.AUTOFILL_HINT_NEW_PASSWORD,
)
private val HINTS_PASSWORD =
HINTS_NEW_PASSWORD +
listOf(
HintConstants.AUTOFILL_HINT_PASSWORD,
HintConstants.AUTOFILL_HINT_WIFI_PASSWORD,
)
private val HINTS_OTP =
listOf(
HintConstants.AUTOFILL_HINT_SMS_OTP,
@ -70,7 +67,6 @@ internal class FormField(
HintConstants.AUTOFILL_HINT_PHONE,
HintConstants.AUTOFILL_HINT_PHONE_NUMBER,
)
private val ANDROID_TEXT_FIELD_CLASS_NAMES =
listOf(
"android.widget.EditText",
@ -79,9 +75,7 @@ internal class FormField(
"android.support.v7.widget.AppCompatEditText",
"com.google.android.material.textfield.TextInputEditText",
)
private const val ANDROID_WEB_VIEW_CLASS_NAME = "android.webkit.WebView"
private fun isPasswordInputType(inputType: Int): Boolean {
val typeClass = inputType and InputType.TYPE_MASK_CLASS
val typeVariation = inputType and InputType.TYPE_MASK_VARIATION
@ -117,7 +111,6 @@ internal class FormField(
(HTML_INPUT_FIELD_TYPES_USERNAME + HTML_INPUT_FIELD_TYPES_PASSWORD + HTML_INPUT_FIELD_TYPES_OTP).toSet().toList()
@RequiresApi(Build.VERSION_CODES.O) private fun isSupportedHint(hint: String) = hint in HINTS_FILLABLE
private val EXCLUDED_TERMS =
listOf(
"url_bar", // Chrome/Edge/Firefox address bar
@ -158,14 +151,13 @@ internal class FormField(
private val List<String>.anyMatchesFieldInfo
get() = any { fieldId.contains(it) || hint.contains(it) || htmlName.contains(it) }
val autofillId: AutofillId = node.autofillId!!
// Information for heuristics and exclusion rules based only on the current field
private val htmlId = node.htmlInfo?.attributes?.firstOrNull { it.first == "id" }?.second
private val resourceId = node.idEntry
private val fieldId = (htmlId ?: resourceId ?: "").toLowerCase(Locale.US)
private val hint = node.hint?.toLowerCase(Locale.US) ?: ""
private val fieldId = (htmlId ?: resourceId ?: "").lowercase(Locale.US)
private val hint = node.hint?.lowercase(Locale.US) ?: ""
private val className: String? = node.className
private val inputType = node.inputType
@ -186,10 +178,9 @@ internal class FormField(
private val htmlTag = node.htmlInfo?.tag
private val htmlAttributes: Map<String, String> =
node.htmlInfo?.attributes?.filter { it.first != null && it.second != null }?.associate {
Pair(it.first.toLowerCase(Locale.US), it.second.toLowerCase(Locale.US))
Pair(it.first.lowercase(Locale.US), it.second.lowercase(Locale.US))
}
?: emptyMap()
private val htmlAttributesDebug = htmlAttributes.entries.joinToString { "${it.key}=${it.value}" }
private val htmlInputType = htmlAttributes["type"]
private val htmlName = htmlAttributes["name"] ?: ""
@ -204,7 +195,6 @@ internal class FormField(
// HTML fields with non-fillable types (such as submit buttons) should be excluded here
private val isAndroidTextField = !isHtmlField && className in ANDROID_TEXT_FIELD_CLASS_NAMES
private val isAndroidPasswordField = isAndroidTextField && hasPasswordInputType
private val isTextField = isAndroidTextField || isHtmlTextField
// Autofill hint detection for native fields

View file

@ -144,7 +144,7 @@ internal class PublicSuffixListData(private val rules: ByteArray, private val ex
companion object {
val WILDCARD_LABEL = byteArrayOf('*'.toByte())
val WILDCARD_LABEL = byteArrayOf('*'.code.toByte())
val PREVAILING_RULE = listOf("*")
val EMPTY_RULE = listOf<String>()
const val EXCEPTION_MARKER = '!'

View file

@ -42,7 +42,7 @@ internal fun ByteArray.binarySearch(labels: List<ByteArray>, labelIndex: Int): S
val byte0 =
if (expectDot) {
expectDot = false
'.'.toByte()
'.'.code.toByte()
} else {
labels[currentLabelIndex][currentLabelByteIndex] and BITMASK
}
@ -109,7 +109,7 @@ internal fun ByteArray.binarySearch(labels: List<ByteArray>, labelIndex: Int): S
/** Search for a '\n' that marks the start of a value. Don't go back past the start of the array. */
private fun ByteArray.findStartOfLineFromIndex(start: Int): Int {
var index = start
while (index > -1 && this[index] != '\n'.toByte()) {
while (index > -1 && this[index] != '\n'.code.toByte()) {
index--
}
index++
@ -119,7 +119,7 @@ private fun ByteArray.findStartOfLineFromIndex(start: Int): Int {
/** Search for a '\n' that marks the end of a value. */
private fun ByteArray.findEndOfLineFromIndex(start: Int): Int {
var end = 1
while (this[start + end] != '\n'.toByte()) {
while (this[start + end] != '\n'.code.toByte()) {
end++
}
return end

View file

@ -41,8 +41,8 @@ dependencies {
implementation("org.jetbrains.kotlinx:binary-compatibility-validator:0.5.0")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.4.30")
implementation("de.undercouch:gradle-download-task:4.1.1")
implementation("com.google.dagger:hilt-android-gradle-plugin:2.34.1-beta")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32")
implementation("com.google.dagger:hilt-android-gradle-plugin:2.35.1")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0")
implementation("com.ncorti.ktfmt.gradle:plugin:0.5.0")
implementation("com.vanniktech:gradle-maven-publish-plugin:0.13.0")
implementation("com.vdurmont:semver4j:3.1.0")

View file

@ -36,6 +36,7 @@ internal fun Project.configureForAllProjects() {
repositories {
google()
mavenCentral()
@Suppress("DEPRECATION")
jcenter {
content {
// https://github.com/zhanghai/AndroidFastScroll/issues/35
@ -57,7 +58,7 @@ internal fun Project.configureForAllProjects() {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs = freeCompilerArgs + additionalCompilerArgs
languageVersion = "1.4"
languageVersion = "1.5"
useIR = true
}
}

View file

@ -13,8 +13,8 @@ import dev.msfjarvis.aps.util.time.UserClock
import dev.msfjarvis.aps.util.totp.Otp
import dev.msfjarvis.aps.util.totp.TotpFinder
import kotlin.collections.set
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlin.time.seconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
@ -84,10 +84,10 @@ constructor(
scope.launch {
updateTotp(clock.millis())
val remainingTime = totpPeriod - (System.currentTimeMillis() % totpPeriod)
delay(remainingTime.seconds)
delay(Duration.seconds(remainingTime))
repeat(Int.MAX_VALUE) {
updateTotp(clock.millis())
delay(totpPeriod.seconds)
delay(Duration.seconds(totpPeriod))
}
}
}

View file

@ -24,7 +24,7 @@ internal object Otp {
}
fun calculateCode(secret: String, counter: Long, algorithm: String, digits: String) = runCatching {
val algo = "Hmac${algorithm.toUpperCase(Locale.ROOT)}"
val algo = "Hmac${algorithm.uppercase(Locale.ROOT)}"
val decodedSecret = BASE_32.decode(secret)
val secretKey = SecretKeySpec(decodedSecret, algo)
val digest =

View file

@ -1,9 +1,9 @@
# Centralized versions for dependencies that share versions
[versions]
androidx_test = "1.4.0-alpha05"
coroutines = "1.4.3"
hilt = "2.34.1-beta"
kotlin = "1.4.32"
coroutines = "1.5.0-RC"
hilt = "2.35.1"
kotlin = "1.5.0"
lifecycle = "2.4.0-alpha01"
[libraries]

View file

@ -2,6 +2,8 @@
### [Unreleased]
- The library now requires Kotlin 1.5.0 configured with `kotlinOptions.languageVersion = "1.5"`.
### [3.0.0] - 2021-04-10
- Relicence under Apache 2.0

View file

@ -46,7 +46,7 @@ public object OpenPgpUtils {
}
private fun convertKeyIdToHex32bit(keyId: Long): String {
var hexString = java.lang.Long.toHexString(keyId and 0xffffffffL).toLowerCase(Locale.ENGLISH)
var hexString = java.lang.Long.toHexString(keyId and 0xffffffffL).lowercase(Locale.ENGLISH)
while (hexString.length < 8) {
hexString = "0$hexString"
}