<lambda>null1package leakcanary 2 3 import android.app.Application 4 import android.os.StrictMode 5 import android.os.StrictMode.ThreadPolicy 6 import androidx.test.platform.app.InstrumentationRegistry 7 import org.assertj.core.api.Assertions.assertThat 8 import org.junit.Test 9 10 class ManualInstallTest { 11 12 private val application: Application 13 get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application 14 15 @Test fun appWatcher_is_not_installed() { 16 assertThat(AppWatcher.isInstalled).isFalse() 17 } 18 19 @Test fun can_update_LeakCanary_config_without_installing() = tryAndRestoreConfig { 20 LeakCanary.config = LeakCanary.config.copy(dumpHeap = LeakCanary.config.dumpHeap) 21 } 22 23 @Test fun no_thread_policy_violations_on_install() { 24 runOnMainSyncRethrowing { 25 throwOnAnyThreadPolicyViolation { 26 AppWatcher.manualInstall(application) 27 } 28 } 29 } 30 31 @Test fun no_thread_policy_violations_on_config_update() { 32 runOnMainSyncRethrowing { 33 throwOnAnyThreadPolicyViolation { 34 LeakCanary.config = LeakCanary.config.copy(dumpHeap = LeakCanary.config.dumpHeap) 35 } 36 } 37 } 38 39 @Test fun no_thread_policy_violations_on_install_then_config_update() { 40 runOnMainSyncRethrowing { 41 throwOnAnyThreadPolicyViolation { 42 AppWatcher.manualInstall(application) 43 LeakCanary.config = LeakCanary.config.copy(dumpHeap = LeakCanary.config.dumpHeap) 44 } 45 } 46 } 47 48 @Test fun no_thread_policy_violations_on_config_update_then_install() { 49 runOnMainSyncRethrowing { 50 throwOnAnyThreadPolicyViolation { 51 LeakCanary.config = LeakCanary.config.copy(dumpHeap = LeakCanary.config.dumpHeap) 52 AppWatcher.manualInstall(application) 53 } 54 } 55 } 56 57 private fun throwOnAnyThreadPolicyViolation(block: () -> Unit) { 58 val previousThreadPolicy = StrictMode.getThreadPolicy() 59 try { 60 StrictMode.setThreadPolicy( 61 ThreadPolicy.Builder() 62 .detectAll() 63 .penaltyDeath() 64 .build() 65 ) 66 block() 67 } finally { 68 StrictMode.setThreadPolicy(previousThreadPolicy) 69 } 70 } 71 72 private fun runOnMainSyncRethrowing(block: () -> Unit) { 73 var mainThreadThrowable: Throwable? = null 74 val instrumentation = InstrumentationRegistry.getInstrumentation() 75 instrumentation.runOnMainSync { 76 try { 77 block() 78 } catch (throwable: Throwable) { 79 mainThreadThrowable = throwable 80 } 81 } 82 mainThreadThrowable?.let { cause -> 83 throw cause 84 } 85 } 86 } 87 88 89