1 /*
2  * Copyright (C) 2018 Square, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package leakcanary.internal
17 
18 import android.app.Activity
19 import android.os.Bundle
20 import androidx.fragment.app.Fragment
21 import androidx.fragment.app.FragmentActivity
22 import androidx.fragment.app.FragmentManager
23 import leakcanary.ReachabilityWatcher
24 
25 internal class AndroidXFragmentDestroyWatcher(
26   private val reachabilityWatcher: ReachabilityWatcher
27 ) : (Activity) -> Unit {
28 
29   private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {
30 
onFragmentCreatednull31     override fun onFragmentCreated(
32       fm: FragmentManager,
33       fragment: Fragment,
34       savedInstanceState: Bundle?
35     ) {
36       ViewModelClearedWatcher.install(fragment, reachabilityWatcher)
37     }
38 
onFragmentViewDestroyednull39     override fun onFragmentViewDestroyed(
40       fm: FragmentManager,
41       fragment: Fragment
42     ) {
43       val view = fragment.view
44       if (view != null) {
45         reachabilityWatcher.expectWeaklyReachable(
46           view, "${fragment::class.java.name} received Fragment#onDestroyView() callback " +
47           "(references to its views should be cleared to prevent leaks)"
48         )
49       }
50     }
51 
onFragmentDestroyednull52     override fun onFragmentDestroyed(
53       fm: FragmentManager,
54       fragment: Fragment
55     ) {
56       reachabilityWatcher.expectWeaklyReachable(
57         fragment, "${fragment::class.java.name} received Fragment#onDestroy() callback"
58       )
59     }
60   }
61 
invokenull62   override fun invoke(activity: Activity) {
63     if (activity is FragmentActivity) {
64       val supportFragmentManager = activity.supportFragmentManager
65       supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
66       ViewModelClearedWatcher.install(activity, reachabilityWatcher)
67     }
68   }
69 }
70