Repository: square/leakcanary
File: shark/shark-android/src/main/java/shark/AndroidReferenceMatchers.kt (Kotlin)

Code before:
 * by the Android SDK, here: https://github.com/square/leakcanary/issues/new
 *
 * We filter on SDK versions and Manufacturers because many of those leaks are specific to a given
 * manufacturer implementation, they usually share their builds across multiple models, and the
 * leaks eventually get fixed in newer versions.
 *
 * Most app developers should use [appDefaults]. However, you can also use a subset of
 * [AndroidReferenceMatchers] by creating an [EnumSet] that matches your needs and calling
 * [buildKnownReferences].
 */
enum class AndroidReferenceMatchers {

  // ######## Android Framework known leaks ########

  PERMISSION_CONTROLLER_MANAGER {
    override fun add(
      references: MutableList<ReferenceMatcher>
    ) {
      references += instanceFieldLeak(
        "android.permission.PermissionControllerManager", "mContext",
        description = "On some devices PermissionControllerManager " +
        "may be initialized with Activity as its Context field. " +
        "Fix: you can \"fix\" this leak by calling getSystemService(\"permission_controller\") " +
        "on an application context. " +
        "Tracked here: https://issuetracker.google.com/issues/318415056"
      )
    }
  },

  IREQUEST_FINISH_CALLBACK {
    override fun add(
      references: MutableList<ReferenceMatcher>
    ) {
      references += instanceFieldLeak(
        "android.app.Activity\$1", "this\$0",
        description = "Android Q added a new android.app.IRequestFinishCallback\$Stub " +
          "class. android.app.Activity creates an implementation of that interface as an " +
          "anonymous subclass. That anonymous subclass has a reference to the activity. " +
          "Another process is keeping the android.app.IRequestFinishCallback\$Stub " +
          "reference alive long after Activity.onDestroyed() has been called, " +
          "causing the activity to leak. " +
          "Fix: You can \"fix\" this leak by overriding Activity.onBackPressed() and calling " +
          "Activity.finishAfterTransition(); instead of super if the activity is task root and the " +
          "fragment stack is empty. " +
          "Tracked here: https://issuetracker.google.com/issues/139738913"
      ) {
        sdkInt == 29
      }
    }
  },


Review comment (suggestion):
Add a version filter as a lambda here:

```
) {
  sdkInt >= 29
}
```

Code after:
 * by the Android SDK, here: https://github.com/square/leakcanary/issues/new
 *
 * We filter on SDK versions and Manufacturers because many of those leaks are specific to a given
 * manufacturer implementation, they usually share their builds across multiple models, and the
 * leaks eventually get fixed in newer versions.
 *
 * Most app developers should use [appDefaults]. However, you can also use a subset of
 * [AndroidReferenceMatchers] by creating an [EnumSet] that matches your needs and calling
 * [buildKnownReferences].
 */
enum class AndroidReferenceMatchers {

  // ######## Android Framework known leaks ########

  PERMISSION_CONTROLLER_MANAGER {
    override fun add(
      references: MutableList<ReferenceMatcher>
    ) {
      references += instanceFieldLeak(
        "android.permission.PermissionControllerManager", "mContext",
        description = "On some devices PermissionControllerManager " +
        "may be initialized with Activity as its Context field. " +
        "Fix: you can \"fix\" this leak by calling getSystemService(\"permission_controller\") " +
        "on an application context. " +
        "Tracked here: https://issuetracker.google.com/issues/318415056"
      ) {
        sdkInt >= 29
      }
    }
  },

  IREQUEST_FINISH_CALLBACK {
    override fun add(
      references: MutableList<ReferenceMatcher>
    ) {
      references += instanceFieldLeak(
        "android.app.Activity\$1", "this\$0",
        description = "Android Q added a new android.app.IRequestFinishCallback\$Stub " +
          "class. android.app.Activity creates an implementation of that interface as an " +
          "anonymous subclass. That anonymous subclass has a reference to the activity. " +
          "Another process is keeping the android.app.IRequestFinishCallback\$Stub " +
          "reference alive long after Activity.onDestroyed() has been called, " +
          "causing the activity to leak. " +
          "Fix: You can \"fix\" this leak by overriding Activity.onBackPressed() and calling " +
          "Activity.finishAfterTransition(); instead of super if the activity is task root and the " +
          "fragment stack is empty. " +
          "Tracked here: https://issuetracker.google.com/issues/139738913"
      ) {
        sdkInt == 29
      }
    }