<lambda>null1 package leakcanary
2 
3 import android.app.Application
4 import android.content.BroadcastReceiver
5 import android.content.Context
6 import android.content.Intent
7 import android.content.Intent.ACTION_SCREEN_OFF
8 import android.content.Intent.ACTION_SCREEN_ON
9 import android.content.IntentFilter
10 import android.os.Build
11 import java.util.concurrent.Executor
12 import leakcanary.internal.friendly.checkMainThread
13 import shark.SharkLog
14 
15 class ScreenOffTrigger(
16   private val application: Application,
17   private val analysisClient: HeapAnalysisClient,
18   /**
19    * The executor on which the analysis is performed and on which [analysisCallback] is called.
20    * This should likely be a single thread executor with a background thread priority.
21    */
22   private val analysisExecutor: Executor,
23 
24   /**
25    * Called back with a [HeapAnalysisJob.Result] after the screen went off and a
26    * heap analysis was attempted. This is called on the same thread that the analysis was
27    * performed on.
28    *
29    * Defaults to logging to [SharkLog] (don't forget to set [SharkLog.logger] if you do want to see
30    * logs).
31    */
32   private val analysisCallback: (HeapAnalysisJob.Result) -> Unit = { result ->
33     SharkLog.d { "$result" }
34   },
35 ) {
36 
37   @Volatile
38   private var currentJob: HeapAnalysisJob? = null
39 
40   private val screenReceiver = object : BroadcastReceiver() {
onReceivenull41     override fun onReceive(
42       context: Context,
43       intent: Intent
44     ) {
45       if (intent.action == ACTION_SCREEN_OFF) {
46         if (currentJob == null) {
47           val job =
48             analysisClient.newJob(JobContext(ScreenOffTrigger::class))
49           currentJob = job
50           analysisExecutor.execute {
51             val result = job.execute()
52             currentJob = null
53             analysisCallback(result)
54           }
55         }
56       } else {
57         currentJob?.cancel("screen on again")
58         currentJob = null
59       }
60     }
61   }
62 
startnull63   fun start() {
64     checkMainThread()
65     val intentFilter = IntentFilter().apply {
66       addAction(ACTION_SCREEN_ON)
67       addAction(ACTION_SCREEN_OFF)
68     }
69     if (Build.VERSION.SDK_INT >= 33) {
70       val flags = Context.RECEIVER_EXPORTED
71       application.registerReceiver(screenReceiver, intentFilter, flags)
72     } else {
73       application.registerReceiver(screenReceiver, intentFilter)
74     }
75   }
76 
stopnull77   fun stop() {
78     checkMainThread()
79     application.unregisterReceiver(screenReceiver)
80   }
81 }
82