<lambda>null1 package com.android.systemui.statusbar.notification.collection.notifcollection
2
3 import android.os.Handler
4 import android.util.ArrayMap
5 import android.util.Log
6 import com.android.systemui.Dumpable
7 import com.android.systemui.statusbar.notification.collection.NotificationEntry
8 import java.io.PrintWriter
9
10 /**
11 * A helpful class that implements the core contract of the lifetime extender internally,
12 * making it easier for coordinators to interact with them
13 */
14 abstract class SelfTrackingLifetimeExtender(
15 private val tag: String,
16 private val name: String,
17 private val debug: Boolean,
18 private val mainHandler: Handler
19 ) : NotifLifetimeExtender, Dumpable {
20 private lateinit var mCallback: NotifLifetimeExtender.OnEndLifetimeExtensionCallback
21 protected val mEntriesExtended = ArrayMap<String, NotificationEntry>()
22 private var mEnding = false
23
24 /**
25 * When debugging, warn if the call is happening during and "end lifetime extension" call.
26 *
27 * Note: this will warn a lot! The pipeline explicitly re-invokes all lifetime extenders
28 * whenever one ends, giving all of them a chance to re-up their lifetime extension.
29 */
30 private fun warnIfEnding() {
31 if (debug && mEnding) Log.w(tag, "reentrant code while ending a lifetime extension")
32 }
33
34 fun endAllLifetimeExtensions() {
35 // clear the map before iterating over a copy of the items, because the pipeline will
36 // always give us another chance to extend the lifetime again, and we don't want
37 // concurrent modification
38 val entries = mEntriesExtended.values.toList()
39 if (debug) Log.d(tag, "$name.endAllLifetimeExtensions() entries=$entries")
40 mEntriesExtended.clear()
41 warnIfEnding()
42 mEnding = true
43 entries.forEach { mCallback.onEndLifetimeExtension(this, it) }
44 mEnding = false
45 }
46
47 fun endLifetimeExtensionAfterDelay(key: String, delayMillis: Long) {
48 if (debug) {
49 Log.d(tag, "$name.endLifetimeExtensionAfterDelay" +
50 "(key=$key, delayMillis=$delayMillis)" +
51 " isExtending=${isExtending(key)}")
52 }
53 if (isExtending(key)) {
54 mainHandler.postDelayed({ endLifetimeExtension(key) }, delayMillis)
55 }
56 }
57
58 fun endLifetimeExtension(key: String) {
59 if (debug) {
60 Log.d(tag, "$name.endLifetimeExtension(key=$key)" +
61 " isExtending=${isExtending(key)}")
62 }
63 warnIfEnding()
64 mEnding = true
65 mEntriesExtended.remove(key)?.let { removedEntry ->
66 mCallback.onEndLifetimeExtension(this, removedEntry)
67 }
68 mEnding = false
69 }
70
71 fun isExtending(key: String) = mEntriesExtended.contains(key)
72
73 final override fun getName(): String = name
74
75 final override fun maybeExtendLifetime(entry: NotificationEntry, reason: Int): Boolean {
76 val shouldExtend = queryShouldExtendLifetime(entry)
77 if (debug) {
78 Log.d(tag, "$name.shouldExtendLifetime(key=${entry.key}, reason=$reason)" +
79 " isExtending=${isExtending(entry.key)}" +
80 " shouldExtend=$shouldExtend")
81 }
82 warnIfEnding()
83 if (shouldExtend && mEntriesExtended.put(entry.key, entry) == null) {
84 onStartedLifetimeExtension(entry)
85 }
86 return shouldExtend
87 }
88
89 final override fun cancelLifetimeExtension(entry: NotificationEntry) {
90 if (debug) {
91 Log.d(tag, "$name.cancelLifetimeExtension(key=${entry.key})" +
92 " isExtending=${isExtending(entry.key)}")
93 }
94 warnIfEnding()
95 mEntriesExtended.remove(entry.key)
96 onCanceledLifetimeExtension(entry)
97 }
98
99 abstract fun queryShouldExtendLifetime(entry: NotificationEntry): Boolean
100 open fun onStartedLifetimeExtension(entry: NotificationEntry) {}
101 open fun onCanceledLifetimeExtension(entry: NotificationEntry) {}
102
103 final override fun setCallback(callback: NotifLifetimeExtender.OnEndLifetimeExtensionCallback) {
104 mCallback = callback
105 }
106
107 final override fun dump(pw: PrintWriter, args: Array<out String>) {
108 pw.println("LifetimeExtender: $name:")
109 pw.println(" mEntriesExtended: ${mEntriesExtended.size}")
110 mEntriesExtended.forEach { pw.println(" * ${it.key}") }
111 }
112 }