Repository: square/leakcanary
File: leakcanary-android-core/src/main/java/leakcanary/internal/InternalLeakCanary.kt (Kotlin)

Code before:
        application, backgroundHandler, AppWatcher.objectWatcher, gcTrigger, heapDumper,
        configProvider
    )
    application.registerVisibilityListener { applicationVisible ->
      this.applicationVisible = applicationVisible
      heapDumpTrigger.onApplicationVisibilityChanged(applicationVisible)
    }
    registerResumedActivityListener(application)
    addDynamicShortcut(application)

    disableDumpHeapInTests()
  }

  private fun checkAllowInNonDebuggableBuild() {
    if (AppWatcher.isDebuggableBuild) {
      return
    }

    if (application.resources.getBoolean(R.bool.leak_canary_allow_in_non_debuggable_build)) {
      // AppWatcher is disabled by default for non-debuggable builds, but we have a developer opt-in.
      AppWatcher.config = AppWatcher.config.copy(enabled = true)
    } else {
      throw Error("""
        LeakCanary in non-debuggable build
        
        LeakCanary should only be used in debug builds, but this APK is not marked as debuggable.
        Please follow the instructions on the "Getting started" page to only include LeakCanary in
        debug builds: https://square.github.io/leakcanary/getting_started/
        
        If you're sure you want to include LeakCanary in a non-debuggable build, you can disable this
        check by overriding the bool/leak_canary_allow_in_non_debuggable_build resource and setting
        the value to 'true'.
      """.trimIndent())
    }
  }

  private fun registerResumedActivityListener(application: Application) {
    application.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks by noOpDelegate() {
      override fun onActivityResumed(activity: Activity) {
        resumedActivity = activity
      }

      override fun onActivityPaused(activity: Activity) {
        if (resumedActivity === activity) {
          resumedActivity = null
        }
      }
    })
  }

  private fun disableDumpHeapInTests() {

Review comment (bug):
> not marked as debuggable

Maybe just `not debuggable` ?

Code after:
    val handlerThread = HandlerThread(LEAK_CANARY_THREAD_NAME)
    handlerThread.start()
    val backgroundHandler = Handler(handlerThread.looper)

    heapDumpTrigger = HeapDumpTrigger(
        application, backgroundHandler, AppWatcher.objectWatcher, gcTrigger, heapDumper,
        configProvider
    )
    application.registerVisibilityListener { applicationVisible ->
      this.applicationVisible = applicationVisible
      heapDumpTrigger.onApplicationVisibilityChanged(applicationVisible)
    }
    registerResumedActivityListener(application)
    addDynamicShortcut(application)

    disableDumpHeapInTests()
  }

  private fun checkRunningInDebuggableBuild() {
    if (isDebuggableBuild) {
      return
    }

    if (application.resources.getBoolean(R.bool.leak_canary_allow_in_non_debuggable_build)) {
      // AppWatcher is disabled by default for non-debuggable builds, but we have a developer opt-in.
      AppWatcher.config = AppWatcher.config.copy(enabled = true)
    } else {
      throw Error("""
        LeakCanary in non-debuggable build
        
        LeakCanary should only be used in debug builds, but this APK is not debuggable.
        Please follow the instructions on the "Getting started" page to only include LeakCanary in
        debug builds: https://square.github.io/leakcanary/getting_started/
        
        If you're sure you want to include LeakCanary in a non-debuggable build, follow the 
        instructions here: https://square.github.io/leakcanary/recipes/#leakcanary-in-release-builds
      """.trimIndent())
    }
  }

  private fun registerResumedActivityListener(application: Application) {
    application.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks by noOpDelegate() {
      override fun onActivityResumed(activity: Activity) {
        resumedActivity = activity
      }

      override fun onActivityPaused(activity: Activity) {
        if (resumedActivity === activity) {
          resumedActivity = null
        }
      }