Enable automatic coding style linting with ktlint (also on CI)

This way the coding style is guaranteed to stay consistent.
This commit is contained in:
Torsten Grote 2020-09-25 10:23:32 -03:00 committed by Chirayu Desai
parent 53937bda2f
commit 6c531066e7
31 changed files with 167 additions and 70 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
[*.{kt,kts}]
indent_size=4
insert_final_newline=true
max_line_length=100

1
.gitignore vendored
View file

@ -9,6 +9,7 @@ out/
lib/
.idea/*
!.idea/runConfigurations*
!.idea/inspectionProfiles*
!.idea/codeStyles*
*.ipr
*.iws

View file

@ -131,6 +131,16 @@
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="RIGHT_MARGIN" value="100" />
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
<option name="ENUM_CONSTANTS_WRAP" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>

View file

@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintMangledCRLF" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="KotlinUnusedImport" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="LongLine" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="RedundantSemicolon" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>

View file

@ -24,7 +24,7 @@ before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
script: ./gradlew check assemble
script: ./gradlew check assemble ktlintCheck
cache:
directories:

View file

@ -1,7 +1,10 @@
import groovy.xml.XmlUtil
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
plugins {
id "com.android.application"
id "kotlin-android"
id "org.jlleitschuh.gradle.ktlint" version "9.4.0"
}
android {
@ -74,6 +77,17 @@ android {
apply from: '../gradle/dependencies.gradle'
ktlint {
version = "0.36.0" // https://github.com/pinterest/ktlint/issues/764
android = true
enableExperimentalRules = false
verbose = true
disabledRules = [
"import-ordering",
"no-blank-line-before-rbrace",
]
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
@ -92,9 +106,14 @@ preBuild.doLast {
def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
def apiString = android.compileSdkVersion.substring("android-".length())
def sdkString = "Android API " + apiString + " Platform"
//noinspection GroovyResultOfObjectAllocationIgnored // the note gets inserted
new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
new Node(parsedXml.component[1], 'orderEntry', [
'type' : 'jdk',
'jdkName': sdkString,
'jdkType': 'Android SDK'
])
XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (NullPointerException | FileNotFoundException ex) {

View file

@ -56,7 +56,7 @@ class App : Application() {
cryptoModule,
headerModule,
metadataModule,
documentsProviderModule, // storage plugin
documentsProviderModule, // storage plugin
backupModule,
restoreModule,
appModule

View file

@ -69,7 +69,9 @@ abstract class UsbMonitor : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action ?: return
if (intent.action == ACTION_USB_DEVICE_ATTACHED || intent.action == ACTION_USB_DEVICE_DETACHED) {
if (intent.action == ACTION_USB_DEVICE_ATTACHED ||
intent.action == ACTION_USB_DEVICE_DETACHED
) {
val device = intent.extras?.getParcelable<UsbDevice>(EXTRA_DEVICE) ?: return
Log.d(TAG, "New USB mass-storage device attached.")
device.log()

View file

@ -115,7 +115,8 @@ internal class CryptoImpl(
val cipher = cipherFactory.createEncryptionCipher()
check(cipher.getOutputSize(cleartext.size) <= MAX_SEGMENT_LENGTH) {
"Cipher's output size ${cipher.getOutputSize(cleartext.size)} is larger than maximum segment length ($MAX_SEGMENT_LENGTH)"
"Cipher's output size ${cipher.getOutputSize(cleartext.size)} is larger" +
"than maximum segment length ($MAX_SEGMENT_LENGTH)"
}
encryptSegment(cipher, outputStream, cleartext)
}
@ -162,9 +163,9 @@ internal class CryptoImpl(
"expected '$expectedPackageName'."
)
}
if (header.key != expectedKey) {
throw SecurityException("Invalid key '${header.key}' in header, expected '$expectedKey'.")
}
if (header.key != expectedKey) throw SecurityException(
"Invalid key '${header.key}' in header, expected '$expectedKey'."
)
return header
}
@ -190,9 +191,9 @@ internal class CryptoImpl(
@Throws(EOFException::class, IOException::class, SecurityException::class)
private fun decryptSegment(inputStream: InputStream, maxSegmentLength: Int): ByteArray {
val segmentHeader = headerReader.readSegmentHeader(inputStream)
if (segmentHeader.segmentLength > maxSegmentLength) {
throw SecurityException("Segment length too long: ${segmentHeader.segmentLength} > $maxSegmentLength")
}
if (segmentHeader.segmentLength > maxSegmentLength) throw SecurityException(
"Segment length too long: ${segmentHeader.segmentLength} > $maxSegmentLength"
)
val buffer = ByteArray(segmentHeader.segmentLength.toInt())
val bytesRead = inputStream.read(buffer)

View file

@ -22,7 +22,9 @@ data class VersionHeader(
"Package $packageName has name longer than $MAX_PACKAGE_LENGTH_SIZE"
}
key?.let {
check(key.length <= MAX_KEY_LENGTH_SIZE) { "Key $key is longer than $MAX_KEY_LENGTH_SIZE" }
check(key.length <= MAX_KEY_LENGTH_SIZE) {
"Key $key is longer than $MAX_KEY_LENGTH_SIZE"
}
}
}
}

View file

@ -33,15 +33,21 @@ internal class HeaderReaderImpl : HeaderReader {
val packageLength = buffer.short.toInt()
if (packageLength <= 0) throw SecurityException("Invalid package length: $packageLength")
if (packageLength > MAX_PACKAGE_LENGTH_SIZE) throw SecurityException("Too large package length: $packageLength")
if (packageLength > buffer.remaining()) throw SecurityException("Not enough bytes for package name")
if (packageLength > MAX_PACKAGE_LENGTH_SIZE) throw SecurityException(
"Too large package length: $packageLength"
)
if (packageLength > buffer.remaining()) throw SecurityException(
"Not enough bytes for package name"
)
val packageName = ByteArray(packageLength)
.apply { buffer.get(this) }
.toString(Utf8)
val keyLength = buffer.short.toInt()
if (keyLength < 0) throw SecurityException("Invalid key length: $keyLength")
if (keyLength > MAX_KEY_LENGTH_SIZE) throw SecurityException("Too large key length: $keyLength")
if (keyLength > MAX_KEY_LENGTH_SIZE) throw SecurityException(
"Too large key length: $keyLength"
)
if (keyLength > buffer.remaining()) throw SecurityException("Not enough bytes for key")
val key = if (keyLength == 0) null else ByteArray(keyLength)
.apply { buffer.get(this) }

View file

@ -80,7 +80,8 @@ class MetadataManager(
"APK backup returned version null"
}
check(it.version == null || it.version < packageMetadata.version) {
"APK backup backed up the same or a smaller version: was ${it.version} is ${packageMetadata.version}"
"APK backup backed up the same or a smaller version:" +
"was ${it.version} is ${packageMetadata.version}"
}
}
val oldPackageMetadata = metadata.packageMetadataMap[packageName]

View file

@ -78,9 +78,9 @@ internal class MetadataReaderImpl(private val crypto: Crypto) : MetadataReader {
)
}
val token = meta.getLong(JSON_METADATA_TOKEN)
if (expectedToken != null && token != expectedToken) {
throw SecurityException("Invalid token '$token' in metadata, expected '$expectedToken'.")
}
if (expectedToken != null && token != expectedToken) throw SecurityException(
"Invalid token '$token' in metadata, expected '$expectedToken'."
)
// get package metadata
val packageMetadataMap = PackageMetadataMap()
for (packageName in json.keys()) {

View file

@ -15,7 +15,9 @@ internal const val REQUEST_CODE_UNINSTALL = 4576841
class RestoreErrorBroadcastReceiver : BroadcastReceiver() {
// using KoinComponent would crash robolectric tests :(
private val notificationManager: BackupNotificationManager by lazy { get().get<BackupNotificationManager>() }
private val notificationManager: BackupNotificationManager by lazy {
get().get<BackupNotificationManager>()
}
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != ACTION_RESTORE_ERROR_UNINSTALL) return
@ -24,7 +26,7 @@ class RestoreErrorBroadcastReceiver : BroadcastReceiver() {
val packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME)!!
@Suppress("DEPRECATION") // the alternative doesn't work for us
@Suppress("DEPRECATION") // the alternative doesn't work for us
val i = Intent(Intent.ACTION_UNINSTALL_PACKAGE).apply {
data = "package:$packageName".toUri()
flags = FLAG_ACTIVITY_NEW_TASK

View file

@ -186,7 +186,9 @@ internal class RestoreViewModel(
// we need to start a new session and retrieve the restore sets before starting the restore
val restoreSetResult = getAvailableRestoreSets()
if (restoreSetResult.hasError()) {
mRestoreBackupResult.postValue(RestoreBackupResult(app.getString(R.string.restore_finished_error)))
mRestoreBackupResult.postValue(
RestoreBackupResult(app.getString(R.string.restore_finished_error))
)
return
}
@ -196,7 +198,9 @@ internal class RestoreViewModel(
if (restoreAllResult != 0) {
if (session == null) Log.e(TAG, "session was null")
else Log.e(TAG, "restoreAll() returned non-zero value")
mRestoreBackupResult.postValue(RestoreBackupResult(app.getString(R.string.restore_finished_error)))
mRestoreBackupResult.postValue(
RestoreBackupResult(app.getString(R.string.restore_finished_error))
)
return
}
}
@ -306,8 +310,9 @@ internal class RestoreViewModel(
val restorableBackups = restoreSets.mapNotNull { set ->
getRestorableBackup(set, backupMetadata[set.token])
}
if (restorableBackups.isEmpty()) RestoreSetResult(app.getString(R.string.restore_set_empty_result))
else RestoreSetResult(restorableBackups)
if (restorableBackups.isEmpty()) {
RestoreSetResult(app.getString(R.string.restore_set_empty_result))
} else RestoreSetResult(restorableBackups)
}
}
continuation.resume(result)

View file

@ -2,7 +2,7 @@ package com.stevesoltys.seedvault.settings
import android.app.backup.IBackupManager
import android.content.Context
import android.content.Context.BACKUP_SERVICE
import android.content.Context.BACKUP_SERVICE // ktlint-disable no-unused-imports
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
@ -11,7 +11,7 @@ import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED
import android.os.Bundle
import android.os.RemoteException
import android.provider.Settings
import android.provider.Settings.Secure.BACKUP_AUTO_RESTORE
import android.provider.Settings.Secure.BACKUP_AUTO_RESTORE // ktlint-disable no-unused-imports
import android.util.Log
import android.view.Menu
import android.view.MenuInflater

View file

@ -2,10 +2,10 @@ package com.stevesoltys.seedvault.transport
import android.app.Service
import android.app.backup.BackupManager
import android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP
import android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP // ktlint-disable no-unused-imports
import android.app.backup.IBackupManager
import android.content.Context
import android.content.Context.BACKUP_SERVICE
import android.content.Context.BACKUP_SERVICE // ktlint-disable no-unused-imports
import android.content.Intent
import android.os.IBinder
import android.os.RemoteException

View file

@ -79,8 +79,8 @@ class ApkBackup(
// do not backup if we have the version already and signatures did not change
if (version <= backedUpVersion && !signaturesChanged(packageMetadata, signatures)) {
Log.d(
TAG,
"Package $packageName with version $version already has a backup ($backedUpVersion)" +
TAG, "Package $packageName with version $version" +
" already has a backup ($backedUpVersion)" +
" with the same signature. Not backing it up."
)
return null

View file

@ -327,12 +327,16 @@ internal class BackupCoordinator(
*/
suspend fun finishBackup(): Int = when {
kv.hasState() -> {
check(!full.hasState()) { "K/V backup has state, but full backup has dangling state as well" }
check(!full.hasState()) {
"K/V backup has state, but full backup has dangling state as well"
}
onPackageBackedUp(kv.getCurrentPackage()!!) // not-null because we have state
kv.finishBackup()
}
full.hasState() -> {
check(!kv.hasState()) { "Full backup has state, but K/V backup has dangling state as well" }
check(!kv.hasState()) {
"Full backup has state, but K/V backup has dangling state as well"
}
onPackageBackedUp(full.getCurrentPackage()!!) // not-null because we have state
full.finishBackup()
}
@ -352,15 +356,17 @@ internal class BackupCoordinator(
val packageName = packageInfo.packageName
try {
nm.onOptOutAppBackup(packageName, i + 1, notAllowedPackages.size)
val packageState = if (packageInfo.isStopped()) WAS_STOPPED else NOT_ALLOWED
val packageState =
if (packageInfo.isStopped()) WAS_STOPPED else NOT_ALLOWED
val wasBackedUp = backUpApk(packageInfo, packageState)
if (!wasBackedUp) {
val packageMetadata = metadataManager.getPackageMetadata(packageName)
val packageMetadata =
metadataManager.getPackageMetadata(packageName)
val oldPackageState = packageMetadata?.state
if (oldPackageState != null && oldPackageState != packageState) {
Log.e(
TAG,
"Package $packageName was in $oldPackageState, update to $packageState"
TAG, "Package $packageName was in $oldPackageState" +
", update to $packageState"
)
plugin.getMetadataOutputStream().use {
metadataManager.onPackageBackupError(packageInfo, packageState, it)

View file

@ -62,7 +62,7 @@ internal class ApkInstaller(private val context: Context) {
}
// Don't set more sessionParams intentionally here.
// We saw strange permission issues when doing setInstallReason() or setting installFlags.
@Suppress("BlockingMethodInNonBlockingContext") // flows on Dispatcher.IO
@Suppress("BlockingMethodInNonBlockingContext") // flows on Dispatcher.IO
val session = installer.openSession(installer.createSession(sessionParams))
val sizeBytes = cachedApk.length()
session.use { s ->
@ -96,7 +96,9 @@ internal class ApkInstaller(private val context: Context) {
val success = i.getIntExtra(EXTRA_STATUS, -1) == STATUS_SUCCESS
val statusMsg = i.getStringExtra(EXTRA_STATUS_MESSAGE)!!
check(packageName == expectedPackageName) { "Expected $expectedPackageName, but got $packageName." }
check(packageName == expectedPackageName) {
"Expected $expectedPackageName, but got $packageName."
}
Log.d(TAG, "Received result for $packageName: success=$success $statusMsg")
// delete cached APK file

View file

@ -95,9 +95,9 @@ internal class ApkRestore(
// check APK's SHA-256 hash
val sha256 = messageDigest.digest().encodeBase64()
if (metadata.sha256 != sha256) {
throw SecurityException("Package $packageName has sha256 '$sha256', but '${metadata.sha256}' expected.")
}
if (metadata.sha256 != sha256) throw SecurityException(
"Package $packageName has sha256 '$sha256', but '${metadata.sha256}' expected."
)
// parse APK (GET_SIGNATURES is needed even though deprecated)
@Suppress("DEPRECATION") val flags = GET_SIGNING_CERTIFICATES or GET_SIGNATURES
@ -105,9 +105,9 @@ internal class ApkRestore(
?: throw IOException("getPackageArchiveInfo returned null")
// check APK package name
if (packageName != packageInfo.packageName) {
throw SecurityException("Package $packageName expected, but ${packageInfo.packageName} found.")
}
if (packageName != packageInfo.packageName) throw SecurityException(
"Package $packageName expected, but ${packageInfo.packageName} found."
)
// check APK version code
if (metadata.version != packageInfo.longVersionCode) {

View file

@ -1,6 +1,5 @@
package com.stevesoltys.seedvault.ui.storage
import android.content.Context
import android.text.format.Formatter
import android.view.LayoutInflater

View file

@ -277,9 +277,15 @@ internal class StorageRootFetcher(private val context: Context, private val isRe
private fun getIcon(context: Context, authority: String, rootId: String, icon: Int): Drawable? {
return getPackageIcon(context, authority, icon) ?: when {
authority == AUTHORITY_STORAGE && rootId == ROOT_ID_DEVICE -> context.getDrawable(R.drawable.ic_phone_android)
authority == AUTHORITY_STORAGE && rootId != ROOT_ID_HOME -> context.getDrawable(R.drawable.ic_usb)
authority == AUTHORITY_NEXTCLOUD -> context.getDrawable(R.drawable.nextcloud)
authority == AUTHORITY_STORAGE && rootId == ROOT_ID_DEVICE -> {
context.getDrawable(R.drawable.ic_phone_android)
}
authority == AUTHORITY_STORAGE && rootId != ROOT_ID_HOME -> {
context.getDrawable(R.drawable.ic_usb)
}
authority == AUTHORITY_NEXTCLOUD -> {
context.getDrawable(R.drawable.nextcloud)
}
else -> null
}
}

View file

@ -23,4 +23,4 @@ class KeyManagerTestImpl : KeyManager {
return key
}
}
}

View file

@ -2090,31 +2090,36 @@ class WordListTest {
@Suppress("MaxLineLength")
fun `12 words generate expected seed`() {
assertEquals(
"64AA8C388EC0F3A13C7E51653BC766E30668D30952AB34381C4B174BF3278774B4EE43D0BA08BCBCE0D0B806DEB7AA364A83525C34847078B2A8002A3E116066",
"64AA8C388EC0F3A13C7E51653BC766E30668D30952AB34381C4B174BF3278774" +
"B4EE43D0BA08BCBCE0D0B806DEB7AA364A83525C34847078B2A8002A3E116066",
SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(
"write wrong yard year yellow you young youth zebra zero zone zoo", ""
).toHexString("")
)
assertEquals(
"E911FAA42F389AA9F6D5A40B2ECB876B06D6D1FFBD5885C54720398EB11918CAB8F7BAD70FD5BE39BEB4EB065610700D1CFF1D4BFAA26F998357E15E79002779",
"E911FAA42F389AA9F6D5A40B2ECB876B06D6D1FFBD5885C54720398EB11918CA" +
"B8F7BAD70FD5BE39BEB4EB065610700D1CFF1D4BFAA26F998357E15E79002779",
SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(
"matrix lava they brand negative spray floor gym purity picture ritual disorder", ""
).toHexString("")
)
assertEquals(
"DDB26091680CF30D0DC615546E4612327DB287B6B2B8B8947A3E12580315D38C3BF7DD0EB4E9E50B10A41925332E0C8ED43C80DBA29281EF331A1DFA858BF1C9",
"DDB26091680CF30D0DC615546E4612327DB287B6B2B8B8947A3E12580315D38C" +
"3BF7DD0EB4E9E50B10A41925332E0C8ED43C80DBA29281EF331A1DFA858BF1C9",
SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(
"middle rack south alert ribbon tube hope involve defy oxygen gloom rabbit", ""
).toHexString("")
)
assertEquals(
"4815B580D0DCDA08334C92B3CB9A8436CD581C55841FB2794FB1E3D6E389F447C8C6520B2FE567720950F5B39BE7EC42C0BC98D3C63F8FEF642B5BD3EE4CDD7B",
"4815B580D0DCDA08334C92B3CB9A8436CD581C55841FB2794FB1E3D6E389F447" +
"C8C6520B2FE567720950F5B39BE7EC42C0BC98D3C63F8FEF642B5BD3EE4CDD7B",
SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(
"interest mask trial hold foot segment fade page monitor apple garden shuffle", ""
).toHexString("")
)
assertEquals(
"FF462543D8FB9DAE6C17FA7BA047238664207FCC797D6688E10DD1B3CFD183D4928AD088E8287B69BABCAEB0F87A2DFF2ADD49A7FDB7EB2554D7344F09C41A76",
"FF462543D8FB9DAE6C17FA7BA047238664207FCC797D6688E10DD1B3CFD183D4" +
"928AD088E8287B69BABCAEB0F87A2DFF2ADD49A7FDB7EB2554D7344F09C41A76",
SeedCalculator(JavaxPBKDF2WithHmacSHA512.INSTANCE).calculateSeed(
"palace glory gospel garment obscure person edge total hunt fix setup uphold\n", ""
).toHexString("")

View file

@ -160,7 +160,9 @@ class MetadataReaderTest {
assertNull(packageMetadata.signatures)
}
private fun getMetadata(packageMetadata: PackageMetadataMap = PackageMetadataMap()): BackupMetadata {
private fun getMetadata(
packageMetadata: PackageMetadataMap = PackageMetadataMap()
): BackupMetadata {
return BackupMetadata(
version = 1.toByte(),
token = Random.nextLong(),

View file

@ -110,7 +110,9 @@ internal class MetadataWriterDecoderTest {
)
}
private fun getMetadata(packageMetadata: HashMap<String, PackageMetadata> = HashMap()): BackupMetadata {
private fun getMetadata(
packageMetadata: HashMap<String, PackageMetadata> = HashMap()
): BackupMetadata {
return BackupMetadata(
version = Random.nextBytes(1)[0],
token = Random.nextLong(),

View file

@ -32,7 +32,6 @@ import java.io.OutputStream
import java.nio.file.Path
import kotlin.random.Random
@Suppress("BlockingMethodInNonBlockingContext")
internal class ApkBackupTest : BackupTest() {
@ -104,7 +103,9 @@ internal class ApkBackupTest : BackupTest() {
@Test
fun `do not accept empty signature`() = runBlocking {
every { settingsManager.backupApks() } returns true
every { metadataManager.getPackageMetadata(packageInfo.packageName) } returns packageMetadata
every {
metadataManager.getPackageMetadata(packageInfo.packageName)
} returns packageMetadata
every { sigInfo.hasMultipleSigners() } returns false
every { sigInfo.signingCertificateHistory } returns emptyArray()
@ -151,7 +152,9 @@ internal class ApkBackupTest : BackupTest() {
private fun expectChecks(packageMetadata: PackageMetadata = this.packageMetadata) {
every { settingsManager.backupApks() } returns true
every { metadataManager.getPackageMetadata(packageInfo.packageName) } returns packageMetadata
every {
metadataManager.getPackageMetadata(packageInfo.packageName)
} returns packageMetadata
every { PackageUtils.computeSha256DigestBytes(signatureBytes) } returns signatureHash
every { sigInfo.hasMultipleSigners() } returns false
every { sigInfo.signingCertificateHistory } returns sigs

View file

@ -246,7 +246,9 @@ internal class BackupCoordinatorTest : BackupTest() {
coEvery { full.performFullBackup(packageInfo, fileDescriptor, 0) } returns TRANSPORT_OK
expectApkBackupAndMetadataWrite()
every { full.getQuota() } returns DEFAULT_QUOTA_FULL_BACKUP
every { full.checkFullBackupSize(DEFAULT_QUOTA_FULL_BACKUP + 1) } returns TRANSPORT_QUOTA_EXCEEDED
every {
full.checkFullBackupSize(DEFAULT_QUOTA_FULL_BACKUP + 1)
} returns TRANSPORT_QUOTA_EXCEEDED
every { full.getCurrentPackage() } returns packageInfo
every {
metadataManager.onPackageBackupError(
@ -347,7 +349,9 @@ internal class BackupCoordinatorTest : BackupTest() {
apkBackup.backupApkIfNecessary(notAllowedPackages[0], NOT_ALLOWED, any())
} returns null
// check old metadata for state changes, because we won't update it otherwise
every { metadataManager.getPackageMetadata(notAllowedPackages[0].packageName) } returns packageMetadata
every {
metadataManager.getPackageMetadata(notAllowedPackages[0].packageName)
} returns packageMetadata
every { packageMetadata.state } returns NOT_ALLOWED // no change
// update notification for second package
@ -386,10 +390,15 @@ internal class BackupCoordinatorTest : BackupTest() {
val oldPackageMetadata: PackageMetadata = mockk()
every { packageService.notAllowedPackages } returns listOf(packageInfo)
every { notificationManager.onOptOutAppBackup(packageInfo.packageName, 1, 1) } just Runs
every {
notificationManager.onOptOutAppBackup(packageInfo.packageName, 1, 1)
} just Runs
coEvery { apkBackup.backupApkIfNecessary(packageInfo, NOT_ALLOWED, any()) } returns null
every { metadataManager.getPackageMetadata(packageInfo.packageName) } returns oldPackageMetadata
every { oldPackageMetadata.state } returns WAS_STOPPED // state differs now, was stopped before
every {
metadataManager.getPackageMetadata(packageInfo.packageName)
} returns oldPackageMetadata
// state differs now, was stopped before
every { oldPackageMetadata.state } returns WAS_STOPPED
coEvery { plugin.getMetadataOutputStream() } returns metadataOutputStream
every {
metadataManager.onPackageBackupError(

View file

@ -215,7 +215,7 @@ internal class ApkRestoreTest : RestoreTest() {
}
@Test
fun `test system apps only get reinstalled when older system apps exist`(@TempDir tmpDir: Path) =
fun `test system apps only reinstalled when older system apps exist`(@TempDir tmpDir: Path) =
runBlocking {
val packageMetadata = this@ApkRestoreTest.packageMetadata.copy(system = true)
packageMetadataMap[packageName] = packageMetadata

View file

@ -165,7 +165,7 @@ internal class RestoreCoordinatorTest : TransportTest() {
}
@Test
fun `startRestore() optimized auto-restore with removed storage but no backup shows no notification`() {
fun `startRestore() with removed storage shows no notification`() {
every { settingsManager.getStorage() } returns storage
every { storage.isUsb } returns true
every { storage.getDocumentFile(context) } returns documentFile