<lambda>null1 package leakcanary
2
3 import android.app.Activity
4 import android.app.Application
5 import android.os.Bundle
6 import android.os.Looper
7 import androidx.annotation.IdRes
8 import androidx.fragment.app.Fragment
9 import androidx.fragment.app.FragmentActivity
10 import androidx.fragment.app.FragmentManager
11 import androidx.lifecycle.ViewModel
12 import androidx.lifecycle.ViewModelProvider
13 import androidx.lifecycle.ViewModelProvider.Factory
14 import androidx.lifecycle.ViewModelStoreOwner
15 import androidx.test.core.app.ApplicationProvider
16 import androidx.test.platform.app.InstrumentationRegistry
17 import androidx.test.rule.ActivityTestRule
18 import java.util.concurrent.CountDownLatch
19 import java.util.concurrent.atomic.AtomicReference
20 import kotlin.reflect.KClass
21 import leakcanary.internal.friendly.noOpDelegate
22
23 interface HasActivityTestRule<T : Activity> {
24 val activityRule: ActivityTestRule<T>
25
26 val activity: T
27 get() = activityRule.activity!!
28 }
29
activityTestRulenull30 inline fun <reified T : Activity> activityTestRule(
31 initialTouchMode: Boolean = false,
32 launchActivity: Boolean = true
33 ): ActivityTestRule<T> = ActivityTestRule(
34 T::class.java, initialTouchMode, launchActivity
35 )
36
37 fun <R> triggersOnActivityCreated(block: () -> R): R {
38 return waitForTriggered(block) { triggered ->
39 val app = ApplicationProvider.getApplicationContext<Application>()
40 app.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks by noOpDelegate() {
41 override fun onActivityCreated(
42 activity: Activity,
43 savedInstanceState: Bundle?
44 ) {
45 app.unregisterActivityLifecycleCallbacks(this)
46 triggered()
47 }
48 })
49 }
50 }
51
retainednull52 infix fun Any.retained(block: () -> Unit) {
53 block()
54 "" + this
55 }
56
triggersOnActivityDestroyednull57 fun <T : FragmentActivity, R> HasActivityTestRule<T>.triggersOnActivityDestroyed(block: () -> R): R {
58 return waitForTriggered(block) { triggered ->
59 val testActivity = activity
60 testActivity.application.registerActivityLifecycleCallbacks(
61 object : Application.ActivityLifecycleCallbacks by noOpDelegate() {
62 override fun onActivityDestroyed(activity: Activity) {
63 if (activity == testActivity) {
64 activity.application.unregisterActivityLifecycleCallbacks(this)
65 Looper.myQueue()
66 .addIdleHandler {
67 triggered()
68 false
69 }
70 }
71 }
72 })
73 }
74 }
75
triggersOnFragmentCreatednull76 fun <T : FragmentActivity, R> HasActivityTestRule<T>.triggersOnFragmentCreated(block: () -> R): R {
77 return waitForTriggered(block) { triggered ->
78 val fragmentManager = activity.supportFragmentManager
79 fragmentManager.registerFragmentLifecycleCallbacks(
80 object : FragmentManager.FragmentLifecycleCallbacks() {
81 override fun onFragmentCreated(
82 fm: FragmentManager,
83 fragment: Fragment,
84 savedInstanceState: Bundle?
85 ) {
86 fragmentManager.unregisterFragmentLifecycleCallbacks(this)
87 triggered()
88 }
89 }, false
90 )
91 }
92 }
93
triggersOnFragmentViewDestroyednull94 fun <T : FragmentActivity, R> HasActivityTestRule<T>.triggersOnFragmentViewDestroyed(block: () -> R): R {
95 return waitForTriggered(block) { triggered ->
96 val fragmentManager = activity.supportFragmentManager
97 fragmentManager.registerFragmentLifecycleCallbacks(
98 object : FragmentManager.FragmentLifecycleCallbacks() {
99 override fun onFragmentViewDestroyed(
100 fm: FragmentManager,
101 fragment: Fragment
102 ) {
103 fragmentManager.unregisterFragmentLifecycleCallbacks(this)
104 triggered()
105 }
106 }, false
107 )
108 }
109 }
110
waitForTriggerednull111 fun <R> waitForTriggered(
112 trigger: () -> R,
113 triggerListener: (triggered: () -> Unit) -> Unit
114 ): R {
115 val latch = CountDownLatch(1)
116 triggerListener {
117 latch.countDown()
118 }
119 val result = trigger()
120 latch.await()
121 return result
122 }
123
getOnMainSyncnull124 fun <T> getOnMainSync(block: () -> T): T {
125 val resultHolder = AtomicReference<T>()
126 val latch = CountDownLatch(1)
127 InstrumentationRegistry.getInstrumentation()
128 .runOnMainSync {
129 resultHolder.set(block())
130 latch.countDown()
131 }
132 latch.await()
133 return resultHolder.get()
134 }
135
runOnMainSyncnull136 fun runOnMainSync(block: () -> Unit) = InstrumentationRegistry.getInstrumentation()
137 .runOnMainSync(block)
138
139 fun <T : ViewModel> ViewModelStoreOwner.installViewModel(modelClass: KClass<T>): T =
140 ViewModelProvider(this, object : Factory {
141 override fun <T : ViewModel> create(modelClass: Class<T>): T = modelClass.newInstance()
142 }).get(modelClass.java)
143
addFragmentNownull144 fun FragmentActivity.addFragmentNow(fragment: Fragment) {
145 supportFragmentManager
146 .beginTransaction()
147 .add(0, fragment)
148 .commitNow()
149 }
150
FragmentActivitynull151 fun FragmentActivity.replaceWithBackStack(
152 fragment: Fragment,
153 @IdRes containerViewId: Int
154 ) {
155 supportFragmentManager
156 .beginTransaction()
157 .addToBackStack(null)
158 .replace(containerViewId, fragment)
159 .commit()
160 }
161
FragmentActivitynull162 fun FragmentActivity.removeFragmentNow(fragment: Fragment) {
163 supportFragmentManager
164 .beginTransaction()
165 .remove(fragment)
166 .commitNow()
167 }
168