From 8789d1cf5b215ad402834891c05b9d36355783ab Mon Sep 17 00:00:00 2001 From: Adam Wushensky Date: Fri, 24 Sep 2021 14:05:53 -0400 Subject: [PATCH 1/2] Fix memory leak and double camera unbind --- build.gradle | 4 ++-- cardscan-demo/build.gradle | 2 ++ .../main/java/com/getbouncer/cardscan/ui/CardScanActivity.kt | 2 -- .../java/com/getbouncer/cardscan/ui/CardScanBaseActivity.kt | 2 ++ gradle/wrapper/gradle-wrapper.properties | 2 +- .../main/java/com/getbouncer/scan/framework/api/Network.kt | 2 +- .../java/com/getbouncer/scan/framework/image/NV21Image.kt | 4 ++-- .../main/java/com/getbouncer/scan/framework/util/Device.kt | 4 ++-- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index 7d4cd599..8035a856 100644 --- a/build.gradle +++ b/build.gradle @@ -10,14 +10,14 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.2.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } plugins { - id 'org.jetbrains.kotlin.plugin.serialization' version "1.4.32" + id 'org.jetbrains.kotlin.plugin.serialization' version "1.5.31" id 'org.jetbrains.dokka' version '1.5.0' id "io.github.gradle-nexus.publish-plugin" version "1.1.0" } diff --git a/cardscan-demo/build.gradle b/cardscan-demo/build.gradle index 533bf4d8..23a7d2e6 100644 --- a/cardscan-demo/build.gradle +++ b/cardscan-demo/build.gradle @@ -53,6 +53,8 @@ dependencies { testImplementation "androidx.test:runner:1.4.0" testImplementation "junit:junit:4.13.2" testImplementation "org.jetbrains.kotlin:kotlin-test:1.5.30" + + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' } dependencies { diff --git a/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanActivity.kt b/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanActivity.kt index cdf9943f..83c93d5f 100644 --- a/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanActivity.kt +++ b/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanActivity.kt @@ -424,9 +424,7 @@ open class CardScanActivity : frames: Collection, isFastDevice: Boolean ) { - cameraAdapter.unbindFromLifecycle(this@CardScanActivity) this@CardScanActivity.pan = pan - launch(Dispatchers.Default) { scanFlow.launchCompletionLoop( context = this@CardScanActivity, diff --git a/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanBaseActivity.kt b/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanBaseActivity.kt index e072ac3b..2cc868ca 100644 --- a/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanBaseActivity.kt +++ b/cardscan-ui/src/main/java/com/getbouncer/cardscan/ui/CardScanBaseActivity.kt @@ -139,6 +139,8 @@ abstract class CardScanBaseActivity : * A final result was received from the aggregator. */ override suspend fun onResult(result: MainLoopAggregator.FinalResult) = launch(Dispatchers.Main) { + changeScanState(ScanState.Correct) + cameraAdapter.unbindFromLifecycle(this@CardScanBaseActivity) resultListener.cardScanned( pan = result.pan, frames = scanFlow.selectCompletionLoopFrames(result.averageFrameRate, result.savedFrames), diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3a95001b..705ba16a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-all.zip diff --git a/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt b/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt index eec150a7..10bedd7f 100644 --- a/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt +++ b/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt @@ -346,7 +346,7 @@ private data class DeviceIdStructure( val d: String ) -private val buildDeviceId = memoize { context: Context -> +private val buildDeviceId = cacheFirstResult { context: Context -> DeviceIds.fromContext(context).run { Base64.encodeToString( Config.json.encodeToString( diff --git a/scan-framework/src/main/java/com/getbouncer/scan/framework/image/NV21Image.kt b/scan-framework/src/main/java/com/getbouncer/scan/framework/image/NV21Image.kt index 3d1898c0..a8349ddb 100644 --- a/scan-framework/src/main/java/com/getbouncer/scan/framework/image/NV21Image.kt +++ b/scan-framework/src/main/java/com/getbouncer/scan/framework/image/NV21Image.kt @@ -17,9 +17,9 @@ import android.util.Size import androidx.annotation.CheckResult import com.getbouncer.scan.framework.Config import com.getbouncer.scan.framework.exception.ImageTypeNotSupportedException +import com.getbouncer.scan.framework.util.cacheFirstResult import com.getbouncer.scan.framework.util.mapArray import com.getbouncer.scan.framework.util.mapToIntArray -import com.getbouncer.scan.framework.util.memoize import com.getbouncer.scan.framework.util.toByteArray import java.io.ByteArrayOutputStream import java.io.IOException @@ -30,7 +30,7 @@ import kotlin.experimental.inv /** * Get the RenderScript instance. */ -val getRenderScript = memoize { context: Context -> RenderScript.create(context) } +val getRenderScript = cacheFirstResult { context: Context -> RenderScript.create(context) } /** * An image made of data in the NV21 format. diff --git a/scan-framework/src/main/java/com/getbouncer/scan/framework/util/Device.kt b/scan-framework/src/main/java/com/getbouncer/scan/framework/util/Device.kt index 671cd51d..fc42f75a 100644 --- a/scan-framework/src/main/java/com/getbouncer/scan/framework/util/Device.kt +++ b/scan-framework/src/main/java/com/getbouncer/scan/framework/util/Device.kt @@ -20,7 +20,7 @@ data class Device( val platform: String ) { companion object { - private val getDeviceDetails = memoize { context: Context -> + private val getDeviceDetails = cacheFirstResult { context: Context -> Device( ids = DeviceIds.fromContext(context), name = getDeviceName(), @@ -44,7 +44,7 @@ data class DeviceIds( val androidId: String? ) { companion object { - private val getDeviceIds = memoize { context: Context -> + private val getDeviceIds = cacheFirstResult { context: Context -> DeviceIds( androidId = getAndroidId(context) ) From c8a61a23ba4d30b59d7f11a41fc79f82028bf588 Mon Sep 17 00:00:00 2001 From: Adam Wushensky Date: Fri, 24 Sep 2021 14:11:33 -0400 Subject: [PATCH 2/2] Fix lint --- .../src/main/java/com/getbouncer/scan/framework/api/Network.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt b/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt index 10bedd7f..2a684ad9 100644 --- a/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt +++ b/scan-framework/src/main/java/com/getbouncer/scan/framework/api/Network.kt @@ -15,7 +15,6 @@ import com.getbouncer.scan.framework.util.getOsVersion import com.getbouncer.scan.framework.util.getPlatform import com.getbouncer.scan.framework.util.getSdkFlavor import com.getbouncer.scan.framework.util.getSdkVersion -import com.getbouncer.scan.framework.util.memoize import com.getbouncer.scan.framework.util.retry import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable