Skip to content

Commit

Permalink
Revisit APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
pyricau committed Apr 24, 2024
1 parent 0ff8788 commit f41ff73
Show file tree
Hide file tree
Showing 36 changed files with 471 additions and 447 deletions.
Expand Up @@ -12,6 +12,10 @@ public final class leakcanary/AndroidDebugHeapDumper : leakcanary/HeapDumper {
public fun dumpHeap (Ljava/io/File;)V
}

public final class leakcanary/AndroidDebugHeapDumperKt {
public static final fun androidDumper (Lleakcanary/HeapDumper$Companion;)Lleakcanary/AndroidDebugHeapDumper;
}

public final class leakcanary/BackgroundThreadHeapAnalyzer : leakcanary/EventListener {
public static final field INSTANCE Lleakcanary/BackgroundThreadHeapAnalyzer;
public fun onEvent (Lleakcanary/EventListener$Event;)V
Expand Down
Expand Up @@ -14,3 +14,5 @@ object AndroidDebugHeapDumper : HeapDumper {
Debug.dumpHprofData(heapDumpFile.absolutePath)
}
}

fun HeapDumper.Companion.androidDumper() = AndroidDebugHeapDumper
Expand Up @@ -19,12 +19,6 @@ public final class leakcanary/AndroidDetectLeaksInterceptor : leakcanary/DetectL
public fun waitUntilReadyForHeapAnalysis ()Lleakcanary/HeapAnalysisDecision;
}

public final class leakcanary/AndroidLiveObjectGrowthDetector {
public static final field INSTANCE Lleakcanary/AndroidLiveObjectGrowthDetector;
public final fun create (IILleakcanary/HeapDumpFileProvider;Lleakcanary/HeapDumper;Lshark/RepeatedObjectGrowthDetector;)Lshark/LiveObjectGrowthDetector;
public static synthetic fun create$default (Lleakcanary/AndroidLiveObjectGrowthDetector;IILleakcanary/HeapDumpFileProvider;Lleakcanary/HeapDumper;Lshark/RepeatedObjectGrowthDetector;ILjava/lang/Object;)Lshark/LiveObjectGrowthDetector;
}

public final class leakcanary/DetectLeaksAfterTestSuccess : org/junit/rules/TestRule {
public static final field Companion Lleakcanary/DetectLeaksAfterTestSuccess$Companion;
public fun <init> ()V
Expand Down
Expand Up @@ -3,6 +3,7 @@ package leakcanary
import android.os.SystemClock
import androidx.test.platform.app.InstrumentationRegistry
import java.io.File
import kotlin.time.Duration.Companion.milliseconds
import leakcanary.HeapAnalysisDecision.NoHeapAnalysis
import leakcanary.internal.InstrumentationHeapAnalyzer
import leakcanary.internal.RetryingHeapAnalyzer
Expand All @@ -11,7 +12,6 @@ import leakcanary.internal.friendly.measureDurationMillis
import shark.HeapAnalysisFailure
import shark.HeapAnalysisSuccess
import shark.SharkLog
import kotlin.time.Duration.Companion.milliseconds

/**
* Default [DetectLeaksAssert] implementation. Uses public helpers so you should be able to
Expand Down Expand Up @@ -41,7 +41,10 @@ class AndroidDetectLeaksAssert(
}
}

private fun runLeakChecks(tag: String, assertionStartUptimeMillis: Long) {
private fun runLeakChecks(
tag: String,
assertionStartUptimeMillis: Long
) {
if (TestDescriptionHolder.isEvaluating()) {
val testDescription = TestDescriptionHolder.testDescription
if (SkipLeakDetection.shouldSkipTest(testDescription, tag)) {
Expand All @@ -58,7 +61,7 @@ class AndroidDetectLeaksAssert(
}
}

val heapDumpFileProvider = leakcanary.HeapDumpFileProvider.dateFormatted(
val heapDumpFileProvider = HeapDumpFileProvider.dateFormattedFileProvider(
directory = File(
InstrumentationRegistry.getInstrumentation().targetContext.filesDir,
"instrumentation_tests"
Expand Down Expand Up @@ -101,6 +104,7 @@ class AndroidDetectLeaksAssert(
TOTAL_DURATION to totalDurationMillis.toString()
),
)

is HeapAnalysisFailure -> it.copy(dumpDurationMillis = heapDumpDurationMillis)
}
}
Expand Down

This file was deleted.

25 changes: 23 additions & 2 deletions leakcanary/leakcanary-core/api/leakcanary-core.api
Expand Up @@ -9,22 +9,43 @@ public final class leakcanary/DateFormatHeapDumpFileProvider : leakcanary/HeapDu
public final class leakcanary/DateFormatHeapDumpFileProvider$Companion {
}

public final class leakcanary/DateFormatHeapDumpFileProviderKt {
public static final fun dateFormattedFileProvider (Lleakcanary/HeapDumpFileProvider$Companion;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Lleakcanary/HeapDumpFileProvider;
public static synthetic fun dateFormattedFileProvider$default (Lleakcanary/HeapDumpFileProvider$Companion;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lleakcanary/HeapDumpFileProvider;
}

public final class leakcanary/DumpingDeletingOnCloseHeapGraphProvider : shark/HeapGraphProvider {
public fun <init> (Lleakcanary/HeapDumpFileProvider;Lleakcanary/HeapDumper;)V
public fun openHeapGraph ()Lshark/CloseableHeapGraph;
}

public final class leakcanary/DumpingDeletingOnCloseHeapGraphProviderKt {
public static final fun dumpingAndDeletingGraphProvider (Lshark/HeapGraphProvider$Companion;Lleakcanary/HeapDumper;Lleakcanary/HeapDumpFileProvider;)Lleakcanary/DumpingDeletingOnCloseHeapGraphProvider;
public static synthetic fun dumpingAndDeletingGraphProvider$default (Lshark/HeapGraphProvider$Companion;Lleakcanary/HeapDumper;Lleakcanary/HeapDumpFileProvider;ILjava/lang/Object;)Lleakcanary/DumpingDeletingOnCloseHeapGraphProvider;
}

public abstract interface class leakcanary/HeapDumpFileProvider {
public static final field Companion Lleakcanary/HeapDumpFileProvider$Companion;
public abstract fun newHeapDumpFile ()Ljava/io/File;
}

public final class leakcanary/HeapDumpFileProvider$Companion {
public final fun dateFormatted (Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Lleakcanary/HeapDumpFileProvider;
public static synthetic fun dateFormatted$default (Lleakcanary/HeapDumpFileProvider$Companion;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lleakcanary/HeapDumpFileProvider;
}

public abstract interface class leakcanary/HeapDumper {
public static final field Companion Lleakcanary/HeapDumper$Companion;
public abstract fun dumpHeap (Ljava/io/File;)V
}

public final class leakcanary/HeapDumper$Companion {
}

public final class leakcanary/TempHeapDumpFileProvider : leakcanary/HeapDumpFileProvider {
public static final field INSTANCE Lleakcanary/TempHeapDumpFileProvider;
public fun newHeapDumpFile ()Ljava/io/File;
}

public final class leakcanary/TempHeapDumpFileProviderKt {
public static final fun tempFileProvider (Lleakcanary/HeapDumpFileProvider$Companion;)Lleakcanary/HeapDumpFileProvider;
}

Expand Up @@ -37,3 +37,24 @@ class DateFormatHeapDumpFileProvider(
const val TIME_PATTERN = "yyyy-MM-dd_HH-mm-ss_SSS"
}
}

fun HeapDumpFileProvider.Companion.dateFormattedFileProvider(
directory: File,
prefix: String = "",
suffix: String = "",
dateProvider: () -> Date = { Date() },
): HeapDumpFileProvider {
return DateFormatHeapDumpFileProvider(
heapDumpDirectoryProvider = {
directory.apply {
mkdirs()
check(exists()) {
"Expected heap dump folder to exist: $absolutePath"
}
}
},
dateProvider = dateProvider,
prefix = prefix,
suffix = suffix
)
}
Expand Up @@ -23,3 +23,8 @@ class DumpingDeletingOnCloseHeapGraphProvider(
}
}
}

fun HeapGraphProvider.Companion.dumpingAndDeletingGraphProvider(
heapDumper: HeapDumper,
heapDumpFileProvider: HeapDumpFileProvider = TempHeapDumpFileProvider,
) = DumpingDeletingOnCloseHeapGraphProvider(heapDumpFileProvider, heapDumper)
Expand Up @@ -10,26 +10,9 @@ fun interface HeapDumpFileProvider {
*/
fun newHeapDumpFile(): File

companion object {
fun dateFormatted(
directory: File,
prefix: String = "",
suffix: String = "",
dateProvider: () -> Date = { Date() },
): HeapDumpFileProvider {
return DateFormatHeapDumpFileProvider(
heapDumpDirectoryProvider = {
directory.apply {
mkdirs()
check(exists()) {
"Expected heap dump folder to exist: $absolutePath"
}
}
},
dateProvider = dateProvider,
prefix = prefix,
suffix = suffix
)
}
}
/**
* This allows external modules to add factory methods for implementations of this interface as
* extension functions of this companion object.
*/
companion object
}
Expand Up @@ -11,4 +11,10 @@ fun interface HeapDumper {
* Implementations can throw a runtime exception if heap dumping failed.
*/
fun dumpHeap(heapDumpFile: File)

/**
* This allows external modules to add factory methods for implementations of this interface as
* extension functions of this companion object.
*/
companion object
}
Expand Up @@ -11,3 +11,6 @@ object TempHeapDumpFileProvider : HeapDumpFileProvider {
return heapDumpFile
}
}

fun HeapDumpFileProvider.Companion.tempFileProvider(): HeapDumpFileProvider =
TempHeapDumpFileProvider
11 changes: 2 additions & 9 deletions leakcanary/leakcanary-jvm-test/api/leakcanary-jvm-test.api
Expand Up @@ -3,14 +3,7 @@ public final class leakcanary/HotSpotHeapDumper : leakcanary/HeapDumper {
public fun dumpHeap (Ljava/io/File;)V
}

public final class leakcanary/JvmLiveObjectGrowthDetector {
public static final field INSTANCE Lleakcanary/JvmLiveObjectGrowthDetector;
public final fun create (IILleakcanary/HeapDumpFileProvider;Lleakcanary/HeapDumper;Lshark/RepeatedObjectGrowthDetector;)Lshark/LiveObjectGrowthDetector;
public static synthetic fun create$default (Lleakcanary/JvmLiveObjectGrowthDetector;IILleakcanary/HeapDumpFileProvider;Lleakcanary/HeapDumper;Lshark/RepeatedObjectGrowthDetector;ILjava/lang/Object;)Lshark/LiveObjectGrowthDetector;
}

public final class leakcanary/TempHeapDumpFileProvider : leakcanary/HeapDumpFileProvider {
public static final field INSTANCE Lleakcanary/TempHeapDumpFileProvider;
public fun newHeapDumpFile ()Ljava/io/File;
public final class leakcanary/HotSpotHeapDumperKt {
public static final fun jvmDumper (Lleakcanary/HeapDumper$Companion;)Lleakcanary/HotSpotHeapDumper;
}

Expand Up @@ -19,3 +19,6 @@ object HotSpotHeapDumper : HeapDumper {
hotspotMBean.dumpHeap(heapDumpFile.absolutePath, live)
}
}

fun HeapDumper.Companion.jvmDumper() = HotSpotHeapDumper

This file was deleted.

Expand Up @@ -2,7 +2,10 @@ package leakcanary

import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import shark.RepeatedObjectGrowthDetectorJvmFactory
import shark.HeapGraphProvider
import shark.ObjectGrowthDetector
import shark.fromHeapDumpingRepeatedScenario
import shark.jvmDetector

class JvmHeapGrowthDetectorConfigTest {

Expand All @@ -12,13 +15,16 @@ class JvmHeapGrowthDetectorConfigTest {

@Test
fun `leaky increase leads to heap growth`() {
val detector = JvmLiveObjectGrowthDetector.create(
repeatedObjectGrowthDetector = RepeatedObjectGrowthDetectorJvmFactory.create()
)
val detector = ObjectGrowthDetector.jvmDetector()
.fromHeapDumpingRepeatedScenario(
heapGraphProvider = HeapGraphProvider.dumpingAndDeletingGraphProvider(
heapDumper = HeapDumper.jvmDumper()
)
)

val growingNodes = detector.findRepeatedlyGrowingObjects {
leakies += Leaky()
}
}.growingNodes

assertThat(growingNodes).hasSize(1)
}
Expand Down
11 changes: 5 additions & 6 deletions shark/shark-android/api/shark-android.api
Expand Up @@ -38,6 +38,11 @@ public final class shark/AndroidMetadataExtractor : shark/MetadataExtractor {
public fun extractMetadata (Lshark/HeapGraph;)Ljava/util/Map;
}

public final class shark/AndroidObjectGrowthDetectorKt {
public static final fun androidDetector (Lshark/ObjectGrowthDetector$Companion;Ljava/util/List;)Lshark/ObjectGrowthDetector;
public static synthetic fun androidDetector$default (Lshark/ObjectGrowthDetector$Companion;Ljava/util/List;ILjava/lang/Object;)Lshark/ObjectGrowthDetector;
}

public abstract class shark/AndroidObjectInspectors : java/lang/Enum, shark/ObjectInspector {
public static final field ACTIVITY Lshark/AndroidObjectInspectors;
public static final field ACTIVITY_THREAD Lshark/AndroidObjectInspectors;
Expand Down Expand Up @@ -233,9 +238,3 @@ public final class shark/AndroidServices {
public final fun getAliveAndroidServiceObjectIds (Lshark/HeapGraph;)Ljava/util/List;
}

public final class shark/RepeatedObjectGrowthDetectorAndroidFactory {
public static final field INSTANCE Lshark/RepeatedObjectGrowthDetectorAndroidFactory;
public final fun create (Ljava/util/List;)Lshark/RepeatedObjectGrowthDetector;
public static synthetic fun create$default (Lshark/RepeatedObjectGrowthDetectorAndroidFactory;Ljava/util/List;ILjava/lang/Object;)Lshark/RepeatedObjectGrowthDetector;
}

Expand Up @@ -17,7 +17,7 @@ enum class AndroidHeapGrowthIgnoredReferences {

HEAP_TRAVERSAL {
override fun add(patterns: MutableList<ReferencePattern>) {
patterns += HeapTraversal.ignoredReferences.map { it.pattern }
patterns += HeapTraversalOutput.ignoredReferences.map { it.pattern }
}
},

Expand Down
@@ -0,0 +1,10 @@
package shark

fun ObjectGrowthDetector.Companion.androidDetector(
referenceMatchers: List<ReferenceMatcher> = AndroidHeapGrowthIgnoredReferences.defaults
): ObjectGrowthDetector {
return ObjectGrowthDetector(
gcRootProvider = MatchingGcRootProvider(referenceMatchers),
referenceReaderFactory = AndroidReferenceReaderFactory(referenceMatchers)
)
}

This file was deleted.

Expand Up @@ -31,7 +31,7 @@ class AndroidReferenceMatcher_XIAMI__RESOURCES_IMPL_Test(

/**
* It's known that some device manufacturers on SDK 30 and above leak
* a statically held [android.content.Context] from a class [android.content.res.ResourcesImpl]
* a statically held [androidDetector.content.Context] from a class [androidDetector.content.res.ResourcesImpl]
* in a variable named [mContext].
*/
const val expectedKnownClassLeakingContext = "android.content.res.ResourcesImpl"
Expand Down

0 comments on commit f41ff73

Please sign in to comment.