Skip to content

Commit

Permalink
Enable automatic coding style linting with ktlint (also on CI)
Browse files Browse the repository at this point in the history
This way the coding style is guaranteed to stay consistent.
  • Loading branch information
grote authored and chirayudesai committed Oct 7, 2020
1 parent 53937bd commit 6c53106
Show file tree
Hide file tree
Showing 31 changed files with 167 additions and 70 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.{kt,kts}]
indent_size=4
insert_final_newline=true
max_line_length=100
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ out/
lib/
.idea/*
!.idea/runConfigurations*
!.idea/inspectionProfiles*
!.idea/codeStyles*
*.ipr
*.iws
Expand Down
10 changes: 10 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
27 changes: 23 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/stevesoltys/seedvault/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class App : Application() {
cryptoModule,
headerModule,
metadataModule,
documentsProviderModule, // storage plugin
documentsProviderModule, // storage plugin
backupModule,
restoreModule,
appModule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
15 changes: 8 additions & 7 deletions app/src/main/java/com/stevesoltys/seedvault/crypto/Crypto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/stevesoltys/seedvault/header/Header.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}
}
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,19 @@ 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
val packageInfo = pm.getPackageArchiveInfo(cachedApk.absolutePath, flags)
?: 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) {
Expand Down
Loading

0 comments on commit 6c53106

Please sign in to comment.