xref: /aosp_15_r20/external/leakcanary2/shark/src/main/java/shark/internal/KeyedWeakReferenceMirror.kt (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1 package shark.internal
2 
3 import shark.HeapObject.HeapInstance
4 import shark.ValueHolder
5 import shark.ValueHolder.ReferenceHolder
6 
7 internal class KeyedWeakReferenceMirror(
8   val referent: ReferenceHolder,
9   val key: String,
10   // The name field does not exist in pre 1.0 heap dumps.
11   val description: String,
12   // null in pre 2.0 alpha 3 heap dumps
13   val watchDurationMillis: Long?,
14   // null in pre 2.0 alpha 3 heap dumps, -1 if the instance is not retained.
15   val retainedDurationMillis: Long?
16 ) {
17 
18   val hasReferent = referent.value != ValueHolder.NULL_REFERENCE
19 
20   val isRetained = retainedDurationMillis == null || retainedDurationMillis != -1L
21 
22   companion object {
23 
24     private const val UNKNOWN_LEGACY = "Unknown (legacy)"
25 
fromInstancenull26     fun fromInstance(
27       weakRef: HeapInstance,
28       // Null for pre 2.0 alpha 3 heap dumps
29       heapDumpUptimeMillis: Long?
30     ): KeyedWeakReferenceMirror {
31 
32       val keyWeakRefClassName = weakRef.instanceClassName
33       val watchDurationMillis = if (heapDumpUptimeMillis != null) {
34         heapDumpUptimeMillis - weakRef[keyWeakRefClassName, "watchUptimeMillis"]!!.value.asLong!!
35       } else {
36         null
37       }
38 
39       val retainedDurationMillis = if (heapDumpUptimeMillis != null) {
40         val retainedUptimeMillis =
41           weakRef[keyWeakRefClassName, "retainedUptimeMillis"]!!.value.asLong!!
42         if (retainedUptimeMillis == -1L) -1L else heapDumpUptimeMillis - retainedUptimeMillis
43       } else {
44         null
45       }
46 
47       val keyString = weakRef[keyWeakRefClassName, "key"]!!.value.readAsJavaString()!!
48 
49       // Changed from name to description after 2.0
50       val description = (weakRef[keyWeakRefClassName, "description"]
51         ?: weakRef[keyWeakRefClassName, "name"])?.value?.readAsJavaString() ?: UNKNOWN_LEGACY
52       return KeyedWeakReferenceMirror(
53         watchDurationMillis = watchDurationMillis,
54         retainedDurationMillis = retainedDurationMillis,
55         referent = weakRef["java.lang.ref.Reference", "referent"]!!.value.holder as ReferenceHolder,
56         key = keyString,
57         description = description
58       )
59     }
60   }
61 }
62 
63